]>
Commit | Line | Data |
---|---|---|
ed80b192 JR |
1 | --- |
2 | Allow gnome-panel to fall back to old style logout if gnome-session 2.24 | |
3 | isn't present. | |
4 | ||
5 | gnome-panel/Makefile.am | 4 | |
6 | gnome-panel/libpanel-util/panel-session-manager.c | 23 + | |
7 | gnome-panel/panel-gdm.c | 417 ++++++++++++++++++++++ | |
8 | gnome-panel/panel-gdm.h | 52 ++ | |
9 | gnome-panel/panel-logout.c | 402 +++++++++++++++++++++ | |
10 | gnome-panel/panel-logout.h | 66 +++ | |
11 | gnome-panel/panel-session.c | 28 + | |
12 | gnome-panel/panel-session.h | 1 | |
13 | 8 files changed, 993 insertions(+) | |
14 | ||
15 | Index: b/gnome-panel/panel-gdm.c | |
16 | =================================================================== | |
17 | --- /dev/null | |
18 | +++ b/gnome-panel/panel-gdm.c | |
19 | @@ -0,0 +1,417 @@ | |
20 | +/* | |
21 | + * gdm-protocol.c: GDM logout action protocol implementation | |
22 | + * | |
23 | + * Copyright (C) 2005 Raffaele Sandrini | |
24 | + * Copyright (C) 2005 Red Hat, Inc. | |
25 | + * Copyright (C) 2002, 2003 George Lebl | |
26 | + * Copyright (C) 2001 Queen of England, | |
27 | + * | |
28 | + * This program is free software; you can redistribute it and/or | |
29 | + * modify it under the terms of the GNU General Public License as | |
30 | + * published by the Free Software Foundation; either version 2 of the | |
31 | + * License, or (at your option) any later version. | |
32 | + * | |
33 | + * This program is distributed in the hope that it will be useful, but | |
34 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
35 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
36 | + * General Public License for more details. | |
37 | + * | |
38 | + * You should have received a copy of the GNU General Public License | |
39 | + * along with this program; if not, write to the Free Software | |
40 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
41 | + * 02111-1307, USA. | |
42 | + * | |
43 | + * Authors: | |
44 | + * Raffaele Sandrini <rasa@gmx.ch> | |
45 | + * George Lebl <jirka@5z.com> | |
46 | + * Mark McLoughlin <mark@skynet.ie> | |
47 | + */ | |
48 | + | |
49 | +#include <config.h> | |
50 | + | |
51 | +#include "panel-gdm.h" | |
52 | + | |
53 | +#include <string.h> | |
54 | +#include <errno.h> | |
55 | +#include <unistd.h> | |
56 | +#include <time.h> | |
57 | +#include <sys/socket.h> | |
58 | +#include <sys/un.h> | |
59 | + | |
60 | +#include <X11/Xauth.h> | |
61 | +#include <gdk/gdk.h> | |
62 | + | |
63 | +#define GDM_PROTOCOL_UPDATE_INTERVAL 1 /* seconds */ | |
64 | + | |
65 | +#define GDM_PROTOCOL_SOCKET_PATH "/var/run/gdm_socket" | |
66 | + | |
67 | +#define GDM_PROTOCOL_MSG_CLOSE "CLOSE" | |
68 | +#define GDM_PROTOCOL_MSG_VERSION "VERSION" | |
69 | +#define GDM_PROTOCOL_MSG_AUTHENTICATE "AUTH_LOCAL" | |
70 | +#define GDM_PROTOCOL_MSG_QUERY_ACTION "QUERY_LOGOUT_ACTION" | |
71 | +#define GDM_PROTOCOL_MSG_SET_ACTION "SET_SAFE_LOGOUT_ACTION" | |
72 | +#define GDM_PROTOCOL_MSG_FLEXI_XSERVER "FLEXI_XSERVER" | |
73 | + | |
74 | +#define GDM_ACTION_STR_NONE "NONE" | |
75 | +#define GDM_ACTION_STR_SHUTDOWN "HALT" | |
76 | +#define GDM_ACTION_STR_REBOOT "REBOOT" | |
77 | +#define GDM_ACTION_STR_SUSPEND "SUSPEND" | |
78 | + | |
79 | +typedef struct { | |
80 | + int fd; | |
81 | + char *auth_cookie; | |
82 | + | |
83 | + GdmLogoutAction available_actions; | |
84 | + GdmLogoutAction current_actions; | |
85 | + | |
86 | + time_t last_update; | |
87 | +} GdmProtocolData; | |
88 | + | |
89 | +static GdmProtocolData gdm_protocol_data = { | |
90 | + 0, | |
91 | + NULL, | |
92 | + GDM_LOGOUT_ACTION_NONE, | |
93 | + GDM_LOGOUT_ACTION_NONE, | |
94 | + 0 | |
95 | +}; | |
96 | + | |
97 | +static char * | |
98 | +gdm_send_protocol_msg (GdmProtocolData *data, | |
99 | + const char *msg) | |
100 | +{ | |
101 | + GString *retval; | |
102 | + char buf[256]; | |
103 | + char *p; | |
104 | + int len; | |
105 | + | |
106 | + p = g_strconcat (msg, "\n", NULL); | |
107 | + if (write (data->fd, p, strlen (p)) < 0) { | |
108 | + g_free (p); | |
109 | + | |
110 | + g_warning ("Failed to send message to GDM: %s", | |
111 | + g_strerror (errno)); | |
112 | + return NULL; | |
113 | + } | |
114 | + g_free (p); | |
115 | + | |
116 | + p = NULL; | |
117 | + retval = NULL; | |
118 | + while ((len = read (data->fd, buf, sizeof (buf) - 1)) > 0) { | |
119 | + buf[len] = '\0'; | |
120 | + | |
121 | + if (!retval) | |
122 | + retval = g_string_new (buf); | |
123 | + else | |
124 | + retval = g_string_append (retval, buf); | |
125 | + | |
126 | + if ((p = strchr (retval->str, '\n'))) | |
127 | + break; | |
128 | + } | |
129 | + | |
130 | + if (p) *p = '\0'; | |
131 | + | |
132 | + return retval ? g_string_free (retval, FALSE) : NULL; | |
133 | +} | |
134 | + | |
135 | +static char * | |
136 | +get_display_number (void) | |
137 | +{ | |
138 | + const char *display_name; | |
139 | + char *retval; | |
140 | + char *p; | |
141 | + | |
142 | + display_name = gdk_display_get_name (gdk_display_get_default ()); | |
143 | + | |
144 | + p = strchr (display_name, ':'); | |
145 | + if (!p) | |
146 | + return g_strdup ("0"); | |
147 | + | |
148 | + while (*p == ':') p++; | |
149 | + | |
150 | + retval = g_strdup (p); | |
151 | + | |
152 | + p = strchr (retval, '.'); | |
153 | + if (p != NULL) | |
154 | + *p = '\0'; | |
155 | + | |
156 | + return retval; | |
157 | +} | |
158 | + | |
159 | +static gboolean | |
160 | +gdm_authenticate_connection (GdmProtocolData *data) | |
161 | +{ | |
162 | +#define GDM_MIT_MAGIC_COOKIE_LEN 16 | |
163 | + | |
164 | + const char *xau_path; | |
165 | + FILE *f; | |
166 | + Xauth *xau; | |
167 | + char *display_number; | |
168 | + gboolean retval; | |
169 | + | |
170 | + if (data->auth_cookie) { | |
171 | + char *msg; | |
172 | + char *response; | |
173 | + | |
174 | + msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s", | |
175 | + data->auth_cookie); | |
176 | + response = gdm_send_protocol_msg (data, msg); | |
177 | + g_free (msg); | |
178 | + | |
179 | + if (response && !strcmp (response, "OK")) { | |
180 | + g_free (response); | |
181 | + return TRUE; | |
182 | + } else { | |
183 | + g_free (response); | |
184 | + g_free (data->auth_cookie); | |
185 | + data->auth_cookie = NULL; | |
186 | + } | |
187 | + } | |
188 | + | |
189 | + if (!(xau_path = XauFileName ())) | |
190 | + return FALSE; | |
191 | + | |
192 | + if (!(f = fopen (xau_path, "r"))) | |
193 | + return FALSE; | |
194 | + | |
195 | + retval = FALSE; | |
196 | + display_number = get_display_number (); | |
197 | + | |
198 | + while ((xau = XauReadAuth (f))) { | |
199 | + char buffer[40]; /* 2*16 == 32, so 40 is enough */ | |
200 | + char *msg; | |
201 | + char *response; | |
202 | + int i; | |
203 | + | |
204 | + if (xau->family != FamilyLocal || | |
205 | + strncmp (xau->number, display_number, xau->number_length) || | |
206 | + strncmp (xau->name, "MIT-MAGIC-COOKIE-1", xau->name_length) || | |
207 | + xau->data_length != GDM_MIT_MAGIC_COOKIE_LEN) { | |
208 | + XauDisposeAuth (xau); | |
209 | + continue; | |
210 | + } | |
211 | + | |
212 | + for (i = 0; i < GDM_MIT_MAGIC_COOKIE_LEN; i++) | |
213 | + g_snprintf (buffer + 2*i, 3, "%02x", (guint)(guchar)xau->data[i]); | |
214 | + | |
215 | + XauDisposeAuth (xau); | |
216 | + | |
217 | + msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s", buffer); | |
218 | + response = gdm_send_protocol_msg (data, msg); | |
219 | + g_free (msg); | |
220 | + | |
221 | + if (response && !strcmp (response, "OK")) { | |
222 | + data->auth_cookie = g_strdup (buffer); | |
223 | + g_free (response); | |
224 | + retval = TRUE; | |
225 | + break; | |
226 | + } | |
227 | + | |
228 | + g_free (response); | |
229 | + } | |
230 | + | |
231 | + g_free (display_number); | |
232 | + | |
233 | + fclose (f); | |
234 | + | |
235 | + return retval; | |
236 | + | |
237 | +#undef GDM_MIT_MAGIC_COOKIE_LEN | |
238 | +} | |
239 | + | |
240 | +static void | |
241 | +gdm_shutdown_protocol_connection (GdmProtocolData *data) | |
242 | +{ | |
243 | + if (data->fd) | |
244 | + close (data->fd); | |
245 | + data->fd = 0; | |
246 | +} | |
247 | + | |
248 | +static gboolean | |
249 | +gdm_init_protocol_connection (GdmProtocolData *data) | |
250 | +{ | |
251 | + struct sockaddr_un addr; | |
252 | + char *response; | |
253 | + | |
254 | + g_assert (data->fd <= 0); | |
255 | + | |
256 | + data->fd = socket (AF_UNIX, SOCK_STREAM, 0); | |
257 | + if (data->fd < 0) { | |
258 | + g_warning ("Failed to create GDM socket: %s", | |
259 | + g_strerror (errno)); | |
260 | + gdm_shutdown_protocol_connection (data); | |
261 | + return FALSE; | |
262 | + } | |
263 | + | |
264 | + if (g_file_test (GDM_PROTOCOL_SOCKET_PATH, G_FILE_TEST_EXISTS)) | |
265 | + strcpy (addr.sun_path, GDM_PROTOCOL_SOCKET_PATH); | |
266 | + else | |
267 | + strcpy (addr.sun_path, "/tmp/.gdm_socket"); | |
268 | + | |
269 | + addr.sun_family = AF_UNIX; | |
270 | + | |
271 | + if (connect (data->fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) { | |
272 | + g_warning ("Failed to establish a connection with GDM: %s", | |
273 | + g_strerror (errno)); | |
274 | + gdm_shutdown_protocol_connection (data); | |
275 | + return FALSE; | |
276 | + } | |
277 | + | |
278 | + response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_VERSION); | |
279 | + if (!response || strncmp (response, "GDM ", strlen ("GDM ") != 0)) { | |
280 | + g_free (response); | |
281 | + | |
282 | + g_warning ("Failed to get protocol version from GDM"); | |
283 | + gdm_shutdown_protocol_connection (data); | |
284 | + | |
285 | + return FALSE; | |
286 | + } | |
287 | + g_free (response); | |
288 | + | |
289 | + if (!gdm_authenticate_connection (data)) { | |
290 | + g_warning ("Failed to authenticate with GDM"); | |
291 | + gdm_shutdown_protocol_connection (data); | |
292 | + return FALSE; | |
293 | + } | |
294 | + | |
295 | + return TRUE; | |
296 | +} | |
297 | + | |
298 | +static void | |
299 | +gdm_parse_query_response (GdmProtocolData *data, | |
300 | + const char *response) | |
301 | +{ | |
302 | + char **actions; | |
303 | + int i; | |
304 | + | |
305 | + data->available_actions = GDM_LOGOUT_ACTION_NONE; | |
306 | + data->current_actions = GDM_LOGOUT_ACTION_NONE; | |
307 | + | |
308 | + if (strncmp (response, "OK ", 3) != 0) | |
309 | + return; | |
310 | + | |
311 | + response += 3; | |
312 | + | |
313 | + actions = g_strsplit (response, ";", -1); | |
314 | + for (i = 0; actions[i]; i++) { | |
315 | + GdmLogoutAction action = GDM_LOGOUT_ACTION_NONE; | |
316 | + gboolean selected = FALSE; | |
317 | + char *str = actions [i]; | |
318 | + int len; | |
319 | + | |
320 | + len = strlen (str); | |
321 | + if (!len) | |
322 | + continue; | |
323 | + | |
324 | + if (str[len - 1] == '!') { | |
325 | + selected = TRUE; | |
326 | + str[len - 1] = '\0'; | |
327 | + } | |
328 | + | |
329 | + if (!strcmp (str, GDM_ACTION_STR_SHUTDOWN)) | |
330 | + action = GDM_LOGOUT_ACTION_SHUTDOWN; | |
331 | + else if (!strcmp (str, GDM_ACTION_STR_REBOOT)) | |
332 | + action = GDM_LOGOUT_ACTION_REBOOT; | |
333 | + else if (!strcmp (str, GDM_ACTION_STR_SUSPEND)) | |
334 | + action = GDM_LOGOUT_ACTION_SUSPEND; | |
335 | + | |
336 | + data->available_actions |= action; | |
337 | + if (selected) | |
338 | + data->current_actions |= action; | |
339 | + } | |
340 | + | |
341 | + g_strfreev (actions); | |
342 | +} | |
343 | + | |
344 | +static void | |
345 | +gdm_update_logout_actions (GdmProtocolData *data) | |
346 | +{ | |
347 | + time_t current_time; | |
348 | + char *response; | |
349 | + | |
350 | + current_time = time (NULL); | |
351 | + if (current_time <= (data->last_update + GDM_PROTOCOL_UPDATE_INTERVAL)) | |
352 | + return; | |
353 | + | |
354 | + data->last_update = current_time; | |
355 | + | |
356 | + if (!gdm_init_protocol_connection (data)) | |
357 | + return; | |
358 | + | |
359 | + if ((response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_QUERY_ACTION))) { | |
360 | + gdm_parse_query_response (data, response); | |
361 | + g_free (response); | |
362 | + } | |
363 | + | |
364 | + gdm_shutdown_protocol_connection (data); | |
365 | +} | |
366 | + | |
367 | +gboolean | |
368 | +gdm_supports_logout_action (GdmLogoutAction action) | |
369 | +{ | |
370 | + gdm_update_logout_actions (&gdm_protocol_data); | |
371 | + | |
372 | + return (gdm_protocol_data.available_actions & action) != 0; | |
373 | +} | |
374 | + | |
375 | +GdmLogoutAction | |
376 | +gdm_get_logout_action (void) | |
377 | +{ | |
378 | + gdm_update_logout_actions (&gdm_protocol_data); | |
379 | + | |
380 | + return gdm_protocol_data.current_actions; | |
381 | +} | |
382 | + | |
383 | +void | |
384 | +gdm_set_logout_action (GdmLogoutAction action) | |
385 | +{ | |
386 | + char *action_str = NULL; | |
387 | + char *msg; | |
388 | + char *response; | |
389 | + | |
390 | + if (!gdm_init_protocol_connection (&gdm_protocol_data)) | |
391 | + return; | |
392 | + | |
393 | + switch (action) { | |
394 | + case GDM_LOGOUT_ACTION_NONE: | |
395 | + action_str = GDM_ACTION_STR_NONE; | |
396 | + break; | |
397 | + case GDM_LOGOUT_ACTION_SHUTDOWN: | |
398 | + action_str = GDM_ACTION_STR_SHUTDOWN; | |
399 | + break; | |
400 | + case GDM_LOGOUT_ACTION_REBOOT: | |
401 | + action_str = GDM_ACTION_STR_REBOOT; | |
402 | + break; | |
403 | + case GDM_LOGOUT_ACTION_SUSPEND: | |
404 | + action_str = GDM_ACTION_STR_SUSPEND; | |
405 | + break; | |
406 | + } | |
407 | + | |
408 | + msg = g_strdup_printf (GDM_PROTOCOL_MSG_SET_ACTION " %s", action_str); | |
409 | + | |
410 | + response = gdm_send_protocol_msg (&gdm_protocol_data, msg); | |
411 | + | |
412 | + g_free (msg); | |
413 | + g_free (response); | |
414 | + | |
415 | + gdm_protocol_data.last_update = 0; | |
416 | + | |
417 | + gdm_shutdown_protocol_connection (&gdm_protocol_data); | |
418 | +} | |
419 | + | |
420 | +void | |
421 | +gdm_new_login (void) | |
422 | +{ | |
423 | + char *response; | |
424 | + | |
425 | + if (!gdm_init_protocol_connection (&gdm_protocol_data)) | |
426 | + return; | |
427 | + | |
428 | + response = gdm_send_protocol_msg (&gdm_protocol_data, | |
429 | + GDM_PROTOCOL_MSG_FLEXI_XSERVER); | |
430 | + | |
431 | + g_free (response); | |
432 | + | |
433 | + gdm_protocol_data.last_update = 0; | |
434 | + | |
435 | + gdm_shutdown_protocol_connection (&gdm_protocol_data); | |
436 | +} | |
437 | Index: b/gnome-panel/panel-logout.c | |
438 | =================================================================== | |
439 | --- /dev/null | |
440 | +++ b/gnome-panel/panel-logout.c | |
441 | @@ -0,0 +1,402 @@ | |
442 | +/* | |
443 | + * panel-logout.c: | |
444 | + * | |
445 | + * Copyright (C) 2006 Vincent Untz | |
446 | + * | |
447 | + * This program is free software; you can redistribute it and/or | |
448 | + * modify it under the terms of the GNU General Public License as | |
449 | + * published by the Free Software Foundation; either version 2 of the | |
450 | + * License, or (at your option) any later version. | |
451 | + * | |
452 | + * This program is distributed in the hope that it will be useful, but | |
453 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
454 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
455 | + * General Public License for more details. | |
456 | + * | |
457 | + * You should have received a copy of the GNU General Public License | |
458 | + * along with this program; if not, write to the Free Software | |
459 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
460 | + * 02111-1307, USA. | |
461 | + * | |
462 | + * Authors: | |
463 | + * Vincent Untz <vuntz@gnome.org> | |
464 | + */ | |
465 | + | |
466 | + | |
467 | +#include <config.h> | |
468 | + | |
469 | +#include <string.h> | |
470 | + | |
471 | +#include <glib/gi18n.h> | |
472 | +#include <gtk/gtkimage.h> | |
473 | +#include <gtk/gtklabel.h> | |
474 | +#include <gtk/gtkstock.h> | |
475 | + | |
476 | +#include <libpanel-util/panel-power-manager.h> | |
477 | + | |
478 | +#include "panel-logout.h" | |
479 | +#include "panel-gdm.h" | |
480 | +#include "panel-session.h" | |
481 | +#include "panel-icon-names.h" | |
482 | + | |
483 | +#define PANEL_LOGOUT_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialogPrivate)) | |
484 | + | |
485 | +#define AUTOMATIC_ACTION_TIMEOUT 60 | |
486 | + | |
487 | +enum { | |
488 | + PANEL_LOGOUT_RESPONSE_LOGOUT, | |
489 | + PANEL_LOGOUT_RESPONSE_SWITCH_USER, | |
490 | + PANEL_LOGOUT_RESPONSE_SHUTDOWN, | |
491 | + PANEL_LOGOUT_RESPONSE_REBOOT, | |
492 | + PANEL_LOGOUT_RESPONSE_STD, | |
493 | + PANEL_LOGOUT_RESPONSE_STR | |
494 | +}; | |
495 | + | |
496 | +struct _PanelLogoutDialogPrivate { | |
497 | + PanelLogoutDialogType type; | |
498 | + | |
499 | + PanelPowerManager *power_manager; | |
500 | + | |
501 | + int timeout; | |
502 | + unsigned int timeout_id; | |
503 | + | |
504 | + unsigned int default_response; | |
505 | +}; | |
506 | + | |
507 | +static PanelLogoutDialog *current_dialog = NULL; | |
508 | + | |
509 | +static void panel_logout_destroy (PanelLogoutDialog *logout_dialog, | |
510 | + gpointer data); | |
511 | +static void panel_logout_response (PanelLogoutDialog *logout_dialog, | |
512 | + guint response_id, | |
513 | + gpointer data); | |
514 | + | |
515 | +enum { | |
516 | + PROP_0, | |
517 | + PROP_MESSAGE_TYPE | |
518 | +}; | |
519 | +G_DEFINE_TYPE (PanelLogoutDialog, panel_logout, GTK_TYPE_MESSAGE_DIALOG); | |
520 | + | |
521 | +static void | |
522 | +panel_logout_set_property (GObject *object, | |
523 | + guint prop_id, | |
524 | + const GValue *value, | |
525 | + GParamSpec *pspec) | |
526 | +{ | |
527 | + switch (prop_id) { | |
528 | + case PROP_MESSAGE_TYPE: | |
529 | + break; | |
530 | + default: | |
531 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | |
532 | + break; | |
533 | + } | |
534 | +} | |
535 | + | |
536 | +static void | |
537 | +panel_logout_get_property (GObject *object, | |
538 | + guint prop_id, | |
539 | + GValue *value, | |
540 | + GParamSpec *pspec) | |
541 | +{ | |
542 | + switch (prop_id) { | |
543 | + case PROP_MESSAGE_TYPE: | |
544 | + g_value_set_enum (value, GTK_MESSAGE_WARNING); | |
545 | + break; | |
546 | + default: | |
547 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | |
548 | + break; | |
549 | + } | |
550 | +} | |
551 | + | |
552 | +static void | |
553 | +panel_logout_class_init (PanelLogoutDialogClass *klass) | |
554 | +{ | |
555 | + GObjectClass *gobject_class; | |
556 | + | |
557 | + gobject_class = G_OBJECT_CLASS (klass); | |
558 | + | |
559 | + /* This is a workaround to avoid a stupid crash: libgnomeui | |
560 | + * listens for the "show" signal on all GtkMessageDialog and | |
561 | + * gets the "message-type" of the dialogs. We will crash when | |
562 | + * it accesses this property if we don't override it since we | |
563 | + * didn't define it. */ | |
564 | + gobject_class->set_property = panel_logout_set_property; | |
565 | + gobject_class->get_property = panel_logout_get_property; | |
566 | + | |
567 | + g_object_class_override_property (gobject_class, | |
568 | + PROP_MESSAGE_TYPE, | |
569 | + "message-type"); | |
570 | + | |
571 | + g_type_class_add_private (klass, sizeof (PanelLogoutDialogPrivate)); | |
572 | +} | |
573 | + | |
574 | +static void | |
575 | +panel_logout_init (PanelLogoutDialog *logout_dialog) | |
576 | +{ | |
577 | + logout_dialog->priv = PANEL_LOGOUT_DIALOG_GET_PRIVATE (logout_dialog); | |
578 | + | |
579 | + logout_dialog->priv->timeout_id = 0; | |
580 | + logout_dialog->priv->timeout = 0; | |
581 | + logout_dialog->priv->default_response = GTK_RESPONSE_CANCEL; | |
582 | + | |
583 | + /* FIXME: we should most probably use gtk_window_set_transient_for(PANEL) */ | |
584 | + gtk_window_set_skip_taskbar_hint (GTK_WINDOW (logout_dialog), TRUE); | |
585 | + gtk_window_set_keep_above (GTK_WINDOW (logout_dialog), TRUE); | |
586 | + gtk_window_stick (GTK_WINDOW (logout_dialog)); | |
587 | + gtk_window_set_position (GTK_WINDOW (logout_dialog), | |
588 | + GTK_WIN_POS_CENTER_ALWAYS); | |
589 | + | |
590 | + logout_dialog->priv->power_manager = panel_power_manager_get (); | |
591 | + | |
592 | + g_signal_connect (logout_dialog, "destroy", | |
593 | + G_CALLBACK (panel_logout_destroy), NULL); | |
594 | + g_signal_connect (logout_dialog, "response", | |
595 | + G_CALLBACK (panel_logout_response), NULL); | |
596 | +} | |
597 | + | |
598 | +static void | |
599 | +panel_logout_destroy (PanelLogoutDialog *logout_dialog, | |
600 | + gpointer data) | |
601 | +{ | |
602 | + if (logout_dialog->priv->timeout_id != 0) | |
603 | + g_source_remove (logout_dialog->priv->timeout_id); | |
604 | + logout_dialog->priv->timeout_id = 0; | |
605 | + | |
606 | + g_object_unref (logout_dialog->priv->power_manager); | |
607 | + logout_dialog->priv->power_manager = NULL; | |
608 | + | |
609 | + current_dialog = NULL; | |
610 | +} | |
611 | + | |
612 | +static void | |
613 | +panel_logout_response (PanelLogoutDialog *logout_dialog, | |
614 | + guint response_id, | |
615 | + gpointer data) | |
616 | +{ | |
617 | + PanelPowerManager *power_manager; | |
618 | + | |
619 | + power_manager = g_object_ref (logout_dialog->priv->power_manager); | |
620 | + gtk_widget_destroy (GTK_WIDGET (logout_dialog)); | |
621 | + | |
622 | + switch (response_id) { | |
623 | + case GTK_RESPONSE_CANCEL: | |
624 | + break; | |
625 | + case PANEL_LOGOUT_RESPONSE_LOGOUT: | |
626 | + gdm_set_logout_action (GDM_LOGOUT_ACTION_NONE); | |
627 | + panel_session_request_logout (); | |
628 | + break; | |
629 | + case PANEL_LOGOUT_RESPONSE_SWITCH_USER: | |
630 | + gdm_new_login (); | |
631 | + break; | |
632 | + case PANEL_LOGOUT_RESPONSE_SHUTDOWN: | |
633 | + gdm_set_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN); | |
634 | + panel_session_request_logout (); | |
635 | + break; | |
636 | + case PANEL_LOGOUT_RESPONSE_REBOOT: | |
637 | + gdm_set_logout_action (GDM_LOGOUT_ACTION_REBOOT); | |
638 | + panel_session_request_logout (); | |
639 | + break; | |
640 | + case PANEL_LOGOUT_RESPONSE_STD: | |
641 | + if (panel_power_manager_can_hibernate (power_manager)) | |
642 | + panel_power_manager_attempt_hibernate (power_manager); | |
643 | + break; | |
644 | + case PANEL_LOGOUT_RESPONSE_STR: | |
645 | + if (panel_power_manager_can_suspend (power_manager)) | |
646 | + panel_power_manager_attempt_suspend (power_manager); | |
647 | + break; | |
648 | + case GTK_RESPONSE_NONE: | |
649 | + case GTK_RESPONSE_DELETE_EVENT: | |
650 | + break; | |
651 | + default: | |
652 | + g_assert_not_reached (); | |
653 | + } | |
654 | + g_object_unref (power_manager); | |
655 | +} | |
656 | + | |
657 | +static gboolean | |
658 | +panel_logout_timeout (gpointer data) | |
659 | +{ | |
660 | + PanelLogoutDialog *logout_dialog; | |
661 | + char *secondary_text; | |
662 | + char *name; | |
663 | + int seconds_to_show; | |
664 | + | |
665 | + logout_dialog = (PanelLogoutDialog *) data; | |
666 | + | |
667 | + if (!logout_dialog->priv->timeout) { | |
668 | + gtk_dialog_response (GTK_DIALOG (logout_dialog), | |
669 | + logout_dialog->priv->default_response); | |
670 | + | |
671 | + return FALSE; | |
672 | + } | |
673 | + | |
674 | + if (logout_dialog->priv->timeout <= 30) | |
675 | + seconds_to_show = logout_dialog->priv->timeout; | |
676 | + else { | |
677 | + seconds_to_show = (logout_dialog->priv->timeout/10) * 10; | |
678 | + if (logout_dialog->priv->timeout % 10) | |
679 | + seconds_to_show += 10; | |
680 | + } | |
681 | + | |
682 | + switch (logout_dialog->priv->type) { | |
683 | + case PANEL_LOGOUT_DIALOG_LOGOUT: | |
684 | + secondary_text = ngettext ("You are currently logged in as " | |
685 | + "\"%s\".\n" | |
686 | + "You will be automatically logged " | |
687 | + "out in %d second.", | |
688 | + "You are currently logged in as " | |
689 | + "\"%s\".\n" | |
690 | + "You will be automatically logged " | |
691 | + "out in %d seconds.", | |
692 | + seconds_to_show); | |
693 | + break; | |
694 | + case PANEL_LOGOUT_DIALOG_SHUTDOWN: | |
695 | + secondary_text = ngettext ("You are currently logged in as " | |
696 | + "\"%s\".\n" | |
697 | + "This system will be automatically " | |
698 | + "shut down in %d second.", | |
699 | + "You are currently logged in as " | |
700 | + "\"%s\".\n" | |
701 | + "This system will be automatically " | |
702 | + "shut down in %d seconds.", | |
703 | + seconds_to_show); | |
704 | + break; | |
705 | + default: | |
706 | + g_assert_not_reached (); | |
707 | + } | |
708 | + | |
709 | + name = g_locale_to_utf8 (g_get_real_name (), -1, NULL, NULL, NULL); | |
710 | + if (!name || name[0] == '\0' || strcmp (name, "Unknown") == 0) | |
711 | + name = g_locale_to_utf8 (g_get_user_name (), -1 , NULL, NULL, NULL); | |
712 | + | |
713 | + if (!name) | |
714 | + name = g_strdup (g_get_user_name ()); | |
715 | + | |
716 | + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (logout_dialog), | |
717 | + secondary_text, | |
718 | + name, | |
719 | + seconds_to_show, | |
720 | + NULL); | |
721 | + | |
722 | + logout_dialog->priv->timeout--; | |
723 | + | |
724 | + g_free (name); | |
725 | + | |
726 | + return TRUE; | |
727 | +} | |
728 | + | |
729 | +static void | |
730 | +panel_logout_set_timeout (PanelLogoutDialog *logout_dialog) | |
731 | +{ | |
732 | + logout_dialog->priv->timeout = AUTOMATIC_ACTION_TIMEOUT; | |
733 | + | |
734 | + /* Sets the secondary text */ | |
735 | + panel_logout_timeout (logout_dialog); | |
736 | + | |
737 | + if (logout_dialog->priv->timeout_id != 0) | |
738 | + g_source_remove (logout_dialog->priv->timeout_id); | |
739 | + | |
740 | + logout_dialog->priv->timeout_id = g_timeout_add (1000, | |
741 | + panel_logout_timeout, | |
742 | + logout_dialog); | |
743 | +} | |
744 | + | |
745 | +void | |
746 | +panel_logout_new (PanelLogoutDialogType type, | |
747 | + GdkScreen *screen, | |
748 | + guint32 activate_time) | |
749 | +{ | |
750 | + PanelLogoutDialog *logout_dialog; | |
751 | + char *icon_name; | |
752 | + char *primary_text; | |
753 | + | |
754 | + if (current_dialog != NULL) { | |
755 | + if (current_dialog->priv->type == type) { | |
756 | + gtk_window_set_screen (GTK_WINDOW (current_dialog), | |
757 | + screen); | |
758 | + gtk_window_present_with_time (GTK_WINDOW (current_dialog), | |
759 | + activate_time); | |
760 | + panel_logout_set_timeout (current_dialog); | |
761 | + //FIXME center the dialog on screen, and reset sticky and above_all? | |
762 | + return; | |
763 | + } else { | |
764 | + gtk_widget_destroy (GTK_WIDGET (current_dialog)); | |
765 | + } | |
766 | + } | |
767 | + | |
768 | + logout_dialog = g_object_new (PANEL_TYPE_LOGOUT_DIALOG, NULL); | |
769 | + current_dialog = logout_dialog; | |
770 | + | |
771 | + gtk_window_set_title (GTK_WINDOW (logout_dialog), ""); | |
772 | + | |
773 | + logout_dialog->priv->type = type; | |
774 | + | |
775 | + icon_name = NULL; | |
776 | + primary_text = NULL; | |
777 | + | |
778 | + switch (type) { | |
779 | + case PANEL_LOGOUT_DIALOG_LOGOUT: | |
780 | + icon_name = PANEL_ICON_LOGOUT; | |
781 | + primary_text = _("Log out of this system now?"); | |
782 | + // FIXME need to verify that this response can be used | |
783 | + logout_dialog->priv->default_response = PANEL_LOGOUT_DIALOG_LOGOUT; | |
784 | + | |
785 | + //FIXME is gdm running? | |
786 | + gtk_dialog_add_button (GTK_DIALOG (logout_dialog), | |
787 | + _("_Switch User"), | |
788 | + PANEL_LOGOUT_RESPONSE_SWITCH_USER); | |
789 | + gtk_dialog_add_button (GTK_DIALOG (logout_dialog), | |
790 | + GTK_STOCK_CANCEL, | |
791 | + GTK_RESPONSE_CANCEL); | |
792 | + gtk_dialog_add_button (GTK_DIALOG (logout_dialog), | |
793 | + _("_Log Out"), | |
794 | + PANEL_LOGOUT_RESPONSE_LOGOUT); | |
795 | + break; | |
796 | + case PANEL_LOGOUT_DIALOG_SHUTDOWN: | |
797 | + icon_name = PANEL_ICON_SHUTDOWN; | |
798 | + primary_text = _("Shut down this system now?"); | |
799 | + | |
800 | + logout_dialog->priv->default_response = PANEL_LOGOUT_RESPONSE_SHUTDOWN; | |
801 | + if (panel_power_manager_can_suspend (logout_dialog->priv->power_manager)) | |
802 | + gtk_dialog_add_button (GTK_DIALOG (logout_dialog), | |
803 | + _("S_uspend"), | |
804 | + PANEL_LOGOUT_RESPONSE_STR); | |
805 | + | |
806 | + if (panel_power_manager_can_hibernate (logout_dialog->priv->power_manager)) | |
807 | + gtk_dialog_add_button (GTK_DIALOG (logout_dialog), | |
808 | + _("_Hibernate"), | |
809 | + PANEL_LOGOUT_RESPONSE_STD); | |
810 | + | |
811 | + if (gdm_supports_logout_action (GDM_LOGOUT_ACTION_REBOOT)) | |
812 | + gtk_dialog_add_button (GTK_DIALOG (logout_dialog), | |
813 | + _("_Restart"), | |
814 | + PANEL_LOGOUT_RESPONSE_REBOOT); | |
815 | + | |
816 | + gtk_dialog_add_button (GTK_DIALOG (logout_dialog), | |
817 | + GTK_STOCK_CANCEL, | |
818 | + GTK_RESPONSE_CANCEL); | |
819 | + | |
820 | + if (gdm_supports_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN)) | |
821 | + gtk_dialog_add_button (GTK_DIALOG (logout_dialog), | |
822 | + _("_Shut Down"), | |
823 | + PANEL_LOGOUT_RESPONSE_SHUTDOWN); | |
824 | + break; | |
825 | + default: | |
826 | + g_assert_not_reached (); | |
827 | + } | |
828 | + | |
829 | + gtk_image_set_from_icon_name (GTK_IMAGE (GTK_MESSAGE_DIALOG (logout_dialog)->image), | |
830 | + icon_name, GTK_ICON_SIZE_DIALOG); | |
831 | + | |
832 | + gtk_label_set_text (GTK_LABEL (GTK_MESSAGE_DIALOG (logout_dialog)->label), | |
833 | + primary_text); | |
834 | + | |
835 | + gtk_dialog_set_default_response (GTK_DIALOG (logout_dialog), | |
836 | + logout_dialog->priv->default_response); | |
837 | + | |
838 | + panel_logout_set_timeout (logout_dialog); | |
839 | + | |
840 | + gtk_window_set_screen (GTK_WINDOW (logout_dialog), screen); | |
841 | + gtk_widget_show (GTK_WIDGET (logout_dialog)); | |
842 | + gdk_window_focus (GTK_WIDGET (current_dialog)->window, activate_time); | |
843 | +} | |
844 | Index: b/gnome-panel/panel-gdm.h | |
845 | =================================================================== | |
846 | --- /dev/null | |
847 | +++ b/gnome-panel/panel-gdm.h | |
848 | @@ -0,0 +1,52 @@ | |
849 | +/* | |
850 | + * gdm-logout-action.h: GDM logout action protocol implementation | |
851 | + * | |
852 | + * Copyright (C) 2005 Raffaele Sandrini | |
853 | + * Copyright (C) 2005 Red Hat, Inc. | |
854 | + * Copyright (C) 2002, 2003 George Lebl | |
855 | + * Copyright (C) 2001 Queen of England, | |
856 | + * | |
857 | + * This program is free software; you can redistribute it and/or | |
858 | + * modify it under the terms of the GNU General Public License as | |
859 | + * published by the Free Software Foundation; either version 2 of the | |
860 | + * License, or (at your option) any later version. | |
861 | + * | |
862 | + * This program is distributed in the hope that it will be useful, but | |
863 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
864 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
865 | + * General Public License for more details. | |
866 | + * | |
867 | + * You should have received a copy of the GNU General Public License | |
868 | + * along with this program; if not, write to the Free Software | |
869 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
870 | + * 02111-1307, USA. | |
871 | + * | |
872 | + * Authors: | |
873 | + * Raffaele Sandrini <rasa@gmx.ch> | |
874 | + * George Lebl <jirka@5z.com> | |
875 | + * Mark McLoughlin <mark@skynet.ie> | |
876 | + */ | |
877 | + | |
878 | +#ifndef __GDM_LOGOUT_ACTION_H__ | |
879 | +#define __GDM_LOGOUT_ACTION_H__ | |
880 | + | |
881 | +#include <glib.h> | |
882 | + | |
883 | +G_BEGIN_DECLS | |
884 | + | |
885 | +typedef enum { | |
886 | + GDM_LOGOUT_ACTION_NONE = 0, | |
887 | + GDM_LOGOUT_ACTION_SHUTDOWN = 1 << 0, | |
888 | + GDM_LOGOUT_ACTION_REBOOT = 1 << 1, | |
889 | + GDM_LOGOUT_ACTION_SUSPEND = 1 << 2 | |
890 | +} GdmLogoutAction; | |
891 | + | |
892 | +gboolean gdm_supports_logout_action (GdmLogoutAction action); | |
893 | + | |
894 | +void gdm_set_logout_action (GdmLogoutAction action); | |
895 | +GdmLogoutAction gdm_get_logout_action (void); | |
896 | +void gdm_new_login (void); | |
897 | + | |
898 | +G_END_DECLS | |
899 | + | |
900 | +#endif /* __GDM_LOGOUT_ACTION_H__ */ | |
901 | Index: b/gnome-panel/panel-logout.h | |
902 | =================================================================== | |
903 | --- /dev/null | |
904 | +++ b/gnome-panel/panel-logout.h | |
905 | @@ -0,0 +1,66 @@ | |
906 | +/* | |
907 | + * panel-logout.h: | |
908 | + * | |
909 | + * Copyright (C) 2006 Vincent Untz | |
910 | + * | |
911 | + * This program is free software; you can redistribute it and/or | |
912 | + * modify it under the terms of the GNU General Public License as | |
913 | + * published by the Free Software Foundation; either version 2 of the | |
914 | + * License, or (at your option) any later version. | |
915 | + * | |
916 | + * This program is distributed in the hope that it will be useful, but | |
917 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
918 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
919 | + * General Public License for more details. | |
920 | + * | |
921 | + * You should have received a copy of the GNU General Public License | |
922 | + * along with this program; if not, write to the Free Software | |
923 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
924 | + * 02111-1307, USA. | |
925 | + * | |
926 | + * Authors: | |
927 | + * Vincent Untz <vuntz@gnome.org> | |
928 | + */ | |
929 | + | |
930 | +#ifndef PANEL_LOGOUT_H | |
931 | +#define PANEL_LOGOUT_H | |
932 | + | |
933 | +#include "gtk/gtkmessagedialog.h" | |
934 | + | |
935 | +G_BEGIN_DECLS | |
936 | + | |
937 | +typedef enum { | |
938 | + PANEL_LOGOUT_DIALOG_LOGOUT, | |
939 | + PANEL_LOGOUT_DIALOG_SHUTDOWN | |
940 | +} PanelLogoutDialogType; | |
941 | + | |
942 | +#define PANEL_TYPE_LOGOUT_DIALOG (panel_logout_get_type ()) | |
943 | +#define PANEL_LOGOUT_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialog)) | |
944 | +#define PANEL_LOGOUT_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialogClass)) | |
945 | +#define PANEL_IS_LOGOUT_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PANEL_TYPE_LOGOUT_DIALOG)) | |
946 | +#define PANEL_IS_LOGOUT_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PANEL_TYPE_LOGOUT_DIALOG)) | |
947 | +#define PANEL_LOGOUT_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), PANEL_TYPE_LOGOUT_DIALOG, PanelLogoutDialogClass)) | |
948 | + | |
949 | +typedef struct _PanelLogoutDialog PanelLogoutDialog; | |
950 | +typedef struct _PanelLogoutDialogClass PanelLogoutDialogClass; | |
951 | +typedef struct _PanelLogoutDialogPrivate PanelLogoutDialogPrivate; | |
952 | + | |
953 | +struct _PanelLogoutDialog { | |
954 | + GtkMessageDialog parent; | |
955 | + | |
956 | + PanelLogoutDialogPrivate *priv; | |
957 | +}; | |
958 | + | |
959 | +struct _PanelLogoutDialogClass { | |
960 | + GtkMessageDialogClass parent_class; | |
961 | +}; | |
962 | + | |
963 | +GType panel_logout_get_type (void) G_GNUC_CONST; | |
964 | + | |
965 | +void panel_logout_new (PanelLogoutDialogType type, | |
966 | + GdkScreen *screen, | |
967 | + guint32 activate_time); | |
968 | + | |
969 | +G_END_DECLS | |
970 | + | |
971 | +#endif /* PANEL_LOGOUT_H */ | |
972 | Index: b/gnome-panel/panel-session.c | |
973 | =================================================================== | |
974 | --- a/gnome-panel/panel-session.c | |
975 | +++ b/gnome-panel/panel-session.c | |
976 | @@ -32,6 +32,34 @@ | |
977 | #include "panel-profile.h" | |
978 | #include "panel-shell.h" | |
979 | ||
980 | +void | |
981 | +panel_session_request_logout (void) | |
982 | +{ | |
983 | + GnomeClient *client; | |
984 | + static int recursion_guard = 0; | |
985 | + | |
986 | + if (recursion_guard) | |
987 | + return; | |
988 | + | |
989 | + recursion_guard++; | |
990 | + | |
991 | + if (!(client = gnome_master_client ())) | |
992 | + return; | |
993 | + | |
994 | + /* Only request a Global save. We only want a Local | |
995 | + * save if the user selects 'Save current setup' | |
996 | + * from the dialog. | |
997 | + */ | |
998 | + gnome_client_request_save (client, | |
999 | + GNOME_SAVE_GLOBAL, | |
1000 | + TRUE, | |
1001 | + GNOME_INTERACT_ANY, | |
1002 | + TRUE, /* do not use the gnome-session gui */ | |
1003 | + TRUE); | |
1004 | + | |
1005 | + recursion_guard--; | |
1006 | +} | |
1007 | + | |
1008 | static void | |
1009 | panel_session_handle_die_request (GnomeClient *client) | |
1010 | { | |
1011 | Index: b/gnome-panel/panel-session.h | |
1012 | =================================================================== | |
1013 | --- a/gnome-panel/panel-session.h | |
1014 | +++ b/gnome-panel/panel-session.h | |
1015 | @@ -29,6 +29,7 @@ G_BEGIN_DECLS | |
1016 | ||
1017 | void panel_session_init (void); | |
1018 | void panel_session_do_not_restart (void); | |
1019 | +void panel_session_request_logout (void); | |
1020 | ||
1021 | G_END_DECLS | |
1022 | ||
1023 | Index: b/gnome-panel/Makefile.am | |
1024 | =================================================================== | |
1025 | --- a/gnome-panel/Makefile.am | |
1026 | +++ b/gnome-panel/Makefile.am | |
1027 | @@ -97,6 +97,8 @@ panel_sources = \ | |
1028 | panel-force-quit.c \ | |
1029 | panel-lockdown.c \ | |
1030 | panel-addto.c \ | |
1031 | + panel-logout.c \ | |
1032 | + panel-gdm.c \ | |
1033 | panel-ditem-editor.c \ | |
1034 | $(NULL) | |
1035 | ||
1036 | @@ -143,6 +145,8 @@ panel_headers = \ | |
1037 | panel-force-quit.h \ | |
1038 | panel-lockdown.h \ | |
1039 | panel-addto.h \ | |
1040 | + panel-logout.h \ | |
1041 | + panel-gdm.h \ | |
1042 | panel-ditem-editor.h \ | |
1043 | panel-icon-names.h \ | |
1044 | $(NULL) | |
1045 | Index: b/gnome-panel/libpanel-util/panel-session-manager.c | |
1046 | =================================================================== | |
1047 | --- a/gnome-panel/libpanel-util/panel-session-manager.c | |
1048 | +++ b/gnome-panel/libpanel-util/panel-session-manager.c | |
1049 | @@ -23,10 +23,13 @@ | |
1050 | */ | |
1051 | ||
1052 | #include <dbus/dbus-glib.h> | |
1053 | +#include <gtk/gtk.h> | |
1054 | ||
1055 | #include "panel-cleanup.h" | |
1056 | #include "panel-dbus-service.h" | |
1057 | ||
1058 | +#include "panel-logout.h" | |
1059 | +#include "panel-session.h" | |
1060 | #include "panel-session-manager.h" | |
1061 | ||
1062 | static GObject *panel_session_manager_constructor (GType type, | |
1063 | @@ -96,6 +99,20 @@ panel_session_manager_request_logout (Pa | |
1064 | g_warning ("Could not connect to session manager: %s", | |
1065 | error->message); | |
1066 | g_error_free (error); | |
1067 | + | |
1068 | + /* Fall back to the old way */ | |
1069 | + switch (mode) { | |
1070 | + case PANEL_SESSION_MANAGER_LOGOUT_MODE_NORMAL: | |
1071 | + panel_logout_new (PANEL_LOGOUT_DIALOG_LOGOUT, | |
1072 | + gdk_screen_get_default (), | |
1073 | + gtk_get_current_event_time ()); | |
1074 | + break; | |
1075 | + case PANEL_SESSION_MANAGER_LOGOUT_MODE_NO_CONFIRMATION: | |
1076 | + panel_session_request_logout (); | |
1077 | + break; | |
1078 | + default: | |
1079 | + g_warning ("Invalid mode requested for logout"); | |
1080 | + } | |
1081 | return; | |
1082 | } | |
1083 | ||
1084 | @@ -126,6 +143,12 @@ panel_session_manager_request_shutdown ( | |
1085 | g_warning ("Could not connect to session manager: %s", | |
1086 | error->message); | |
1087 | g_error_free (error); | |
1088 | + | |
1089 | + /* Fall back to the old way */ | |
1090 | + panel_logout_new (PANEL_LOGOUT_DIALOG_SHUTDOWN, | |
1091 | + gdk_screen_get_default (), | |
1092 | + gtk_get_current_event_time ()); | |
1093 | + | |
1094 | return; | |
1095 | } | |
1096 |