Merge lp:~robert-ancell/unity-greeter/end-session-dialog into lp:unity-greeter

Proposed by Robert Ancell
Status: Superseded
Proposed branch: lp:~robert-ancell/unity-greeter/end-session-dialog
Merge into: lp:unity-greeter
Diff against target: 820 lines (+575/-17)
12 files modified
configure.ac (+1/-1)
data/Makefile.am (+13/-0)
debian/changelog (+7/-0)
po/POTFILES.in (+1/-1)
po/POTFILES.skip (+1/-0)
src/Makefile.am (+1/-0)
src/fixes.vapi (+6/-0)
src/main-window.vala (+75/-14)
src/settings-daemon.vala (+36/-0)
src/shutdown-dialog.vala (+381/-0)
src/unity-greeter.vala (+51/-0)
tests/Makefile.am (+2/-1)
To merge this branch: bzr merge lp:~robert-ancell/unity-greeter/end-session-dialog
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Michael Terry (community) Needs Fixing
Review via email: mp+191937@code.launchpad.net

This proposal has been superseded by a proposal from 2013-11-05.

Commit message

Use Unity style shutdown dialogs
Handle hardware power button in greeter

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1017. By Robert Ancell

Fix copyright header

1018. By Robert Ancell

Mark strings as translatable

1019. By Robert Ancell

Add bug link about DBusConnection.call_with_unix_fd_list being broken

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1020. By Robert Ancell

Fix typo

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1021. By Robert Ancell

Add shutdown-dialog.c to POTFILES.skip

1022. By Robert Ancell

Use real ellipses

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michael Terry (mterry) wrote :

So we talked about this on IRC. Sounds like it needs at least keyboard navigation before landing. Also mentioned was the use of a well-known DBus name vs unique.

Revision history for this message
Michael Terry (mterry) wrote :

Whoops, forgot to set status.

review: Needs Fixing
1023. By Robert Ancell

Merge with trunk

1024. By Robert Ancell

Fix indent to be clearer

1025. By Robert Ancell

Use clicked signal instead of pressed signal which is deprecated

1026. By Robert Ancell

Bus.own_name doesn't throw an error

1027. By Robert Ancell

Mark D-Bus interface as public so it doesn't warn about unused fields

1028. By Robert Ancell

Close dialog when selecting a button

1029. By Robert Ancell

Disable input to login box when shutdown dialog open

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1030. By Robert Ancell

note that the shutdown dialog click out is broken

1031. By Robert Ancell

