Merge lp:~3v1n0/unity-greeter/shutdown-blurred-bg into lp:unity-greeter

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Robert Ancell
Approved revision: 1048
Merged at revision: 1022
Proposed branch: lp:~3v1n0/unity-greeter/shutdown-blurred-bg
Merge into: lp:unity-greeter
Prerequisite: lp:~3v1n0/unity-greeter/shutdown-average-color-bg
Diff against target: 651 lines (+353/-66)
10 files modified
configure.ac (+1/-0)
debian/changelog (+8/-0)
debian/control (+1/-0)
src/Makefile.am (+2/-0)
src/background.vala (+9/-1)
src/cairo-utils.vala (+238/-0)
src/dash-box.vala (+1/-19)
src/main-window.vala (+2/-2)
src/shutdown-dialog.vala (+89/-42)
src/toggle-box.vala (+2/-2)
To merge this branch: bzr merge lp:~3v1n0/unity-greeter/shutdown-blurred-bg
Reviewer Review Type Date Requested Status
Robert Ancell Approve
Review via email: mp+194792@code.launchpad.net

Commit message

ShutdownDialog: blur the background under the dialog

This is done by copying the the area under the dialog into a new ImageSurface
before drawing over it, then we apply some blur on it (only when it changes) and
finally we fill the dialog rectangle with it.

Description of the change

Moved some Cairo utility functions inside the CairoUtils namespace, added Gaussian and Exponential blur implementations based on Nux code and using them to blur the window area below the dialog.

Also fixed the spelling of "Shut Down" labels so that it matches unity.

Final result: http://i.imgur.com/ZHnFc35.png

To post a comment you must log in.
Revision history for this message
Robert Ancell (robert-ancell) wrote :

This was in my too-hard-basket :) Works well here!

review: Approve
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Just merged this one with previous branch in queue, removed the signal as the background average color is now a property, and using notify instead.

1049. By Marco Trevisan (Treviño)

Merging with trunk

1050. By Marco Trevisan (Treviño)

ShutdownDialog: fix background margin for good (hopefully)

But now we've buttons with no border or paddings, it should be enough.

1051. By Marco Trevisan (Treviño)

