Merge lp:~robert-ancell/unity-greeter/end-session-dialog into lp:unity-greeter
- end-session-dialog
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Michael Terry |
Approved revision: | 1031 |
Merged at revision: | 1013 |
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Michael Terry (community) | Approve | ||
Review via email: mp+193880@code.launchpad.net |
This proposal supersedes a proposal from 2013-10-21.
Commit message
Use Unity style shutdown dialogs
Handle hardware power button in greeter
Description of the change
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1018
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1020
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1022
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michael Terry (mterry) wrote : Posted in a previous version of this proposal | # |
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.
Michael Terry (mterry) wrote : Posted in a previous version of this proposal | # |
Whoops, forgot to set status.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1029
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Robert Ancell (robert-ancell) wrote : | # |
Should be good now - can you re-review?
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1031
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1031
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1031
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michael Terry (mterry) wrote : | # |
Works better for me now, thanks!
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'configure.ac' |
2 | --- configure.ac 2013-10-02 17:46:49 +0000 |
3 | +++ configure.ac 2013-11-05 04:29:38 +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:29:38 +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' |
46 | Binary files data/dialog_close.png 1970-01-01 00:00:00 +0000 and data/dialog_close.png 2013-11-05 04:29:38 +0000 differ |
47 | === added file 'data/dialog_close_highlight.png' |
48 | Binary files data/dialog_close_highlight.png 1970-01-01 00:00:00 +0000 and data/dialog_close_highlight.png 2013-11-05 04:29:38 +0000 differ |
49 | === added file 'data/hibernate.png' |
50 | Binary files data/hibernate.png 1970-01-01 00:00:00 +0000 and data/hibernate.png 2013-11-05 04:29:38 +0000 differ |
51 | === added file 'data/hibernate_highlight.png' |
52 | Binary files data/hibernate_highlight.png 1970-01-01 00:00:00 +0000 and data/hibernate_highlight.png 2013-11-05 04:29:38 +0000 differ |
53 | === added file 'data/restart.png' |
54 | Binary files data/restart.png 1970-01-01 00:00:00 +0000 and data/restart.png 2013-11-05 04:29:38 +0000 differ |
55 | === added file 'data/restart_highlight.png' |
56 | Binary files data/restart_highlight.png 1970-01-01 00:00:00 +0000 and data/restart_highlight.png 2013-11-05 04:29:38 +0000 differ |
57 | === added file 'data/shutdown.png' |
58 | Binary files data/shutdown.png 1970-01-01 00:00:00 +0000 and data/shutdown.png 2013-11-05 04:29:38 +0000 differ |
59 | === added file 'data/shutdown_highlight.png' |
60 | Binary files data/shutdown_highlight.png 1970-01-01 00:00:00 +0000 and data/shutdown_highlight.png 2013-11-05 04:29:38 +0000 differ |
61 | === added file 'data/suspend.png' |
62 | Binary files data/suspend.png 1970-01-01 00:00:00 +0000 and data/suspend.png 2013-11-05 04:29:38 +0000 differ |
63 | === added file 'data/suspend_highlight.png' |
64 | Binary files data/suspend_highlight.png 1970-01-01 00:00:00 +0000 and data/suspend_highlight.png 2013-11-05 04:29:38 +0000 differ |
65 | === added file 'data/switcher_corner.png' |
66 | Binary files data/switcher_corner.png 1970-01-01 00:00:00 +0000 and data/switcher_corner.png 2013-11-05 04:29:38 +0000 differ |
67 | === added file 'data/switcher_left.png' |
68 | Binary files data/switcher_left.png 1970-01-01 00:00:00 +0000 and data/switcher_left.png 2013-11-05 04:29:38 +0000 differ |
69 | === added file 'data/switcher_top.png' |
70 | Binary files data/switcher_top.png 1970-01-01 00:00:00 +0000 and data/switcher_top.png 2013-11-05 04:29:38 +0000 differ |
71 | === modified file 'debian/changelog' |
72 | --- debian/changelog 2013-10-03 13:59:34 +0000 |
73 | +++ debian/changelog 2013-11-05 04:29:38 +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:29:38 +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:29:38 +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:29:38 +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:29:38 +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:29:38 +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:29:38 +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:29:38 +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:29:38 +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:29:38 +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 = \ |
PASSED: Continuous integration, rev:1016 jenkins. qa.ubuntu. com/job/ unity-greeter- ci/13/ jenkins. qa.ubuntu. com/job/ unity-greeter- saucy-amd64- ci/13 jenkins. qa.ubuntu. com/job/ unity-greeter- saucy-armhf- ci/8
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: 10.97.0. 26:8080/ job/unity- greeter- ci/13/rebuild
http://