Support keyboard shortcuts

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Unmerged revisions

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-02 17:46:49 +0000
3+++ configure.ac 2013-11-05 04:15:26 +0000
4@@ -2,7 +2,7 @@
5
6 dnl Process this file with autoconf to produce a configure script.
7
8-AC_INIT(unity-greeter, 13.10.3)
9+AC_INIT(unity-greeter, 14.04.0)
10 AC_CONFIG_MACRO_DIR(m4)
11 AM_INIT_AUTOMAKE
12 AM_PROG_CC_C_O
13
14=== modified file 'data/Makefile.am'
15--- data/Makefile.am 2012-10-18 14:45:57 +0000
16+++ data/Makefile.am 2013-11-05 04:15:26 +0000
17@@ -9,13 +9,26 @@
18 arrow_left.png \
19 arrow_right.png \
20 cof.png \
21+ dialog_close_highlight.png \
22+ dialog_close.png \
23 gnome_badge.png \
24+ hibernate_highlight.png \
25+ hibernate.png \
26 kde_badge.png \
27 logo.png \
28 message.png \
29 recovery_console_badge.png \
30 remote_login_help.png \
31+ restart_highlight.png \
32+ restart.png \
33 shadow.png \
34+ shutdown_highlight.png \
35+ shutdown.png \
36+ suspend_highlight.png \
37+ suspend.png \
38+ switcher_corner.png \
39+ switcher_left.png \
40+ switcher_top.png \
41 ubuntu_badge.png \
42 unknown_badge.png
43
44
45=== added file 'data/dialog_close.png'
46Binary files data/dialog_close.png 1970-01-01 00:00:00 +0000 and data/dialog_close.png 2013-11-05 04:15:26 +0000 differ
47=== added file 'data/dialog_close_highlight.png'
48Binary files data/dialog_close_highlight.png 1970-01-01 00:00:00 +0000 and data/dialog_close_highlight.png 2013-11-05 04:15:26 +0000 differ
49=== added file 'data/hibernate.png'
50Binary files data/hibernate.png 1970-01-01 00:00:00 +0000 and data/hibernate.png 2013-11-05 04:15:26 +0000 differ
51=== added file 'data/hibernate_highlight.png'
52Binary files data/hibernate_highlight.png 1970-01-01 00:00:00 +0000 and data/hibernate_highlight.png 2013-11-05 04:15:26 +0000 differ
53=== added file 'data/restart.png'
54Binary files data/restart.png 1970-01-01 00:00:00 +0000 and data/restart.png 2013-11-05 04:15:26 +0000 differ
55=== added file 'data/restart_highlight.png'
56Binary files data/restart_highlight.png 1970-01-01 00:00:00 +0000 and data/restart_highlight.png 2013-11-05 04:15:26 +0000 differ
57=== added file 'data/shutdown.png'
58Binary files data/shutdown.png 1970-01-01 00:00:00 +0000 and data/shutdown.png 2013-11-05 04:15:26 +0000 differ
59=== added file 'data/shutdown_highlight.png'
60Binary files data/shutdown_highlight.png 1970-01-01 00:00:00 +0000 and data/shutdown_highlight.png 2013-11-05 04:15:26 +0000 differ
61=== added file 'data/suspend.png'
62Binary files data/suspend.png 1970-01-01 00:00:00 +0000 and data/suspend.png 2013-11-05 04:15:26 +0000 differ
63=== added file 'data/suspend_highlight.png'
64Binary files data/suspend_highlight.png 1970-01-01 00:00:00 +0000 and data/suspend_highlight.png 2013-11-05 04:15:26 +0000 differ
65=== added file 'data/switcher_corner.png'
66Binary files data/switcher_corner.png 1970-01-01 00:00:00 +0000 and data/switcher_corner.png 2013-11-05 04:15:26 +0000 differ
67=== added file 'data/switcher_left.png'
68Binary files data/switcher_left.png 1970-01-01 00:00:00 +0000 and data/switcher_left.png 2013-11-05 04:15:26 +0000 differ
69=== added file 'data/switcher_top.png'
70Binary files data/switcher_top.png 1970-01-01 00:00:00 +0000 and data/switcher_top.png 2013-11-05 04:15:26 +0000 differ
71=== modified file 'debian/changelog'
72--- debian/changelog 2013-10-03 13:59:34 +0000
73+++ debian/changelog 2013-11-05 04:15:26 +0000
74@@ -1,3 +1,10 @@
75+unity-greeter (14.04.0-0ubuntu1) UNRELEASED; urgency=low
76+
77+ * Use Unity style shutdown dialogs
78+ * Handle hardware power button in greeter
79+
80+ -- Robert Ancell <robert.ancell@canonical.com> Mon, 21 Oct 2013 17:15:38 +1300
81+
82 unity-greeter (13.10.3-0ubuntu1) saucy; urgency=low
83
84 [ William Hua ]
85
86=== modified file 'po/POTFILES.in'
87--- po/POTFILES.in 2012-11-08 15:48:14 +0000
88+++ po/POTFILES.in 2013-11-05 04:15:26 +0000
89@@ -19,8 +19,8 @@
90 src/session-list.vala
91 src/settings-daemon.vala
92 src/settings.vala
93+src/shutdown-dialog.vala
94 src/toggle-box.vala
95 src/unity-greeter.vala
96 src/user-list.vala
97 src/user-prompt-box.vala
98-
99
100=== modified file 'po/POTFILES.skip'
101--- po/POTFILES.skip 2012-11-08 15:48:14 +0000
102+++ po/POTFILES.skip 2013-11-05 04:15:26 +0000
103@@ -17,6 +17,7 @@
104 src/session-list.c
105 src/settings-daemon.c
106 src/settings.c
107+src/shutdown-dialog.c
108 src/toggle-box.c
109 src/unity-greeter.c
110 src/user-list.c
111
112=== modified file 'src/Makefile.am'
113--- src/Makefile.am 2013-10-17 22:09:16 +0000
114+++ src/Makefile.am 2013-11-05 04:15:26 +0000
115@@ -27,6 +27,7 @@
116 remote-login-service.vala \
117 settings.vala \
118 settings-daemon.vala \
119+ shutdown-dialog.vala \
120 toggle-box.vala \
121 unity-greeter.vala \
122 user-list.vala \
123
124=== modified file 'src/fixes.vapi'
125--- src/fixes.vapi 2013-10-24 12:27:03 +0000
126+++ src/fixes.vapi 2013-11-05 04:15:26 +0000
127@@ -33,12 +33,16 @@
128 public const int KEY_Page_Down;
129 public const int KEY_Up;
130 public const int KEY_Down;
131+ public const int KEY_Left;
132+ public const int KEY_Right;
133 public const int KEY_KP_Home;
134 public const int KEY_KP_End;
135 public const int KEY_KP_Page_Up;
136 public const int KEY_KP_Page_Down;
137 public const int KEY_KP_Up;
138 public const int KEY_KP_Down;
139+ public const int KEY_KP_Left;
140+ public const int KEY_KP_Right;
141 public const int KEY_F10;
142 public const int KEY_0;
143 public const int KEY_g;
144@@ -47,10 +51,12 @@
145 public const int KEY_m;
146 public const int KEY_M;
147 public const int KEY_s;
148+ public const int KEY_z;
149 public const int KEY_plus;
150 public const int KEY_minus;
151 public const int KEY_equal;
152 public const int CONTROL_MASK;
153+ public const int KEY_PowerOff;
154 }
155
156 namespace Gtk
157
158=== modified file 'src/main-window.vala'
159--- src/main-window.vala 2013-02-08 15:53:16 +0000
160+++ src/main-window.vala 2013-11-05 04:15:26 +0000
161@@ -24,10 +24,12 @@
162 public MenuBar menubar;
163
164 private List<Monitor> monitors;
165+ private Monitor active_monitor;
166 private Background background;
167 private Gtk.Box login_box;
168 private Gtk.Box hbox;
169 private Gtk.Button back_button;
170+ private ShutdownDialog? shutdown_dialog = null;
171
172 public ListStack stack;
173
174@@ -245,9 +247,16 @@
175
176 private void move_to_monitor (Monitor monitor)
177 {
178+ active_monitor = monitor;
179 login_box.set_size_request (monitor.width, monitor.height);
180 background.set_active_monitor (monitor);
181 background.move (login_box, monitor.x, monitor.y);
182+
183+ if (shutdown_dialog != null)
184+ {
185+ shutdown_dialog.set_size_request (monitor.width, monitor.height);
186+ background.move (shutdown_dialog, monitor.x, monitor.y);
187+ }
188 }
189
190 private void add_user_list ()
191@@ -266,36 +275,88 @@
192 switch (event.keyval)
193 {
194 case Gdk.KEY_Escape:
195- top.cancel_authentication ();
196- break;
197+ if (login_box.sensitive)
198+ top.cancel_authentication ();
199+ if (shutdown_dialog != null)
200+ shutdown_dialog.cancel ();
201+ return true;
202 case Gdk.KEY_Page_Up:
203 case Gdk.KEY_KP_Page_Up:
204- top.scroll (GreeterList.ScrollTarget.START);
205- break;
206+ if (login_box.sensitive)
207+ top.scroll (GreeterList.ScrollTarget.START);
208+ return true;
209 case Gdk.KEY_Page_Down:
210 case Gdk.KEY_KP_Page_Down:
211- top.scroll (GreeterList.ScrollTarget.END);
212- break;
213+ if (login_box.sensitive)
214+ top.scroll (GreeterList.ScrollTarget.END);
215+ return true;
216 case Gdk.KEY_Up:
217 case Gdk.KEY_KP_Up:
218- top.scroll (GreeterList.ScrollTarget.UP);
219- break;
220+ if (login_box.sensitive)
221+ top.scroll (GreeterList.ScrollTarget.UP);
222+ return true;
223 case Gdk.KEY_Down:
224 case Gdk.KEY_KP_Down:
225- top.scroll (GreeterList.ScrollTarget.DOWN);
226- break;
227+ if (login_box.sensitive)
228+ top.scroll (GreeterList.ScrollTarget.DOWN);
229+ return true;
230+ case Gdk.KEY_Left:
231+ case Gdk.KEY_KP_Left:
232+ if (shutdown_dialog != null)
233+ shutdown_dialog.focus_prev ();
234+ return true;
235+ case Gdk.KEY_Right:
236+ case Gdk.KEY_KP_Right:
237+ if (shutdown_dialog != null)
238+ shutdown_dialog.focus_next ();
239+ return true;
240 case Gdk.KEY_F10:
241- menubar.select_first (false);
242+ if (login_box.sensitive)
243+ menubar.select_first (false);
244+ return true;
245+ case Gdk.KEY_PowerOff:
246+ show_shutdown_dialog (ShutdownDialogType.SHUTDOWN);
247+ return true;
248+ case Gdk.KEY_z:
249+ if (UnityGreeter.singleton.test_mode && (event.state & Gdk.ModifierType.MOD1_MASK) != 0)
250+ {
251+ show_shutdown_dialog (ShutdownDialogType.SHUTDOWN);
252+ return true;
253+ }
254 break;
255- default:
256- return base.key_press_event (event);
257 }
258
259- return true;
260+ return base.key_press_event (event);
261 }
262
263 public void set_keyboard_state ()
264 {
265 menubar.set_keyboard_state ();
266 }
267+
268+ public void show_shutdown_dialog (ShutdownDialogType type)
269+ {
270+ if (shutdown_dialog != null)
271+ shutdown_dialog.destroy ();
272+
273+ /* Stop input to login box */
274+ login_box.sensitive = false;
275+
276+ shutdown_dialog = new ShutdownDialog (type);
277+ shutdown_dialog.visible = true;
278+ shutdown_dialog.close.connect (close_shutdown_dialog);
279+ background.add (shutdown_dialog);
280+ move_to_monitor (active_monitor);
281+ }
282+
283+ public void close_shutdown_dialog ()
284+ {
285+ if (shutdown_dialog == null)
286+ return;
287+
288+ shutdown_dialog.destroy ();
289+ shutdown_dialog = null;
290+
291+ login_box.sensitive = true;
292+ }
293 }
294
295=== modified file 'src/settings-daemon.vala'
296--- src/settings-daemon.vala 2013-01-30 20:31:38 +0000
297+++ src/settings-daemon.vala 2013-11-05 04:15:26 +0000
298@@ -19,6 +19,8 @@
299
300 public class SettingsDaemon : Object
301 {
302+ private int logind_inhibit_fd = -1;
303+
304 public async void start ()
305 {
306 configure ();
307@@ -64,6 +66,40 @@
308 require gnome-session and it's Presence DBus interface to be run. */
309 GLib.Bus.own_name (GLib.BusType.SESSION, "org.gnome.ScreenSaver",
310 GLib.BusNameOwnerFlags.NONE);
311+
312+ /* The media-keys plugin inhibits the power key, but we don't want
313+ all the other keys doing things. So inhibit it ourselves */
314+ /* NOTE: We are using the synchronous method here since there is a bug in Vala/GLib in that
315+ * g_dbus_connection_call_with_unix_fd_list_finish and g_dbus_proxy_call_with_unix_fd_list_finish
316+ * don't have the GAsyncResult as the second argument.
317+ * https://bugzilla.gnome.org/show_bug.cgi?id=688907
318+ */
319+ try
320+ {
321+ var b = Bus.get_sync (BusType.SYSTEM);
322+ UnixFDList fd_list;
323+ var result = b.call_with_unix_fd_list_sync ("org.freedesktop.login1",
324+ "/org/freedesktop/login1",
325+ "org.freedesktop.login1.Manager",
326+ "Inhibit",
327+ new Variant ("(ssss)",
328+ "handle-power-key",
329+ Environment.get_user_name (),
330+ "Unity Greeter handling keypresses",
331+ "block"),
332+ new VariantType ("(h)"),
333+ DBusCallFlags.NONE,
334+ -1,
335+ null,
336+ out fd_list);
337+ int32 index = -1;
338+ result.get ("(h)", &index);
339+ logind_inhibit_fd = fd_list.get (index);
340+ }
341+ catch (Error e)
342+ {
343+ warning ("Failed to inhibit power keys: %s", e.message);
344+ }
345 }
346
347 private void set_plugin_enabled (string schema_name, bool enabled)
348
349=== added file 'src/shutdown-dialog.vala'
350--- src/shutdown-dialog.vala 1970-01-01 00:00:00 +0000
351+++ src/shutdown-dialog.vala 2013-11-05 04:15:26 +0000
352@@ -0,0 +1,381 @@
353+/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 4 -*-
354+ *
355+ * Copyright (C) 2013 Canonical Ltd
356+ *
357+ * This program is free software: you can redistribute it and/or modify
358+ * it under the terms of the GNU General Public License version 3 as
359+ * published by the Free Software Foundation.
360+ *
361+ * This program is distributed in the hope that it will be useful,
362+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
363+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
364+ * GNU General Public License for more details.
365+ *
366+ * You should have received a copy of the GNU General Public License
367+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
368+ *
369+ * Authors: Robert Ancell <robert.ancell@canonical.com>
370+ */
371+
372+public enum ShutdownDialogType
373+{
374+ LOGOUT,
375+ SHUTDOWN,
376+ RESTART
377+}
378+
379+public class ShutdownDialog : Gtk.Fixed
380+{
381+ public signal void close ();
382+
383+ private Cairo.ImageSurface? corner_surface = null;
384+ private Cairo.ImageSurface? left_surface = null;
385+ private Cairo.ImageSurface? top_surface = null;
386+ private Cairo.Pattern? corner_pattern = null;
387+ private Cairo.Pattern? left_pattern = null;
388+ private Cairo.Pattern? top_pattern = null;
389+
390+ private const int BORDER_SIZE = 30;
391+ private const int CLOSE_OFFSET = 3;
392+
393+ private Gtk.Box vbox;
394+ private DialogButton close_button;
395+ private Gtk.Box button_box;
396+
397+ public ShutdownDialog (ShutdownDialogType type)
398+ {
399+ vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 10);
400+ vbox.visible = true;
401+ add (vbox);
402+
403+ vbox.border_width = 20;
404+
405+ var title_label = new Gtk.Label (_("Shutdown"));
406+ title_label.override_font (Pango.FontDescription.from_string ("Ubuntu Light 15"));
407+ title_label.override_color (Gtk.StateFlags.NORMAL, { 1.0f, 1.0f, 1.0f, 1.0f });
408+ title_label.set_alignment (0.0f, 0.5f);
409+ vbox.pack_start (title_label, false, false, 0);
410+
411+ string text;
412+ if (type == ShutdownDialogType.SHUTDOWN)
413+ text = _("Goodbye. Would you like to…");
414+ else
415+ {
416+ text = _("Are you sure you want to shut down the computer?");
417+ title_label.visible = true;
418+ }
419+ var label = new Gtk.Label (text);
420+ label.set_line_wrap (true);
421+ label.override_font (Pango.FontDescription.from_string ("Ubuntu Light 12"));
422+ label.override_color (Gtk.StateFlags.NORMAL, { 1.0f, 1.0f, 1.0f, 1.0f });
423+ label.set_alignment (0.0f, 0.5f);
424+ label.visible = true;
425+ vbox.pack_start (label, false, false, 0);
426+
427+ button_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 20);
428+ button_box.visible = true;
429+ vbox.pack_start (button_box, false, false, 0);
430+
431+ if (type == ShutdownDialogType.SHUTDOWN)
432+ {
433+ if (LightDM.get_can_suspend ())
434+ {
435+ var button = add_button (_("Suspend"), Path.build_filename (Config.PKGDATADIR, "suspend.png"), Path.build_filename (Config.PKGDATADIR, "suspend_highlight.png"));
436+ button.clicked.connect (() =>
437+ {
438+ try
439+ {
440+ LightDM.suspend ();
441+ close ();
442+ }
443+ catch (Error e)
444+ {
445+ warning ("Failed to suspend: %s", e.message);
446+ }
447+ });
448+ }
449+
450+ if (LightDM.get_can_hibernate ())
451+ {
452+ var button = add_button (_("Hibernate"), Path.build_filename (Config.PKGDATADIR, "hibernate.png"), Path.build_filename (Config.PKGDATADIR, "hibernate_highlight.png"));
453+ button.clicked.connect (() =>
454+ {
455+ try
456+ {
457+ LightDM.hibernate ();
458+ close ();
459+ }
460+ catch (Error e)
461+ {
462+ warning ("Failed to hibernate: %s", e.message);
463+ }
464+ });
465+ }
466+ }
467+
468+ if (LightDM.get_can_restart ())
469+ {
470+ var button = add_button (_("Restart"), Path.build_filename (Config.PKGDATADIR, "restart.png"), Path.build_filename (Config.PKGDATADIR, "restart_highlight.png"));
471+ button.clicked.connect (() =>
472+ {
473+ try
474+ {
475+ LightDM.restart ();
476+ close ();
477+ }
478+ catch (Error e)
479+ {
480+ warning ("Failed to restart: %s", e.message);
481+ }
482+ });
483+ }
484+
485+ if (LightDM.get_can_shutdown ())
486+ {
487+ var button = add_button (_("Shutdown"), Path.build_filename (Config.PKGDATADIR, "shutdown.png"), Path.build_filename (Config.PKGDATADIR, "shutdown_highlight.png"));
488+ button.clicked.connect (() =>
489+ {
490+ try
491+ {
492+ LightDM.shutdown ();
493+ close ();
494+ }
495+ catch (Error e)
496+ {
497+ warning ("Failed to shutdown: %s", e.message);
498+ }
499+ });
500+ }
501+
502+ close_button = new DialogButton (Path.build_filename (Config.PKGDATADIR, "dialog_close.png"), Path.build_filename (Config.PKGDATADIR, "dialog_close_highlight.png"));
503+ close_button.can_focus = false;
504+ close_button.clicked.connect (() => { close (); });
505+ close_button.visible = true;
506+ add (close_button);
507+ }
508+
509+ public void focus_next ()
510+ {
511+ (get_toplevel () as Gtk.Window).move_focus (Gtk.DirectionType.TAB_FORWARD);
512+ }
513+
514+ public void focus_prev ()
515+ {
516+ (get_toplevel () as Gtk.Window).move_focus (Gtk.DirectionType.TAB_BACKWARD);
517+ }
518+
519+ public void cancel ()
520+ {
521+ var widget = (get_toplevel () as Gtk.Window).get_focus ();
522+ if (widget is DialogButton)
523+ (get_toplevel () as Gtk.Window).set_focus (null);
524+ else
525+ close ();
526+ }
527+
528+ public override void size_allocate (Gtk.Allocation allocation)
529+ {
530+ base.size_allocate (allocation);
531+
532+ var content_allocation = Gtk.Allocation ();
533+ int minimum_width, natural_width, minimum_height, natural_height;
534+ vbox.get_preferred_width (out minimum_width, out natural_width);
535+ vbox.get_preferred_height_for_width (minimum_width, out minimum_height, out natural_height);
536+ content_allocation.x = allocation.x + (allocation.width - minimum_width) / 2;
537+ content_allocation.y = allocation.y + (allocation.height - minimum_height) / 2;
538+ content_allocation.width = minimum_width;
539+ content_allocation.height = minimum_height;
540+ vbox.size_allocate (content_allocation);
541+
542+ var a = Gtk.Allocation ();
543+ close_button.get_preferred_width (out minimum_width, out natural_width);
544+ close_button.get_preferred_height (out minimum_height, out natural_height);
545+ a.x = content_allocation.x - BORDER_SIZE + CLOSE_OFFSET;
546+ a.y = content_allocation.y - BORDER_SIZE + CLOSE_OFFSET;
547+ a.width = minimum_width;
548+ a.height = minimum_height;
549+ close_button.size_allocate (a);
550+ }
551+
552+ public override bool draw (Cairo.Context c)
553+ {
554+ if (corner_surface == null)
555+ {
556+ corner_surface = new Cairo.ImageSurface.from_png (Path.build_filename (Config.PKGDATADIR, "switcher_corner.png"));
557+ left_surface = new Cairo.ImageSurface.from_png (Path.build_filename (Config.PKGDATADIR, "switcher_left.png"));
558+ top_surface = new Cairo.ImageSurface.from_png (Path.build_filename (Config.PKGDATADIR, "switcher_top.png"));
559+ corner_pattern = new Cairo.Pattern.for_surface (corner_surface);
560+ left_pattern = new Cairo.Pattern.for_surface (left_surface);
561+ left_pattern.set_extend (Cairo.Extend.REPEAT);
562+ top_pattern = new Cairo.Pattern.for_surface (top_surface);
563+ top_pattern.set_extend (Cairo.Extend.REPEAT);
564+ }
565+
566+ var width = vbox.get_allocated_width () + 20 * 2 + BORDER_SIZE * 2;
567+ var height = vbox.get_allocated_height () + 20 * 2 + BORDER_SIZE * 2;
568+
569+ /* Darken background */
570+ c.set_source_rgba (0, 0, 0, 0.25);
571+ c.paint ();
572+
573+ /* Draw dialog */
574+ c.save ();
575+ c.translate ((get_allocated_width () - width) * 0.5, (get_allocated_height () - height) * 0.5);
576+
577+ /* Top left */
578+ var m = Cairo.Matrix.identity ();
579+ corner_pattern.set_matrix (m);
580+ c.set_source (corner_pattern);
581+ c.rectangle (0, 0, BORDER_SIZE, BORDER_SIZE);
582+ c.fill ();
583+
584+ /* Top right */
585+ m = Cairo.Matrix.identity ();
586+ m.translate (width, 0);
587+ m.scale (-1, 1);
588+ corner_pattern.set_matrix (m);
589+ c.set_source (corner_pattern);
590+ c.rectangle (width - BORDER_SIZE, 0, BORDER_SIZE, BORDER_SIZE);
591+ c.fill ();
592+
593+ /* Bottom left */
594+ m = Cairo.Matrix.identity ();
595+ m.translate (0, height);
596+ m.scale (1, -1);
597+ corner_pattern.set_matrix (m);
598+ c.set_source (corner_pattern);
599+ c.rectangle (0, height - BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
600+ c.fill ();
601+
602+ /* Bottom right */
603+ m = Cairo.Matrix.identity ();
604+ m.translate (width, height);
605+ m.scale (-1, -1);
606+ corner_pattern.set_matrix (m);
607+ c.set_source (corner_pattern);
608+ c.rectangle (width - BORDER_SIZE, height - BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
609+ c.fill ();
610+
611+ /* Left */
612+ m = Cairo.Matrix.identity ();
613+ left_pattern.set_matrix (m);
614+ c.set_source (left_pattern);
615+ c.rectangle (0, BORDER_SIZE, BORDER_SIZE, height - BORDER_SIZE * 2);
616+ c.fill ();
617+
618+ /* Right */
619+ m = Cairo.Matrix.identity ();
620+ m.translate (width, 0);
621+ m.scale (-1, 1);
622+ left_pattern.set_matrix (m);
623+ c.set_source (left_pattern);
624+ c.rectangle (width - BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, height - BORDER_SIZE * 2);
625+ c.fill ();
626+
627+ /* Top */
628+ m = Cairo.Matrix.identity ();
629+ top_pattern.set_matrix (m);
630+ c.set_source (top_pattern);
631+ c.rectangle (BORDER_SIZE, 0, width - BORDER_SIZE * 2, BORDER_SIZE);
632+ c.fill ();
633+
634+ /* Right */
635+ m = Cairo.Matrix.identity ();
636+ m.translate (0, height);
637+ m.scale (1, -1);
638+ top_pattern.set_matrix (m);
639+ c.set_source (top_pattern);
640+ c.rectangle (BORDER_SIZE, height - BORDER_SIZE, width - BORDER_SIZE * 2, BORDER_SIZE);
641+ c.fill ();
642+
643+ /* Background */
644+ DashBox.cairo_rounded_rectangle (c, 20, 20, width - 40, height - 40, 5);
645+ c.set_source_rgba (0, 0, 0, 0.75);
646+ c.fill ();
647+
648+ c.restore ();
649+
650+ return base.draw (c);
651+ }
652+
653+ public override bool button_press_event (Gdk.EventButton event)
654+ {
655+ /* Close when selecting the background */
656+ // FIXME: Broken..
657+ close ();
658+ return true;
659+ }
660+
661+ private DialogButton add_button (string text, string inactive_filename, string active_filename)
662+ {
663+ var b = new Gtk.Box (Gtk.Orientation.VERTICAL, 9);
664+ b.visible = true;
665+ button_box.pack_start (b, false, false, 0);
666+
667+ var label = new Gtk.Label (text);
668+ label.visible = true;
669+ label.override_font (Pango.FontDescription.from_string ("Ubuntu Light 12"));
670+ label.override_color (Gtk.StateFlags.NORMAL, { 1.0f, 1.0f, 1.0f, 0.0f });
671+ var button = new DialogButton (inactive_filename, active_filename, label);
672+ button.visible = true;
673+
674+ b.pack_start (button, false, false, 0);
675+ b.pack_start (label, false, false, 0);
676+
677+ return button;
678+ }
679+}
680+
681+private class DialogButton : Gtk.Button
682+{
683+ private string inactive_filename;
684+ private string active_filename;
685+ private Gtk.Image i;
686+ private Gtk.Label? l;
687+
688+ public DialogButton (string inactive_filename, string active_filename, Gtk.Label? label = null)
689+ {
690+ this.inactive_filename = inactive_filename;
691+ this.active_filename = active_filename;
692+ l = label;
693+ relief = Gtk.ReliefStyle.NONE;
694+ focus_on_click = false;
695+ i = new Gtk.Image.from_file (inactive_filename);
696+ i.visible = true;
697+ add (i);
698+ }
699+
700+ public override bool enter_notify_event (Gdk.EventCrossing event)
701+ {
702+ grab_focus ();
703+ return base.enter_notify_event (event);
704+ }
705+
706+ public override bool leave_notify_event (Gdk.EventCrossing event)
707+ {
708+ (get_toplevel () as Gtk.Window).set_focus (null);
709+ return base.leave_notify_event (event);
710+ }
711+
712+ public override bool focus_in_event (Gdk.EventFocus event)
713+ {
714+ i.set_from_file (active_filename);
715+ if (l != null)
716+ l.override_color (Gtk.StateFlags.NORMAL, { 1.0f, 1.0f, 1.0f, 1.0f });
717+ return base.focus_in_event (event);
718+ }
719+
720+ public override bool focus_out_event (Gdk.EventFocus event)
721+ {
722+ i.set_from_file (inactive_filename);
723+ if (l != null)
724+ l.override_color (Gtk.StateFlags.NORMAL, { 1.0f, 1.0f, 1.0f, 0.0f });
725+ return base.focus_out_event (event);
726+ }
727+
728+ public override bool draw (Cairo.Context c)
729+ {
730+ i.draw (c);
731+ return true;
732+ }
733+}
734
735=== modified file 'src/unity-greeter.vala'
736--- src/unity-greeter.vala 2013-10-02 17:46:49 +0000
737+++ src/unity-greeter.vala 2013-11-05 04:15:26 +0000
738@@ -46,6 +46,8 @@
739
740 private static Timer log_timer;
741
742+ private DialogDBusInterface dbus_object;
743+
744 private UnityGreeter (bool test_mode_)
745 {
746 singleton = this;
747@@ -98,6 +100,38 @@
748
749 main_window = new MainWindow ();
750
751+ dbus_object = new DialogDBusInterface ();
752+ dbus_object.open_dialog.connect ((type) =>
753+ {
754+ ShutdownDialogType dialog_type;
755+ switch (type)
756+ {
757+ default:
758+ case 1:
759+ dialog_type = ShutdownDialogType.LOGOUT;
760+ break;
761+ case 2:
762+ dialog_type = ShutdownDialogType.RESTART;
763+ break;
764+ }
765+ main_window.show_shutdown_dialog (dialog_type);
766+ });
767+ dbus_object.close_dialog.connect ((type) => { main_window.close_shutdown_dialog (); });
768+ Bus.own_name (BusType.SESSION, "com.canonical.Unity", BusNameOwnerFlags.NONE,
769+ (c) =>
770+ {
771+ try
772+ {
773+ c.register_object ("/org/gnome/SessionManager/EndSessionDialog", dbus_object);
774+ }
775+ catch (Error e)
776+ {
777+ warning ("Failed to register /org/gnome/SessionManager/EndSessionDialog: %s", e.message);
778+ }
779+ },
780+ null,
781+ () => debug ("Failed to acquire name com.canonical.Unity"));
782+
783 start_fake_wm ();
784 Gdk.threads_add_idle (ready_cb);
785 }
786@@ -535,3 +569,20 @@
787 return Posix.EXIT_SUCCESS;
788 }
789 }
790+
791+[DBus (name="org.gnome.SessionManager.EndSessionDialog")]
792+public class DialogDBusInterface : Object
793+{
794+ public signal void open_dialog (uint32 type);
795+ public signal void close_dialog ();
796+
797+ public void open (uint32 type, uint32 timestamp, uint32 seconds_to_stay_open, ObjectPath[] inhibitor_object_paths)
798+ {
799+ open_dialog (type);
800+ }
801+
802+ public void close ()
803+ {
804+ close_dialog ();
805+ }
806+}
807
808=== modified file 'tests/Makefile.am'
809--- tests/Makefile.am 2013-10-17 22:09:16 +0000
810+++ tests/Makefile.am 2013-11-05 04:15:26 +0000
811@@ -34,7 +34,8 @@
812 ../src/session-list.vala \
813 ../src/main-window.vala \
814 ../src/list-stack.vala \
815- ../src/settings.vala
816+ ../src/settings.vala \
817+ ../src/shutdown-dialog.vala
818
819
820 unity_greeter_test_CFLAGS = \

Subscribers

People subscribed via source and target branches