debian/control: build-depends on libpixman-1-dev

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configure.ac'
2--- configure.ac 2013-10-21 04:38:12 +0000
3+++ configure.ac 2013-11-13 05:34:24 +0000
4@@ -26,6 +26,7 @@
5 freetype2
6 cairo-ft
7 libcanberra
8+ pixman-1
9 x11
10 ])
11
12
13=== modified file 'debian/changelog'
14--- debian/changelog 2013-11-11 04:21:48 +0000
15+++ debian/changelog 2013-11-13 05:34:24 +0000
16@@ -1,3 +1,11 @@
17+unity-greeter (14.04.0-0ubuntu2) UNRELEASED; urgency=low
18+
19+ * debian/control:
20+ - build-depends on libpixman-1-dev
21+ - Improved Unity style shutdown dialogs with blurred bg
22+
23+ -- Marco Trevisan <marco@ubuntu.com> Wed, 13 Nov 2013 06:32:17 +0100
24+
25 unity-greeter (14.04.0-0ubuntu1) trusty; urgency=low
26
27 * New upstream release:
28
29=== modified file 'debian/control'
30--- debian/control 2013-09-20 18:11:17 +0000
31+++ debian/control 2013-11-13 05:34:24 +0000
32@@ -15,6 +15,7 @@
33 libindicator3-dev,
34 libido3-0.1-dev (>= 13.10.0),
35 liblightdm-gobject-1-dev (>= 1.4.0),
36+ libpixman-1-dev,
37 valac (>= 0.20.0),
38 xvfb,
39 Homepage: https://launchpad.net/unity-greeter
40
41=== modified file 'src/Makefile.am'
42--- src/Makefile.am 2013-11-05 02:46:46 +0000
43+++ src/Makefile.am 2013-11-13 05:34:24 +0000
44@@ -9,6 +9,7 @@
45 animate-timer.vala \
46 background.vala \
47 cached-image.vala \
48+ cairo-utils.vala \
49 email-autocompleter.vala \
50 dash-box.vala \
51 dash-button.vala \
52@@ -52,6 +53,7 @@
53 --pkg liblightdm-gobject-1 \
54 --pkg libcanberra \
55 --pkg gio-2.0 \
56+ --pkg pixman-1 \
57 --target-glib 2.32
58
59 unity_greeter_LDADD = \
60
61=== modified file 'src/background.vala'
62--- src/background.vala 2013-11-13 03:43:29 +0000
63+++ src/background.vala 2013-11-13 05:34:24 +0000
64@@ -374,6 +374,14 @@
65 this.width = width;
66 this.height = height;
67 }
68+
69+ public bool equals (Monitor? other)
70+ {
71+ if (other != null)
72+ return (x == other.x && y == other.y && width == other.width && height == other.height);
73+
74+ return false;
75+ }
76 }
77
78 public class Background : Gtk.Fixed
79@@ -574,7 +582,6 @@
80 private void animate_cb (double progress)
81 {
82 alpha = progress;
83-
84 queue_draw ();
85
86 /* Stop when we get there */
87@@ -681,6 +688,7 @@
88
89 void publish_average_color ()
90 {
91+ notify_property ("average-color");
92 var rgba = current.average_color.to_string ();
93 var root = get_screen ().get_root_window ();
94
95
96=== added file 'src/cairo-utils.vala'
97--- src/cairo-utils.vala 1970-01-01 00:00:00 +0000
98+++ src/cairo-utils.vala 2013-11-13 05:34:24 +0000
99@@ -0,0 +1,238 @@
100+/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 4 -*-
101+ *
102+ * Copyright (C) 2013 Canonical Ltd
103+ *
104+ * This program is free software: you can redistribute it and/or modify
105+ * it under the terms of the GNU General Public License version 3 as
106+ * published by the Free Software Foundation.
107+ *
108+ * This program is distributed in the hope that it will be useful,
109+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
110+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
111+ * GNU General Public License for more details.
112+ *
113+ * You should have received a copy of the GNU General Public License
114+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
115+ *
116+ * Authors: Marco Trevisan <marco.trevisan@canonical.com>
117+ * Mirco "MacSlow" Mueller <mirco.mueller@canonical.com>
118+ */
119+
120+namespace CairoUtils
121+{
122+
123+public void rounded_rectangle (Cairo.Context c, double x, double y,
124+ double width, double height, double radius)
125+{
126+ var w = width - radius * 2;
127+ var h = height - radius * 2;
128+ var kappa = 0.5522847498 * radius;
129+ c.move_to (x + radius, y);
130+ c.rel_line_to (w, 0);
131+ c.rel_curve_to (kappa, 0, radius, radius - kappa, radius, radius);
132+ c.rel_line_to (0, h);
133+ c.rel_curve_to (0, kappa, kappa - radius, radius, -radius, radius);
134+ c.rel_line_to (-w, 0);
135+ c.rel_curve_to (-kappa, 0, -radius, kappa - radius, -radius, -radius);
136+ c.rel_line_to (0, -h);
137+ c.rel_curve_to (0, -kappa, radius - kappa, -radius, radius, -radius);
138+}
139+
140+class GaussianBlur
141+{
142+ /* Gaussian Blur, based on Mirco Mueller work on notify-osd */
143+
144+ public static void surface (Cairo.ImageSurface surface, uint radius, double sigma = 0.0f)
145+ {
146+ if (surface.get_format () != Cairo.Format.ARGB32)
147+ {
148+ warning ("Impossible to blur a non ARGB32-formatted ImageSurface");
149+ return;
150+ }
151+
152+ surface.flush ();
153+
154+ double radiusf = Math.fabs (radius) + 1.0f;
155+
156+ if (sigma == 0.0f)
157+ sigma = Math.sqrt (-(radiusf * radiusf) / (2.0f * Math.log (1.0f / 255.0f)));
158+
159+ int w = surface.get_width ();
160+ int h = surface.get_height ();
161+ int s = surface.get_stride ();
162+
163+ // create pixman image for cairo image surface
164+ unowned uchar[] p = surface.get_data ();
165+ var src = new Pixman.Image.bits (Pixman.Format.A8R8G8B8, w, h, p, s);
166+
167+ // attach gaussian kernel to pixman image
168+ var params = create_gaussian_blur_kernel ((int) radius, sigma);
169+ src.set_filter (Pixman.Filter.CONVOLUTION, params);
170+
171+ // render blured image to new pixman image
172+ Pixman.Image.composite (Pixman.Operation.SRC, src, null, src,
173+ 0, 0, 0, 0, 0, 0, (uint16) w, (uint16) h);
174+
175+ surface.mark_dirty ();
176+ }
177+
178+ private static Pixman.Fixed[] create_gaussian_blur_kernel (int radius, double sigma)
179+ {
180+ double scale2 = 2.0f * sigma * sigma;
181+ double scale1 = 1.0f / (Math.PI * scale2);
182+ int size = 2 * radius + 1;
183+ int n_params = size * size;
184+ double sum = 0;
185+
186+ var tmp = new double[n_params];
187+
188+ // caluclate gaussian kernel in floating point format
189+ for (int i = 0, x = -radius; x <= radius; ++x)
190+ {
191+ for (int y = -radius; y <= radius; ++y, ++i)
192+ {
193+ double u = x * x;
194+ double v = y * y;
195+
196+ tmp[i] = scale1 * Math.exp (-(u+v)/scale2);
197+
198+ sum += tmp[i];
199+ }
200+ }
201+
202+ // normalize gaussian kernel and convert to fixed point format
203+ var params = new Pixman.Fixed[n_params + 2];
204+
205+ params[0] = Pixman.Fixed.int (size);
206+ params[1] = Pixman.Fixed.int (size);
207+
208+ for (int i = 2; i < params.length; ++i)
209+ params[i] = Pixman.Fixed.double (tmp[i] / sum);
210+
211+ return params;
212+ }
213+}
214+
215+class ExponentialBlur
216+{
217+ /* Exponential Blur, based on the Nux version */
218+
219+ const int APREC = 16;
220+ const int ZPREC = 7;
221+
222+ public static void surface (Cairo.ImageSurface surface, int radius)
223+ {
224+ if (radius < 1)
225+ return;
226+
227+ // before we mess with the surface execute any pending drawing
228+ surface.flush ();
229+
230+ unowned uchar[] pixels = surface.get_data ();
231+ var width = surface.get_width ();
232+ var height = surface.get_height ();
233+ var format = surface.get_format ();
234+
235+ switch (format)
236+ {
237+ case Cairo.Format.ARGB32:
238+ blur (pixels, width, height, 4, radius);
239+ break;
240+
241+ case Cairo.Format.RGB24:
242+ blur (pixels, width, height, 3, radius);
243+ break;
244+
245+ case Cairo.Format.A8:
246+ blur (pixels, width, height, 1, radius);
247+ break;
248+
249+ default :
250+ // do nothing
251+ break;
252+ }
253+
254+ // inform cairo we altered the surfaces contents
255+ surface.mark_dirty ();
256+ }
257+
258+ static void blur (uchar[] pixels, int width, int height, int channels, int radius)
259+ {
260+ // calculate the alpha such that 90% of
261+ // the kernel is within the radius.
262+ // (Kernel extends to infinity)
263+
264+ int alpha = (int) ((1 << APREC) * (1.0f - Math.expf(-2.3f / (radius + 1.0f))));
265+
266+ for (int row = 0; row < height; ++row)
267+ blurrow (pixels, width, height, channels, row, alpha);
268+
269+ for (int col = 0; col < width; ++col)
270+ blurcol (pixels, width, height, channels, col, alpha);
271+ }
272+
273+ static void blurrow (uchar[] pixels, int width, int height, int channels, int line, int alpha)
274+ {
275+ var scanline = &(pixels[line * width * channels]);
276+
277+ int zR = *scanline << ZPREC;
278+ int zG = *(scanline + 1) << ZPREC;
279+ int zB = *(scanline + 2) << ZPREC;
280+ int zA = *(scanline + 3) << ZPREC;
281+
282+ for (int index = 0; index < width; ++index)
283+ {
284+ blurinner (&scanline[index * channels], alpha, ref zR, ref zG, ref zB, ref zA);
285+ }
286+
287+ for (int index = width - 2; index >= 0; --index)
288+ {
289+ blurinner (&scanline[index * channels], alpha, ref zR, ref zG, ref zB, ref zA);
290+ }
291+ }
292+
293+ static void blurcol (uchar[] pixels, int width, int height, int channels, int x, int alpha)
294+ {
295+ var ptr = &(pixels[x * channels]);
296+
297+ int zR = *ptr << ZPREC;
298+ int zG = *(ptr + 1) << ZPREC;
299+ int zB = *(ptr + 2) << ZPREC;
300+ int zA = *(ptr + 3) << ZPREC;
301+
302+ for (int index = width; index < (height - 1) * width; index += width)
303+ {
304+ blurinner (&ptr[index * channels], alpha, ref zR, ref zG, ref zB, ref zA);
305+ }
306+
307+ for (int index = (height - 2) * width; index >= 0; index -= width)
308+ {
309+ blurinner (&ptr[index * channels], alpha, ref zR, ref zG, ref zB, ref zA);
310+ }
311+ }
312+
313+ static void blurinner (uchar *pixel, int alpha, ref int zR, ref int zG, ref int zB, ref int zA)
314+ {
315+ int R;
316+ int G;
317+ int B;
318+ uchar A;
319+
320+ R = *pixel;
321+ G = *(pixel + 1);
322+ B = *(pixel + 2);
323+ A = *(pixel + 3);
324+
325+ zR += (alpha * ((R << ZPREC) - zR)) >> APREC;
326+ zG += (alpha * ((G << ZPREC) - zG)) >> APREC;
327+ zB += (alpha * ((B << ZPREC) - zB)) >> APREC;
328+ zA += (alpha * ((A << ZPREC) - zA)) >> APREC;
329+
330+ *pixel = zR >> ZPREC;
331+ *(pixel + 1) = zG >> ZPREC;
332+ *(pixel + 2) = zB >> ZPREC;
333+ *(pixel + 3) = zA >> ZPREC;
334+ }
335+}
336+
337+}
338
339=== modified file 'src/dash-box.vala'
340--- src/dash-box.vala 2012-10-23 20:01:56 +0000
341+++ src/dash-box.vala 2013-11-13 05:34:24 +0000
342@@ -214,7 +214,7 @@
343
344 c.save ();
345
346- cairo_rounded_rectangle (c, 0, box_y, box_w, box_h, box_r);
347+ CairoUtils.rounded_rectangle (c, 0, box_y, box_w, box_h, box_r);
348
349 c.set_source_rgba (0.1, 0.1, 0.1, 0.4);
350 c.fill_preserve ();
351@@ -227,22 +227,4 @@
352
353 return base.draw (c);
354 }
355-
356- public static void cairo_rounded_rectangle (Cairo.Context c, double x,
357- double y, double width,
358- double height, double radius)
359- {
360- var w = width - radius * 2;
361- var h = height - radius * 2;
362- var kappa = 0.5522847498 * radius;
363- c.move_to (x + radius, y);
364- c.rel_line_to (w, 0);
365- c.rel_curve_to (kappa, 0, radius, radius - kappa, radius, radius);
366- c.rel_line_to (0, h);
367- c.rel_curve_to (0, kappa, kappa - radius, radius, -radius, radius);
368- c.rel_line_to (-w, 0);
369- c.rel_curve_to (-kappa, 0, -radius, kappa - radius, -radius, -radius);
370- c.rel_line_to (0, -h);
371- c.rel_curve_to (0, -kappa, radius - kappa, -radius, radius, -radius);
372- }
373 }
374
375=== modified file 'src/main-window.vala'
376--- src/main-window.vala 2013-11-13 03:32:25 +0000
377+++ src/main-window.vala 2013-11-13 05:34:24 +0000
378@@ -254,7 +254,7 @@
379
380 if (shutdown_dialog != null)
381 {
382- shutdown_dialog.set_size_request (monitor.width, monitor.height);
383+ shutdown_dialog.set_active_monitor (monitor);
384 background.move (shutdown_dialog, monitor.x, monitor.y);
385 }
386 }
387@@ -342,7 +342,7 @@
388 /* Stop input to login box */
389 login_box.sensitive = false;
390
391- shutdown_dialog = new ShutdownDialog (type, background.average_color);
392+ shutdown_dialog = new ShutdownDialog (type, background);
393 shutdown_dialog.visible = true;
394 shutdown_dialog.close.connect (close_shutdown_dialog);
395 background.add (shutdown_dialog);
396
397=== modified file 'src/shutdown-dialog.vala'
398--- src/shutdown-dialog.vala 2013-11-13 05:23:57 +0000
399+++ src/shutdown-dialog.vala 2013-11-13 05:34:24 +0000
400@@ -15,6 +15,7 @@
401 * along with this program. If not, see <http://www.gnu.org/licenses/>.
402 *
403 * Authors: Robert Ancell <robert.ancell@canonical.com>
404+ * Marco Trevisan <marco.trevisan@canonical.com>
405 */
406
407 public enum ShutdownDialogType
408@@ -28,6 +29,7 @@
409 {
410 public signal void close ();
411
412+ private Cairo.ImageSurface? bg_surface = null;
413 private Cairo.ImageSurface? corner_surface = null;
414 private Cairo.ImageSurface? left_surface = null;
415 private Cairo.ImageSurface? top_surface = null;
416@@ -36,22 +38,27 @@
417 private Cairo.Pattern? top_pattern = null;
418
419 private const int BORDER_SIZE = 30;
420+ private const int BORDER_INTERNAL_SIZE = 10;
421+ private const int BORDER_EXTERNAL_SIZE = BORDER_SIZE - BORDER_INTERNAL_SIZE;
422 private const int CLOSE_OFFSET = 3;
423 private const int BUTTON_TEXT_SPACE = 9;
424- private const int VBOX_EXTERNAL_PADDING = 10;
425+ private const int BLUR_RADIUS = 4;
426+
427+ private Monitor monitor;
428+ private weak Background background;
429
430 private Gtk.Box vbox;
431 private DialogButton close_button;
432 private Gtk.Box button_box;
433-
434 private Gtk.EventBox monitor_events;
435 private Gtk.EventBox vbox_events;
436
437- private Gdk.RGBA avg_color;
438
439- public ShutdownDialog (ShutdownDialogType type, Gdk.RGBA average_color)
440+ public ShutdownDialog (ShutdownDialogType type, Background bg)
441 {
442- this.avg_color = average_color;
443+ background = bg;
444+ background.notify["alpha"].connect (rebuild_background);
445+ background.notify["average-color"].connect (rebuild_background);
446
447 // This event box covers the monitor size, and closes the dialog on click.
448 monitor_events = new Gtk.EventBox ();
449@@ -66,12 +73,12 @@
450
451 vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 10);
452 vbox.visible = true;
453- add (vbox);
454
455- vbox.margin_top = 10;
456- vbox.margin_left = 22;
457- vbox.margin_right = 18;
458- vbox.margin_bottom = 0;
459+ vbox.margin = BORDER_INTERNAL_SIZE;
460+ vbox.margin_top += 10;
461+ vbox.margin_left += 20;
462+ vbox.margin_right += 20;
463+ vbox.margin_bottom += 0;
464
465 // This event box consumes the click events inside the vbox
466 vbox_events = new Gtk.EventBox();
467@@ -79,24 +86,27 @@
468 vbox_events.set_visible_window (false);
469 vbox_events.events |= Gdk.EventMask.BUTTON_PRESS_MASK;
470 vbox_events.button_press_event.connect (() => { return true; });
471+ vbox_events.add (vbox);
472 monitor_events.add (vbox_events);
473
474- var title_label = new Gtk.Label (_("Shutdown"));
475- title_label.override_font (Pango.FontDescription.from_string ("Ubuntu Light 15"));
476- title_label.override_color (Gtk.StateFlags.NORMAL, { 1.0f, 1.0f, 1.0f, 1.0f });
477- title_label.set_alignment (0.0f, 0.5f);
478- vbox.pack_start (title_label, false, false, 0);
479-
480 string text;
481+
482 if (type == ShutdownDialogType.SHUTDOWN)
483 {
484 text = _("Goodbye. Would you like to…");
485 }
486 else
487 {
488+ var title_label = new Gtk.Label (_("Shut Down"));
489+ title_label.visible = true;
490+ title_label.override_font (Pango.FontDescription.from_string ("Ubuntu Light 15"));
491+ title_label.override_color (Gtk.StateFlags.NORMAL, { 1.0f, 1.0f, 1.0f, 1.0f });
492+ title_label.set_alignment (0.0f, 0.5f);
493+ vbox.pack_start (title_label, false, false, 0);
494+
495 text = _("Are you sure you want to shut down the computer?");
496- title_label.visible = true;
497 }
498+
499 var label = new Gtk.Label (text);
500 label.set_line_wrap (true);
501 label.override_font (Pango.FontDescription.from_string ("Ubuntu Light 12"));
502@@ -165,7 +175,7 @@
503
504 if (LightDM.get_can_shutdown ())
505 {
506- var button = add_button (_("Shutdown"), Path.build_filename (Config.PKGDATADIR, "shutdown.png"), Path.build_filename (Config.PKGDATADIR, "shutdown_highlight.png"));
507+ var button = add_button (_("Shut Down"), Path.build_filename (Config.PKGDATADIR, "shutdown.png"), Path.build_filename (Config.PKGDATADIR, "shutdown_highlight.png"));
508 button.clicked.connect (() =>
509 {
510 try
511@@ -187,6 +197,22 @@
512 add (close_button);
513 }
514
515+ private void rebuild_background ()
516+ {
517+ bg_surface = null;
518+ queue_draw ();
519+ }
520+
521+ public void set_active_monitor (Monitor m)
522+ {
523+ if (m == this.monitor || m.equals (this.monitor))
524+ return;
525+
526+ monitor = m;
527+ rebuild_background ();
528+ set_size_request (monitor.width, monitor.height);
529+ }
530+
531 public void focus_next ()
532 {
533 (get_toplevel () as Gtk.Window).move_focus (Gtk.DirectionType.TAB_FORWARD);
534@@ -213,26 +239,19 @@
535
536 var content_allocation = Gtk.Allocation ();
537 int minimum_width, natural_width, minimum_height, natural_height;
538- vbox.get_preferred_width (out minimum_width, out natural_width);
539- vbox.get_preferred_height_for_width (minimum_width, out minimum_height, out natural_height);
540+ vbox_events.get_preferred_width (out minimum_width, out natural_width);
541+ vbox_events.get_preferred_height_for_width (minimum_width, out minimum_height, out natural_height);
542 content_allocation.x = allocation.x + (allocation.width - minimum_width) / 2;
543 content_allocation.y = allocation.y + (allocation.height - minimum_height) / 2;
544 content_allocation.width = minimum_width;
545 content_allocation.height = minimum_height;
546- vbox.size_allocate (content_allocation);
547-
548- var events_allocation = content_allocation;
549- events_allocation.x -= VBOX_EXTERNAL_PADDING;
550- events_allocation.y -= VBOX_EXTERNAL_PADDING;
551- events_allocation.width += VBOX_EXTERNAL_PADDING * 2;
552- events_allocation.height += VBOX_EXTERNAL_PADDING * 2;
553- vbox_events.size_allocate (events_allocation);
554+ vbox_events.size_allocate (content_allocation);
555
556 var a = Gtk.Allocation ();
557 close_button.get_preferred_width (out minimum_width, out natural_width);
558 close_button.get_preferred_height (out minimum_height, out natural_height);
559- a.x = content_allocation.x - BORDER_SIZE + CLOSE_OFFSET;
560- a.y = content_allocation.y - BORDER_SIZE + CLOSE_OFFSET;
561+ a.x = content_allocation.x - BORDER_EXTERNAL_SIZE + CLOSE_OFFSET;
562+ a.y = content_allocation.y - BORDER_EXTERNAL_SIZE + CLOSE_OFFSET;
563 a.width = minimum_width;
564 a.height = minimum_height;
565 close_button.size_allocate (a);
566@@ -252,16 +271,51 @@
567 top_pattern.set_extend (Cairo.Extend.REPEAT);
568 }
569
570- var width = vbox.get_allocated_width () + BORDER_SIZE * 2 + vbox.margin_left + vbox.margin_right;
571- var height = vbox.get_allocated_height () + BORDER_SIZE * 2 + vbox.margin_top + vbox.margin_bottom;
572+ int width = vbox_events.get_allocated_width ();
573+ int height = vbox_events.get_allocated_height ();
574+ int x = (get_allocated_width () - width) / 2;
575+ int y = (get_allocated_height () - height) / 2;
576
577 /* Darken background */
578 c.set_source_rgba (0, 0, 0, 0.25);
579 c.paint ();
580
581- /* Draw dialog */
582- c.save ();
583- c.translate ((get_allocated_width () - width) * 0.5, (get_allocated_height () - height) * 0.5);
584+ if (bg_surface == null)
585+ {
586+ /* Create a new blurred surface of the current surface */
587+ bg_surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, width, height);
588+ var bg_cr = new Cairo.Context (bg_surface);
589+
590+ bg_cr.set_source_surface (c.get_target (), -x - monitor.x, -y - monitor.y);
591+ bg_cr.rectangle (0, 0, width, height);
592+ bg_cr.fill ();
593+
594+ CairoUtils.ExponentialBlur.surface (bg_surface, BLUR_RADIUS);
595+ }
596+
597+ /* Background */
598+ c.save ();
599+ c.translate (x, y);
600+
601+ var avg_color = background.average_color;
602+ CairoUtils.rounded_rectangle (c, 0, 0, width, height, 4);
603+ c.set_source_surface (bg_surface, 0, 0);
604+ c.fill_preserve ();
605+ c.set_source_rgba (0.0, 0.0, 0.0, 0.55f);
606+ c.fill_preserve ();
607+ c.set_source_rgba (avg_color.red, avg_color.green, avg_color.blue, 0.35);
608+ c.fill ();
609+
610+ c.restore();
611+
612+ /* Draw borders */
613+ x -= BORDER_EXTERNAL_SIZE;
614+ y -= BORDER_EXTERNAL_SIZE;
615+ width += BORDER_EXTERNAL_SIZE * 2;
616+ height += BORDER_EXTERNAL_SIZE * 2;
617+
618+ c.save ();
619+ c.translate (x, y);
620
621 /* Top left */
622 var m = Cairo.Matrix.identity ();
623@@ -329,13 +383,6 @@
624 c.rectangle (BORDER_SIZE, height - BORDER_SIZE, width - BORDER_SIZE * 2, BORDER_SIZE);
625 c.fill ();
626
627- /* Background */
628- DashBox.cairo_rounded_rectangle (c, 20, 20, width - 40, height - 40, 4);
629- c.set_source_rgba (0.0, 0.0, 0.0, 0.75f);
630- c.fill_preserve ();
631- c.set_source_rgba (avg_color.red, avg_color.green, avg_color.blue, 0.35);
632- c.fill ();
633-
634 c.restore ();
635
636 return base.draw (c);
637
638=== modified file 'src/toggle-box.vala'
639--- src/toggle-box.vala 2012-10-23 20:01:56 +0000
640+++ src/toggle-box.vala 2013-11-13 05:34:24 +0000
641@@ -54,8 +54,8 @@
642 Gtk.Allocation allocation;
643 get_allocation (out allocation);
644
645- DashBox.cairo_rounded_rectangle (c, 0, 0, allocation.width,
646- allocation.height, 0.1 * grid_size);
647+ CairoUtils.rounded_rectangle (c, 0, 0, allocation.width,
648+ allocation.height, 0.1 * grid_size);
649 c.set_source_rgba (0.5, 0.5, 0.5, 0.5);
650 c.set_line_width (1);
651 c.stroke ();

Subscribers

People subscribed via source and target branches