windowManager: shade the actor, not the texture

Applying the "dim window" effect to the MetaWindowActor has two avantages:
first it avoids triggering bugs where ClutterOffscreenEffect doesn't handle
clone paint correctly. Second, it avoids showing the window as dimmed in
alt-Tab and the overview, which is weird.

The small downside of this is that the shadow becomes slightly gray when
the window dimmed, which is wrong - if we switched from blending with gray
to a combination of desaturation and darkening, this problem wouldn't
happen.

Revert out the addition of startY to the shader, since we don't need it
and fix the application of alpha, since we need to handle alpha correctly
for the shadow.

https://bugzilla.gnome.org/show_bug.cgi?id=659634
This commit is contained in:
Owen W. Taylor 2011-09-20 14:21:45 -04:00
parent 526a53bdd4
commit fb30822860
2 changed files with 14 additions and 21 deletions

View File

@ -1,6 +1,5 @@
#version 110 #version 110
uniform sampler2D tex; uniform sampler2D tex;
uniform float startY;
uniform float fraction; uniform float fraction;
uniform float height; uniform float height;
const float c = -0.2; const float c = -0.2;
@ -17,14 +16,12 @@ void main()
float y = height * cogl_tex_coord_in[0].y; float y = height * cogl_tex_coord_in[0].y;
// To reduce contrast, blend with a mid gray // To reduce contrast, blend with a mid gray
cogl_color_out = color * contrast - off * c; cogl_color_out = color * contrast - off * c * color.a;
// We only fully dim at a distance of BORDER_MAX_HEIGHT from startY and // We only fully dim at a distance of BORDER_MAX_HEIGHT from the top and
// when the fraction is 1.0. For other locations and fractions we linearly // when the fraction is 1.0. For other locations and fractions we linearly
// interpolate back to the original undimmed color, so the top of the window // interpolate back to the original undimmed color, so the top of the window
// is at full color. // is at full color.
cogl_color_out = color + (cogl_color_out - color) * max(min((y - startY) / border_max_height, 1.0), 0.0); cogl_color_out = color + (cogl_color_out - color) * max(min(y / border_max_height, 1.0), 0.0);
cogl_color_out = color + (cogl_color_out - color) * fraction; cogl_color_out = color + (cogl_color_out - color) * fraction;
cogl_color_out *= color.a;
} }

View File

@ -31,16 +31,15 @@ function getTopInvisibleBorder(metaWindow) {
return outerRect.y - inputRect.y; return outerRect.y - inputRect.y;
} }
function WindowDimmer(actor, window) { function WindowDimmer(actor) {
this._init(actor, window); this._init(actor);
} }
WindowDimmer.prototype = { WindowDimmer.prototype = {
_init: function(actor, window) { _init: function(actor) {
this.effect = new Clutter.ShaderEffect({ shader_type: Clutter.ShaderType.FRAGMENT_SHADER }); this.effect = new Clutter.ShaderEffect({ shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
this.effect.set_shader_source(getDimShaderSource()); this.effect.set_shader_source(getDimShaderSource());
this.window = window;
this.actor = actor; this.actor = actor;
}, },
@ -52,7 +51,6 @@ WindowDimmer.prototype = {
} }
if (fraction > 0.01) { if (fraction > 0.01) {
Shell.shader_effect_set_double_uniform(this.effect, 'startY', getTopInvisibleBorder(this.window));
Shell.shader_effect_set_double_uniform(this.effect, 'height', this.actor.get_height()); Shell.shader_effect_set_double_uniform(this.effect, 'height', this.actor.get_height());
Shell.shader_effect_set_double_uniform(this.effect, 'fraction', fraction); Shell.shader_effect_set_double_uniform(this.effect, 'fraction', fraction);
@ -71,11 +69,11 @@ WindowDimmer.prototype = {
_dimFraction: 0.0 _dimFraction: 0.0
}; };
function getWindowDimmer(texture, window) { function getWindowDimmer(actor) {
if (!texture._windowDimmer) if (!actor._windowDimmer)
texture._windowDimmer = new WindowDimmer(texture, window); actor._windowDimmer = new WindowDimmer(actor);
return texture._windowDimmer; return actor._windowDimmer;
} }
function WindowManager() { function WindowManager() {
@ -270,30 +268,28 @@ WindowManager.prototype = {
let actor = window.get_compositor_private(); let actor = window.get_compositor_private();
if (!actor) if (!actor)
return; return;
let texture = actor.get_texture();
if (animate) if (animate)
Tweener.addTween(getWindowDimmer(texture, window), Tweener.addTween(getWindowDimmer(actor),
{ dimFraction: 1.0, { dimFraction: 1.0,
time: DIM_TIME, time: DIM_TIME,
transition: 'linear' transition: 'linear'
}); });
else else
getWindowDimmer(texture, window).dimFraction = 1.0; getWindowDimmer(actor).dimFraction = 1.0;
}, },
_undimWindow: function(window, animate) { _undimWindow: function(window, animate) {
let actor = window.get_compositor_private(); let actor = window.get_compositor_private();
if (!actor) if (!actor)
return; return;
let texture = actor.get_texture();
if (animate) if (animate)
Tweener.addTween(getWindowDimmer(texture, window), Tweener.addTween(getWindowDimmer(actor),
{ dimFraction: 0.0, { dimFraction: 0.0,
time: UNDIM_TIME, time: UNDIM_TIME,
transition: 'linear' transition: 'linear'
}); });
else else
getWindowDimmer(texture, window).dimFraction = 0.0; getWindowDimmer(actor).dimFraction = 0.0;
}, },
_mapWindow : function(shellwm, actor) { _mapWindow : function(shellwm, actor) {