From 192be127691af87a88f4ac15d4fe3dd9296499b0 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 12 Jun 2012 00:39:31 -0500 Subject: use GDBus in users-service-dbus.c... major rewrite here. --- src/settings-helper.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/settings-helper.c') diff --git a/src/settings-helper.c b/src/settings-helper.c index 007f83f..6a09498 100644 --- a/src/settings-helper.c +++ b/src/settings-helper.c @@ -22,9 +22,6 @@ with this program. If not, see . #include #include -#include -#include - #include #include -- cgit v1.2.3 From 4998ebc6c4f9f9ce742193a2ff29645f1fe065af Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 14 Jun 2012 12:27:04 -0500 Subject: a step in merging the two menus: remove the 'should show user menu' flag --- .../com.canonical.indicator.session.gschema.xml.in | 5 - src/indicator-session.c | 110 +++------------------ src/session-dbus.c | 31 ------ src/session-dbus.h | 1 - src/settings-helper.c | 7 -- src/settings-helper.h | 1 - src/user-menu-mgr.c | 5 - 7 files changed, 14 insertions(+), 146 deletions(-) (limited to 'src/settings-helper.c') diff --git a/data/com.canonical.indicator.session.gschema.xml.in b/data/com.canonical.indicator.session.gschema.xml.in index 0ef3d00..c26d8c1 100644 --- a/data/com.canonical.indicator.session.gschema.xml.in +++ b/data/com.canonical.indicator.session.gschema.xml.in @@ -25,11 +25,6 @@ Determine the visibility of the User's real name on the panel Allow for the Removal of the users name from the panel - - true - Determine the visibility of the User Menu - Allow for the user menu to be hidden by the user. - false Determine what string to use for the user's name in the switch menuitem. diff --git a/src/indicator-session.c b/src/indicator-session.c index 1af2552..d74b8f8 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -52,18 +52,19 @@ with this program. If not, see . typedef struct _IndicatorSession IndicatorSession; typedef struct _IndicatorSessionClass IndicatorSessionClass; -struct _IndicatorSessionClass { - IndicatorObjectClass parent_class; +struct _IndicatorSessionClass +{ + IndicatorObjectClass parent_class; }; -struct _IndicatorSession { - IndicatorObject parent; - IndicatorServiceManager * service; +struct _IndicatorSession +{ + IndicatorObject parent; + IndicatorServiceManager * service; IndicatorObjectEntry users; IndicatorObjectEntry devices; - gboolean show_users_entry; - GCancellable * service_proxy_cancel; - GDBusProxy * service_proxy; + GCancellable * service_proxy_cancel; + GDBusProxy * service_proxy; }; static gboolean greeter_mode; @@ -93,7 +94,6 @@ static void service_connection_cb (IndicatorServiceManager * sm, gboolean connec static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data); static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data); static void user_real_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data); -static void user_menu_visibility_get_cb (GObject* obj, GAsyncResult* res, gpointer user_data); static void indicator_session_class_init (IndicatorSessionClass *klass); static void indicator_session_init (IndicatorSession *self); @@ -125,7 +125,6 @@ indicator_session_init (IndicatorSession *self) self->service = NULL; self->service_proxy_cancel = NULL; self->service_proxy = NULL; - self->show_users_entry = FALSE; /* Now let's fire these guys up. */ self->service = indicator_service_manager_new_version(INDICATOR_SESSION_DBUS_NAME, @@ -242,18 +241,15 @@ indicator_session_finalize (GObject *object) static GList* indicator_session_get_entries (IndicatorObject* obj) { - g_return_val_if_fail(IS_INDICATOR_SESSION(obj), NULL); + g_return_val_if_fail(IS_INDICATOR_SESSION(obj), NULL); IndicatorSession* self = INDICATOR_SESSION (obj); g_debug ("get entries"); - GList * retval = NULL; - // Only show the users menu if we have more than one - if (self->show_users_entry == TRUE){ - retval = g_list_prepend (retval, &self->users); - } - retval = g_list_prepend (retval, &self->devices); - return g_list_reverse (retval); + GList * entries = NULL; + entries = g_list_append (entries, &self->users); + entries = g_list_append (entries, &self->devices); + return entries; } static guint @@ -281,14 +277,6 @@ service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointe if (self->service_proxy != NULL){ // Its a reconnect ! // Fetch synchronisation data and return (proxy is still legit) - g_dbus_proxy_call (self->service_proxy, - "GetUserMenuVisibility", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - user_menu_visibility_get_cb, - user_data); g_dbus_proxy_call (self->service_proxy, "GetUserRealName", NULL, @@ -339,16 +327,6 @@ service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self); - // Figure out whether we should show the user menu at all. - g_dbus_proxy_call (self->service_proxy, - "GetUserMenuVisibility", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - user_menu_visibility_get_cb, - user_data); - // Fetch the user's real name for the user entry label g_dbus_proxy_call (self->service_proxy, "GetUserRealName", @@ -414,42 +392,6 @@ user_real_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data) return; } -static void -user_menu_visibility_get_cb (GObject* obj, GAsyncResult* res, gpointer user_data) -{ - IndicatorSession * self = INDICATOR_SESSION(user_data); - GError * error = NULL; - GVariant * result; - - result = g_dbus_proxy_call_finish(self->service_proxy, res, &error); - - if (error != NULL) { - g_warning ("unable to complete real name dbus query"); - g_error_free (error); - return; - } - gboolean update; - g_variant_get (result, "(b)", &update); - - // If it is what we had before no need to do anything... - if (self->show_users_entry == update){ - return; - } - //Otherwise - self->show_users_entry = update; - - if (self->show_users_entry == TRUE){ - g_signal_emit_by_name ((gpointer)self, - "entry-added", - &self->users); - } - else{ - g_signal_emit_by_name ((gpointer)self, - "entry-removed", - &self->users); - } -} - /* Receives all signals from the service, routed to the appropriate functions */ static void receive_signal (GDBusProxy * proxy, @@ -465,30 +407,6 @@ receive_signal (GDBusProxy * proxy, g_variant_get (parameters, "(&s)", &username); indicator_session_update_users_label (self, username); } - else if (g_strcmp0(signal_name, "UserMenuIsVisible") == 0) { - gboolean update; - g_variant_get (parameters, "(b)", &update); - - // If it is what we had before no need to do anything... - if (self->show_users_entry == update){ - return; - } - - //Otherwise - self->show_users_entry = update; - - if (self->show_users_entry == TRUE){ - g_signal_emit_by_name ((gpointer)self, - "entry-added", - &self->users); - - } - else{ - g_signal_emit_by_name ((gpointer)self, - "entry-removed", - &self->users); - } - } else if (g_strcmp0(signal_name, "RestartRequired") == 0) { if (greeter_mode == TRUE){ indicator_image_helper_update(self->devices.image, GREETER_ICON_RESTART); diff --git a/src/session-dbus.c b/src/session-dbus.c index 232e440..124733a 100644 --- a/src/session-dbus.c +++ b/src/session-dbus.c @@ -38,7 +38,6 @@ static void bus_method_call (GDBusConnection * connection, const gchar * sender, typedef struct _SessionDbusPrivate SessionDbusPrivate; struct _SessionDbusPrivate { gchar * name; - gboolean user_menu_is_visible; GDBusConnection * bus; GCancellable * bus_cancel; guint dbus_registration; @@ -104,7 +103,6 @@ session_dbus_init (SessionDbus *self) priv->bus = NULL; priv->bus_cancel = NULL; priv->dbus_registration = 0; - priv->user_menu_is_visible = FALSE; priv->bus_cancel = g_cancellable_new(); g_bus_get(G_BUS_TYPE_SESSION, @@ -164,16 +162,12 @@ bus_method_call (GDBusConnection * connection, const gchar * sender, GDBusMethodInvocation * invocation, gpointer user_data) { SessionDbus * service = SESSION_DBUS (user_data); - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE (service); GVariant * retval = NULL; if (g_strcmp0(method, "GetUserRealName") == 0) { retval = get_users_real_name (service); } - else if (g_strcmp0 (method, "GetUserMenuVisibility") == 0){ - retval = g_variant_new ("(b)", priv->user_menu_is_visible); - } else { g_warning("Calling method '%s' on the indicator service and it's unknown", method); } @@ -269,31 +263,6 @@ session_dbus_set_users_real_name (SessionDbus * session, const gchar * name) return; } -void -session_dbus_set_user_menu_visibility (SessionDbus* session, - gboolean visible) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session); - GError * error = NULL; - - priv->user_menu_is_visible = visible; - - if (priv->bus != NULL) { - g_dbus_connection_emit_signal (priv->bus, - NULL, - INDICATOR_SESSION_SERVICE_DBUS_OBJECT, - INDICATOR_SESSION_SERVICE_DBUS_IFACE, - "UserMenuIsVisible", - g_variant_new ("(b)", priv->user_menu_is_visible), - &error); - - if (error != NULL) { - g_warning("Unable to send UserMenuIsVisible signal: %s", error->message); - g_error_free(error); - } - } -} - void session_dbus_restart_required (SessionDbus* session) { SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session); diff --git a/src/session-dbus.h b/src/session-dbus.h index 4dc340a..7520f06 100644 --- a/src/session-dbus.h +++ b/src/session-dbus.h @@ -50,7 +50,6 @@ GType session_dbus_get_type (void); SessionDbus * session_dbus_new (void); void session_dbus_set_name (SessionDbus * session, const gchar * name); void session_dbus_set_users_real_name (SessionDbus * session, const gchar * name); -void session_dbus_set_user_menu_visibility (SessionDbus* session, gboolean visible); void session_dbus_restart_required (SessionDbus* session); G_END_DECLS diff --git a/src/settings-helper.c b/src/settings-helper.c index 6a09498..d8e858f 100644 --- a/src/settings-helper.c +++ b/src/settings-helper.c @@ -53,13 +53,6 @@ supress_confirmations (void) { return g_settings_get_boolean (settings, SUPPRESS_KEY) ; } -gboolean -should_show_user_menu (void) { - gboolean settings_built = build_settings(); - g_return_val_if_fail(settings_built, TRUE); - return g_settings_get_boolean (settings, SHOW_USER_MENU) ; -} - gboolean show_logout (void) { gboolean settings_built = build_settings(); diff --git a/src/settings-helper.h b/src/settings-helper.h index f50c4d8..29372f3 100644 --- a/src/settings-helper.h +++ b/src/settings-helper.h @@ -55,7 +55,6 @@ gboolean supress_confirmations (void); gboolean show_logout (void); gboolean show_restart (void); gboolean show_shutdown (void); -gboolean should_show_user_menu (void); #endif /* __GCONF_HELPER__ */ diff --git a/src/user-menu-mgr.c b/src/user-menu-mgr.c index 89fb841..2fe042a 100644 --- a/src/user-menu-mgr.c +++ b/src/user-menu-mgr.c @@ -294,12 +294,7 @@ user_menu_mgr_rebuild_items (UserMenuMgr *self) { /* TODO: This needs to be updated once the ability to query guest session support is available */ GList * users = users_service_dbus_get_user_list (self->users_dbus_interface); - const gint user_count = g_list_length(users); const gboolean guest_enabled = users_service_dbus_guest_session_enabled (self->users_dbus_interface); - const gboolean is_guest = guest_enabled && is_this_guest_session(); - const gboolean other_users_exist = user_count>1 || (is_guest && user_count>0); - const gboolean visible = !self->greeter_mode && should_show_user_menu() && other_users_exist; - session_dbus_set_user_menu_visibility (self->session_dbus_interface, visible); /* TODO we should really return here if the menu is not going to be shown. */ -- cgit v1.2.3 From 63b800e6036bc9d5096d8f7b7db42a814b8a2bed Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 17 Jun 2012 14:03:25 -0500 Subject: a step in merging the two menus: consolidate & clean up the code in session-menu-mgr --- src/Makefile.am | 4 +- src/gtk-logout-helper.c | 1 + src/lock-helper.c | 184 ------- src/lock-helper.h | 31 -- src/session-menu-mgr.c | 1259 ++++++++++++++++++++++++++--------------------- src/session-menu-mgr.h | 4 +- src/settings-helper.c | 133 +---- src/settings-helper.h | 24 - 8 files changed, 716 insertions(+), 924 deletions(-) delete mode 100644 src/lock-helper.c delete mode 100644 src/lock-helper.h (limited to 'src/settings-helper.c') diff --git a/src/Makefile.am b/src/Makefile.am index 9391d86..24f2ee8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -100,8 +100,8 @@ dbus_upower_sources = \ $(dbus_upower_sources): upower.xml gdbus-codegen \ --interface-prefix org.freedesktop \ - --c-namespace IndicatorSession \ --generate-c-code dbus-upower \ + --c-namespace DBus \ $^ gen-%.xml.c: %.xml @@ -126,8 +126,6 @@ indicator_session_service_SOURCES = \ $(dbus_display_manager_sources) \ $(dbus_upower_sources) \ $(dbus_user_sources) \ - lock-helper.c \ - lock-helper.h \ session-service.c \ session-dbus.c \ session-dbus.h \ diff --git a/src/gtk-logout-helper.c b/src/gtk-logout-helper.c index 4f23ba2..360dd0f 100644 --- a/src/gtk-logout-helper.c +++ b/src/gtk-logout-helper.c @@ -24,6 +24,7 @@ with this program. If not, see . #include #include #include +#include /* textdomain(), bindtextdomain() */ #include #include #include "dialog.h" diff --git a/src/lock-helper.c b/src/lock-helper.c deleted file mode 100644 index 11bcbd1..0000000 --- a/src/lock-helper.c +++ /dev/null @@ -1,184 +0,0 @@ -/* -A small helper for locking the screen. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see . -*/ - -#include -#include -#include "lock-helper.h" - -#define SCREENSAVER_SCHEMA "org.gnome.desktop.screensaver" -#define SCREENSAVER_LOCK_ENABLED_KEY "lock-enabled" - -static GDBusProxy * gss_proxy = NULL; - -static GMainLoop * gss_mainloop = NULL; - -static gboolean is_guest = FALSE; - -static GSettings * settings = NULL; - -void build_gss_proxy (void); - -/* This is our logic on whether the screen should be locked - or not. It effects everything else. */ -gboolean -will_lock_screen (void) -{ - if (is_guest) { - return FALSE; - } - - if (settings == NULL) { - settings = g_settings_new (SCREENSAVER_SCHEMA); - } - - return g_settings_get_boolean (settings, SCREENSAVER_LOCK_ENABLED_KEY); -} - -/* When the screensave goes active, - if we've got a mainloop running we should quit it. */ -static void -on_gss_signal (GDBusProxy *proxy, - gchar *sender_name, - gchar *signal_name, - GVariant *parameters, - gpointer user_data) -{ - g_debug ("%s sender_name: %s", G_STRLOC, sender_name); - g_debug ("%s signal_name: %s", G_STRLOC, signal_name); - - if (!g_strcmp0 (signal_name, "ActiveChanged")) - { - gboolean active = FALSE; - g_variant_get_child (parameters, 0, "b", &active); - g_debug ("%s active: %i", G_STRLOC, active); - - if (active && gss_mainloop != NULL) - { - g_main_loop_quit(gss_mainloop); - } - } -} - -static gboolean -get_greeter_mode (void) -{ - const gchar *var; - var = g_getenv("INDICATOR_GREETER_MODE"); - return (g_strcmp0(var, "1") == 0); -} - -/* Build the gss proxy and set up its signals */ -void -build_gss_proxy (void) -{ - if (gss_proxy == NULL) { - if (get_greeter_mode ()) - return; /* Don't start/lock the screensaver from the login screen */ - - - GError * error = NULL; - gss_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.ScreenSaver", - "/", - "org.gnome.ScreenSaver", - NULL, - &error); - if (error != NULL) { - g_message ("Unable to get ScreenSaver proxy: %s", error->message); - g_error_free (error); - } - - g_return_if_fail (gss_proxy != NULL); - g_signal_connect (gss_proxy, "g-signal", G_CALLBACK(on_gss_signal), NULL); - } - - return; -} - -/* This is a timeout, we only want to wait for the screen to - lock for a little bit, but not forever. */ -static gboolean -activate_timeout (gpointer data) -{ - /* Clear the ID for the timeout */ - guint * address = (guint *)data; - *address = 0; - - /* Quit the mainloop */ - if (gss_mainloop != NULL) { - g_main_loop_quit(gss_mainloop); - } - - return FALSE; -} - -/* A fun little function to actually lock the screen. - If that's what you want, let's do it! */ -void -lock_screen (DbusmenuMenuitem * mi, guint timestamp, gpointer data) -{ - g_debug("Lock Screen"); - - build_gss_proxy(); - g_return_if_fail(gss_proxy != NULL); - - GError * error = NULL; - GVariant * ret = g_dbus_proxy_call_sync (gss_proxy, - "Lock", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - g_variant_unref (ret); - if (error != NULL) { - g_warning ("Unable to lock: %s", error->message); - g_error_free (error); - } - if (gss_mainloop == NULL) { - gss_mainloop = g_main_loop_new(NULL, FALSE); - } - - guint timer = g_timeout_add_seconds(1, activate_timeout, &timer); - - g_main_loop_run(gss_mainloop); - - if (timer != 0) { - g_source_remove(timer); - } - - return; -} - -/* Do what it takes to make the lock screen function work - and be happy. */ -gboolean -lock_screen_setup (gpointer data) -{ - if (!g_strcmp0(g_get_user_name(), "guest")) { - is_guest = TRUE; - } - - return FALSE; -} - diff --git a/src/lock-helper.h b/src/lock-helper.h deleted file mode 100644 index e2d5106..0000000 --- a/src/lock-helper.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -A small helper for locking the screen. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see . -*/ - -#ifndef LOCK_HELPER_H__ -#define LOCK_HELPER_H__ - -#include - -gboolean will_lock_screen (void); -void lock_screen (DbusmenuMenuitem * mi, guint timestamp, gpointer data); -gboolean lock_screen_setup (gpointer data); - -#endif /* LOCK_HELPER_H__ */ diff --git a/src/session-menu-mgr.c b/src/session-menu-mgr.c index 0fdaeb5..c6de0b1 100644 --- a/src/session-menu-mgr.c +++ b/src/session-menu-mgr.c @@ -3,6 +3,7 @@ Copyright 2011 Canonical Ltd. Authors: Conor Curran + Charles Kerr This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published @@ -19,126 +20,182 @@ with this program. If not, see . #include +#include +#include + #include -#include +#include #include #include #include "dbus-shared-names.h" #include "dbus-upower.h" -#include "lock-helper.h" #include "session-menu-mgr.h" -#include "settings-helper.h" #include "users-service-dbus.h" -#define UP_ADDRESS "org.freedesktop.UPower" -#define UP_OBJECT "/org/freedesktop/UPower" -#define UP_INTERFACE "org.freedesktop.UPower" +#define UPOWER_ADDRESS "org.freedesktop.UPower" +#define UPOWER_PATH "/org/freedesktop/UPower" + +#define CMD_HELP "yelp" +#define CMD_INFO "gnome-control-center info" +#define CMD_SYSTEM_SETTINGS "gnome-control-center" +#ifdef HAVE_GTKLOGOUTHELPER + #define CMD_LOGOUT LIBEXECDIR"/gtk-logout-helper --logout" + #define CMD_SHUTDOWN LIBEXECDIR"/gtk-logout-helper --shutdown" + #define CMD_RESTART LIBEXECDIR"/gtk-logout-helper --restart" +#else + #define CMD_LOGOUT "gnome-session-quit --logout" + #define CMD_SHUTDOWN "gnome-session-quit --power-off" + #define CMD_RESTART CMD_SHUTDOWN /* hmm, no gnome-session-quit --restart? */ +#endif -#define EXTRA_LAUNCHER_DIR "/usr/share/indicators/session/applications" +/** + * Which switch menuitem to show -- based on lockdown settings, + * greeter mode, number of users in the system, and so on. + * See get_switcher_mode() + */ +typedef enum +{ + SWITCHER_MODE_SCREENSAVER, + SWITCHER_MODE_LOCK, + SWITCHER_MODE_SWITCH, + SWITCHER_MODE_SWITCH_OR_LOCK +} +SwitcherMode; + +typedef struct +{ + SessionMenuMgr * mgr; + AccountsUser * user; +} +ActivateUserSessionData; struct _SessionMenuMgr { GObject parent_instance; + DbusmenuMenuitem * parent_mi; - SessionDbus* session_dbus_interface; + DbusmenuMenuitem * lock_mi; + DbusmenuMenuitem * lock_switch_mi; + DbusmenuMenuitem * guest_mi; + DbusmenuMenuitem * logout_mi; + DbusmenuMenuitem * suspend_mi; + DbusmenuMenuitem * hibernate_mi; + DbusmenuMenuitem * restart_mi; + DbusmenuMenuitem * shutdown_mi; - GSettings *lockdown_settings; - GSettings * keybinding_settings; + GSList * user_menuitems; + gint user_menuitem_index; - DbusmenuMenuitem * hibernate_mi; - DbusmenuMenuitem * suspend_mi; - DbusmenuMenuitem * lock_mi; + GSettings * lockdown_settings; + GSettings * indicator_settings; + GSettings * keybinding_settings; gboolean can_hibernate; gboolean can_suspend; gboolean allow_hibernate; gboolean allow_suspend; + gboolean greeter_mode; - IndicatorSessionUPower * upower_proxy; GCancellable * cancellable; - - UsersServiceDbus* users_dbus_interface; - DbusmenuMenuitem * guest_mi; - gboolean greeter_mode; + DBusUPower * upower_proxy; + SessionDbus * session_dbus; + UsersServiceDbus * users_dbus_facade; }; -static void setup_up (SessionMenuMgr* self); -static void session_menu_mgr_rebuild_items (SessionMenuMgr *self); -static void screensaver_keybinding_changed (GSettings*, const gchar*, gpointer); - -static void activate_new_session (DbusmenuMenuitem * mi, - guint timestamp, - gpointer user_data); -static void activate_user_session (DbusmenuMenuitem *mi, - guint timestamp, - gpointer user_data); -static void activate_user_accounts (DbusmenuMenuitem *mi, - guint timestamp, - gpointer user_data); -static gint compare_users_by_username (gconstpointer a, - gconstpointer b); -static void activate_user_accounts (DbusmenuMenuitem *mi, - guint timestamp, - gpointer user_data); -static void menu_mgr_rebuild_users (SessionMenuMgr *self); -static void on_user_list_changed (UsersServiceDbus *service, - SessionMenuMgr * umm); - -static void on_guest_logged_in_changed (UsersServiceDbus * users_dbus, - SessionMenuMgr * self); - -static void on_user_logged_in_changed (UsersServiceDbus * users_dbus, - AccountsUser * user, - SessionMenuMgr * self); -static gboolean is_this_guest_session (void); -static void activate_guest_session (DbusmenuMenuitem * mi, - guint timestamp, - gpointer user_data); - +static SwitcherMode get_switcher_mode (SessionMenuMgr *); +static void init_upower_proxy (SessionMenuMgr *); +static void update_screensaver_shortcut (SessionMenuMgr *); +static void update_user_menuitems (SessionMenuMgr *); +static void update_session_menuitems (SessionMenuMgr *); +static void update_confirmation_labels (SessionMenuMgr *); -G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); +static void action_func_lock (SessionMenuMgr *); +static void action_func_suspend (SessionMenuMgr *); +static void action_func_hibernate (SessionMenuMgr *); +static void action_func_switch_to_lockscreen (SessionMenuMgr *); +static void action_func_switch_to_greeter (SessionMenuMgr *); +static void action_func_switch_to_guest (SessionMenuMgr *); +static void action_func_switch_to_user (ActivateUserSessionData *); +static void action_func_spawn_async (const char * fmt, ...); -static void -session_menu_mgr_init (SessionMenuMgr *self) -{ - self->can_hibernate = TRUE; - self->can_suspend = TRUE; - self->allow_hibernate = TRUE; - self->allow_suspend = TRUE; +static gboolean is_this_guest_session (void); +static gboolean is_this_live_session (void); - self->lockdown_settings = g_settings_new (LOCKDOWN_SCHEMA); - g_signal_connect_swapped (self->lockdown_settings, "changed::" LOCKDOWN_KEY_USER, G_CALLBACK(session_menu_mgr_rebuild_items), self); - g_signal_connect_swapped (self->lockdown_settings, "changed::" LOCKDOWN_KEY_SCREENSAVER, G_CALLBACK(session_menu_mgr_rebuild_items), self); +static void on_guest_logged_in_changed (UsersServiceDbus *, + SessionMenuMgr *); - self->keybinding_settings = g_settings_new (KEYBINDING_SCHEMA); - g_signal_connect (self->keybinding_settings, "changed::" KEY_LOCK_SCREEN, G_CALLBACK(screensaver_keybinding_changed), self); +static void on_user_logged_in_changed (UsersServiceDbus *, + AccountsUser *, + SessionMenuMgr *); - setup_up(self); +/** +*** GObject init / dispose / finalize +**/ - /* users */ - self->users_dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); - g_signal_connect (self->users_dbus_interface, "user-list-changed", - G_CALLBACK (on_user_list_changed), self); - g_signal_connect (self->users_dbus_interface, "user-logged-in-changed", - G_CALLBACK(on_user_logged_in_changed), self); - g_signal_connect (self->users_dbus_interface, "guest-logged-in-changed", - G_CALLBACK(on_guest_logged_in_changed), self); +G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); - g_idle_add(lock_screen_setup, NULL); +static void +session_menu_mgr_init (SessionMenuMgr *mgr) +{ + mgr->can_hibernate = TRUE; + mgr->can_suspend = TRUE; + mgr->allow_hibernate = TRUE; + mgr->allow_suspend = TRUE; + + /* Lockdown settings */ + GSettings * s = g_settings_new ("org.gnome.desktop.lockdown"); + g_signal_connect_swapped (s, "changed", + G_CALLBACK(update_session_menuitems), mgr); + g_signal_connect_swapped (s, "changed::disable-lock-screen", + G_CALLBACK(update_user_menuitems), mgr); + g_signal_connect_swapped (s, "changed::disable-user-switching", + G_CALLBACK(update_user_menuitems), mgr); + mgr->lockdown_settings = s; + + /* Indicator settings */ + s = g_settings_new ("com.canonical.indicator.session"); + g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(update_confirmation_labels), mgr); + g_signal_connect (s, "changed", G_CALLBACK(update_session_menuitems), mgr); + mgr->indicator_settings = s; + + /* Keybinding settings */ + s = g_settings_new ("org.gnome.settings-daemon.plugins.media-keys"); + g_signal_connect_swapped (s, "changed::screensaver", + G_CALLBACK(update_screensaver_shortcut), mgr); + mgr->keybinding_settings = s; + + /* listen for users who appear or log in or log out */ + mgr->users_dbus_facade = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); + g_signal_connect_swapped (mgr->users_dbus_facade, "user-list-changed", + G_CALLBACK (update_user_menuitems), mgr); + g_signal_connect (mgr->users_dbus_facade, "user-logged-in-changed", + G_CALLBACK(on_user_logged_in_changed), mgr); + g_signal_connect (mgr->users_dbus_facade, "guest-logged-in-changed", + G_CALLBACK(on_guest_logged_in_changed), mgr); + + init_upower_proxy (mgr); } static void session_menu_mgr_dispose (GObject *object) { - SessionMenuMgr * self = SESSION_MENU_MGR (object); - g_clear_object (&self->lockdown_settings); - g_clear_object (&self->keybinding_settings); - g_clear_object (&self->upower_proxy); - g_clear_object (&self->cancellable); - g_clear_object (&self->users_dbus_interface); + SessionMenuMgr * mgr = SESSION_MENU_MGR (object); + + if (mgr->cancellable != NULL) + { + g_cancellable_cancel (mgr->cancellable); + g_clear_object (&mgr->cancellable); + } + + g_clear_object (&mgr->indicator_settings); + g_clear_object (&mgr->lockdown_settings); + g_clear_object (&mgr->keybinding_settings); + g_clear_object (&mgr->upower_proxy); + g_clear_object (&mgr->users_dbus_facade); G_OBJECT_CLASS (session_menu_mgr_parent_class)->finalize (object); } @@ -158,117 +215,68 @@ session_menu_mgr_class_init (SessionMenuMgrClass *klass) } /*** -**** +**** Menuitem Helpers ***/ -static void -update_screensaver_shortcut (DbusmenuMenuitem * menuitem, GSettings * settings) +static inline void +mi_set_label (DbusmenuMenuitem * mi, const char * str) { - if (menuitem != NULL) - { - gchar * val = g_settings_get_string (settings, KEY_LOCK_SCREEN); - g_debug ("Keybinding changed to: %s", val); - dbusmenu_menuitem_property_set_shortcut_string (menuitem, val); - g_free (val); - } + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, str); } -static void -screensaver_keybinding_changed (GSettings * settings, - const gchar * key G_GNUC_UNUSED, - gpointer userdata) +static inline void +mi_set_type (DbusmenuMenuitem * mi, const char * str) { - update_screensaver_shortcut (SESSION_MENU_MGR(userdata)->lock_mi, settings); + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, str); } - -static void -machine_sleep_from_suspend (DbusmenuMenuitem * mi G_GNUC_UNUSED, - guint timestamp G_GNUC_UNUSED, - gpointer userdata) +static inline void +mi_set_visible (DbusmenuMenuitem * mi, gboolean b) { - GError * error = NULL; - SessionMenuMgr * mgr = SESSION_MENU_MGR (userdata); - - indicator_session_upower_call_suspend_sync (mgr->upower_proxy, mgr->cancellable, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } + dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, b); } -static void -machine_sleep_from_hibernate (DbusmenuMenuitem * mi G_GNUC_UNUSED, - guint timestamp G_GNUC_UNUSED, - gpointer userdata) +static inline void +mi_set_logged_in (DbusmenuMenuitem * mi, gboolean b) { - GError * error = NULL; - SessionMenuMgr * mgr = SESSION_MENU_MGR (userdata); - - indicator_session_upower_call_hibernate_sync (mgr->upower_proxy, mgr->cancellable, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } + dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b); } -/*** -**** -***/ - -/* When allow-suspend changes, rebuild the menus */ -static void -allowed_suspend_cb (GObject * source, GAsyncResult * res, gpointer userdata) +static DbusmenuMenuitem* +mi_new_separator (void) { - gboolean allowed; - GError * error = NULL; - SessionMenuMgr * mgr = SESSION_MENU_MGR (userdata); - - indicator_session_upower_call_suspend_allowed_finish (mgr->upower_proxy, &allowed, res, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - } - else if (mgr->allow_suspend != allowed) - { - mgr->allow_suspend = allowed; - session_menu_mgr_rebuild_items (mgr); - } + DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); + mi_set_type (mi, DBUSMENU_CLIENT_TYPES_SEPARATOR); + return mi; } -/* When allow-hibernate changes, rebuild the menus */ -static void -allowed_hibernate_cb (GObject * source, GAsyncResult * res, gpointer userdata) +static DbusmenuMenuitem* +mi_new (const char * label) { - gboolean allowed; - GError * error = NULL; - SessionMenuMgr * mgr = SESSION_MENU_MGR (userdata); - - indicator_session_upower_call_hibernate_allowed_finish (mgr->upower_proxy, &allowed, res, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_error_free (error); - } - else if (mgr->allow_hibernate != allowed) - { - mgr->allow_hibernate = allowed; - session_menu_mgr_rebuild_items (mgr); - } + DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); + mi_set_label (mi, label); + return mi; } +/*** +**** UPower Proxy: +**** +**** 1. While bootstrapping, we invoke the AllowSuspend and AllowHibernate +**** methods to find out whether or not those functions are allowed. +**** 2. While bootstrapping, we get the CanSuspend and CanHibernate properties +**** and also listen for property changes. +**** 3. These four values are used to set suspend and hibernate's visibility +**** +***/ static void -on_upower_properties_changed (IndicatorSessionUPower * upower_proxy, SessionMenuMgr * mgr) +on_upower_properties_changed (SessionMenuMgr * mgr) { gboolean b; gboolean refresh = FALSE; /* suspend */ - b = indicator_session_upower_get_can_suspend (upower_proxy); + b = dbus_upower_get_can_suspend (mgr->upower_proxy); if (mgr->can_suspend != b) { mgr->can_suspend = b; @@ -276,7 +284,7 @@ on_upower_properties_changed (IndicatorSessionUPower * upower_proxy, SessionMenu } /* hibernate */ - b = indicator_session_upower_get_can_hibernate (upower_proxy); + b = dbus_upower_get_can_hibernate (mgr->upower_proxy); if (mgr->can_hibernate != b) { mgr->can_hibernate = b; @@ -285,230 +293,185 @@ on_upower_properties_changed (IndicatorSessionUPower * upower_proxy, SessionMenu if (refresh) { - session_menu_mgr_rebuild_items (mgr); + update_session_menuitems (mgr); } } -/* This function goes through and sets up what we need for DKp checking. - We're even setting up the calls for the props we need */ static void -setup_up (SessionMenuMgr* self) +init_upower_proxy (SessionMenuMgr * mgr) { - self->cancellable = g_cancellable_new (); + mgr->cancellable = g_cancellable_new (); GError * error = NULL; - self->upower_proxy = indicator_session_upower_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - 0, - UP_ADDRESS, - UP_OBJECT, - NULL, - &error); + mgr->upower_proxy = dbus_upower_proxy_new_for_bus_sync ( + G_BUS_TYPE_SYSTEM, + 0, + UPOWER_ADDRESS, + UPOWER_PATH, + NULL, + &error); if (error != NULL) { - g_warning ("Error creating cups notify handler: %s", error->message); - g_error_free (error); + g_warning ("Error creating upower proxy: %s", error->message); + g_clear_error (&error); } else { - /* Check to see if these are getting blocked by PolicyKit */ - indicator_session_upower_call_suspend_allowed (self->upower_proxy, self->cancellable, allowed_suspend_cb, self); - indicator_session_upower_call_hibernate_allowed (self->upower_proxy, self->cancellable, allowed_hibernate_cb, self); - - g_signal_connect (self->upower_proxy, "changed", G_CALLBACK(on_upower_properties_changed), self); - - /* trigger an initial "changed" event */ - on_upower_properties_changed (self->upower_proxy, self); - } - - -} - -static void -spawn_command_line_async (const char * fmt, ...) -{ - va_list marker; - va_start (marker, fmt); - gchar * cmd = g_strdup_vprintf (fmt, marker); - va_end (marker); - - GError * error = NULL; - if (!g_spawn_command_line_async (cmd, &error)) - { - g_warning ("Unable to show \"%s\": %s", cmd, error->message); + dbus_upower_call_suspend_allowed_sync (mgr->upower_proxy, + &mgr->allow_suspend, + NULL, + &error); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); + } + + dbus_upower_call_hibernate_allowed_sync (mgr->upower_proxy, + &mgr->allow_hibernate, + NULL, + &error); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); + } + + on_upower_properties_changed (mgr); + g_signal_connect_swapped (mgr->upower_proxy, "changed", + G_CALLBACK(on_upower_properties_changed), mgr); } - - g_clear_error (&error); - g_free (cmd); } +/*** +**** Admin Menuitems +***/ -/* This is the function to show a dialog on actions that - can destroy data. Currently it just calls the GTK version - but it seems that in the future it should figure out - what's going on and something better. */ -static void -show_dialog (DbusmenuMenuitem * mi, guint timestamp, gchar * type) -{ -#ifdef HAVE_GTKLOGOUTHELPER - gchar * helper = g_build_filename(LIBEXECDIR, "gtk-logout-helper", NULL); -#else - gchar * helper = g_build_filename("gnome-session-quit", NULL); -#endif /* HAVE_GTKLOGOUTHELPER */ - spawn_command_line_async ("%s --%s", helper, type); - g_free (helper); -} +#define DEBUG_SHOW_ALL 1 static void -session_menu_mgr_build_static_items (SessionMenuMgr* self, gboolean greeter_mode) +build_admin_menuitems (SessionMenuMgr * mgr) { - const char * name; DbusmenuMenuitem * mi; - DbusmenuMenuitem * logout_mi = NULL; - DbusmenuMenuitem * shutdown_mi = NULL; - - /*** - **** Admin items - ***/ + const gboolean show_settings = DEBUG_SHOW_ALL || !mgr->greeter_mode; - name = _("About This Computer"); - mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append (self->parent_mi, mi); + mi = mi_new (_("About This Computer")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_INFO); + mi = mi_new (_("Ubuntu Help")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(spawn_command_line_async), "gnome-control-center info"); + G_CALLBACK(action_func_spawn_async), CMD_HELP); + + mi = mi_new_separator (); + mi_set_visible (mi, show_settings); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); - name = _("Ubuntu Help"); - mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append (self->parent_mi, mi); + mi = mi_new (_("System Settings\342\200\246")); + mi_set_visible (mi, show_settings); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(spawn_command_line_async), "yelp"); - - if (!greeter_mode) - { - mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - - name = _("System Settings…"); - mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(spawn_command_line_async), "gnome-control-center"); - } + G_CALLBACK(action_func_spawn_async), + CMD_SYSTEM_SETTINGS); - mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append (self->parent_mi, mi); + mi = mi_new_separator (); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); +} - /*** - **** Account-switching items - ***/ +/*** +**** Session Menuitems +***/ - /* TODO: FIXME */ +static void +update_session_menuitems (SessionMenuMgr * mgr) +{ + gboolean v; + GSettings * s = mgr->indicator_settings; - const gboolean can_lockscreen = !g_settings_get_boolean (self->lockdown_settings, LOCKDOWN_KEY_SCREENSAVER); - if (can_lockscreen) - { - name = _("Lock Screen"); - self->lock_mi = mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - update_screensaver_shortcut (mi, self->keybinding_settings); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(lock_screen), NULL); - } + v = !mgr->greeter_mode + && !is_this_live_session() + && !g_settings_get_boolean (mgr->lockdown_settings, "disable-logout") + && !g_settings_get_boolean (s, "suppress-logout-menuitem"); + mi_set_visible (mgr->logout_mi, v); - /*** - **** Session Items - ***/ + v = mgr->can_suspend + && mgr->allow_suspend; + mi_set_visible (mgr->suspend_mi, v); - mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append (self->parent_mi, mi); + v = mgr->can_hibernate + && mgr->allow_hibernate; + mi_set_visible (mgr->hibernate_mi, v); - if (!greeter_mode) - { - name = supress_confirmations() ? _("Log Out") : _("Log Out\342\200\246"); - logout_mi = mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, show_logout()); - dbusmenu_menuitem_child_append(self->parent_mi, mi); - g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(show_dialog), "logout"); - } + v = !g_settings_get_boolean (s, "suppress-restart-menuitem"); + mi_set_visible (mgr->restart_mi, v); - if (self->can_suspend && self->allow_suspend) - { - name = _("Suspend"); - self->suspend_mi = mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(machine_sleep_from_suspend), self); - } + v = !g_settings_get_boolean (s, "suppress-shutdown-menuitem"); + mi_set_visible (mgr->shutdown_mi, v); +} - if (self->can_hibernate && self->allow_hibernate) - { - name = _("Hibernate"); - self->hibernate_mi = mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append(self->parent_mi, mi); - g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(machine_sleep_from_hibernate), self); - } +/* if confirmation is enabled, + add ellipsis to the labels of items whose actions need confirmation */ +static void +update_confirmation_labels (SessionMenuMgr * mgr) +{ + const gboolean confirm_needed = !g_settings_get_boolean ( + mgr->indicator_settings, + "suppress-logout-restart-shutdown"); - name = _("Restart"); - mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - /* FIXME: not implemented */ - - name = supress_confirmations() ? _("Shut Down") : _("Shut Down\342\200\246"); - shutdown_mi = mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, show_shutdown()); - dbusmenu_menuitem_child_append (self->parent_mi, mi); - g_signal_connect (G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, -#ifdef HAVE_GTKLOGOUTHELPER - G_CALLBACK(show_dialog), "shutdown"); -#else - G_CALLBACK(show_dialog), "power-off"); -#endif /* HAVE_GTKLOGOUTHELPER */ + mi_set_label (mgr->logout_mi, confirm_needed ? _("Log Out\342\200\246") + : _("Log Out")); - RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi = g_new0 (RestartShutdownLogoutMenuItems, 1); - restart_shutdown_logout_mi->logout_mi = logout_mi; - restart_shutdown_logout_mi->shutdown_mi = shutdown_mi; + mi_set_label (mgr->shutdown_mi, confirm_needed ? _("Switch Off\342\200\246") + : _("Switch Off")); - update_menu_entries(restart_shutdown_logout_mi); + dbusmenu_menuitem_property_set (mgr->restart_mi, RESTART_ITEM_LABEL, + confirm_needed ? _("Restart\342\200\246") + : _("Restart")); } static void -session_menu_mgr_rebuild_items (SessionMenuMgr* self) +build_session_menuitems (SessionMenuMgr* mgr) { - dbusmenu_menuitem_property_set_bool (self->hibernate_mi, - DBUSMENU_MENUITEM_PROP_VISIBLE, - self->can_hibernate && self->allow_hibernate); - dbusmenu_menuitem_property_set_bool (self->suspend_mi, - DBUSMENU_MENUITEM_PROP_VISIBLE, - self->can_suspend && self->allow_suspend); -} + DbusmenuMenuitem * mi; -/*** -**** User Menu -***/ + mi = mi_new_separator (); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); -struct ActivateUserSessionData -{ - SessionMenuMgr * menu_mgr; - AccountsUser * user; -}; + mi = mgr->logout_mi = mi_new (_("Log Out\342\200\246")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_LOGOUT); -/*** -**** -***/ + mi = mgr->suspend_mi = mi_new ("Suspend"); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_suspend), mgr); + + mi = mgr->hibernate_mi = mi_new (_("Hibernate")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_hibernate), mgr); + + mi = mgr->restart_mi = mi_new (_("Restart\342\200\246")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_RESTART); + + mi = mgr->shutdown_mi = mi_new (_("Switch Off\342\200\246")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_SHUTDOWN); + + update_confirmation_labels (mgr); +} + +/**** +***** User Menuitems +****/ + +/* Local Extensions to AccountsUser */ static GQuark get_menuitem_quark (void) @@ -532,12 +495,14 @@ user_get_menuitem (AccountsUser * user) static void user_set_menuitem (AccountsUser * user, DbusmenuMenuitem * mi) { - g_message ("%s %s() associating user %s with mi %p", G_STRLOC, G_STRFUNC, accounts_user_get_user_name(user), mi); - g_object_set_qdata_full (G_OBJECT(user), get_menuitem_quark(), g_object_ref(G_OBJECT(mi)), g_object_unref); + g_message ("%s %s() associating user %s with mi %p", + G_STRLOC, G_STRFUNC, accounts_user_get_user_name(user), mi); + g_object_set_qdata_full (G_OBJECT(user), get_menuitem_quark(), + g_object_ref(G_OBJECT(mi)), g_object_unref); } static GQuark -get_name_collision_quark (void) +get_collision_quark (void) { static GQuark q = 0; @@ -550,15 +515,15 @@ get_name_collision_quark (void) } static gboolean -get_user_name_collision (AccountsUser * user) +user_has_name_collision (AccountsUser * u) { - return g_object_get_qdata (G_OBJECT(user), get_name_collision_quark()) != NULL; + return g_object_get_qdata (G_OBJECT(u), get_collision_quark()) != NULL; } static void -set_user_name_collision (AccountsUser * user, gboolean b) +user_set_name_collision (AccountsUser * u, gboolean b) { - g_object_set_qdata (G_OBJECT(user), get_name_collision_quark(), GINT_TO_POINTER(b)); + g_object_set_qdata (G_OBJECT(u), get_collision_quark(), GINT_TO_POINTER(b)); } /*** @@ -566,7 +531,42 @@ set_user_name_collision (AccountsUser * user, gboolean b) ***/ static void -update_menuitem_icon (DbusmenuMenuitem * mi, AccountsUser * user) +on_guest_logged_in_changed (UsersServiceDbus * usd, + SessionMenuMgr * mgr) +{ + mi_set_logged_in (mgr->guest_mi, + users_service_dbus_is_guest_logged_in (usd)); +} + +/* When a user's login state changes, + update the corresponding menuitem's LOGGED_IN property */ +static void +on_user_logged_in_changed (UsersServiceDbus * usd, + AccountsUser * user, + SessionMenuMgr * mgr) +{ + DbusmenuMenuitem * mi = user_get_menuitem (user); + + if (mi != NULL) + { + mi_set_logged_in (mi, users_service_dbus_is_user_logged_in (usd, user)); + } +} + +static void +update_screensaver_shortcut (SessionMenuMgr * mgr) +{ + gchar * s = g_settings_get_string (mgr->keybinding_settings, "screensaver"); + g_debug ("Keybinding changed to: %s", s); + dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_mi, s); + dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_switch_mi, s); + g_free (s); +} + +static void +on_user_icon_file_changed (AccountsUser * user, + GParamSpec * pspec G_GNUC_UNUSED, + DbusmenuMenuitem * mi) { const gchar * str = accounts_user_get_icon_file (user); @@ -578,299 +578,439 @@ update_menuitem_icon (DbusmenuMenuitem * mi, AccountsUser * user) dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_ICON, str); } +typedef struct +{ + AccountsUser * user; + gulong handler_id; +} +UserChangeListenerData; + +/* when the menuitem is destroyed, + it should stop listening for changes to the UserAccount properties :) */ static void -on_user_icon_file_changed (AccountsUser * user, GParamSpec * pspec, DbusmenuMenuitem * mi) +on_user_menuitem_destroyed (UserChangeListenerData * data) { - update_menuitem_icon (mi, user); + g_signal_handler_disconnect (data->user, data->handler_id); + g_free (data); } static DbusmenuMenuitem* -create_user_menuitem (SessionMenuMgr * menu_mgr, AccountsUser * user) +user_menuitem_new (AccountsUser * user, SessionMenuMgr * mgr) { DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (mi, - DBUSMENU_MENUITEM_PROP_TYPE, - USER_ITEM_TYPE); + mi_set_type (mi, USER_ITEM_TYPE); /* set the name property */ - const gchar * const real_name = accounts_user_get_real_name (user); - const gchar * const user_name = accounts_user_get_user_name (user); - char * str = get_user_name_collision (user) - ? g_strdup_printf ("%s (%s)", real_name, user_name) - : g_strdup (real_name); - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, str); - g_free (str); + GString * gstr = g_string_new (accounts_user_get_real_name (user)); + if (user_has_name_collision (user)) + { + g_string_append_printf (gstr, " (%s)", accounts_user_get_user_name(user)); + } + dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, gstr->str); + g_string_free (gstr, TRUE); /* set the logged-in property */ - const gboolean is_logged_in = users_service_dbus_is_user_logged_in (menu_mgr->users_dbus_interface, user); - dbusmenu_menuitem_property_set_bool (mi, - USER_ITEM_PROP_LOGGED_IN, - is_logged_in); + mi_set_logged_in (mi, + users_service_dbus_is_user_logged_in (mgr->users_dbus_facade, user)); - /* set the icon property */ - update_menuitem_icon (mi, user); - g_signal_connect (user, "notify::icon-file", G_CALLBACK(on_user_icon_file_changed), mi); + /* set the icon property & listen for changes */ + UserChangeListenerData * cd = g_new0 (UserChangeListenerData, 1); + cd->user = user; + cd->handler_id = g_signal_connect (user, "notify::icon-file", + G_CALLBACK(on_user_icon_file_changed), mi); + g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)on_user_menuitem_destroyed, cd); + on_user_icon_file_changed (user, NULL, mi); /* set the is-current-user property */ + const gboolean is_current_user = + !g_strcmp0 (g_get_user_name(), accounts_user_get_user_name(user)); dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_IS_CURRENT_USER, - !g_strcmp0 (user_name, g_get_user_name())); + is_current_user); /* set the activate callback */ - struct ActivateUserSessionData * data = g_new (struct ActivateUserSessionData, 1); + ActivateUserSessionData * data = g_new (ActivateUserSessionData, 1); data->user = user; - data->menu_mgr = menu_mgr; + data->mgr = mgr; g_signal_connect_data (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activate_user_session), + G_CALLBACK (action_func_switch_to_user), data, (GClosureNotify)g_free, - 0); + G_CONNECT_SWAPPED); /* give this AccountsUser a hook back to this menuitem */ user_set_menuitem (user, mi); - /* done */ return mi; } -static void -on_guest_logged_in_changed (UsersServiceDbus * users_service_dbus, - SessionMenuMgr * self) +/* for sorting AccountsUsers from most to least frequently used */ +static gint +compare_users_by_login_frequency (gconstpointer a, gconstpointer b) { - if (self->guest_mi != NULL) - { - const gboolean b = users_service_dbus_is_guest_logged_in (users_service_dbus); - dbusmenu_menuitem_property_set_bool (self->guest_mi, USER_ITEM_PROP_LOGGED_IN, b); - } + const guint64 a_freq = accounts_user_get_login_frequency (ACCOUNTS_USER(a)); + const guint64 b_freq = accounts_user_get_login_frequency (ACCOUNTS_USER(b)); + if (a_freq > b_freq) return -1; + if (a_freq < b_freq) return 1; + return 0; } -/* When a user's login state changes, - update the corresponding menuitem's LOGGED_IN property */ -static void -on_user_logged_in_changed (UsersServiceDbus * users_service_dbus, - AccountsUser * user, - SessionMenuMgr * self) +/* for sorting AccountsUsers by name */ +static gint +compare_users_by_username (gconstpointer ga, gconstpointer gb) { - DbusmenuMenuitem * mi = user_get_menuitem (user); + AccountsUser * a = ACCOUNTS_USER(ga); + AccountsUser * b = ACCOUNTS_USER(gb); - if (mi != NULL) + const int ret = g_strcmp0 (accounts_user_get_real_name (a), + accounts_user_get_real_name (b)); + + if (!ret) /* names are the same, so both have a name collision */ { - const gboolean b = users_service_dbus_is_user_logged_in (users_service_dbus, user); - dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b); + user_set_name_collision (a, TRUE); + user_set_name_collision (b, TRUE); } + + return ret; } -/* Builds up the menu for us */ -static void -menu_mgr_rebuild_users (SessionMenuMgr *self) +static gboolean +is_user_switching_allowed (SessionMenuMgr * mgr) { - GList *u; - gboolean can_activate; + /* maybe it's locked down */ + if (g_settings_get_boolean (mgr->lockdown_settings, "disable-user-switching")) + return FALSE; - /* Check to see which menu items we're allowed to have */ - can_activate = users_service_dbus_can_activate_session (self->users_dbus_interface) && - !g_settings_get_boolean (self->lockdown_settings, LOCKDOWN_KEY_USER); + /* maybe the seat doesn't support activation */ + if (!users_service_dbus_can_activate_session (mgr->users_dbus_facade)) + return FALSE; - /* Remove the old menu items if that makes sense */ -#warning FIXME -#if 0 - GList * children = dbusmenu_menuitem_take_children (self->root_item); - g_list_foreach (children, (GFunc)g_object_unref, NULL); - g_list_free (children); -#endif + return TRUE; +} - /* Set to NULL in case we don't end up building one */ - self->guest_mi = NULL; - - /* Build all of the user switching items */ - if (can_activate) - { - /* TODO: This needs to be updated once the ability to query guest session support is available */ - GList * users = users_service_dbus_get_user_list (self->users_dbus_interface); - const gboolean guest_enabled = users_service_dbus_guest_session_enabled (self->users_dbus_interface); - - /* TODO we should really return here if the menu is not going to be shown. */ - - DbusmenuMenuitem * switch_menuitem = dbusmenu_menuitem_new (); -/* - dbusmenu_menuitem_property_set (switch_menuitem, - DBUSMENU_MENUITEM_PROP_TYPE, - MENU_SWITCH_TYPE); -*/ - dbusmenu_menuitem_property_set (switch_menuitem, - USER_ITEM_PROP_NAME, - _("Switch User Account…")); - dbusmenu_menuitem_child_append (self->parent_mi, switch_menuitem); -g_message ("appending Switch button to %p", self->parent_mi); - g_signal_connect (G_OBJECT (switch_menuitem), - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activate_new_session), - self); - - if ( !is_this_guest_session () && guest_enabled) +static void +build_user_menuitems (SessionMenuMgr * mgr) +{ + DbusmenuMenuitem * mi; + GSList * items = NULL; + gint pos = mgr->user_menuitem_index; + const char * current_real_name = NULL; + + /** + *** Start Screen Saver + *** Switch Account... + *** Lock + *** Lock / Switch Account... + **/ + + const gboolean show_all = DEBUG_SHOW_ALL; + const SwitcherMode mode = get_switcher_mode (mgr); + + mi = mi_new (_("Start Screen Saver")); + mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SCREENSAVER)); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_lock), mgr); + + mi = mi_new (_("Switch User Account\342\200\246")); + mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SWITCH)); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_switch_to_greeter), mgr); + + mi = mgr->lock_mi = mi_new (_("Lock")); + mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_LOCK)); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_switch_to_lockscreen), mgr); + + mi = mgr->lock_switch_mi = mi_new (_("Lock/Switch Account\342\200\246")); + mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SWITCH_OR_LOCK)); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_switch_to_lockscreen), mgr); + + const gboolean guest_allowed = + users_service_dbus_guest_session_enabled (mgr->users_dbus_facade); + const gboolean is_guest = is_this_guest_session(); + mi = mi_new (_("Guest Session")); + mi_set_type (mi, USER_ITEM_TYPE); + mi_set_visible (mi, guest_allowed && !is_guest); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + on_guest_logged_in_changed (mgr->users_dbus_facade, mgr); + items = g_slist_prepend (items, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_switch_to_guest), mgr); + mgr->guest_mi = mi; + if (guest_allowed && is_guest) { - self->guest_mi = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (self->guest_mi, - DBUSMENU_MENUITEM_PROP_TYPE, - USER_ITEM_TYPE); - dbusmenu_menuitem_property_set (self->guest_mi, - USER_ITEM_PROP_NAME, - _("Guest Session")); - on_guest_logged_in_changed (self->users_dbus_interface, self); - dbusmenu_menuitem_child_append (self->parent_mi, self->guest_mi); - g_signal_connect (G_OBJECT (self->guest_mi), - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activate_guest_session), - self); - } - else{ - session_dbus_set_users_real_name (self->session_dbus_interface, - _("Guest")); + current_real_name = _("Guest"); } - - - - users = g_list_sort (users, compare_users_by_username); + + /*** + **** Users + ***/ - for (u = users; u != NULL; u = g_list_next (u)) - { - AccountsUser * user = u->data; + /* if we can switch to another user account, show them here */ + if (is_user_switching_allowed (mgr)) + { + GList * users = users_service_dbus_get_user_list (mgr->users_dbus_facade); + + /* pick the most frequently used accounts */ + const int MAX_USERS = 12; /* this limit comes from the spec */ + if (g_list_length(users) > MAX_USERS) + { + users = g_list_sort (users, compare_users_by_login_frequency); + GList * last = g_list_nth (users, MAX_USERS-1); + GList * remainder = last->next; + last->next = NULL; + remainder->prev = NULL; + g_list_free (remainder); + } + + /* Sort the users by name for display */ + users = g_list_sort (users, compare_users_by_username); + + /* Create menuitems for them */ + int i; + GList * u; + const char * const username = g_get_user_name(); + for (i=0, u=users; inext, i++) + { + AccountsUser * user = u->data; + DbusmenuMenuitem * mi = user_menuitem_new (user, mgr); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); + + if (!g_strcmp0 (username, accounts_user_get_user_name(user))) + { + current_real_name = accounts_user_get_real_name (user); + } + } + g_list_free(users); + } - DbusmenuMenuitem * mi = create_user_menuitem (self, user); - dbusmenu_menuitem_child_append (self->parent_mi, mi); + /* separator */ + mi = mi_new_separator (); + dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); + items = g_slist_prepend (items, mi); - const char * const user_name = accounts_user_get_user_name (user); - if (!g_strcmp0 (user_name, g_get_user_name())) - { - const char * const real_name = accounts_user_get_real_name (user); - session_dbus_set_users_real_name (self->session_dbus_interface, real_name); - } - } + if (current_real_name != NULL) + { + session_dbus_set_users_real_name (mgr->session_dbus, + current_real_name); + } - g_list_free(users); - } + update_screensaver_shortcut (mgr); + mgr->user_menuitems = items; +} - // Add the user accounts and separator - DbusmenuMenuitem * separator1 = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (separator1, - DBUSMENU_MENUITEM_PROP_TYPE, - DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append (self->parent_mi, separator1); +static void +update_user_menuitems (SessionMenuMgr * mgr) +{ + /* remove any previous user menuitems */ + GSList * l; + for (l=mgr->user_menuitems; l!=NULL; l=l->next) + { + dbusmenu_menuitem_child_delete (mgr->parent_mi, l->data); + } + g_slist_free (mgr->user_menuitems); + mgr->user_menuitems = NULL; - DbusmenuMenuitem * user_accounts_item = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set (user_accounts_item, - DBUSMENU_MENUITEM_PROP_TYPE, - DBUSMENU_CLIENT_TYPES_DEFAULT); - dbusmenu_menuitem_property_set (user_accounts_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("User Accounts…")); + /* add fresh user menuitems */ + build_user_menuitems (mgr); +} - g_signal_connect (G_OBJECT (user_accounts_item), - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (activate_user_accounts), - NULL); - - dbusmenu_menuitem_child_append (self->parent_mi, user_accounts_item); +/*** +**** +***/ +static void +action_func_spawn_async (const char * fmt, ...) +{ + va_list marker; + va_start (marker, fmt); + gchar * cmd = g_strdup_vprintf (fmt, marker); + va_end (marker); + + GError * error = NULL; + if (!g_spawn_command_line_async (cmd, &error)) + { + g_warning ("Unable to show \"%s\": %s", cmd, error->message); + } + g_clear_error (&error); + g_free (cmd); } -/* Check to see if the lockdown key is protecting from - locking the screen. If not, lock it. */ +/* Calling "Lock" locks the screen & goes to black. + Calling "SimulateUserActivity" afterwards shows the Lock Screen. */ static void -lock_if_possible (SessionMenuMgr * menu_mgr) +lock_helper (SessionMenuMgr * mgr, gboolean show_lock_screen) { - if (!g_settings_get_boolean (menu_mgr->lockdown_settings, LOCKDOWN_KEY_SCREENSAVER)) + if (!g_settings_get_boolean (mgr->lockdown_settings, "disable-lock-screen")) { - lock_screen(NULL, 0, NULL); + GError * error = NULL; + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_sync ( + G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.gnome.ScreenSaver", + "/org/gnome/ScreenSaver", + "org.gnome.ScreenSaver", + NULL, + &error); + + if (error == NULL) + { + g_dbus_proxy_call_sync (proxy, "Lock", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, + &error); + } + + if ((error == NULL) && show_lock_screen) + { + g_dbus_proxy_call_sync (proxy, "SimulateUserActivity", + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, + &error); + } + + if (error != NULL) + { + g_warning ("Error locking screen: %s", error->message); + } + + g_clear_object (&proxy); + g_clear_error (&error); } } -/* Starts a new generic session */ static void -activate_new_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data) +action_func_lock (SessionMenuMgr * mgr) { - SessionMenuMgr * menu_mgr = SESSION_MENU_MGR (user_data); - g_return_if_fail (menu_mgr != NULL); + lock_helper (mgr, FALSE); +} - lock_if_possible (menu_mgr); - users_service_dbus_show_greeter (menu_mgr->users_dbus_interface); +static void +action_func_switch_to_lockscreen (SessionMenuMgr * mgr) +{ + lock_helper (mgr, TRUE); } -/* Activates a session for a particular user. */ static void -activate_user_session (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data) +action_func_switch_to_greeter (SessionMenuMgr * mgr) { - struct ActivateUserSessionData * data = user_data; + action_func_lock (mgr); + users_service_dbus_show_greeter (mgr->users_dbus_facade); +} - lock_if_possible (data->menu_mgr); - users_service_dbus_activate_user_session (data->menu_mgr->users_dbus_interface, data->user); +static void +action_func_switch_to_user (ActivateUserSessionData * data) +{ + action_func_lock (data->mgr); + users_service_dbus_activate_user_session (data->mgr->users_dbus_facade, + data->user); } -/* Comparison function to look into the UserData struct - to compare by using the username value */ -static gint -compare_users_by_username (gconstpointer ga, gconstpointer gb) +static void +action_func_switch_to_guest (SessionMenuMgr * mgr) { - AccountsUser * a = ACCOUNTS_USER(ga); - AccountsUser * b = ACCOUNTS_USER(gb); + action_func_lock (mgr); + users_service_dbus_activate_guest_session (mgr->users_dbus_facade); +} - const int ret = g_strcmp0 (accounts_user_get_real_name (a), - accounts_user_get_real_name (b)); +static void +action_func_suspend (SessionMenuMgr * mgr) +{ + GError * error = NULL; - if (!ret) /* names are the same, so both have a name collision */ + dbus_upower_call_suspend_sync (mgr->upower_proxy, + mgr->cancellable, + &error); + + if (error != NULL) { - set_user_name_collision (a, TRUE); - set_user_name_collision (b, TRUE); + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); } - - return ret; } static void -activate_user_accounts (DbusmenuMenuitem *mi, - guint timestamp, - gpointer user_data) +action_func_hibernate (SessionMenuMgr * mgr) { GError * error = NULL; - if (!g_spawn_command_line_async("gnome-control-center user-accounts", &error)) - { - g_warning("Unable to show control centre: %s", error->message); - g_error_free(error); - } -} -/* Signal called when a user is added. - It updates the count and rebuilds the menu */ -static void -on_user_list_changed (UsersServiceDbus * service G_GNUC_UNUSED, - SessionMenuMgr * menu_mgr) -{ - g_return_if_fail (IS_SESSION_MENU_MGR(menu_mgr)); + dbus_upower_call_hibernate_sync (mgr->upower_proxy, + mgr->cancellable, + &error); - menu_mgr_rebuild_users (menu_mgr); + if (error != NULL) + { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_clear_error (&error); + } } +/*** +**** +***/ -/* Checks to see if we should show the guest session item. - System users shouldn't have guest account shown. - Mostly this would be the case of the guest user itself. */ static gboolean is_this_guest_session (void) { return geteuid() < 500; } -/* Called when someone clicks on the guest session item. */ -static void -activate_guest_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data) +static gboolean +is_this_live_session (void) +{ + const struct passwd * const pw = getpwuid (geteuid()); + return (pw->pw_uid==999) && !g_strcmp0("ubuntu",pw->pw_name); +} + +static SwitcherMode +get_switcher_mode (SessionMenuMgr * mgr) { - SessionMenuMgr * menu_mgr = SESSION_MENU_MGR (user_data); - g_return_if_fail (menu_mgr != NULL); + SwitcherMode mode; + + const gboolean can_lock = !g_settings_get_boolean (mgr->lockdown_settings, + "disable-lock-screen"); + const gboolean can_switch = is_user_switching_allowed (mgr); + + if (!can_lock && !can_switch) /* hmm, quite an extreme lockdown */ + { + mode = SWITCHER_MODE_SCREENSAVER; + } + else if (is_this_live_session()) /* live sessions can't lock or switch */ + { + mode = SWITCHER_MODE_SCREENSAVER; + } + else if (!can_switch) /* switching's locked down */ + { + mode = SWITCHER_MODE_LOCK; + } + else if (is_this_guest_session ()) /* guest sessions can't lock */ + { + mode = SWITCHER_MODE_SWITCH; + } + else + { + GList * l = users_service_dbus_get_user_list (mgr->users_dbus_facade); + const size_t user_count = g_list_length (l); + g_list_free (l); - lock_if_possible (menu_mgr); - users_service_dbus_activate_guest_session (menu_mgr->users_dbus_interface); + mode = user_count < 2 + ? SWITCHER_MODE_LOCK /* you can't switch if no other users */ + : SWITCHER_MODE_SWITCH_OR_LOCK; + } + + return mode; } + /*** **** ***/ @@ -879,11 +1019,14 @@ SessionMenuMgr* session_menu_mgr_new (DbusmenuMenuitem * parent_mi, SessionDbus * session_dbus, gboolean greeter_mode) { - SessionMenuMgr* menu_mgr = g_object_new (SESSION_TYPE_MENU_MGR, NULL); - menu_mgr->parent_mi = parent_mi; - menu_mgr->greeter_mode = greeter_mode; - menu_mgr->session_dbus_interface = session_dbus; - session_menu_mgr_build_static_items (menu_mgr, greeter_mode); - menu_mgr_rebuild_users (menu_mgr); - return menu_mgr; + SessionMenuMgr* mgr = g_object_new (SESSION_TYPE_MENU_MGR, NULL); + mgr->parent_mi = parent_mi; + mgr->greeter_mode = greeter_mode; + mgr->session_dbus = session_dbus; + build_admin_menuitems (mgr); + const guint n = g_list_length (dbusmenu_menuitem_get_children (parent_mi)); + mgr->user_menuitem_index = n; + build_user_menuitems (mgr); + build_session_menuitems (mgr); + return mgr; } diff --git a/src/session-menu-mgr.h b/src/session-menu-mgr.h index 0fa7baa..21d5356 100644 --- a/src/session-menu-mgr.h +++ b/src/session-menu-mgr.h @@ -45,8 +45,8 @@ struct _SessionMenuMgrClass GType session_menu_mgr_get_type (void) G_GNUC_CONST; SessionMenuMgr* session_menu_mgr_new (DbusmenuMenuitem * parent_mi, - SessionDbus * session_dbus, - gboolean greeter_mode); + SessionDbus * session_dbus, + gboolean greeter_mode); G_END_DECLS diff --git a/src/settings-helper.c b/src/settings-helper.c index d8e858f..0ab188a 100644 --- a/src/settings-helper.c +++ b/src/settings-helper.c @@ -20,138 +20,27 @@ with this program. If not, see . */ #include -#include - -#include -#include #include "dbus-shared-names.h" #include "settings-helper.h" static GSettings* settings = NULL; -static guint confirmation_notify = 0; -static guint logout_notify = 0; -static guint restart_notify = 0; -static guint shutdown_notify = 0; - static gboolean -build_settings (void) { - if (settings == NULL) { - settings = g_settings_new (SESSION_SCHEMA); - } - if (settings == NULL) { - return FALSE; - } - return TRUE; -} - -gboolean -supress_confirmations (void) { - gboolean settings_built = build_settings(); - g_return_val_if_fail(settings_built, FALSE); - return g_settings_get_boolean (settings, SUPPRESS_KEY) ; -} +build_settings (void) +{ + if (G_UNLIKELY(settings == NULL)) + { + settings = g_settings_new (SESSION_SCHEMA); + } -gboolean -show_logout (void) { - gboolean settings_built = build_settings(); - g_return_val_if_fail(settings_built, TRUE); - return !g_settings_get_boolean (settings, LOGOUT_KEY) ; + return settings != NULL; } gboolean -show_restart (void) { - gboolean settings_built = build_settings(); - g_return_val_if_fail(settings_built, TRUE); - return !g_settings_get_boolean (settings, RESTART_KEY) ; -} - -gboolean -show_shutdown (void) { - gboolean settings_built = build_settings(); - g_return_val_if_fail(settings_built, TRUE); - return !g_settings_get_boolean (settings, SHUTDOWN_KEY) ; -} - -static void update_menu_entries_callback (GSettings * settings, const gchar * key, gpointer data) { - RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi = (RestartShutdownLogoutMenuItems*) data; - - if(g_strcmp0 (key, SUPPRESS_KEY) == 0) { - if (g_settings_get_boolean (settings, key)) { - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out")); - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->restart_mi, RESTART_ITEM_LABEL, _("Restart")); - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->shutdown_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shut Down")); - } else { - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out…")); - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->restart_mi, RESTART_ITEM_LABEL, _("Restart…")); - dbusmenu_menuitem_property_set(restart_shutdown_logout_mi->shutdown_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shut Down…")); - } - } -} - -static void -update_logout_callback (GSettings * settings, const gchar * key, gpointer data) { - DbusmenuMenuitem * mi = (DbusmenuMenuitem*) data; +supress_confirmations (void) +{ + g_return_val_if_fail (build_settings(), FALSE); - if(g_strcmp0 (key, LOGOUT_KEY) == 0) { - dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_VISIBLE, !g_settings_get_boolean(settings, key)); - } + return g_settings_get_boolean (settings, SUPPRESS_KEY) ; } - -static void -update_restart_callback (GSettings * settings, const gchar * key, gpointer data) { - DbusmenuMenuitem * mi = (DbusmenuMenuitem*) data; - - if(g_strcmp0 (key, RESTART_KEY) == 0) { - dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_VISIBLE, !g_settings_get_boolean(settings, key)); - } -} - -static void -update_shutdown_callback (GSettings * settings, const gchar * key, gpointer data) { - DbusmenuMenuitem * mi = (DbusmenuMenuitem*) data; - - if(g_strcmp0 (key, SHUTDOWN_KEY) == 0) { - dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_VISIBLE, !g_settings_get_boolean(settings, key)); - } -} - -void -update_menu_entries(RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi) { - /* If we don't have a client, build one. */ - gboolean settings_built = build_settings(); - g_return_if_fail(settings_built); - - if (confirmation_notify != 0) { - g_signal_handler_disconnect (settings, confirmation_notify); - confirmation_notify = 0; - } - - if (logout_notify != 0) { - g_signal_handler_disconnect (settings, logout_notify); - logout_notify = 0; - } - - if (restart_notify != 0) { - g_signal_handler_disconnect (settings, restart_notify); - restart_notify = 0; - } - - if (shutdown_notify != 0) { - g_signal_handler_disconnect (settings, shutdown_notify); - shutdown_notify = 0; - } - - confirmation_notify = g_signal_connect (settings, "changed::" SUPPRESS_KEY, - G_CALLBACK(update_menu_entries_callback), restart_shutdown_logout_mi); - logout_notify = g_signal_connect (settings, "changed::" LOGOUT_KEY, - G_CALLBACK(update_logout_callback), restart_shutdown_logout_mi->logout_mi); - restart_notify = g_signal_connect (settings, "changed::" RESTART_KEY, - G_CALLBACK(update_restart_callback), restart_shutdown_logout_mi->restart_mi); - shutdown_notify = g_signal_connect (settings, "changed::" SHUTDOWN_KEY, - G_CALLBACK(update_shutdown_callback), restart_shutdown_logout_mi->shutdown_mi); - - return; -} - diff --git a/src/settings-helper.h b/src/settings-helper.h index 17304af..8c4b2e8 100644 --- a/src/settings-helper.h +++ b/src/settings-helper.h @@ -23,11 +23,6 @@ with this program. If not, see . #ifndef __GCONF_HELPER_H__ #define __GCONF_HELPER_H__ -#include - -#include -#include - #define SESSION_SCHEMA "com.canonical.indicator.session" #define SUPPRESS_KEY "suppress-logout-restart-shutdown" #define LOGOUT_KEY "suppress-logout-menuitem" @@ -35,25 +30,6 @@ with this program. If not, see . #define SHUTDOWN_KEY "suppress-shutdown-menuitem" #define SHOW_USER_MENU "user-show-menu" -#define LOCKDOWN_SCHEMA "org.gnome.desktop.lockdown" -#define LOCKDOWN_KEY_USER "disable-user-switching" -#define LOCKDOWN_KEY_SCREENSAVER "disable-lock-screen" -#define KEYBINDING_SCHEMA "org.gnome.settings-daemon.plugins.media-keys" -#define KEY_LOCK_SCREEN "screensaver" - -typedef struct _RestartShutdownLogoutMenuItems -{ - DbusmenuMenuitem * logout_mi; - DbusmenuMenuitem * restart_mi; - DbusmenuMenuitem * shutdown_mi; -} -RestartShutdownLogoutMenuItems; - -void update_menu_entries(RestartShutdownLogoutMenuItems*); gboolean supress_confirmations (void); -gboolean show_logout (void); -gboolean show_restart (void); -gboolean show_shutdown (void); - #endif /* __GCONF_HELPER__ */ -- cgit v1.2.3 From c9e0ebffe5cb3787c5437bd6ad8482ed8a432ddb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 18 Jun 2012 12:35:05 -0500 Subject: clearing house: the remainder of bugfixes & readability changes --- src/Makefile.am | 5 +- src/dbus-shared-names.h | 69 ------ src/gtk-logout-helper.c | 35 +-- src/indicator-session.c | 83 ++++--- src/session-dbus.c | 5 +- src/session-menu-mgr.c | 546 +++++++++++++++++++++++++++++------------------ src/session-service.c | 68 +++--- src/settings-helper.c | 46 ---- src/settings-helper.h | 35 --- src/shared-names.h | 57 +++++ src/users-service-dbus.c | 10 +- 11 files changed, 489 insertions(+), 470 deletions(-) delete mode 100644 src/dbus-shared-names.h delete mode 100644 src/settings-helper.c delete mode 100644 src/settings-helper.h create mode 100644 src/shared-names.h (limited to 'src/settings-helper.c') diff --git a/src/Makefile.am b/src/Makefile.am index 24f2ee8..7bc6306 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,7 +20,7 @@ sessionlib_LTLIBRARIES = libsession.la libsession_la_SOURCES = \ indicator-session.c \ gen-session-dbus.xml.h \ - dbus-shared-names.h \ + shared-names.h \ user-widget.c \ user-widget.h libsession_la_CFLAGS = \ @@ -130,7 +130,6 @@ indicator_session_service_SOURCES = \ session-dbus.c \ session-dbus.h \ gen-session-dbus.xml.c \ - settings-helper.c \ users-service-dbus.h \ users-service-dbus.c \ session-menu-mgr.h \ @@ -157,8 +156,6 @@ if BUILD_GTKLOGOUTHELPER gtk_logout_helper_SOURCES = \ $(dbus_consolekit_manager_sources) \ gtk-logout-helper.c \ - settings-helper.c \ - settings-helper.h \ dialog.c \ dialog.h diff --git a/src/dbus-shared-names.h b/src/dbus-shared-names.h deleted file mode 100644 index 876735a..0000000 --- a/src/dbus-shared-names.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see . -*/ - -#ifndef __DBUS_SHARED_NAMES_H__ -#define __DBUS_SHARED_NAMES_H__ - -typedef enum { - UP_TO_DATE, - CHECKING_FOR_UPDATES, - UPDATES_AVAILABLE, - UPGRADE_IN_PROGRESS, - FINISHED, - RESTART_NEEDED, - DONT_KNOW -}AptState; - -typedef enum { - SIMULATION, - REAL -}TransactionType; - -//#define INDICATOR_USERS_DBUS_NAME INDICATOR_SESSION_DBUS_NAME -//#define INDICATOR_USERS_DBUS_OBJECT "/com/canonical/indicator/users/menu" -//#define INDICATOR_USERS_SERVICE_DBUS_OBJECT "/org/gnome/DisplayManager/UserManager" -//#define INDICATOR_USERS_SERVICE_DBUS_INTERFACE "org.gnome.DisplayManager.UserManager" - -#define INDICATOR_SESSION_DBUS_NAME "com.canonical.indicator.session" -#define INDICATOR_SESSION_DBUS_OBJECT "/com/canonical/indicator/session/menu" -#define INDICATOR_SESSION_DBUS_VERSION 0 - -#define INDICATOR_SESSION_SERVICE_DBUS_OBJECT "/com/canonical/indicator/session/service" -#define INDICATOR_SESSION_SERVICE_DBUS_IFACE "com.canonical.indicator.session.service" - -#define USER_ITEM_TYPE "x-canonical-user-item" -#define USER_ITEM_PROP_NAME "user-item-name" -#define USER_ITEM_PROP_LOGGED_IN "user-item-logged-in" -#define USER_ITEM_PROP_IS_CURRENT_USER "user-item-is-current-user" -#define USER_ITEM_PROP_ICON "user-item-icon-path" -#define USER_ITEM_ICON_DEFAULT "avatar-default" - -#define RESTART_ITEM_TYPE "x-canonical-restart-item" -#define RESTART_ITEM_LABEL "restart-label" -#define RESTART_ITEM_ICON "restart-icon" - -#define ICON_DEFAULT "system-devices-panel" -#define ICON_RESTART "system-devices-panel-alert" -#define GREETER_ICON_DEFAULT "system-shutdown-panel" -#define GREETER_ICON_RESTART "system-shutdown-panel-restart" - -#endif /* __DBUS_SHARED_NAMES_H__ */ diff --git a/src/gtk-logout-helper.c b/src/gtk-logout-helper.c index 360dd0f..b311701 100644 --- a/src/gtk-logout-helper.c +++ b/src/gtk-logout-helper.c @@ -8,16 +8,16 @@ Authors: Ted Gould Christoph Korn -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -28,7 +28,7 @@ with this program. If not, see . #include #include #include "dialog.h" -#include "settings-helper.h" +#include "shared-names.h" static void consolekit_fallback (LogoutDialogType action) @@ -91,7 +91,7 @@ session_action (LogoutDialogType action) GError * error = NULL; gboolean res = FALSE; - sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); if (sbus == NULL) { g_warning("Unable to get DBus session bus."); return; @@ -113,15 +113,15 @@ session_action (LogoutDialogType action) if (action == LOGOUT_DIALOG_TYPE_LOG_OUT) { g_debug("Asking Session manager to 'Logout'"); - res = dbus_g_proxy_call_with_timeout (sm_proxy, "Logout", INT_MAX, &error, + res = dbus_g_proxy_call_with_timeout (sm_proxy, "Logout", INT_MAX, &error, G_TYPE_UINT, 1, G_TYPE_INVALID, G_TYPE_INVALID); } else if (action == LOGOUT_DIALOG_TYPE_SHUTDOWN) { g_debug("Asking Session manager to 'RequestShutdown'"); - res = dbus_g_proxy_call_with_timeout (sm_proxy, "RequestShutdown", INT_MAX, &error, + res = dbus_g_proxy_call_with_timeout (sm_proxy, "RequestShutdown", INT_MAX, &error, G_TYPE_INVALID, G_TYPE_INVALID); } else if (action == LOGOUT_DIALOG_TYPE_RESTART) { g_debug("Asking Session manager to 'RequestReboot'"); - res = dbus_g_proxy_call_with_timeout (sm_proxy, "RequestReboot", INT_MAX, &error, + res = dbus_g_proxy_call_with_timeout (sm_proxy, "RequestReboot", INT_MAX, &error, G_TYPE_INVALID, G_TYPE_INVALID); } else { g_warning ("Unknown session action"); @@ -177,6 +177,17 @@ static GOptionEntry options[] = { {NULL} }; +static gboolean +suppress_confirmations (void) +{ + GSettings * s = g_settings_new (SESSION_SCHEMA); + const gboolean suppress = g_settings_get_boolean (s, SUPPRESS_KEY); + g_clear_object (&s); + return suppress; +} + + + int main (int argc, char * argv[]) { @@ -205,7 +216,7 @@ main (int argc, char * argv[]) INDICATOR_ICONS_DIR); GtkWidget * dialog = NULL; - if (!supress_confirmations()) { + if (!suppress_confirmations()) { g_debug("Showing dialog to ask for user confirmation"); dialog = GTK_WIDGET(logout_dialog_new(type)); } diff --git a/src/indicator-session.c b/src/indicator-session.c index d6c2599..53ff87e 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -1,23 +1,23 @@ /* A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. +into the gnome-panel using its applet interface. Copyright 2009 Canonical Ltd. Authors: Ted Gould Conor Curran - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -38,7 +38,7 @@ with this program. If not, see . #include #include -#include "dbus-shared-names.h" +#include "shared-names.h" #include "user-widget.h" #define INDICATOR_SESSION_TYPE (indicator_session_get_type ()) @@ -97,10 +97,10 @@ static void indicator_session_finalize (GObject *object); static GList* indicator_session_get_entries (IndicatorObject* obj); static guint indicator_session_get_location (IndicatorObject * io, IndicatorObjectEntry * entry); - + G_DEFINE_TYPE (IndicatorSession, indicator_session, INDICATOR_OBJECT_TYPE); -static void +static void indicator_session_class_init (IndicatorSessionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -139,12 +139,12 @@ indicator_session_init (IndicatorSession *self) g_settings_bind (self->settings, "show-real-name-on-panel", self->entry.label, "visible", G_SETTINGS_BIND_GET); - + gtk_widget_show (GTK_WIDGET(self->entry.menu)); gtk_widget_show (GTK_WIDGET(self->entry.image)); g_object_ref_sink (self->entry.menu); g_object_ref_sink (self->entry.image); - + // set up the handlers DbusmenuClient * menu_client = DBUSMENU_CLIENT(dbusmenu_gtkmenu_get_client(DBUSMENU_GTKMENU(self->entry.menu))); dbusmenu_client_add_type_handler (menu_client, @@ -198,7 +198,7 @@ static guint indicator_session_get_location (IndicatorObject * io, IndicatorObjectEntry * entry) { - return 0; + return 0; } /* callback for the service manager state of being */ @@ -218,10 +218,10 @@ service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointe -1, NULL, user_real_name_get_cb, - user_data); + user_data); return; } - + self->service_proxy_cancel = g_cancellable_new(); g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, @@ -232,7 +232,7 @@ service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointe self->service_proxy_cancel, service_proxy_cb, self); - } + } return; } @@ -260,7 +260,7 @@ service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) self->service_proxy = proxy; g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self); - + // Fetch the user's real name for the user entry label g_dbus_proxy_call (self->service_proxy, "GetUserRealName", @@ -277,17 +277,13 @@ service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) static gboolean new_user_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data) + DbusmenuClient * client, + gpointer user_data) { - - - GtkWidget* user_item = NULL; - - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + g_return_val_if_fail (DBUSMENU_IS_MENUITEM(newitem), FALSE); + g_return_val_if_fail (DBUSMENU_IS_GTKCLIENT(client), FALSE); - user_item = user_widget_new(newitem); + GtkWidget * user_item = user_widget_new (newitem); GtkMenuItem *user_widget = GTK_MENU_ITEM(user_item); @@ -308,22 +304,23 @@ new_user_item (DbusmenuMenuitem * newitem, static void user_real_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data) { - IndicatorSession * self = INDICATOR_SESSION(user_data); - GError * error = NULL; - GVariant * result; + IndicatorSession * self = INDICATOR_SESSION(user_data); - result = g_dbus_proxy_call_finish(self->service_proxy, res, &error); + GError * error = NULL; + GVariant * result = g_dbus_proxy_call_finish(self->service_proxy, res, &error); - if (error != NULL) { - g_warning ("unable to complete real name dbus query"); - g_error_free (error); - return; - } - - const gchar* username = NULL; - g_variant_get (result, "(&s)", &username); - indicator_session_update_users_label (self, username); - return; + if (error != NULL) + { + g_warning ("Unable to complete real name dbus query: %s", error->message); + g_clear_error (&error); + } + else + { + const gchar * username = NULL; + g_variant_get (result, "(&s)", &username); + indicator_session_update_users_label (self, username); + g_variant_unref (result); + } } /* Receives all signals from the service, routed to the appropriate functions */ @@ -409,8 +406,8 @@ build_restart_item (DbusmenuMenuitem * newitem, } static void -indicator_session_update_users_label (IndicatorSession * self, +indicator_session_update_users_label (IndicatorSession * self, const gchar * name) -{ +{ gtk_label_set_text (self->entry.label, name ? name : ""); } diff --git a/src/session-dbus.c b/src/session-dbus.c index 4b9d45f..4ece444 100644 --- a/src/session-dbus.c +++ b/src/session-dbus.c @@ -235,11 +235,8 @@ session_dbus_set_users_real_name (SessionDbus * session, const gchar * name) { SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session); GError * error = NULL; - if (priv->name != NULL) { - g_free(priv->name); - priv->name = NULL; - } + g_free (priv->name); priv->name = g_strdup(name); if (priv->bus != NULL) { diff --git a/src/session-menu-mgr.c b/src/session-menu-mgr.c index c6de0b1..752a6a6 100644 --- a/src/session-menu-mgr.c +++ b/src/session-menu-mgr.c @@ -2,26 +2,26 @@ Copyright 2011 Canonical Ltd. Authors: - Conor Curran Charles Kerr + Conor Curran -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include -#include +#include /* geteuid(), getpwuid() */ #include #include @@ -29,11 +29,13 @@ with this program. If not, see . #include #include -#include "dbus-shared-names.h" #include "dbus-upower.h" #include "session-menu-mgr.h" +#include "shared-names.h" #include "users-service-dbus.h" +#define DEBUG_SHOW_ALL FALSE + #define UPOWER_ADDRESS "org.freedesktop.UPower" #define UPOWER_PATH "/org/freedesktop/UPower" @@ -41,13 +43,15 @@ with this program. If not, see . #define CMD_INFO "gnome-control-center info" #define CMD_SYSTEM_SETTINGS "gnome-control-center" #ifdef HAVE_GTKLOGOUTHELPER + #define HAVE_RESTART_CMD TRUE + #define CMD_RESTART LIBEXECDIR"/gtk-logout-helper --restart" #define CMD_LOGOUT LIBEXECDIR"/gtk-logout-helper --logout" #define CMD_SHUTDOWN LIBEXECDIR"/gtk-logout-helper --shutdown" - #define CMD_RESTART LIBEXECDIR"/gtk-logout-helper --restart" #else + #define HAVE_RESTART_CMD FALSE /* hmm, no gnome-session-quit --restart? */ + #define CMD_RESTART "" #define CMD_LOGOUT "gnome-session-quit --logout" #define CMD_SHUTDOWN "gnome-session-quit --power-off" - #define CMD_RESTART CMD_SHUTDOWN /* hmm, no gnome-session-quit --restart? */ #endif /** @@ -64,18 +68,23 @@ typedef enum } SwitcherMode; -typedef struct -{ - SessionMenuMgr * mgr; - AccountsUser * user; -} -ActivateUserSessionData; - +/** + * Creates and manages the menumodel and associated actions for the + * session menu described at . + * + * This is a pretty straightforward class: it creates the menumodel + * and listens for events that can affect the model's properties. + * + * Simple event sources, such as GSettings and a UPower DBus proxy, + * are handled here. More involved event sources are delegated to + * UsersServiceDBus facade class. + */ struct _SessionMenuMgr { GObject parent_instance; DbusmenuMenuitem * parent_mi; + DbusmenuMenuitem * screensaver_mi; DbusmenuMenuitem * lock_mi; DbusmenuMenuitem * lock_switch_mi; DbusmenuMenuitem * guest_mi; @@ -92,19 +101,22 @@ struct _SessionMenuMgr GSettings * indicator_settings; GSettings * keybinding_settings; + /* cached settings taken from the upower proxy */ gboolean can_hibernate; gboolean can_suspend; gboolean allow_hibernate; gboolean allow_suspend; + gboolean greeter_mode; GCancellable * cancellable; DBusUPower * upower_proxy; - SessionDbus * session_dbus; + SessionDbus * session_dbus; UsersServiceDbus * users_dbus_facade; }; static SwitcherMode get_switcher_mode (SessionMenuMgr *); + static void init_upower_proxy (SessionMenuMgr *); static void update_screensaver_shortcut (SessionMenuMgr *); @@ -118,21 +130,21 @@ static void action_func_hibernate (SessionMenuMgr *); static void action_func_switch_to_lockscreen (SessionMenuMgr *); static void action_func_switch_to_greeter (SessionMenuMgr *); static void action_func_switch_to_guest (SessionMenuMgr *); -static void action_func_switch_to_user (ActivateUserSessionData *); +static void action_func_switch_to_user (AccountsUser *); static void action_func_spawn_async (const char * fmt, ...); -static gboolean is_this_guest_session (void); -static gboolean is_this_live_session (void); +static gboolean is_this_guest_session (void); +static gboolean is_this_live_session (void); -static void on_guest_logged_in_changed (UsersServiceDbus *, - SessionMenuMgr *); +static void on_guest_logged_in_changed (UsersServiceDbus *, + SessionMenuMgr *); -static void on_user_logged_in_changed (UsersServiceDbus *, - AccountsUser *, - SessionMenuMgr *); +static void on_user_logged_in_changed (UsersServiceDbus *, + AccountsUser *, + SessionMenuMgr *); /** -*** GObject init / dispose / finalize +*** GObject init / dispose **/ G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); @@ -140,14 +152,9 @@ G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); static void session_menu_mgr_init (SessionMenuMgr *mgr) { - mgr->can_hibernate = TRUE; - mgr->can_suspend = TRUE; - mgr->allow_hibernate = TRUE; - mgr->allow_suspend = TRUE; - /* Lockdown settings */ GSettings * s = g_settings_new ("org.gnome.desktop.lockdown"); - g_signal_connect_swapped (s, "changed", + g_signal_connect_swapped (s, "changed::disable-log-out", G_CALLBACK(update_session_menuitems), mgr); g_signal_connect_swapped (s, "changed::disable-lock-screen", G_CALLBACK(update_user_menuitems), mgr); @@ -159,7 +166,12 @@ session_menu_mgr_init (SessionMenuMgr *mgr) s = g_settings_new ("com.canonical.indicator.session"); g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", G_CALLBACK(update_confirmation_labels), mgr); - g_signal_connect (s, "changed", G_CALLBACK(update_session_menuitems), mgr); + g_signal_connect_swapped (s, "changed::suppress-logout-menuitem", + G_CALLBACK(update_session_menuitems), mgr); + g_signal_connect_swapped (s, "changed::suppress-restart-menuitem", + G_CALLBACK(update_session_menuitems), mgr); + g_signal_connect_swapped (s, "changed::suppress-shutdown-menuitem", + G_CALLBACK(update_session_menuitems), mgr); mgr->indicator_settings = s; /* Keybinding settings */ @@ -168,7 +180,7 @@ session_menu_mgr_init (SessionMenuMgr *mgr) G_CALLBACK(update_screensaver_shortcut), mgr); mgr->keybinding_settings = s; - /* listen for users who appear or log in or log out */ + /* listen for user events */ mgr->users_dbus_facade = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); g_signal_connect_swapped (mgr->users_dbus_facade, "user-list-changed", G_CALLBACK (update_user_menuitems), mgr); @@ -177,7 +189,7 @@ session_menu_mgr_init (SessionMenuMgr *mgr) g_signal_connect (mgr->users_dbus_facade, "guest-logged-in-changed", G_CALLBACK(on_guest_logged_in_changed), mgr); - init_upower_proxy (mgr); + init_upower_proxy (mgr); } static void @@ -197,13 +209,7 @@ session_menu_mgr_dispose (GObject *object) g_clear_object (&mgr->upower_proxy); g_clear_object (&mgr->users_dbus_facade); - G_OBJECT_CLASS (session_menu_mgr_parent_class)->finalize (object); -} - -static void -session_menu_mgr_finalize (GObject *object) -{ - G_OBJECT_CLASS (session_menu_mgr_parent_class)->finalize (object); + G_OBJECT_CLASS (session_menu_mgr_parent_class)->dispose (object); } static void @@ -211,61 +217,16 @@ session_menu_mgr_class_init (SessionMenuMgrClass *klass) { GObjectClass* object_class = G_OBJECT_CLASS (klass); object_class->dispose = session_menu_mgr_dispose; - object_class->finalize = session_menu_mgr_finalize; -} - -/*** -**** Menuitem Helpers -***/ - -static inline void -mi_set_label (DbusmenuMenuitem * mi, const char * str) -{ - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, str); -} - -static inline void -mi_set_type (DbusmenuMenuitem * mi, const char * str) -{ - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, str); -} - -static inline void -mi_set_visible (DbusmenuMenuitem * mi, gboolean b) -{ - dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, b); -} - -static inline void -mi_set_logged_in (DbusmenuMenuitem * mi, gboolean b) -{ - dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b); -} - -static DbusmenuMenuitem* -mi_new_separator (void) -{ - DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - mi_set_type (mi, DBUSMENU_CLIENT_TYPES_SEPARATOR); - return mi; -} - -static DbusmenuMenuitem* -mi_new (const char * label) -{ - DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - mi_set_label (mi, label); - return mi; } /*** **** UPower Proxy: **** **** 1. While bootstrapping, we invoke the AllowSuspend and AllowHibernate -**** methods to find out whether or not those functions are allowed. +**** methods to find out whether or not those features are allowed. **** 2. While bootstrapping, we get the CanSuspend and CanHibernate properties **** and also listen for property changes. -**** 3. These four values are used to set suspend and hibernate's visibility +**** 3. These four values are used to set suspend and hibernate's visibility. **** ***/ @@ -273,14 +234,14 @@ static void on_upower_properties_changed (SessionMenuMgr * mgr) { gboolean b; - gboolean refresh = FALSE; + gboolean need_refresh = FALSE; /* suspend */ b = dbus_upower_get_can_suspend (mgr->upower_proxy); if (mgr->can_suspend != b) { mgr->can_suspend = b; - refresh = TRUE; + need_refresh = TRUE; } /* hibernate */ @@ -288,10 +249,10 @@ on_upower_properties_changed (SessionMenuMgr * mgr) if (mgr->can_hibernate != b) { mgr->can_hibernate = b; - refresh = TRUE; + need_refresh = TRUE; } - if (refresh) + if (need_refresh) { update_session_menuitems (mgr); } @@ -300,6 +261,12 @@ on_upower_properties_changed (SessionMenuMgr * mgr) static void init_upower_proxy (SessionMenuMgr * mgr) { + /* default values */ + mgr->can_suspend = TRUE; + mgr->can_hibernate = TRUE; + mgr->allow_suspend = TRUE; + mgr->allow_hibernate = TRUE; + mgr->cancellable = g_cancellable_new (); GError * error = NULL; @@ -344,44 +311,92 @@ init_upower_proxy (SessionMenuMgr * mgr) } /*** -**** Admin Menuitems +**** Menuitem Helpers ***/ -#define DEBUG_SHOW_ALL 1 +static inline void +mi_set_label (DbusmenuMenuitem * mi, const char * str) +{ + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, str); +} -static void -build_admin_menuitems (SessionMenuMgr * mgr) +static inline void +mi_set_type (DbusmenuMenuitem * mi, const char * str) { - DbusmenuMenuitem * mi; - const gboolean show_settings = DEBUG_SHOW_ALL || !mgr->greeter_mode; + dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, str); +} - mi = mi_new (_("About This Computer")); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), CMD_INFO); +static inline void +mi_set_visible (DbusmenuMenuitem * mi, gboolean b) +{ + dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, + b || DEBUG_SHOW_ALL); +} - mi = mi_new (_("Ubuntu Help")); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), CMD_HELP); +static inline void +mi_set_logged_in (DbusmenuMenuitem * mi, gboolean b) +{ + dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b); +} - mi = mi_new_separator (); - mi_set_visible (mi, show_settings); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); +static DbusmenuMenuitem* +mi_new_separator (void) +{ + DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); + mi_set_type (mi, DBUSMENU_CLIENT_TYPES_SEPARATOR); + return mi; +} - mi = mi_new (_("System Settings\342\200\246")); - mi_set_visible (mi, show_settings); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), - CMD_SYSTEM_SETTINGS); +static DbusmenuMenuitem* +mi_new (const char * label) +{ + DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); + mi_set_label (mi, label); + return mi; +} - mi = mi_new_separator (); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); +/*** +**** Admin Menuitems +**** +***/ + +static void +build_admin_menuitems (SessionMenuMgr * mgr) +{ + if (!mgr->greeter_mode) + { + DbusmenuMenuitem * mi; + const gboolean show_settings = !mgr->greeter_mode; + + mi = mi_new (_("About This Computer")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_INFO); + + mi = mi_new (_("Ubuntu Help")); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), CMD_HELP); + + mi = mi_new_separator (); + mi_set_visible (mi, show_settings); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + + mi = mi_new (_("System Settings")); + mi_set_visible (mi, show_settings); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(action_func_spawn_async), + CMD_SYSTEM_SETTINGS); + + mi = mi_new_separator (); + dbusmenu_menuitem_child_append (mgr->parent_mi, mi); + } } /*** **** Session Menuitems +**** ***/ static void @@ -392,7 +407,7 @@ update_session_menuitems (SessionMenuMgr * mgr) v = !mgr->greeter_mode && !is_this_live_session() - && !g_settings_get_boolean (mgr->lockdown_settings, "disable-logout") + && !g_settings_get_boolean (mgr->lockdown_settings, "disable-log-out") && !g_settings_get_boolean (s, "suppress-logout-menuitem"); mi_set_visible (mgr->logout_mi, v); @@ -404,15 +419,20 @@ update_session_menuitems (SessionMenuMgr * mgr) && mgr->allow_hibernate; mi_set_visible (mgr->hibernate_mi, v); - v = !g_settings_get_boolean (s, "suppress-restart-menuitem"); + v = HAVE_RESTART_CMD + && !g_settings_get_boolean (s, "suppress-restart-menuitem"); mi_set_visible (mgr->restart_mi, v); v = !g_settings_get_boolean (s, "suppress-shutdown-menuitem"); mi_set_visible (mgr->shutdown_mi, v); } -/* if confirmation is enabled, - add ellipsis to the labels of items whose actions need confirmation */ +/* Update the ellipses when the confirmation setting changes. + * + * : + * "Label the menu item with a trailing ellipsis ("...") only if the + * command requires further input from the user before it can be performed." + */ static void update_confirmation_labels (SessionMenuMgr * mgr) { @@ -436,9 +456,6 @@ build_session_menuitems (SessionMenuMgr* mgr) { DbusmenuMenuitem * mi; - mi = mi_new_separator (); - dbusmenu_menuitem_child_append (mgr->parent_mi, mi); - mi = mgr->logout_mi = mi_new (_("Log Out\342\200\246")); dbusmenu_menuitem_child_append (mgr->parent_mi, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, @@ -454,24 +471,28 @@ build_session_menuitems (SessionMenuMgr* mgr) g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(action_func_hibernate), mgr); - mi = mgr->restart_mi = mi_new (_("Restart\342\200\246")); + mi = mgr->restart_mi = dbusmenu_menuitem_new (); + mi_set_type (mi, RESTART_ITEM_TYPE); + dbusmenu_menuitem_property_set (mi, RESTART_ITEM_LABEL, _("Restart\342\200\246")); dbusmenu_menuitem_child_append (mgr->parent_mi, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(action_func_spawn_async), CMD_RESTART); - + mi = mgr->shutdown_mi = mi_new (_("Switch Off\342\200\246")); dbusmenu_menuitem_child_append (mgr->parent_mi, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(action_func_spawn_async), CMD_SHUTDOWN); update_confirmation_labels (mgr); + update_session_menuitems (mgr); } /**** ***** User Menuitems +***** https://wiki.ubuntu.com/SystemMenu#Account-switching_items ****/ -/* Local Extensions to AccountsUser */ +/* Local extensions to AccountsUser */ static GQuark get_menuitem_quark (void) @@ -492,15 +513,49 @@ user_get_menuitem (AccountsUser * user) return g_object_get_qdata (G_OBJECT(user), get_menuitem_quark()); } +static void +user_clear_menuitem (AccountsUser * user) +{ + g_object_steal_qdata (G_OBJECT(user), get_menuitem_quark()); +} + static void user_set_menuitem (AccountsUser * user, DbusmenuMenuitem * mi) { - g_message ("%s %s() associating user %s with mi %p", - G_STRLOC, G_STRFUNC, accounts_user_get_user_name(user), mi); - g_object_set_qdata_full (G_OBJECT(user), get_menuitem_quark(), - g_object_ref(G_OBJECT(mi)), g_object_unref); + g_object_set_qdata (G_OBJECT(user), get_menuitem_quark(), mi); + + g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)user_clear_menuitem, user); } +/***/ + +static GQuark +get_mgr_quark (void) +{ + static GQuark q = 0; + + if (G_UNLIKELY(!q)) + { + q = g_quark_from_static_string ("session-menu-mgr"); + } + + return q; +} + +static SessionMenuMgr* +user_get_mgr (AccountsUser * user) +{ + return g_object_get_qdata (G_OBJECT(user), get_mgr_quark()); +} + +static void +user_set_mgr (AccountsUser * user, SessionMenuMgr * mgr) +{ + g_object_set_qdata (G_OBJECT(user), get_mgr_quark(), mgr); +} + +/***/ + static GQuark get_collision_quark (void) { @@ -534,8 +589,11 @@ static void on_guest_logged_in_changed (UsersServiceDbus * usd, SessionMenuMgr * mgr) { - mi_set_logged_in (mgr->guest_mi, - users_service_dbus_is_guest_logged_in (usd)); + if (mgr->guest_mi != NULL) + { + mi_set_logged_in (mgr->guest_mi, + users_service_dbus_is_guest_logged_in (usd)); + } } /* When a user's login state changes, @@ -557,19 +615,31 @@ static void update_screensaver_shortcut (SessionMenuMgr * mgr) { gchar * s = g_settings_get_string (mgr->keybinding_settings, "screensaver"); - g_debug ("Keybinding changed to: %s", s); - dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_mi, s); - dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_switch_mi, s); + g_debug ("%s Screensaver shortcut changed to: '%s'", G_STRLOC, s); + + if (mgr->lock_mi != NULL) + { + dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_mi, s); + } + + if (mgr->lock_switch_mi != NULL) + { + dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_switch_mi, s); + } + + if (mgr->screensaver_mi != NULL) + { + dbusmenu_menuitem_property_set_shortcut_string (mgr->screensaver_mi, s); + } + g_free (s); } static void -on_user_icon_file_changed (AccountsUser * user, - GParamSpec * pspec G_GNUC_UNUSED, - DbusmenuMenuitem * mi) +update_user_menuitem_icon (DbusmenuMenuitem * mi, AccountsUser * user) { const gchar * str = accounts_user_get_icon_file (user); - + if (!str || !*str) { str = USER_ITEM_ICON_DEFAULT; @@ -578,19 +648,62 @@ on_user_icon_file_changed (AccountsUser * user, dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_ICON, str); } +static void +update_user_menuitem_name (DbusmenuMenuitem * mi, AccountsUser * user) +{ + GString * gstr = g_string_new (accounts_user_get_real_name (user)); + + if (user_has_name_collision (user)) + { + g_string_append_printf (gstr, " (%s)", accounts_user_get_user_name(user)); + } + + dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, gstr->str); + g_string_free (gstr, TRUE); +} + +static void +on_user_property_changed (AccountsUser * user, + GParamSpec * pspec, + DbusmenuMenuitem * mi) +{ + static const char * interned_icon_file = NULL; + static const char * interned_real_name = NULL; + static const char * interned_user_name = NULL; + + if (G_UNLIKELY (interned_icon_file == NULL)) + { + interned_icon_file = g_intern_static_string ("icon-file"); + interned_user_name = g_intern_static_string ("user-name"); + interned_real_name = g_intern_static_string ("real-name"); + } + + if (pspec->name == interned_icon_file) + { + update_user_menuitem_icon (mi, user); + } + else if ((pspec->name == interned_real_name) + || (pspec->name == interned_user_name)) + { + /* name changing can affect other menuitems too by invalidating + the sort order or name collision flags... so let's rebuild */ + update_user_menuitems (user_get_mgr (user)); + } +} + typedef struct { - AccountsUser * user; + gpointer instance; gulong handler_id; } -UserChangeListenerData; +SignalHandlerData; -/* when the menuitem is destroyed, - it should stop listening for changes to the UserAccount properties :) */ +/* when a user menuitem is destroyed, + it should stop listening for its UserAccount's property changes */ static void -on_user_menuitem_destroyed (UserChangeListenerData * data) +on_user_menuitem_destroyed (SignalHandlerData * data) { - g_signal_handler_disconnect (data->user, data->handler_id); + g_signal_handler_disconnect (data->instance, data->handler_id); g_free (data); } @@ -600,27 +713,20 @@ user_menuitem_new (AccountsUser * user, SessionMenuMgr * mgr) DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); mi_set_type (mi, USER_ITEM_TYPE); - /* set the name property */ - GString * gstr = g_string_new (accounts_user_get_real_name (user)); - if (user_has_name_collision (user)) - { - g_string_append_printf (gstr, " (%s)", accounts_user_get_user_name(user)); - } - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, gstr->str); - g_string_free (gstr, TRUE); + /* set the name & icon and listen for property changes */ + update_user_menuitem_name (mi, user); + update_user_menuitem_icon (mi, user); + SignalHandlerData * hd = g_new0 (SignalHandlerData, 1); + hd->instance = user; + hd->handler_id = g_signal_connect (user, "notify", + G_CALLBACK(on_user_property_changed), mi); + g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)on_user_menuitem_destroyed, hd); + /* set the logged-in property */ mi_set_logged_in (mi, users_service_dbus_is_user_logged_in (mgr->users_dbus_facade, user)); - /* set the icon property & listen for changes */ - UserChangeListenerData * cd = g_new0 (UserChangeListenerData, 1); - cd->user = user; - cd->handler_id = g_signal_connect (user, "notify::icon-file", - G_CALLBACK(on_user_icon_file_changed), mi); - g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)on_user_menuitem_destroyed, cd); - on_user_icon_file_changed (user, NULL, mi); - /* set the is-current-user property */ const gboolean is_current_user = !g_strcmp0 (g_get_user_name(), accounts_user_get_user_name(user)); @@ -628,17 +734,13 @@ user_menuitem_new (AccountsUser * user, SessionMenuMgr * mgr) USER_ITEM_PROP_IS_CURRENT_USER, is_current_user); - /* set the activate callback */ - ActivateUserSessionData * data = g_new (ActivateUserSessionData, 1); - data->user = user; - data->mgr = mgr; - g_signal_connect_data (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (action_func_switch_to_user), - data, (GClosureNotify)g_free, - G_CONNECT_SWAPPED); + /* set the switch-to-user action */ + g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK (action_func_switch_to_user), user); /* give this AccountsUser a hook back to this menuitem */ user_set_menuitem (user, mi); + user_set_mgr (user, mgr); return mi; } @@ -654,7 +756,7 @@ compare_users_by_login_frequency (gconstpointer a, gconstpointer b) return 0; } -/* for sorting AccountsUsers by name */ +/* for sorting AccountsUsers alphabetically */ static gint compare_users_by_username (gconstpointer ga, gconstpointer gb) { @@ -690,6 +792,8 @@ is_user_switching_allowed (SessionMenuMgr * mgr) static void build_user_menuitems (SessionMenuMgr * mgr) { + g_return_if_fail (!mgr->greeter_mode); + DbusmenuMenuitem * mi; GSList * items = NULL; gint pos = mgr->user_menuitem_index; @@ -702,63 +806,78 @@ build_user_menuitems (SessionMenuMgr * mgr) *** Lock / Switch Account... **/ - const gboolean show_all = DEBUG_SHOW_ALL; const SwitcherMode mode = get_switcher_mode (mgr); - mi = mi_new (_("Start Screen Saver")); - mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SCREENSAVER)); + mi = mgr->screensaver_mi = mi_new (_("Start Screen Saver")); + mi_set_visible (mi, mode == SWITCHER_MODE_SCREENSAVER); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); items = g_slist_prepend (items, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (action_func_lock), mgr); mi = mi_new (_("Switch User Account\342\200\246")); - mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SWITCH)); + mi_set_visible (mi, mode == SWITCHER_MODE_SWITCH); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); items = g_slist_prepend (items, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (action_func_switch_to_greeter), mgr); mi = mgr->lock_mi = mi_new (_("Lock")); - mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_LOCK)); + mi_set_visible (mi, mode == SWITCHER_MODE_LOCK); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); items = g_slist_prepend (items, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (action_func_switch_to_lockscreen), mgr); mi = mgr->lock_switch_mi = mi_new (_("Lock/Switch Account\342\200\246")); - mi_set_visible (mi, show_all || (mode == SWITCHER_MODE_SWITCH_OR_LOCK)); + mi_set_visible (mi, mode == SWITCHER_MODE_SWITCH_OR_LOCK); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); items = g_slist_prepend (items, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (action_func_switch_to_lockscreen), mgr); - const gboolean guest_allowed = - users_service_dbus_guest_session_enabled (mgr->users_dbus_facade); - const gboolean is_guest = is_this_guest_session(); - mi = mi_new (_("Guest Session")); + const gboolean is_guest = is_this_guest_session (); + const gboolean guest_allowed = users_service_dbus_guest_session_enabled (mgr->users_dbus_facade); + mi = mgr->guest_mi = dbusmenu_menuitem_new (); mi_set_type (mi, USER_ITEM_TYPE); - mi_set_visible (mi, guest_allowed && !is_guest); + mi_set_visible (mi, !is_guest && guest_allowed); + dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, _("Guest Session")); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); on_guest_logged_in_changed (mgr->users_dbus_facade, mgr); items = g_slist_prepend (items, mi); g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK (action_func_switch_to_guest), mgr); - mgr->guest_mi = mi; + if (guest_allowed && is_guest) { current_real_name = _("Guest"); } - + /*** **** Users ***/ /* if we can switch to another user account, show them here */ - if (is_user_switching_allowed (mgr)) + const char * const username = g_get_user_name(); + GList * users = users_service_dbus_get_user_list (mgr->users_dbus_facade); + + /* since we're building (or rebuilding) from scratch, + clear the name collision flags */ + GList * u; + for (u=users; u!=NULL; u=u->next) { - GList * users = users_service_dbus_get_user_list (mgr->users_dbus_facade); + AccountsUser * user = ACCOUNTS_USER(u->data); + + user_set_name_collision (user, FALSE); + + if (!g_strcmp0 (username, accounts_user_get_user_name(user))) + { + current_real_name = accounts_user_get_real_name (user); + } + } + if (is_user_switching_allowed (mgr)) + { /* pick the most frequently used accounts */ const int MAX_USERS = 12; /* this limit comes from the spec */ if (g_list_length(users) > MAX_USERS) @@ -776,21 +895,14 @@ build_user_menuitems (SessionMenuMgr * mgr) /* Create menuitems for them */ int i; - GList * u; - const char * const username = g_get_user_name(); for (i=0, u=users; inext, i++) { AccountsUser * user = u->data; DbusmenuMenuitem * mi = user_menuitem_new (user, mgr); dbusmenu_menuitem_child_add_position (mgr->parent_mi, mi, pos++); items = g_slist_prepend (items, mi); - - if (!g_strcmp0 (username, accounts_user_get_user_name(user))) - { - current_real_name = accounts_user_get_real_name (user); - } } - g_list_free(users); + g_list_free (users); } /* separator */ @@ -821,11 +933,14 @@ update_user_menuitems (SessionMenuMgr * mgr) mgr->user_menuitems = NULL; /* add fresh user menuitems */ - build_user_menuitems (mgr); + if (!mgr->greeter_mode) + { + build_user_menuitems (mgr); + } } /*** -**** +**** Actions! ***/ static void @@ -835,14 +950,15 @@ action_func_spawn_async (const char * fmt, ...) va_start (marker, fmt); gchar * cmd = g_strdup_vprintf (fmt, marker); va_end (marker); - - GError * error = NULL; - if (!g_spawn_command_line_async (cmd, &error)) + + GError * error = NULL; + g_spawn_command_line_async (cmd, &error); + if (error != NULL) { - g_warning ("Unable to show \"%s\": %s", cmd, error->message); + g_warning ("Unable to execute \"%s\": %s", cmd, error->message); + g_clear_error (&error); } - g_clear_error (&error); g_free (cmd); } @@ -908,11 +1024,12 @@ action_func_switch_to_greeter (SessionMenuMgr * mgr) } static void -action_func_switch_to_user (ActivateUserSessionData * data) +action_func_switch_to_user (AccountsUser * user) { - action_func_lock (data->mgr); - users_service_dbus_activate_user_session (data->mgr->users_dbus_facade, - data->user); + SessionMenuMgr * mgr = user_get_mgr (user); + g_return_if_fail (mgr != NULL); + action_func_lock (mgr); + users_service_dbus_activate_user_session (mgr->users_dbus_facade, user); } static void @@ -961,6 +1078,8 @@ action_func_hibernate (SessionMenuMgr * mgr) static gboolean is_this_guest_session (void) { + /* FIXME: this test has been here awhile and seems to work, + but seems brittle to me */ return geteuid() < 500; } @@ -996,15 +1115,16 @@ get_switcher_mode (SessionMenuMgr * mgr) { mode = SWITCHER_MODE_SWITCH; } - else + else /* both locking & switching are allowed */ { GList * l = users_service_dbus_get_user_list (mgr->users_dbus_facade); const size_t user_count = g_list_length (l); g_list_free (l); - mode = user_count < 2 - ? SWITCHER_MODE_LOCK /* you can't switch if no other users */ - : SWITCHER_MODE_SWITCH_OR_LOCK; + /* only show switch mode if we have users to switch to */ + mode = user_count > (is_this_guest_session() ? 0 : 1) + ? SWITCHER_MODE_SWITCH_OR_LOCK + : SWITCHER_MODE_LOCK; } return mode; @@ -1026,7 +1146,7 @@ SessionMenuMgr* session_menu_mgr_new (DbusmenuMenuitem * parent_mi, build_admin_menuitems (mgr); const guint n = g_list_length (dbusmenu_menuitem_get_children (parent_mi)); mgr->user_menuitem_index = n; - build_user_menuitems (mgr); + update_user_menuitems (mgr); build_session_menuitems (mgr); return mgr; } diff --git a/src/session-service.c b/src/session-service.c index 598fcce..2349684 100644 --- a/src/session-service.c +++ b/src/session-service.c @@ -11,16 +11,16 @@ Authors: Conor Curran Charles Kerr -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -42,34 +42,31 @@ with this program. If not, see . #include -#include "dbus-shared-names.h" -#include "users-service-dbus.h" #include "session-dbus.h" #include "session-menu-mgr.h" +#include "shared-names.h" +#include "users-service-dbus.h" -//static UsersServiceDbus *dbus_interface = NULL; -static SessionDbus *session_dbus = NULL; +static SessionDbus * session_dbus = NULL; static GMainLoop * mainloop = NULL; -/* When the service interface starts to shutdown, we - should follow it. */ +/* When the service interface starts to shutdown, + we should follow it. */ void service_shutdown (IndicatorService * service, gpointer user_data) { - if (mainloop != NULL) { - g_debug("Service shutdown"); - g_main_loop_quit(mainloop); - } - return; + if (mainloop != NULL) + { + g_debug ("Service shutdown"); + g_main_loop_quit (mainloop); + } } -static gboolean -get_greeter_mode (void) +static inline gboolean +is_greeter_mode (void) { - const gchar *var; - var = g_getenv("INDICATOR_GREETER_MODE"); - return (g_strcmp0(var, "1") == 0); + return !g_strcmp0 (g_getenv ("INDICATOR_GREETER_MODE"), "1"); } /* Main, is well, main. It brings everything up and throws @@ -77,34 +74,29 @@ get_greeter_mode (void) int main (int argc, char ** argv) { - gboolean greeter_mode; - g_type_init(); - /* Setting up i18n and gettext. Apparently, we need - all of these. */ - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); + /* Setting up i18n and gettext. + Apparently we need all of these. */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); - IndicatorService * service = indicator_service_new_version (INDICATOR_SESSION_DBUS_NAME, - INDICATOR_SESSION_DBUS_VERSION); - g_signal_connect (G_OBJECT(service), - INDICATOR_SERVICE_SIGNAL_SHUTDOWN, + IndicatorService * service = indicator_service_new_version (INDICATOR_SESSION_DBUS_NAME, + INDICATOR_SESSION_DBUS_VERSION); + g_signal_connect (G_OBJECT(service), INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), NULL); - session_dbus = session_dbus_new(); - - greeter_mode = get_greeter_mode(); + session_dbus = session_dbus_new(); DbusmenuMenuitem * root_item = dbusmenu_menuitem_new (); - session_menu_mgr_new (root_item, session_dbus, greeter_mode); + session_menu_mgr_new (root_item, session_dbus, is_greeter_mode()); DbusmenuServer* server = dbusmenu_server_new (INDICATOR_SESSION_DBUS_OBJECT); dbusmenu_server_set_root (server, root_item); mainloop = g_main_loop_new(NULL, FALSE); g_main_loop_run(mainloop); - + return 0; } diff --git a/src/settings-helper.c b/src/settings-helper.c deleted file mode 100644 index 0ab188a..0000000 --- a/src/settings-helper.c +++ /dev/null @@ -1,46 +0,0 @@ -/* -A small wrapper utility for connecting to GSettings. - -Copyright 2009 Canonical Ltd. - -Authors: - Christoph Korn - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see . -*/ - -#include - -#include "dbus-shared-names.h" -#include "settings-helper.h" - -static GSettings* settings = NULL; - -static gboolean -build_settings (void) -{ - if (G_UNLIKELY(settings == NULL)) - { - settings = g_settings_new (SESSION_SCHEMA); - } - - return settings != NULL; -} - -gboolean -supress_confirmations (void) -{ - g_return_val_if_fail (build_settings(), FALSE); - - return g_settings_get_boolean (settings, SUPPRESS_KEY) ; -} diff --git a/src/settings-helper.h b/src/settings-helper.h deleted file mode 100644 index 8c4b2e8..0000000 --- a/src/settings-helper.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -A small wrapper utility for connecting to GSettings. - -Copyright 2009 Canonical Ltd. - -Authors: - Christoph Korn - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see . -*/ - - -#ifndef __GCONF_HELPER_H__ -#define __GCONF_HELPER_H__ - -#define SESSION_SCHEMA "com.canonical.indicator.session" -#define SUPPRESS_KEY "suppress-logout-restart-shutdown" -#define LOGOUT_KEY "suppress-logout-menuitem" -#define RESTART_KEY "suppress-restart-menuitem" -#define SHUTDOWN_KEY "suppress-shutdown-menuitem" -#define SHOW_USER_MENU "user-show-menu" - -gboolean supress_confirmations (void); - -#endif /* __GCONF_HELPER__ */ diff --git a/src/shared-names.h b/src/shared-names.h new file mode 100644 index 0000000..dcda182 --- /dev/null +++ b/src/shared-names.h @@ -0,0 +1,57 @@ +/* +A small wrapper utility to load indicators and put them as menu items +into the gnome-panel using it's applet interface. + +Copyright 2009 Canonical Ltd. + +Authors: + Ted Gould + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#ifndef __DBUS_SHARED_NAMES_H__ +#define __DBUS_SHARED_NAMES_H__ + +#define INDICATOR_SESSION_DBUS_NAME "com.canonical.indicator.session" +#define INDICATOR_SESSION_DBUS_OBJECT "/com/canonical/indicator/session/menu" +#define INDICATOR_SESSION_DBUS_VERSION 0 + +#define INDICATOR_SESSION_SERVICE_DBUS_OBJECT "/com/canonical/indicator/session/service" +#define INDICATOR_SESSION_SERVICE_DBUS_IFACE "com.canonical.indicator.session.service" +#define USER_ITEM_TYPE "x-canonical-user-item" +#define USER_ITEM_PROP_NAME "user-item-name" +#define USER_ITEM_PROP_LOGGED_IN "user-item-logged-in" +#define USER_ITEM_PROP_IS_CURRENT_USER "user-item-is-current-user" +#define USER_ITEM_PROP_ICON "user-item-icon-path" +#define USER_ITEM_ICON_DEFAULT "avatar-default" + +#define RESTART_ITEM_TYPE "x-canonical-restart-item" +#define RESTART_ITEM_LABEL "restart-label" +#define RESTART_ITEM_ICON "restart-icon" + +#define ICON_DEFAULT "system-devices-panel" +#define ICON_RESTART "system-devices-panel-alert" +#define GREETER_ICON_DEFAULT "system-shutdown-panel" +#define GREETER_ICON_RESTART "system-shutdown-panel-restart" + +/* the session indicator's settings */ +#define SESSION_SCHEMA "com.canonical.indicator.session" +#define SUPPRESS_KEY "suppress-logout-restart-shutdown" +#define LOGOUT_KEY "suppress-logout-menuitem" +#define RESTART_KEY "suppress-restart-menuitem" +#define SHUTDOWN_KEY "suppress-shutdown-menuitem" +#define SHOW_USER_MENU "user-show-menu" + + +#endif /* __DBUS_SHARED_NAMES_H__ */ diff --git a/src/users-service-dbus.c b/src/users-service-dbus.c index 57cc3a6..8a050fc 100644 --- a/src/users-service-dbus.c +++ b/src/users-service-dbus.c @@ -30,13 +30,13 @@ #include /* getpwuid() */ -#include "dbus-shared-names.h" #include "dbus-accounts.h" #include "dbus-consolekit-manager.h" #include "dbus-consolekit-seat.h" #include "dbus-consolekit-session.h" #include "dbus-display-manager.h" #include "dbus-user.h" +#include "shared-names.h" #include "users-service-dbus.h" #define CK_ADDR "org.freedesktop.ConsoleKit" @@ -326,7 +326,6 @@ create_consolekit_session_proxy (const char * ssid) ssid, NULL, &error); - if (error != NULL) { g_warning ("%s: %s", G_STRLOC, error->message); @@ -644,7 +643,6 @@ update_user_list (UsersServiceDbus *self) GError * error = NULL; char ** object_paths = NULL; UsersServiceDbusPrivate * priv = self->priv; - g_debug ("%s updating the user list", G_STRLOC); accounts_call_list_cached_users_sync (priv->accounts_proxy, &object_paths, @@ -680,7 +678,7 @@ on_user_added (Accounts * o G_GNUC_UNUSED, { /* We see a new user but we might not want to list it -- for example, lightdm shows up when we switch to the greeter. - So instead of adding the user directly here, let's ask + So instead of adding the user directly here, let's ask org.freedesktop.Accounts for a fresh list of users because it filters out special cases. */ update_user_list (service); @@ -790,7 +788,7 @@ get_unix_username_from_ssid (UsersServiceDbus * self, g_warning ("Failed to lookup user id %d: %s", (int)uid, g_strerror(errno)); } else - { + { username = g_strdup (pwent->pw_name); } } @@ -807,7 +805,7 @@ is_guest_username (const char * username) if (!g_strcmp0 (username, "guest")) return TRUE; - if ((strlen(username)==12) && !memcmp(username,"guest-",6)) + if (username && (strlen(username)==12) && !memcmp(username,"guest-",6)) return TRUE; return FALSE; -- cgit v1.2.3