Merge lp:~diego-rocha-comp/wingpanel/fix-1473563 into lp:~wingpanel-devs/wingpanel/trunk

Proposed by Diego Rocha
Status: Merged
Approved by: Cody Garver
Approved revision: 109
Merged at revision: 109
Proposed branch: lp:~diego-rocha-comp/wingpanel/fix-1473563
Merge into: lp:~wingpanel-devs/wingpanel/trunk
Diff against target: 342 lines (+102/-51)
6 files modified
src/Services/BackgroundManager.vala (+3/-2)
src/Widgets/Panel.vala (+9/-2)
wingpanel-interface/BackgroundManager.vala (+54/-14)
wingpanel-interface/CMakeLists.txt (+1/-1)
wingpanel-interface/DBusServer.vala (+4/-4)
wingpanel-interface/Utils.vala (+31/-28)
To merge this branch: bzr merge lp:~diego-rocha-comp/wingpanel/fix-1473563
Reviewer Review Type Date Requested Status
WingPanel Devs Pending
Review via email: mp+286452@code.launchpad.net

Commit message

Improve the logic used to define the panel's style by accounting for luminance, contrast and sharpness, and adding the TRANSLUCENT state.

This new state is used when the desktop wallpaper is complex or has high contrast.

Description of the change

Improves the logic used to define the panel's style by accounting for luminance, contrast and sharpness, and adding the TRANSLUCENT state.

This new state is used when the desktop wallpaper is complex or has high contrast.

Depends on https://code.launchpad.net/~diego-rocha-comp/egtk/fix-1473563/+merge/286451

To post a comment you must log in.
108. By Diego Rocha

backgroundmanager: added TRANSLUCENT state and improved state selection logic

109. By Diego Rocha

