diff options
author | Ted Gould <ted@canonical.com> | 2009-07-22 12:48:41 -0500 |
---|---|---|
committer | Ted Gould <ted@canonical.com> | 2009-07-22 12:48:41 -0500 |
commit | 3852caea472d3a95891ae5b58463f417877472a3 (patch) | |
tree | f2e34e75ccf7d9c0f87aebb2a29cbf5ce9294632 | |
parent | 49a4fd2bd3e8539fb6faf717dd4016ffcfd58c52 (diff) | |
parent | c9cfcc8a9aefd2122e80e3674c0da96ffe849a34 (diff) | |
download | ayatana-indicator-session-3852caea472d3a95891ae5b58463f417877472a3.tar.gz ayatana-indicator-session-3852caea472d3a95891ae5b58463f417877472a3.tar.bz2 ayatana-indicator-session-3852caea472d3a95891ae5b58463f417877472a3.zip |
Adding a helper for the logout window. And setting things
up to call it.
-rw-r--r-- | .bzrignore | 3 | ||||
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | debian/changelog | 7 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/gtk-dialog/Makefile.am | 13 | ||||
-rw-r--r-- | src/gtk-dialog/ck-pk-helper.c | 214 | ||||
-rw-r--r-- | src/gtk-dialog/ck-pk-helper.h | 10 | ||||
-rw-r--r-- | src/gtk-dialog/gtk-logout-helper.c | 14 | ||||
-rw-r--r-- | src/gtk-dialog/logout-dialog.c | 367 | ||||
-rw-r--r-- | src/gtk-dialog/logout-dialog.h | 99 | ||||
-rw-r--r-- | src/session-service.c | 47 |
11 files changed, 752 insertions, 32 deletions
@@ -35,3 +35,6 @@ debian/indicator-sus.debhelper.log debian/indicator-sus.postinst.debhelper debian/indicator-sus.postrm.debhelper debian/indicator-sus.substvars +gtk-logout-helper +.deps +.libs diff --git a/configure.ac b/configure.ac index d299a0d..1e65958 100644 --- a/configure.ac +++ b/configure.ac @@ -48,6 +48,12 @@ PKG_CHECK_MODULES(SESSIONSERVICE, dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSIO AC_SUBST(SESSIONERVICE_CFLAGS) AC_SUBST(SESSIONERVICE_LIBS) +PKG_CHECK_MODULES(GTKLOGOUTHELPER, gtk+-2.0 >= $GTK_REQUIRED_VERSION + polkit-gnome) + +AC_SUBST(GTKLOGOUTHELPER_CFLAGS) +AC_SUBST(GTKLOGOUTHELPER_LIBS) + ########################### # Check to see if we're local ########################### @@ -84,6 +90,7 @@ AC_SUBST(DBUSSERVICEDIR) AC_OUTPUT([ Makefile src/Makefile +src/gtk-dialog/Makefile data/Makefile ]) diff --git a/debian/changelog b/debian/changelog index 31b226a..0dbf9bc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +indicator-sus (0.1~ppa2~indicator9ubuntu2) UNRELEASED; urgency=low + + * Adding a helper for the logout window. And setting things + up to call it. + + -- Ted Gould <ted@ubuntu.com> Wed, 22 Jul 2009 12:48:04 -0500 + indicator-sus (0.1~ppa2~indicator9ubuntu1) karmic; urgency=low * Adding in lots of fun menu items. This way the menu looks diff --git a/src/Makefile.am b/src/Makefile.am index b681b5b..ab79f0f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,4 @@ +SUBDIRS = gtk-dialog libexec_PROGRAMS = indicator-status-service indicator-users-service indicator-session-service @@ -58,7 +59,7 @@ indicator_users_service_LDADD = $(USERSSERVICE_LIBS) ################# indicator_session_service_SOURCES = session-service.c -indicator_session_service_CFLAGS = $(SESSIONSERVICE_CFLAGS) +indicator_session_service_CFLAGS = $(SESSIONSERVICE_CFLAGS) -DLIBEXECDIR=\"$(libexecdir)\" indicator_session_service_LDADD = $(SESSIONSERVICE_LIBS) ############### diff --git a/src/gtk-dialog/Makefile.am b/src/gtk-dialog/Makefile.am new file mode 100644 index 0000000..9aa0097 --- /dev/null +++ b/src/gtk-dialog/Makefile.am @@ -0,0 +1,13 @@ + +libexec_PROGRAMS = gtk-logout-helper + +gtk_logout_helper_SOURCES = \ + gtk-logout-helper.c \ + ck-pk-helper.c \ + ck-pk-helper.h \ + logout-dialog.c \ + logout-dialog.h + +gtk_logout_helper_CFLAGS = $(GTKLOGOUTHELPER_CFLAGS) -Wall -Werror +gtk_logout_helper_LDADD = $(GTKLOGOUTHELPER_LIBS) + diff --git a/src/gtk-dialog/ck-pk-helper.c b/src/gtk-dialog/ck-pk-helper.c new file mode 100644 index 0000000..9278905 --- /dev/null +++ b/src/gtk-dialog/ck-pk-helper.c @@ -0,0 +1,214 @@ + +#include <unistd.h> +#include <glib.h> +#include <dbus/dbus-glib.h> +#include <polkit-gnome/polkit-gnome.h> + +#include "logout-dialog.h" +#include "ck-pk-helper.h" + +static gboolean +ck_multiple_users (void) +{ + DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL); + g_return_val_if_fail(sbus != NULL, TRUE); /* worst case */ + DBusGProxy * proxy = dbus_g_proxy_new_for_name(sbus, "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager"); + + if (proxy == NULL) { + return TRUE; + } + + gboolean result; + GPtrArray * seats = NULL; + + result = dbus_g_proxy_call(proxy, "GetSeats", NULL, G_TYPE_INVALID, + dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &seats, G_TYPE_INVALID); + + if (!result) { + g_warning("Unable to get the seats for ConsoleKit"); + g_object_unref(proxy); + return TRUE; + } + + gchar * this_session_id = NULL; + + result = dbus_g_proxy_call(proxy, "GetCurrentSession", NULL, G_TYPE_INVALID, + DBUS_TYPE_G_OBJECT_PATH, &this_session_id, G_TYPE_INVALID); + + g_object_unref(proxy); + + if (!result) { + g_warning("Unable to get current session from ConsoleKit"); + return TRUE; + } + + proxy = dbus_g_proxy_new_for_name(sbus, "org.freedesktop.ConsoleKit", + this_session_id, "org.freedesktop.ConsoleKit.Session"); + + if (proxy == NULL) { + return TRUE; + } + + guint this_session_uid; + + result = dbus_g_proxy_call(proxy, "GetUnixUser", NULL, G_TYPE_INVALID, + G_TYPE_UINT, &this_session_uid, G_TYPE_INVALID); + + if (!result) { + g_warning("Unable to get UID from ConsoleKit"); + return TRUE; + } + + guint seat; + gboolean multiple_users = FALSE; + for (seat = 0; seat < seats->len; seat++) { + gchar * seat_id = g_ptr_array_index(seats, seat); + DBusGProxy * seat_proxy = dbus_g_proxy_new_for_name(sbus, "org.freedesktop.ConsoleKit", + seat_id, "org.freedesktop.ConsoleKit.Seat"); + g_free(seat_id); + + if (seat_proxy == NULL) { + continue; + } + + GPtrArray * sessions = NULL; + + gboolean result = dbus_g_proxy_call(seat_proxy, + "GetSessions", NULL, G_TYPE_INVALID, + dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &sessions, G_TYPE_INVALID); + + g_object_unref(seat_proxy); + if (!result) { + continue; + } + + guint session; + for (session = 0; session < sessions->len; session++) { + gchar * session_id = g_ptr_array_index(sessions, session); + if (g_strcmp0(this_session_id, session_id) == 0) { + continue; + } + DBusGProxy * session_proxy = dbus_g_proxy_new_for_name(sbus, "org.freedesktop.ConsoleKit", + session_id, "org.freedesktop.ConsoleKit.Session"); + g_free(session_id); + + if (session_proxy == NULL) { + continue; + } + + guint session_uid; + result = dbus_g_proxy_call(session_proxy, "GetUnixUser", NULL, G_TYPE_INVALID, + G_TYPE_UINT, &session_uid, G_TYPE_INVALID); + g_object_unref(session_proxy); + + if (!result) { + continue; + } + + if (session_uid != this_session_uid) { + multiple_users = TRUE; + break; + } + } + + g_ptr_array_free(sessions, TRUE); + + if (multiple_users) { + break; + } + } + + g_ptr_array_free(seats, TRUE); + g_object_unref(proxy); + g_free(this_session_id); + + return multiple_users; +} + +gboolean +pk_require_auth (LogoutDialogAction action) { + if (action == LOGOUT_DIALOG_LOGOUT) { + return FALSE; + } + + gchar * pk_action; + if (ck_multiple_users()) { + if (action == LOGOUT_DIALOG_RESTART) { + pk_action = "org.freedesktop.consolekit.system.restart-multiple-users"; + } else { + pk_action = "org.freedesktop.consolekit.system.stop-multiple-users"; + } + } else { + if (action == LOGOUT_DIALOG_RESTART) { + pk_action = "org.freedesktop.consolekit.system.restart"; + } else { + pk_action = "org.freedesktop.consolekit.system.stop"; + } + } + + PolKitResult polres; + if (pk_can_do_action(pk_action, &polres)) { + if (polres == POLKIT_RESULT_YES) { + return FALSE; + } + return TRUE; + } + return FALSE; +} + +gboolean +pk_can_do_action (const gchar *action_id, PolKitResult * pol_result) +{ + PolKitGnomeContext *gnome_context; + PolKitAction *action; + PolKitCaller *caller; + DBusError dbus_error; + PolKitError *error; + PolKitResult result; + + gnome_context = polkit_gnome_context_get (NULL); + + if (gnome_context == NULL) { + return FALSE; + } + + if (gnome_context->pk_tracker == NULL) { + return FALSE; + } + + dbus_error_init (&dbus_error); + caller = polkit_tracker_get_caller_from_pid (gnome_context->pk_tracker, + getpid (), + &dbus_error); + dbus_error_free (&dbus_error); + + if (caller == NULL) { + return FALSE; + } + + action = polkit_action_new (); + if (!polkit_action_set_action_id (action, action_id)) { + polkit_action_unref (action); + polkit_caller_unref (caller); + return FALSE; + } + + result = POLKIT_RESULT_UNKNOWN; + error = NULL; + result = polkit_context_is_caller_authorized (gnome_context->pk_context, + action, caller, FALSE, + &error); + if (polkit_error_is_set (error)) { + polkit_error_free (error); + } + polkit_action_unref (action); + polkit_caller_unref (caller); + + if (pol_result != NULL) { + *pol_result = result; + } + + return result != POLKIT_RESULT_NO && result != POLKIT_RESULT_UNKNOWN; +} diff --git a/src/gtk-dialog/ck-pk-helper.h b/src/gtk-dialog/ck-pk-helper.h new file mode 100644 index 0000000..fb5936e --- /dev/null +++ b/src/gtk-dialog/ck-pk-helper.h @@ -0,0 +1,10 @@ + +#ifndef __CK_PK_HELPER_H__ +#define __CK_PK_HELPER_H__ 1 + +#include <polkit-gnome/polkit-gnome.h> + +gboolean pk_require_auth (LogoutDialogAction action); +gboolean pk_can_do_action (const gchar *action_id, PolKitResult * pol_result); + +#endif /* __CK_PK_HELPER__ */ diff --git a/src/gtk-dialog/gtk-logout-helper.c b/src/gtk-dialog/gtk-logout-helper.c new file mode 100644 index 0000000..f6598bc --- /dev/null +++ b/src/gtk-dialog/gtk-logout-helper.c @@ -0,0 +1,14 @@ + +#include <gtk/gtk.h> +#include "logout-dialog.h" + +int +main (int argc, char * argv[]) +{ + gtk_init(&argc, &argv); + + GtkWidget * dialog = logout_dialog_new(LOGOUT_DIALOG_LOGOUT); + gtk_dialog_run(GTK_DIALOG(dialog)); + + return 0; +} diff --git a/src/gtk-dialog/logout-dialog.c b/src/gtk-dialog/logout-dialog.c new file mode 100644 index 0000000..cd49b00 --- /dev/null +++ b/src/gtk-dialog/logout-dialog.c @@ -0,0 +1,367 @@ +/* + * libgksuui -- Gtk+ widget and convenience functions for requesting passwords + * Copyright (C) 2004 Gustavo Noronha Silva + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <string.h> +#include <math.h> + +#include <gtk/gtk.h> +#include <gdk/gdkx.h> +#include <glib/gi18n.h> +#include <X11/XKBlib.h> + +#include "logout-dialog.h" +#include "ck-pk-helper.h" + +enum { + PROP_ZERO, + PROP_ACTION +}; + + +static void +logout_dialog_class_init (LogoutDialogClass *klass); + +static void +logout_dialog_init (LogoutDialog *logout_dialog); + +static void +set_property (GObject * object, guint param_id, const GValue * value, GParamSpec *pspec); + +static void +get_property (GObject * object, guint param_id, GValue * value, GParamSpec *pspec); + +static gboolean +timer_cb (gpointer data); + +static void +show_cb (GtkWidget * widget, gpointer data); + +static void +check_restart (LogoutDialog * dialog); + +static gchar* +get_plural_string (LogoutDialog * dialog); + +static const gchar * title_strings[LOGOUT_DIALOG_ACTION_CNT] = { + /* LOGOUT_DIALOG_LOGOUT, */ NC_("title", "Log Out"), + /* LOGOUT_DIALOG_RESTART, */ NC_("title", "Restart"), + /* LOGOUT_DIALOG_SHUTDOWN, */ NC_("title", "Shut Down") +}; + +static const gchar * button_strings[LOGOUT_DIALOG_ACTION_CNT] = { + /* LOGOUT_DIALOG_LOGOUT, */ NC_("button", "Log Out"), + /* LOGOUT_DIALOG_RESTART, */ NC_("button", "Restart"), + /* LOGOUT_DIALOG_SHUTDOWN, */ NC_("button", "Shut Down") +}; + +static const gchar * restart_auth = N_("Restart..."); + +static const gchar * body_logout_update = N_("You recently installed updates which will only take effect after a restart. Restart to apply software updates."); + +static const gchar * icon_strings[LOGOUT_DIALOG_ACTION_CNT] = { + /* LOGOUT_DIALOG_LOGOUT, */ "system-log-out", + /* LOGOUT_DIALOG_RESTART, */ "system-restart", + /* LOGOUT_DIALOG_SHUTDOWN, */ "system-shutdown" +}; + +GType +logout_dialog_get_type (void) +{ + static GType type = 0; + + if (type == 0) + { + static const GTypeInfo info = + { + sizeof (LogoutDialogClass), /* size of class */ + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) logout_dialog_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (LogoutDialog), /* size of object */ + 0, /* n_preallocs */ + (GInstanceInitFunc) logout_dialog_init /* instance_init */ + }; + type = g_type_register_static (gtk_dialog_get_type (), + "LogoutDialogType", + &info, 0); + } + + return type; +} + +static gchar* +get_plural_string (LogoutDialog * dialog) +{ + static gchar *plural_string = ""; + + switch (dialog->action) + { + case LOGOUT_DIALOG_LOGOUT: + plural_string = ngettext("You will be logged out in %d second.", + "You will be logged out in %d seconds.", + dialog->timeout); + break; + case LOGOUT_DIALOG_RESTART: + plural_string = ngettext("The computer will restart in %d second.", + "The computer will restart in %d seconds.", + dialog->timeout); + break; + case LOGOUT_DIALOG_SHUTDOWN: + plural_string = ngettext("The computer will be shut down in %d second.", + "The computer will be shut down in %d seconds.", + dialog->timeout); + break; + default: + break; + } + + return plural_string; +} + +static void +logout_dialog_class_init (LogoutDialogClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = set_property; + gobject_class->get_property = get_property; + + g_object_class_install_property(gobject_class, PROP_ACTION, + g_param_spec_int("action", NULL, NULL, + LOGOUT_DIALOG_LOGOUT, LOGOUT_DIALOG_SHUTDOWN, + LOGOUT_DIALOG_LOGOUT, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + return; +} + +static void +set_property (GObject * object, guint param_id, const GValue * value, GParamSpec *pspec) +{ + g_return_if_fail(param_id == PROP_ACTION); + + LogoutDialog * dialog = LOGOUT_DIALOG(object); + dialog->action = (LogoutDialogAction)g_value_get_int(value); + + gtk_image_set_from_icon_name(GTK_IMAGE(dialog->image), icon_strings[dialog->action], GTK_ICON_SIZE_DIALOG); + gtk_window_set_title (GTK_WINDOW(dialog), _(title_strings[dialog->action])); + gtk_widget_hide(dialog->message); + gtk_button_set_label(GTK_BUTTON(dialog->ok_button), _(button_strings[dialog->action])); + + gchar * timeouttxt = g_strdup_printf(get_plural_string(dialog), dialog->timeout); + gtk_label_set_text(GTK_LABEL(dialog->timeout_text), timeouttxt); + g_free(timeouttxt); + + check_restart(dialog); + + return; +} + +static void +get_property (GObject * object, guint param_id, GValue * value, GParamSpec *pspec) +{ + g_return_if_fail(param_id == PROP_ACTION); + g_value_set_int(value, LOGOUT_DIALOG(object)->action); +} + +static gboolean +timer_cb (gpointer data) +{ + LogoutDialog * dialog = LOGOUT_DIALOG(data); + + if (dialog->timeout == 0) { + gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + dialog->timerfunc = 0; + return FALSE; + } else { + dialog->timeout--; + + gchar * timeouttxt = g_strdup_printf(get_plural_string(dialog), dialog->timeout); + gtk_label_set_text(GTK_LABEL(dialog->timeout_text), timeouttxt); + g_free(timeouttxt); + } + + return TRUE; +} + +static void +show_cb (GtkWidget * widget, gpointer data) +{ + LogoutDialog * dialog = LOGOUT_DIALOG(widget); + + if (dialog->timerfunc != 0) { + g_source_remove(dialog->timerfunc); + dialog->timerfunc = 0; + } + + dialog->timerfunc = g_timeout_add_seconds(1, timer_cb, dialog); + return; +} + +static void +check_restart (LogoutDialog * dialog) +{ + if (dialog->action != LOGOUT_DIALOG_LOGOUT) { + return; + } + + if (g_file_test("/var/run/reboot-required", G_FILE_TEST_EXISTS)) { + if (pk_can_do_action("org.freedesktop.consolekit.system.restart", NULL) || + pk_can_do_action("org.freedesktop.consolekit.system.restart-multiple-users", NULL)) { + + gtk_label_set_text(GTK_LABEL(dialog->message), _(body_logout_update)); + gtk_widget_show(dialog->message); + if (pk_require_auth(LOGOUT_DIALOG_RESTART)) { + gtk_button_set_label(GTK_BUTTON(dialog->restart_button), _(restart_auth)); + } else { + gtk_button_set_label(GTK_BUTTON(dialog->restart_button), _(button_strings[LOGOUT_DIALOG_RESTART])); + } + gtk_widget_show(dialog->restart_button); + } + } + + return; +} + +static gboolean +focus_out_cb (GtkWidget *widget, GdkEventFocus *event, gpointer user_data) +{ + gtk_window_present (GTK_WINDOW(widget)); + return TRUE; +} + +static void +logout_dialog_init (LogoutDialog *logout_dialog) +{ + GtkDialog *dialog; + gint border_width = 6; + + logout_dialog->timeout = 60; + logout_dialog->timerfunc = 0; + + /* dialog window */ + dialog = GTK_DIALOG(logout_dialog); + + /* make sure that our window will always have the focus */ + g_signal_connect (G_OBJECT(dialog), "focus-out-event", + G_CALLBACK(focus_out_cb), NULL); + + logout_dialog->main_vbox = dialog->vbox; + + gtk_window_set_title (GTK_WINDOW(logout_dialog), ""); + gtk_dialog_set_has_separator (GTK_DIALOG(logout_dialog), FALSE); + gtk_container_set_border_width (GTK_CONTAINER(logout_dialog), border_width); + gtk_box_set_spacing (GTK_BOX(logout_dialog->main_vbox), 12); + gtk_window_set_resizable (GTK_WINDOW(logout_dialog), FALSE); + + gtk_window_stick(GTK_WINDOW(logout_dialog)); + gtk_window_set_keep_above(GTK_WINDOW(logout_dialog), TRUE); + gtk_widget_realize(GTK_WIDGET(logout_dialog)); + gdk_window_set_functions(GTK_WIDGET(logout_dialog)->window, GDK_FUNC_CLOSE); + + /* center window */ + gtk_window_set_position (GTK_WINDOW(logout_dialog), GTK_WIN_POS_CENTER); + + /* the action buttons */ + /* the cancel button */ + logout_dialog->restart_button = gtk_dialog_add_button (dialog, + GTK_STOCK_HELP, + GTK_RESPONSE_HELP); + gtk_button_set_label(GTK_BUTTON(logout_dialog->restart_button), _(button_strings[LOGOUT_DIALOG_RESTART])); + gtk_widget_hide(logout_dialog->restart_button); + + /* the cancel button */ + logout_dialog->cancel_button = gtk_dialog_add_button (dialog, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL); + /* the ok button */ + logout_dialog->ok_button = gtk_dialog_add_button (dialog, + GTK_STOCK_OK, + GTK_RESPONSE_OK); + gtk_widget_grab_default (logout_dialog->ok_button); + + /* Title */ + gtk_window_set_title (GTK_WINDOW(logout_dialog), _(title_strings[logout_dialog->action])); + + /* hbox */ + logout_dialog->hbox = gtk_hbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER(logout_dialog->hbox), 6); + gtk_box_pack_start (GTK_BOX(logout_dialog->main_vbox), + logout_dialog->hbox, FALSE, FALSE, 0); + gtk_widget_show (logout_dialog->hbox); + + /* image */ + logout_dialog->image = + gtk_image_new_from_icon_name (icon_strings[logout_dialog->action], + GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC(logout_dialog->image), 0.5, 0); + gtk_box_pack_start (GTK_BOX(logout_dialog->hbox), logout_dialog->image, + FALSE, FALSE, 0); + gtk_widget_show (logout_dialog->image); + + /* vbox for text */ + logout_dialog->vbox_text = gtk_vbox_new(FALSE, 12); + gtk_box_pack_start(GTK_BOX(logout_dialog->hbox), logout_dialog->vbox_text, TRUE, TRUE, 0); + gtk_widget_show(logout_dialog->vbox_text); + + /* Message */ + logout_dialog->message = gtk_label_new(""); + gtk_label_set_line_wrap(GTK_LABEL(logout_dialog->message), TRUE); + gtk_label_set_single_line_mode(GTK_LABEL(logout_dialog->message), FALSE); + gtk_label_set_selectable(GTK_LABEL(logout_dialog->message), TRUE); + gtk_misc_set_alignment (GTK_MISC(logout_dialog->message), 0.0, 0.0); + gtk_box_pack_start(GTK_BOX(logout_dialog->vbox_text), logout_dialog->message, TRUE, TRUE, 0); + gtk_widget_show(logout_dialog->message); + + /* timeout */ + logout_dialog->timeout_text = gtk_label_new(""); + gtk_label_set_line_wrap(GTK_LABEL(logout_dialog->timeout_text), TRUE); + gtk_label_set_single_line_mode(GTK_LABEL(logout_dialog->timeout_text), FALSE); + gtk_label_set_selectable(GTK_LABEL(logout_dialog->timeout_text), FALSE); + gtk_misc_set_alignment (GTK_MISC(logout_dialog->timeout_text), 0.0, 0.5); + gtk_box_pack_start(GTK_BOX(logout_dialog->vbox_text), logout_dialog->timeout_text, TRUE, TRUE, 0); + gtk_widget_show(logout_dialog->timeout_text); + + g_signal_connect(G_OBJECT(logout_dialog), "show", G_CALLBACK(show_cb), logout_dialog); + + return; +} + +/** + * logout_dialog_new: + * + * Creates a new #LogoutDialog. + * + * Returns: the new #LogoutDialog + */ +GtkWidget* +logout_dialog_new (LogoutDialogAction action) +{ + LogoutDialog * dialog = g_object_new (LOGOUT_TYPE_DIALOG, "action", action, NULL); + return GTK_WIDGET(dialog); +} + +LogoutDialogAction +logout_dialog_get_action (LogoutDialog * dialog) +{ + return dialog->action; +} + diff --git a/src/gtk-dialog/logout-dialog.h b/src/gtk-dialog/logout-dialog.h new file mode 100644 index 0000000..b0e19b7 --- /dev/null +++ b/src/gtk-dialog/logout-dialog.h @@ -0,0 +1,99 @@ +/* + * libgksuui -- Gtk+ widget and convenience functions for requesting passwords + * Copyright (C) 2004 Gustavo Noronha Silva + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __LOGOUT_DIALOG_H__ +#define __LOGOUT_DIALOG_H__ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define LOGOUT_TYPE_DIALOG (logout_dialog_get_type ()) +#define LOGOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), LOGOUT_TYPE_DIALOG, LogoutDialog)) +#define LOGOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), LOGOUT_TYPE_DIALOG, LogoutDialogClass)) +#define LOGOUT_IS_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), LOGOUT_TYPE_DIALOG)) +#define LOGOUT_IS_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LOGOUT_TYPE_CONTEXT)) +#define LOGOUT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LOGOUT_TYPE_DIALOG, LogoutDialogClass)) + +typedef struct _LogoutDialogClass LogoutDialogClass; +typedef struct _LogoutDialog LogoutDialog; +typedef enum _LogoutDialogAction LogoutDialogAction; + +enum _LogoutDialogAction { + LOGOUT_DIALOG_LOGOUT, + LOGOUT_DIALOG_RESTART, + LOGOUT_DIALOG_SHUTDOWN, + LOGOUT_DIALOG_ACTION_CNT +}; + +struct _LogoutDialogClass +{ + GtkDialogClass parent_class; +}; + +/** + * LogoutDialog: + * @dialog: parent widget + * @main_vbox: GtkDialog's vbox + * @hbox: box to separate the image of the right-side widgets + * @image: the authorization image, left-side widget + * @entry_vbox: right-side widgets container + * @label: message describing what is required from the user, + * right-side widget + * @entry: place to type the password in, right-side widget + * @ok_button: OK button of the dialog + * @cancel_button: Cancel button of the dialog + * + * Convenience widget based on #GtkDialog to request a password. + */ +struct _LogoutDialog +{ + GtkDialog dialog; + + GtkWidget *main_vbox; + GtkWidget *hbox; + GtkWidget *image; + GtkWidget *ok_button; + GtkWidget *cancel_button; + GtkWidget *restart_button; + GtkWidget *vbox_text; + GtkWidget *message; + GtkWidget *timeout_text; + + LogoutDialogAction action; + + /* private */ + gchar * timeout_result; + guint timeout; + guint timerfunc; +}; + +GType +logout_dialog_get_type (void); + +GtkWidget* +logout_dialog_new (LogoutDialogAction action); + +LogoutDialogAction +logout_dialog_get_action (LogoutDialog * widget); + +G_END_DECLS + +#endif diff --git a/src/session-service.c b/src/session-service.c index 80d4172..b301baf 100644 --- a/src/session-service.c +++ b/src/session-service.c @@ -13,37 +13,22 @@ static DbusmenuMenuitem * root_menuitem = NULL; static GMainLoop * mainloop = NULL; static void -log_out (DbusmenuMenuitem * mi, gpointer userdata) +show_dialog (DbusmenuMenuitem * mi, gchar * type) { - g_debug("Log Out"); - return; -} + gchar * helper = g_build_path(LIBEXECDIR, "gtk-logout-helper", NULL); + gchar * dialog_line = g_strdup_printf("%s --%s", helper, type); + g_free(helper); -static void -suspend (DbusmenuMenuitem * mi, gpointer userdata) -{ - g_debug("Suspend"); - return; -} + g_debug("Showing dialog '%s'", dialog_line); -static void -hibernate (DbusmenuMenuitem * mi, gpointer userdata) -{ - g_debug("Hibernate"); - return; -} + GError * error = NULL; + if (!g_spawn_command_line_async(dialog_line, &error)) { + g_warning("Unable to show dialog: %s", error->message); + g_error_free(error); + } -static void -restart (DbusmenuMenuitem * mi, gpointer userdata) -{ - g_debug("Restart"); - return; -} + g_free(dialog_line); -static void -shutdown (DbusmenuMenuitem * mi, gpointer userdata) -{ - g_debug("Shutdown"); return; } @@ -54,27 +39,27 @@ create_items (DbusmenuMenuitem * root) { mi = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(mi, "label", _("Log Out")); dbusmenu_menuitem_child_append(root, mi); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(log_out), NULL); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "logout"); mi = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(mi, "label", _("Suspend")); dbusmenu_menuitem_child_append(root, mi); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(suspend), NULL); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "suspend"); mi = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(mi, "label", _("Hibernate")); dbusmenu_menuitem_child_append(root, mi); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(hibernate), NULL); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "hibernate"); mi = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(mi, "label", _("Restart")); dbusmenu_menuitem_child_append(root, mi); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(restart), NULL); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "restart"); mi = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(mi, "label", _("Shutdown")); dbusmenu_menuitem_child_append(root, mi); - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(shutdown), NULL); + g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "shutdown"); return; } |