windowManager: Replace custom shader with builtin ClutterEffects

While modal dialogs were attached to the parent's titlebar, it
made sense to leave the top of the parent window at full color.
With the new position of modal dialogs, it makes more sense to dim
the entire parent window, so we can use a combination of Clutter's
BrightnessContrast- and DesaturateEffect instead of our own custom
shader.

https://bugzilla.gnome.org/show_bug.cgi?id=674499
This commit is contained in:
Florian Müllner 2012-07-13 19:57:36 +02:00
parent 04570ac783
commit c671ff74c6
5 changed files with 31 additions and 107 deletions

View File

@ -73,17 +73,11 @@ all-local: gschemas.compiled
convertdir = $(datadir)/GConf/gsettings
convert_DATA = gnome-shell-overrides.convert
shadersdir = $(pkgdatadir)/shaders
shaders_DATA = \
shaders/dim-window.glsl
EXTRA_DIST = \
gnome-shell.desktop.in.in \
gnome-shell-extension-prefs.desktop.in.in \
$(introspection_DATA) \
$(menu_DATA) \
$(shaders_DATA) \
$(convert_DATA) \
org.gnome.shell.gschema.xml.in.in

View File

@ -1,27 +0,0 @@
#version 110
uniform sampler2D tex;
uniform float fraction;
uniform float height;
const float c = -0.2;
const float border_max_height = 60.0;
mat4 contrast = mat4 (1.0 + c, 0.0, 0.0, 0.0,
0.0, 1.0 + c, 0.0, 0.0,
0.0, 0.0, 1.0 + c, 0.0,
0.0, 0.0, 0.0, 1.0);
vec4 off = vec4(0.633, 0.633, 0.633, 0);
void main()
{
vec4 color = texture2D(tex, cogl_tex_coord_in[0].xy);
float y = height * cogl_tex_coord_in[0].y;
// To reduce contrast, blend with a mid gray
cogl_color_out = color * contrast - off * c * color.a;
// 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
// interpolate back to the original undimmed color, so the top of the window
// is at full color.
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;
}

View File

@ -15,59 +15,38 @@ const Tweener = imports.ui.tweener;
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
const WINDOW_ANIMATION_TIME = 0.25;
const DIM_DESATURATION = 0.6;
const DIM_BRIGHTNESS = -0.1;
const DIM_TIME = 0.500;
const UNDIM_TIME = 0.250;
var dimShader = undefined;
function getDimShaderSource() {
if (!dimShader)
dimShader = Shell.get_file_contents_utf8_sync(global.datadir + '/shaders/dim-window.glsl');
return dimShader;
}
const WindowDimmer = new Lang.Class({
Name: 'WindowDimmer',
_init: function(actor) {
if (Clutter.feature_available(Clutter.FeatureFlags.SHADERS_GLSL)) {
this._effect = new Clutter.ShaderEffect({ shader_type: Clutter.ShaderType.FRAGMENT_SHADER });
this._effect.set_shader_source(getDimShaderSource());
} else {
this._effect = null;
}
this._desaturateEffect = new Clutter.DesaturateEffect();
this._brightnessEffect = new Clutter.BrightnessContrastEffect();
actor.add_effect(this._desaturateEffect);
actor.add_effect(this._brightnessEffect);
this.actor = actor;
this._dimFactor = 0.0;
},
set dimFraction(fraction) {
this._dimFraction = fraction;
setEnabled: function(enabled) {
this._desaturateEffect.enabled = enabled;
this._brightnessEffect.enabled = enabled;
},
if (this._effect == null)
return;
set dimFactor(factor) {
this._dimFactor = factor;
this._desaturateEffect.set_factor(factor * DIM_DESATURATION);
this._brightnessEffect.set_brightness(factor * DIM_BRIGHTNESS);
},
if (!Meta.prefs_get_attach_modal_dialogs()) {
this._effect.enabled = false;
return;
get dimFactor() {
return this._dimFactor;
}
if (fraction > 0.01) {
Shell.shader_effect_set_double_uniform(this._effect, 'height', this.actor.get_height());
Shell.shader_effect_set_double_uniform(this._effect, 'fraction', fraction);
if (!this._effect.actor)
this.actor.add_effect(this._effect);
} else {
if (this._effect.actor)
this.actor.remove_effect(this._effect);
}
},
get dimFraction() {
return this._dimFraction;
},
_dimFraction: 0.0
});
function getWindowDimmer(actor) {
@ -280,8 +259,13 @@ const WindowManager = new Lang.Class({
let actor = window.get_compositor_private();
if (!actor)
return;
Tweener.addTween(getWindowDimmer(actor),
{ dimFraction: 1.0,
let dimmer = getWindowDimmer(actor);
let enabled = Meta.prefs_get_attach_modal_dialogs();
dimmer.setEnabled(enabled);
if (!enabled)
return;
Tweener.addTween(dimmer,
{ dimFactor: 1.0,
time: DIM_TIME,
transition: 'linear'
});
@ -291,8 +275,13 @@ const WindowManager = new Lang.Class({
let actor = window.get_compositor_private();
if (!actor)
return;
Tweener.addTween(getWindowDimmer(actor),
{ dimFraction: 0.0,
let dimmer = getWindowDimmer(actor);
let enabled = Meta.prefs_get_attach_modal_dialogs();
dimmer.setEnabled(enabled);
if (!enabled)
return;
Tweener.addTween(dimmer,
{ dimFactor: 0.0,
time: UNDIM_TIME,
transition: 'linear'
});

View File

@ -773,34 +773,6 @@ shell_parse_search_provider (const char *data,
return FALSE;
}
/**
* shell_shader_effect_set_double_uniform:
* @effect: The #ClutterShaderEffect
* @name: The name of the uniform
* @value: The value to set it to.
*
* Set a double uniform on a ClutterShaderEffect.
*
* The problem here is that JavaScript doesn't have more than
* one number type, and gjs tries to automatically guess what
* type we want to set a GValue to. If the number is "1.0" or
* something, it will use an integer, which will cause errors
* in GLSL.
*/
void
shell_shader_effect_set_double_uniform (ClutterShaderEffect *effect,
const gchar *name,
gdouble value)
{
GValue gvalue = G_VALUE_INIT;
g_value_init (&gvalue, G_TYPE_DOUBLE);
g_value_set_double (&gvalue, value);
clutter_shader_effect_set_uniform_value (effect,
name,
&gvalue);
}
/**
* shell_session_is_active_for_systemd:
*

View File

@ -39,10 +39,6 @@ gboolean shell_parse_search_provider (const char *data,
char **icon_data_uri,
GError **error);
void shell_shader_effect_set_double_uniform (ClutterShaderEffect *effect,
const gchar *name,
gdouble value);
gboolean shell_session_is_active_for_systemd (void);
gboolean shell_util_wifexited (int status,