backgroundmanager: load background color information before checking for initial state

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/Services/BackgroundManager.vala'
2--- src/Services/BackgroundManager.vala 2015-12-02 20:52:48 +0000
3+++ src/Services/BackgroundManager.vala 2016-02-19 22:10:36 +0000
4@@ -21,7 +21,8 @@
5 public enum BackgroundState {
6 LIGHT,
7 DARK,
8- MAXIMIZED
9+ MAXIMIZED,
10+ TRANSLUCENT
11 }
12
13 [DBus (name = "org.pantheon.gala.WingpanelInterface")]
14@@ -113,4 +114,4 @@
15 return instance;
16 }
17 }
18-}
19\ No newline at end of file
20+}
21
22=== modified file 'src/Widgets/Panel.vala'
23--- src/Widgets/Panel.vala 2015-10-21 21:48:36 +0000
24+++ src/Widgets/Panel.vala 2016-02-19 22:10:36 +0000
25@@ -18,8 +18,6 @@
26 */
27
28 public class Wingpanel.Widgets.Panel : Gtk.Box {
29- private static const double ALPHA_ANIMATION_STEP = 0.05;
30-
31 public Services.PopoverManager popover_manager { get; construct; }
32
33 private IndicatorMenuBar right_menubar;
34@@ -126,16 +124,25 @@
35 style_context.add_class ("color-light");
36 style_context.remove_class ("color-dark");
37 style_context.remove_class ("maximized");
38+ style_context.remove_class ("translucent");
39 break;
40 case Services.BackgroundState.LIGHT:
41 style_context.add_class ("color-dark");
42 style_context.remove_class ("color-light");
43 style_context.remove_class ("maximized");
44+ style_context.remove_class ("translucent");
45 break;
46 case Services.BackgroundState.MAXIMIZED:
47 style_context.add_class ("maximized");
48 style_context.remove_class ("color-light");
49 style_context.remove_class ("color-dark");
50+ style_context.remove_class ("translucent");
51+ break;
52+ case Services.BackgroundState.TRANSLUCENT:
53+ style_context.add_class ("translucent");
54+ style_context.remove_class ("color-light");
55+ style_context.remove_class ("color-dark");
56+ style_context.remove_class ("maximized");
57 break;
58 }
59 }
60
61=== renamed file 'wingpanel-interface/AlphaManager.vala' => 'wingpanel-interface/BackgroundManager.vala'
62--- wingpanel-interface/AlphaManager.vala 2015-12-02 20:28:08 +0000
63+++ wingpanel-interface/BackgroundManager.vala 2016-02-19 22:10:36 +0000
64@@ -20,11 +20,15 @@
65 public enum BackgroundState {
66 LIGHT,
67 DARK,
68- MAXIMIZED
69+ MAXIMIZED,
70+ TRANSLUCENT
71 }
72
73-public class WingpanelInterface.AlphaManager : Object {
74+public class WingpanelInterface.BackgroundManager : Object {
75 private const int WALLPAPER_TRANSITION_DURATION = 150;
76+ private const double ACUTANCE_THRESHOLD = 8;
77+ private const double STD_THRESHOLD = 45;
78+ private const double LUMINANCE_THRESHOLD = 180;
79
80 public signal void state_changed (BackgroundState state, uint animation_duration);
81
82@@ -36,16 +40,20 @@
83 private Meta.Workspace? current_workspace = null;
84
85 private BackgroundState current_state = BackgroundState.LIGHT;
86- private bool needs_dark_background = false;
87+
88+ private Utils.ColorInformation? bk_color_info = null;
89
90- public AlphaManager (int monitor, int panel_height) {
91+ public BackgroundManager (int monitor, int panel_height) {
92 Object (monitor : monitor, panel_height: panel_height);
93
94 connect_signals ();
95- update_current_workspace ();
96+ update_bk_color_info.begin ((obj, res) => {
97+ update_bk_color_info.end (res);
98+ update_current_workspace ();
99+ });
100 }
101
102- ~AlphaManager () {
103+ ~BackgroundManager () {
104 var signal_id = GLib.Signal.lookup ("changed", Main.wm.background_group.get_type ());
105 GLib.Signal.remove_emission_hook (signal_id, wallpaper_hook_id);
106 }
107@@ -58,7 +66,10 @@
108 var signal_id = GLib.Signal.lookup ("changed", Main.wm.background_group.get_type ());
109
110 wallpaper_hook_id = GLib.Signal.add_emission_hook (signal_id, 0, (ihint, param_values) => {
111- update_alpha_state.begin ();
112+ update_bk_color_info.begin ((obj, res) => {
113+ update_bk_color_info.end (res);
114+ check_for_state_change (WALLPAPER_TRANSITION_DURATION);
115+ });
116
117 return true;
118 }, null);
119@@ -112,14 +123,35 @@
120 check_for_state_change (AnimationSettings.get_default ().snap_duration);
121 }
122
123- public async void update_alpha_state () {
124- Utils.background_needed.begin (Main.wm, monitor, panel_height, (obj, res) => {
125- needs_dark_background = Utils.background_needed.end (res);
126-
127- check_for_state_change (WALLPAPER_TRANSITION_DURATION);
128+ public async void update_bk_color_info () {
129+ SourceFunc callback = update_bk_color_info.callback;
130+ Gdk.Rectangle monitor_geometry;
131+
132+ Gdk.Screen.get_default ().get_monitor_geometry (monitor, out monitor_geometry);
133+
134+ Utils.get_background_color_information.begin (Main.wm, monitor, 0, 0, monitor_geometry.width, panel_height, (obj, res) => {
135+ try {
136+ bk_color_info = Utils.get_background_color_information.end (res);
137+ } catch (Error e) {
138+ warning (e.message);
139+ } finally {
140+ callback ();
141+ }
142 });
143+
144+ yield;
145 }
146
147+ /**
148+ * Check if Wingpanel's background state should change.
149+ *
150+ * The state is defined as follows:
151+ * - If there's a maximized window, the state should be MAXIMIZED;
152+ * - If no information about the background could be gathered, it should be TRANSLUCENT;
153+ * - If there's too much contrast or sharpness, it should be TRANSLUCENT;
154+ * - If the background is too bright, it should be DARK;
155+ * - Else it should be LIGHT.
156+ */
157 private void check_for_state_change (uint animation_duration) {
158 bool has_maximized_window = false;
159
160@@ -136,12 +168,20 @@
161
162 if (has_maximized_window) {
163 new_state = BackgroundState.MAXIMIZED;
164+ } else if (bk_color_info == null) {
165+ new_state = BackgroundState.TRANSLUCENT;
166 } else {
167- new_state = needs_dark_background ? BackgroundState.DARK : BackgroundState.LIGHT;
168+ var luminance_std = Math.sqrt (bk_color_info.luminance_variance);
169+
170+ new_state = luminance_std > STD_THRESHOLD ||
171+ (bk_color_info.mean_luminance < LUMINANCE_THRESHOLD &&
172+ bk_color_info.mean_luminance + 1.645 * luminance_std > LUMINANCE_THRESHOLD ) ||
173+ bk_color_info.mean_acutance > ACUTANCE_THRESHOLD ? BackgroundState.TRANSLUCENT :
174+ bk_color_info.mean_luminance > LUMINANCE_THRESHOLD ? BackgroundState.DARK : BackgroundState.LIGHT;
175 }
176
177 if (new_state != current_state) {
178 state_changed (current_state = new_state, animation_duration);
179 }
180 }
181-}
182\ No newline at end of file
183+}
184
185=== modified file 'wingpanel-interface/CMakeLists.txt'
186--- wingpanel-interface/CMakeLists.txt 2015-05-25 16:19:07 +0000
187+++ wingpanel-interface/CMakeLists.txt 2016-02-19 22:10:36 +0000
188@@ -14,7 +14,7 @@
189 vala_precompile (VALA_C ${WINGPANELINTERFACE}
190 Main.vala
191 DBusServer.vala
192- AlphaManager.vala
193+ BackgroundManager.vala
194 FocusManager.vala
195 Settings.vala
196 Utils.vala
197
198=== modified file 'wingpanel-interface/DBusServer.vala'
199--- wingpanel-interface/DBusServer.vala 2015-10-20 23:43:37 +0000
200+++ wingpanel-interface/DBusServer.vala 2016-02-19 22:10:36 +0000
201@@ -19,13 +19,13 @@
202
203 [DBus (name = "org.pantheon.gala.WingpanelInterface")]
204 public class WingpanelInterface.DBusServer : Object {
205- private AlphaManager alpha_manager;
206+ private BackgroundManager background_manager;
207
208 public signal void state_changed (BackgroundState state, uint animation_duration);
209
210 public void initialize (int monitor, int panel_height) {
211- alpha_manager = new AlphaManager (monitor, panel_height);
212- alpha_manager.state_changed.connect ((state, animation_duration) => {
213+ background_manager = new BackgroundManager (monitor, panel_height);
214+ background_manager.state_changed.connect ((state, animation_duration) => {
215 state_changed (state, animation_duration);
216 });
217 }
218@@ -37,4 +37,4 @@
219 public void restore_focused_window () {
220 FocusManager.get_default ().restore_focused_window ();
221 }
222-}
223\ No newline at end of file
224+}
225
226=== modified file 'wingpanel-interface/Utils.vala'
227--- wingpanel-interface/Utils.vala 2015-10-20 14:07:04 +0000
228+++ wingpanel-interface/Utils.vala 2016-02-19 22:10:36 +0000
229@@ -25,8 +25,6 @@
230 namespace WingpanelInterface.Utils {
231 private const double SATURATION_WEIGHT = 1.5;
232 private const double WEIGHT_THRESHOLD = 1.0;
233- private const double MIN_VARIANCE = 50;
234- private const double MIN_LUM = 25;
235
236 private class DummyOffscreenEffect : Clutter.OffscreenEffect {
237 public signal void done_painting ();
238@@ -41,8 +39,9 @@
239 double average_red;
240 double average_green;
241 double average_blue;
242- double mean;
243- double variance;
244+ double mean_luminance;
245+ double luminance_variance;
246+ double mean_acutance;
247 }
248
249 public async ColorInformation get_background_color_information (Gala.WindowManager wm, int monitor,
250@@ -68,7 +67,7 @@
251 throw new DBusError.INVALID_ARGS ("Invalid rectangle specified: %i, %i, %i, %i".printf (x_start, y_start, width, height));
252 }
253
254- double variance = 0, mean = 0, rTotal = 0, gTotal = 0, bTotal = 0;
255+ double mean_acutance = 0, variance = 0, mean = 0, rTotal = 0, gTotal = 0, bTotal = 0;
256 ulong paint_signal_handler = 0;
257
258 paint_signal_handler = effect.done_painting.connect (() => {
259@@ -77,6 +76,7 @@
260
261 var texture = (Cogl.Texture)effect.get_texture ();
262 var pixels = new uint8[texture.get_width () * texture.get_height () * 4];
263+ var pixel_lums = new double[texture.get_width () * texture.get_height ()];
264
265 CoglFixes.texture_get_data (texture, Cogl.PixelFormat.BGRA_8888_PRE, 0, pixels);
266
267@@ -100,7 +100,9 @@
268 uint8 g = pixels[i + 1];
269 uint8 b = pixels[i + 2];
270
271- pixel = (0.3 * r + 0.6 * g + 0.11 * b) - 128f;
272+ pixel = (0.3 * r + 0.59 * g + 0.11 * b) ;
273+
274+ pixel_lums[y * width + x] = pixel;
275
276 min = uint8.min (r, uint8.min (g, b));
277 max = uint8.max (r, uint8.max (g, b));
278@@ -123,6 +125,21 @@
279 mean_squares += pixel * pixel;
280 }
281 }
282+
283+ for (int y = y_start + 1; y < height - 1; y++) {
284+ for (int x = x_start + 1; x < width - 1; x++) {
285+ var acutance =
286+ (pixel_lums[y * width + x] * 4) -
287+ (
288+ pixel_lums[y * width + x - 1] +
289+ pixel_lums[y * width + x + 1] +
290+ pixel_lums[(y - 1) * width + x] +
291+ pixel_lums[(y + 1) * width + x]
292+ );
293+
294+ mean_acutance += acutance > 0 ? acutance : -acutance;
295+ }
296+ }
297
298 scoreTotal /= size;
299 bTotal /= size;
300@@ -163,9 +180,11 @@
301 }
302
303 mean /= size;
304- mean_squares *= mean_squares / size;
305+ mean_squares = mean_squares / size;
306
307- variance = Math.sqrt (mean_squares - mean * mean) / (double)size;
308+ variance = (mean_squares - (mean * mean));
309+
310+ mean_acutance /= (width - 2) * (height - 2);
311
312 get_background_color_information.callback ();
313 });
314@@ -174,23 +193,7 @@
315
316 yield;
317
318- return { rTotal, gTotal, bTotal, mean, variance };
319- }
320-
321- public async bool background_needed (Gala.WindowManager wm, int screen, int panel_height) {
322- Gdk.Rectangle monitor_geometry;
323- ColorInformation? color_info = null;
324-
325- Gdk.Screen.get_default ().get_monitor_geometry (screen, out monitor_geometry);
326-
327- try {
328- color_info = yield get_background_color_information (wm, screen, 0, 0, monitor_geometry.width, panel_height);
329- } catch (Error e) {
330- warning (e.message);
331-
332- return false;
333- }
334-
335- return color_info != null && (color_info.mean > MIN_LUM || color_info.variance > MIN_VARIANCE);
336- }
337-}
338\ No newline at end of file
339+ return { rTotal, gTotal, bTotal, mean, variance, mean_acutance };
340+ }
341+
342+}

Subscribers

People subscribed via source and target branches

to all changes: