From ae39f7001e5603010afc02de29787ade6d48ef14 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 22 Mar 2013 16:34:34 -0500 Subject: port indicator-session to GMenu/cmake. Code coverage increased from 0% to 95.4%. --- src/backend-dbus/actions.c | 730 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 730 insertions(+) create mode 100644 src/backend-dbus/actions.c (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c new file mode 100644 index 0000000..8994710 --- /dev/null +++ b/src/backend-dbus/actions.c @@ -0,0 +1,730 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * 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 + * 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-end-session-dialog.h" +#include "dbus-upower.h" +#include "dbus-webcredentials.h" +#include "gnome-screen-saver.h" +#include "gnome-session-manager.h" + +#include "actions.h" + +enum +{ + END_SESSION_TYPE_LOGOUT = 0, + END_SESSION_TYPE_SHUTDOWN, + END_SESSION_TYPE_REBOOT +}; + +struct _IndicatorSessionActionsDbusPriv +{ + GCancellable * cancellable; + + GSettings * lockdown_settings; + UPower * upower; + GnomeScreenSaver * screen_saver; + GnomeSessionManager * session_manager; + ConsoleKitManager * ck_manager; + ConsoleKitSeat * ck_seat; + DisplayManagerSeat * dm_seat; + Webcredentials * webcredentials; + EndSessionDialog * end_session_dialog; + + gboolean suspend_allowed; + gboolean hibernate_allowed; + gboolean seat_allows_activation; +}; + +typedef IndicatorSessionActionsDbusPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionActionsDbus, + indicator_session_actions_dbus, + INDICATOR_TYPE_SESSION_ACTIONS) + +/*** +**** +***/ + +static void +log_and_clear_error (GError ** err, const char * loc, const char * func) +{ + if (*err) + { + g_warning ("%s %s: %s", loc, func, (*err)->message); + g_clear_error (err); + } +} + +static void +on_can_activate_sessions (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gboolean can_activate_sessions; + + err = NULL; + can_activate_sessions = FALSE; + console_kit_seat_call_can_activate_sessions_finish (CONSOLE_KIT_SEAT(o), + &can_activate_sessions, + res, + &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + p->seat_allows_activation = can_activate_sessions; + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +set_ck_seat (IndicatorSessionActionsDbus * self, ConsoleKitSeat * seat) +{ + priv_t * p = self->priv; + + g_clear_object (&p->ck_seat); + + if (seat != NULL) + { + p->ck_seat = g_object_ref (seat); + + console_kit_seat_call_can_activate_sessions (seat, + p->cancellable, + on_can_activate_sessions, + self); + } +} + +/*** +**** +***/ + +static void +set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * seat) +{ + priv_t * p = self->priv; + + if (p->dm_seat != NULL) + { + g_signal_handlers_disconnect_by_data (p->dm_seat, self); + g_clear_object (&p->dm_seat); + } + + if (seat != NULL) + { + p->dm_seat = g_object_ref (seat); + /*g_signal_connect (seat, "notify::has-actions-account", G_CALLBACK(on_notify_has_actions_account), self);*/ + } +} + +static void +on_screensaver_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + GnomeScreenSaver * ss; + + err = NULL; + ss = gnome_screen_saver_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->screen_saver = ss; + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_suspend_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gboolean allowed = FALSE; + + err = NULL; + upower_call_suspend_allowed_finish (UPOWER(o), &allowed, res, &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + + if (p->suspend_allowed != allowed) + { + p->suspend_allowed = allowed; + indicator_session_actions_notify_can_suspend (gself); + } + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_hibernate_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gboolean allowed = FALSE; + + err = NULL; + upower_call_hibernate_allowed_finish (UPOWER(o), &allowed, res, &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + + if (p->hibernate_allowed != allowed) + { + p->hibernate_allowed = allowed; + indicator_session_actions_notify_can_hibernate (gself); + } + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_upower_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + UPower * upower; + + err = NULL; + upower = upower_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + + p->upower = upower; + + g_signal_connect_swapped (upower, "notify::can-suspend", + G_CALLBACK(indicator_session_actions_notify_can_suspend), gself); + + g_signal_connect_swapped (upower, "notify::can-hibernate", + G_CALLBACK(indicator_session_actions_notify_can_hibernate), gself); + + upower_call_suspend_allowed (upower, p->cancellable, on_suspend_allowed_ready, gself); + + upower_call_hibernate_allowed (upower, p->cancellable, on_hibernate_allowed_ready, gself); + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_session_manager_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + GnomeSessionManager * sm; + + err = NULL; + sm = gnome_session_manager_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->session_manager = sm; + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_webcredentials_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + Webcredentials * webcredentials; + + err = NULL; + webcredentials = webcredentials_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->webcredentials = webcredentials; + + g_signal_connect_swapped (webcredentials, "notify::error-status", + G_CALLBACK(indicator_session_actions_notify_has_online_account_error), gself); + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_end_session_dialog_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + EndSessionDialog * end_session_dialog; + + err = NULL; + end_session_dialog = end_session_dialog_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->end_session_dialog = end_session_dialog; + + indicator_session_actions_notify_can_prompt (INDICATOR_SESSION_ACTIONS(gself)); + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +/*** +**** Virtual Functions +***/ + +static gboolean +my_can_lock (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return !g_settings_get_boolean (p->lockdown_settings, "disable-lock-screen"); +} + +static gboolean +my_can_logout (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return !g_settings_get_boolean (p->lockdown_settings, "disable-log-out"); +} + +static gboolean +my_can_switch (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p->seat_allows_activation + && !g_settings_get_boolean (p->lockdown_settings, "disable-user-switching"); +} + +static gboolean +my_can_suspend (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p && p->upower && p->suspend_allowed && upower_get_can_suspend (p->upower); +} + +static gboolean +my_can_hibernate (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p && p->upower && p->hibernate_allowed && upower_get_can_hibernate (p->upower); +} + +static gboolean +my_can_prompt (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return (p != NULL) + && (p->end_session_dialog != NULL) + && (g_dbus_proxy_get_name_owner (G_DBUS_PROXY(p->end_session_dialog)) != NULL); +} + +static gboolean +my_has_online_account_error (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p && (p->webcredentials) && (webcredentials_get_error_status (p->webcredentials)); +} + +static void +my_suspend (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->upower != NULL); + + upower_call_suspend (p->upower, p->cancellable, NULL, NULL); +} + +static void +my_hibernate (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->upower != NULL); + + upower_call_hibernate (p->upower, p->cancellable, NULL, NULL); +} + +/*** +**** End Session Dialog +***/ + +static void +logout_now (IndicatorSessionActions * self, gboolean try_to_prompt) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + const int type = try_to_prompt ? 0 : 1; + + g_return_if_fail (p->session_manager != NULL); + + gnome_session_manager_call_logout (p->session_manager, + type, + p->cancellable, + NULL, + NULL); +} + +static void +logout_now_with_prompt (IndicatorSessionActions * self) +{ + logout_now (self, TRUE); +} + +static void +logout_now_quietly (IndicatorSessionActions * self) +{ + logout_now (self, FALSE); +} + +static void +restart_now (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->ck_manager != NULL); + + console_kit_manager_call_restart (p->ck_manager, p->cancellable, NULL, NULL); +} + +static void +shutdown_now (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->ck_manager != NULL); + + console_kit_manager_call_stop (p->ck_manager, p->cancellable, NULL, NULL); +} + +static void +stop_listening_to_dialog (IndicatorSessionActionsDbus * self) +{ + g_signal_handlers_disconnect_by_data (self->priv->end_session_dialog, self); +} +static void +on_end_session_dialog_canceled (IndicatorSessionActionsDbus * self) +{ + stop_listening_to_dialog (self); +} +static void +on_end_session_dialog_closed (IndicatorSessionActionsDbus * self) +{ + stop_listening_to_dialog (self); +} + +static void +on_open_end_session_dialog_ready (GObject * o, + GAsyncResult * res, + gpointer gself G_GNUC_UNUSED) +{ + GError * err = NULL; + end_session_dialog_call_open_finish (END_SESSION_DIALOG(o), res, &err); + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + gpointer o = p->end_session_dialog; + const char * inhibitor_paths[] = { NULL }; + + g_assert (o != NULL); + + g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now_quietly), self); + g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(restart_now), self); + g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(shutdown_now), self); + g_signal_connect_swapped (o, "canceled", G_CALLBACK(on_end_session_dialog_canceled), self); + g_signal_connect_swapped (o, "closed", G_CALLBACK(on_end_session_dialog_closed), self); + + end_session_dialog_call_open (p->end_session_dialog, type, 0, 0, inhibitor_paths, + p->cancellable, + on_open_end_session_dialog_ready, + self); +} + +static void +my_logout (IndicatorSessionActions * self) +{ + if (my_can_prompt (self)) + show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_LOGOUT); + else + logout_now_with_prompt (self); +} + + +static void +my_restart (IndicatorSessionActions * self) +{ + if (my_can_prompt (self)) + show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); + else + restart_now (self); +} + +static void +my_shutdown (IndicatorSessionActions * self) +{ + /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because + the latter adds lock & logout options in Unity... */ + if (my_can_prompt (self)) + show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); + else + shutdown_now (self); +} + +/*** +**** +***/ + +static void +run_outside_app (const char * cmd) +{ + GError * err = NULL; + g_debug ("%s calling \"%s\"", G_STRFUNC, cmd); + g_spawn_command_line_async (cmd, &err); + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +my_help (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("yelp"); +} + +static void +my_settings (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("gnome-control-center"); +} + +static void +my_about (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("gnome-control-center info"); +} + +/*** +**** +***/ + +static void +my_switch_to_screensaver (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->screen_saver != NULL); + + gnome_screen_saver_call_lock (p->screen_saver, p->cancellable, NULL, NULL); +} + +static void +my_switch_to_greeter (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_greeter (p->dm_seat, p->cancellable, + NULL, NULL); +} + +static void +my_switch_to_guest (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_guest (p->dm_seat, "", + p->cancellable, + NULL, NULL); +} + +static void +my_switch_to_username (IndicatorSessionActions * self, const char * username) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_user (p->dm_seat, username, "", + p->cancellable, + NULL, NULL); +} + +static void +my_dispose (GObject * o) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (o); + priv_t * p = self->priv; + + if (p->cancellable != NULL) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + + g_clear_object (&p->lockdown_settings); + g_clear_object (&p->ck_manager); + g_clear_object (&p->upower); + g_clear_object (&p->screen_saver); + g_clear_object (&p->session_manager); + g_clear_object (&p->webcredentials); + g_clear_object (&p->end_session_dialog); + set_dm_seat (self, NULL); + set_ck_seat (self, NULL); + + G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + /*IndicatorSessionActionsDbus * u = INDICATOR_SESSION_ACTIONS_DBUS (o);*/ + + G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->finalize (o); +} + +/*** +**** GObject Boilerplate +***/ + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionActionsClass * actions_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); + actions_class->can_lock = my_can_lock; + actions_class->can_logout = my_can_logout; + actions_class->can_switch = my_can_switch; + actions_class->can_suspend = my_can_suspend; + actions_class->can_hibernate = my_can_hibernate; + actions_class->can_prompt = my_can_prompt; + actions_class->has_online_account_error = my_has_online_account_error; + actions_class->logout = my_logout; + actions_class->suspend = my_suspend; + actions_class->hibernate = my_hibernate; + actions_class->restart = my_restart; + actions_class->shutdown = my_shutdown; + actions_class->settings = my_settings; + actions_class->help = my_help; + actions_class->about = my_about; + actions_class->switch_to_screensaver = my_switch_to_screensaver; + actions_class->switch_to_greeter = my_switch_to_greeter; + actions_class->switch_to_guest = my_switch_to_guest; + actions_class->switch_to_username = my_switch_to_username; + + g_type_class_add_private (klass, sizeof (IndicatorSessionActionsDbusPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) +{ + priv_t * p; + GSettings * s; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_ACTIONS_DBUS, + IndicatorSessionActionsDbusPriv); + p->cancellable = g_cancellable_new (); + p->seat_allows_activation = TRUE; + self->priv = p; + + s = g_settings_new ("org.gnome.desktop.lockdown"); + g_signal_connect_swapped (s, "changed::disable-lock-screen", + G_CALLBACK(indicator_session_actions_notify_can_lock), self); + g_signal_connect_swapped (s, "changed::disable-log-out", + G_CALLBACK(indicator_session_actions_notify_can_logout), self); + g_signal_connect_swapped (s, "changed::disable-user-switching", + G_CALLBACK(indicator_session_actions_notify_can_switch), self); + p->lockdown_settings = s; + + gnome_screen_saver_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.ScreenSaver", + "/org/gnome/ScreenSaver", + p->cancellable, + on_screensaver_proxy_ready, + self); + + upower_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.UPower", + "/org/freedesktop/UPower", + p->cancellable, + on_upower_proxy_ready, + self); + + gnome_session_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + p->cancellable, + on_session_manager_proxy_ready, + self); + + webcredentials_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "com.canonical.indicators.webcredentials", + "/com/canonical/indicators/webcredentials", + p->cancellable, + on_webcredentials_proxy_ready, + self); + + end_session_dialog_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "com.canonical.Unity", + "/org/gnome/SessionManager/EndSessionDialog", + p->cancellable, + on_end_session_dialog_proxy_ready, + self); +} + +/*** +**** Public +***/ + +IndicatorSessionActions * +indicator_session_actions_dbus_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_ACTIONS_DBUS, NULL); + + return INDICATOR_SESSION_ACTIONS (o); +} + +void +indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, + ConsoleKitManager * ck_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * ck_seat) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS_DBUS(self)); + + self->priv->ck_manager = g_object_ref (ck_manager); + + set_dm_seat (self, dm_seat); + + set_ck_seat (self, ck_seat); +} -- cgit v1.2.3 From 093aed6a5e8c35bfe5a3e187fed3e293e2d12183 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Jun 2013 18:16:56 -0500 Subject: in our async callbacks, don't call g_warning() if the task was cancelled by the client --- src/backend-dbus/actions.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 8994710..bc196f2 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -68,7 +68,9 @@ log_and_clear_error (GError ** err, const char * loc, const char * func) { if (*err) { - g_warning ("%s %s: %s", loc, func, (*err)->message); + if (!g_error_matches (*err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", loc, func, (*err)->message); + g_clear_error (err); } } @@ -591,14 +593,6 @@ my_dispose (GObject * o) G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); } -static void -my_finalize (GObject * o) -{ - /*IndicatorSessionActionsDbus * u = INDICATOR_SESSION_ACTIONS_DBUS (o);*/ - - G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->finalize (o); -} - /*** **** GObject Boilerplate ***/ @@ -612,7 +606,6 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; - object_class->finalize = my_finalize; actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); actions_class->can_lock = my_can_lock; -- cgit v1.2.3 From 1b73a52e6a30b9217cdddc7b6f166a421613eaf6 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:07:12 -0500 Subject: migrate from consolekit to login1 --- src/backend-dbus/actions.c | 180 ++++++++++++++++++++++----------------------- 1 file changed, 86 insertions(+), 94 deletions(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index bc196f2..a74a524 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -20,7 +20,7 @@ #include #include "dbus-end-session-dialog.h" -#include "dbus-upower.h" +#include "dbus-login1-manager.h" #include "dbus-webcredentials.h" #include "gnome-screen-saver.h" #include "gnome-session-manager.h" @@ -39,17 +39,16 @@ struct _IndicatorSessionActionsDbusPriv GCancellable * cancellable; GSettings * lockdown_settings; - UPower * upower; GnomeScreenSaver * screen_saver; GnomeSessionManager * session_manager; - ConsoleKitManager * ck_manager; - ConsoleKitSeat * ck_seat; + Login1Manager * login1_manager; + Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; Webcredentials * webcredentials; EndSessionDialog * end_session_dialog; - gboolean suspend_allowed; - gboolean hibernate_allowed; + gboolean can_suspend; + gboolean can_hibernate; gboolean seat_allows_activation; }; @@ -75,42 +74,38 @@ log_and_clear_error (GError ** err, const char * loc, const char * func) } } +/*** +**** +***/ + static void -on_can_activate_sessions (GObject * o, GAsyncResult * res, gpointer gself) +on_seat_notify_multi_session (IndicatorSessionActionsDbus * self) { - GError * err; - gboolean can_activate_sessions; + priv_t * p = self->priv; + gboolean b; - err = NULL; - can_activate_sessions = FALSE; - console_kit_seat_call_can_activate_sessions_finish (CONSOLE_KIT_SEAT(o), - &can_activate_sessions, - res, - &err); - if (err == NULL) + b = login1_seat_get_can_multi_session (p->login1_seat); + + if (p->seat_allows_activation != b) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - p->seat_allows_activation = can_activate_sessions; - } + p->seat_allows_activation = b; - log_and_clear_error (&err, G_STRLOC, G_STRFUNC); + indicator_session_actions_notify_can_switch (INDICATOR_SESSION_ACTIONS(self)); + } } static void -set_ck_seat (IndicatorSessionActionsDbus * self, ConsoleKitSeat * seat) +set_login1_seat (IndicatorSessionActionsDbus * self, Login1Seat * seat) { priv_t * p = self->priv; - g_clear_object (&p->ck_seat); + g_clear_object (&p->login1_seat); if (seat != NULL) { - p->ck_seat = g_object_ref (seat); + p->login1_seat = g_object_ref (seat); - console_kit_seat_call_can_activate_sessions (seat, - p->cancellable, - on_can_activate_sessions, - self); + g_signal_connect_swapped (seat, "notify::can-multi-session", G_CALLBACK(on_seat_notify_multi_session), self); } } @@ -153,75 +148,83 @@ on_screensaver_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpoin } static void -on_suspend_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +on_can_suspend_ready (GObject * o, GAsyncResult * res, gpointer gself) { + char * str; GError * err; - gboolean allowed = FALSE; + str = NULL; err = NULL; - upower_call_suspend_allowed_finish (UPOWER(o), &allowed, res, &err); + login1_manager_call_can_suspend_finish (LOGIN1_MANAGER(o), &str, res, &err); if (err == NULL) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - if (p->suspend_allowed != allowed) + const gboolean b = !g_strcmp0 (str, "yes") || + !g_strcmp0 (str, "challenge"); + + if (p->can_suspend != b) { - p->suspend_allowed = allowed; + p->can_suspend = b; indicator_session_actions_notify_can_suspend (gself); } + + g_free (str); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); } static void -on_hibernate_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +on_can_hibernate_ready (GObject * o, GAsyncResult * res, gpointer gself) { + gchar * str; GError * err; - gboolean allowed = FALSE; + str = NULL; err = NULL; - upower_call_hibernate_allowed_finish (UPOWER(o), &allowed, res, &err); + login1_manager_call_can_hibernate_finish (LOGIN1_MANAGER(o), &str, res, &err); if (err == NULL) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - if (p->hibernate_allowed != allowed) + const gboolean b = !g_strcmp0 (str, "yes") || + !g_strcmp0 (str, "challenge"); + + if (p->can_hibernate != b) { - p->hibernate_allowed = allowed; + p->can_hibernate = b; indicator_session_actions_notify_can_hibernate (gself); } + + g_free (str); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); } static void -on_upower_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +set_login1_manager (IndicatorSessionActionsDbus * self, + Login1Manager * login1_manager) { - GError * err; - UPower * upower; - - err = NULL; - upower = upower_proxy_new_for_bus_finish (res, &err); - if (err == NULL) - { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - - p->upower = upower; + priv_t * p = self->priv; - g_signal_connect_swapped (upower, "notify::can-suspend", - G_CALLBACK(indicator_session_actions_notify_can_suspend), gself); + g_clear_object (&p->login1_manager); - g_signal_connect_swapped (upower, "notify::can-hibernate", - G_CALLBACK(indicator_session_actions_notify_can_hibernate), gself); + if (login1_manager != NULL) + { + p->login1_manager = g_object_ref (login1_manager); - upower_call_suspend_allowed (upower, p->cancellable, on_suspend_allowed_ready, gself); + login1_manager_call_can_suspend (p->login1_manager, + p->cancellable, + on_can_suspend_ready, + self); - upower_call_hibernate_allowed (upower, p->cancellable, on_hibernate_allowed_ready, gself); + login1_manager_call_can_hibernate (p->login1_manager, + p->cancellable, + on_can_hibernate_ready, + self); } - - log_and_clear_error (&err, G_STRLOC, G_STRFUNC); } static void @@ -311,7 +314,7 @@ my_can_suspend (IndicatorSessionActions * self) { const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return p && p->upower && p->suspend_allowed && upower_get_can_suspend (p->upower); + return p && p->can_suspend; } static gboolean @@ -319,7 +322,7 @@ my_can_hibernate (IndicatorSessionActions * self) { const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return p && p->upower && p->hibernate_allowed && upower_get_can_hibernate (p->upower); + return p && p->can_hibernate; } static gboolean @@ -345,9 +348,9 @@ my_suspend (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->upower != NULL); + g_return_if_fail (p->login1_manager != NULL); - upower_call_suspend (p->upower, p->cancellable, NULL, NULL); + login1_manager_call_suspend (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } static void @@ -355,9 +358,9 @@ my_hibernate (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->upower != NULL); + g_return_if_fail (p->login1_manager != NULL); - upower_call_hibernate (p->upower, p->cancellable, NULL, NULL); + login1_manager_call_hibernate (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } /*** @@ -392,23 +395,23 @@ logout_now_quietly (IndicatorSessionActions * self) } static void -restart_now (IndicatorSessionActions * self) +reboot_now (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->ck_manager != NULL); + g_return_if_fail (p->login1_manager != NULL); - console_kit_manager_call_restart (p->ck_manager, p->cancellable, NULL, NULL); + login1_manager_call_reboot (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } static void -shutdown_now (IndicatorSessionActions * self) +power_off_now (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->ck_manager != NULL); + g_return_if_fail (p->login1_manager != NULL); - console_kit_manager_call_stop (p->ck_manager, p->cancellable, NULL, NULL); + login1_manager_call_power_off (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } static void @@ -447,8 +450,8 @@ show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) g_assert (o != NULL); g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now_quietly), self); - g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(restart_now), self); - g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(shutdown_now), self); + g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(reboot_now), self); + g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(power_off_now), self); g_signal_connect_swapped (o, "canceled", G_CALLBACK(on_end_session_dialog_canceled), self); g_signal_connect_swapped (o, "closed", G_CALLBACK(on_end_session_dialog_closed), self); @@ -469,23 +472,23 @@ my_logout (IndicatorSessionActions * self) static void -my_restart (IndicatorSessionActions * self) +my_reboot (IndicatorSessionActions * self) { if (my_can_prompt (self)) show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); else - restart_now (self); + reboot_now (self); } static void -my_shutdown (IndicatorSessionActions * self) +my_power_off (IndicatorSessionActions * self) { /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because the latter adds lock & logout options in Unity... */ if (my_can_prompt (self)) show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); else - shutdown_now (self); + power_off_now (self); } /*** @@ -581,14 +584,13 @@ my_dispose (GObject * o) } g_clear_object (&p->lockdown_settings); - g_clear_object (&p->ck_manager); - g_clear_object (&p->upower); g_clear_object (&p->screen_saver); g_clear_object (&p->session_manager); g_clear_object (&p->webcredentials); g_clear_object (&p->end_session_dialog); set_dm_seat (self, NULL); - set_ck_seat (self, NULL); + set_login1_manager (self, NULL); + set_login1_seat (self, NULL); G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); } @@ -618,8 +620,8 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl actions_class->logout = my_logout; actions_class->suspend = my_suspend; actions_class->hibernate = my_hibernate; - actions_class->restart = my_restart; - actions_class->shutdown = my_shutdown; + actions_class->reboot = my_reboot; + actions_class->power_off = my_power_off; actions_class->settings = my_settings; actions_class->help = my_help; actions_class->about = my_about; @@ -662,14 +664,6 @@ indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) on_screensaver_proxy_ready, self); - upower_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.UPower", - "/org/freedesktop/UPower", - p->cancellable, - on_upower_proxy_ready, - self); - gnome_session_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, "org.gnome.SessionManager", @@ -709,15 +703,13 @@ indicator_session_actions_dbus_new (void) void indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, - ConsoleKitManager * ck_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * ck_seat) + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * dm_seat) { g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS_DBUS(self)); - self->priv->ck_manager = g_object_ref (ck_manager); - + set_login1_manager (self, login1_manager); + set_login1_seat (self, login1_seat); set_dm_seat (self, dm_seat); - - set_ck_seat (self, ck_seat); } -- cgit v1.2.3 From e986476c83c3e647dab067087865f895cd32a899 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 13:07:52 -0500 Subject: only show the restart or hibernate menuitems if login1 says these features are available --- src/backend-dbus/actions.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index a74a524..3f0e6ec 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -160,8 +160,7 @@ on_can_suspend_ready (GObject * o, GAsyncResult * res, gpointer gself) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - const gboolean b = !g_strcmp0 (str, "yes") || - !g_strcmp0 (str, "challenge"); + const gboolean b = !g_strcmp0 (str, "yes"); if (p->can_suspend != b) { @@ -188,8 +187,7 @@ on_can_hibernate_ready (GObject * o, GAsyncResult * res, gpointer gself) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - const gboolean b = !g_strcmp0 (str, "yes") || - !g_strcmp0 (str, "challenge"); + const gboolean b = !g_strcmp0 (str, "yes"); if (p->can_hibernate != b) { -- cgit v1.2.3 From cc57405ebf537239ab2953b41b27908b6dadfbeb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 21:43:13 -0500 Subject: in actions.c's my_can_prompt(), don't leak the string returned by g_dbus_proxy_get_name_owner --- src/backend-dbus/actions.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 3f0e6ec..67fe9f1 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -326,11 +326,18 @@ my_can_hibernate (IndicatorSessionActions * self) static gboolean my_can_prompt (IndicatorSessionActions * self) { + gboolean can_prompt = FALSE; const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return (p != NULL) - && (p->end_session_dialog != NULL) - && (g_dbus_proxy_get_name_owner (G_DBUS_PROXY(p->end_session_dialog)) != NULL); + if (p && p->end_session_dialog) + { + GDBusProxy * proxy = G_DBUS_PROXY (p->end_session_dialog); + char * name = g_dbus_proxy_get_name_owner (proxy); + can_prompt = name != NULL; + g_free (name); + } + + return can_prompt; } static gboolean -- cgit v1.2.3 From b252745c8111c9be1d7e95a88daab1e2568b1afc Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:33:08 -0500 Subject: in backend-dbus/actions.c's set_login1_seat(), disconnect from the previous seat's signals before unreff'ing it --- src/backend-dbus/actions.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 67fe9f1..8c1b70b 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -99,13 +99,18 @@ set_login1_seat (IndicatorSessionActionsDbus * self, Login1Seat * seat) { priv_t * p = self->priv; - g_clear_object (&p->login1_seat); + if (p->login1_seat != NULL) + { + g_signal_handlers_disconnect_by_data (p->login1_seat, self); + g_clear_object (&p->login1_seat); + } if (seat != NULL) { p->login1_seat = g_object_ref (seat); - g_signal_connect_swapped (seat, "notify::can-multi-session", G_CALLBACK(on_seat_notify_multi_session), self); + g_signal_connect_swapped (seat, "notify::can-multi-session", + G_CALLBACK(on_seat_notify_multi_session), self); } } -- cgit v1.2.3 From 37694a94d8c188b909740f2eed7a984273dc2320 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:35:17 -0500 Subject: in backend-dbus/actions.c's set_dm_seat(), since we don't listen to displaymanager's signals anymore, remove unnecessary g_signal_handlers_disconnect() call. --- src/backend-dbus/actions.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 8c1b70b..1756a0f 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -123,17 +123,10 @@ set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * seat) { priv_t * p = self->priv; - if (p->dm_seat != NULL) - { - g_signal_handlers_disconnect_by_data (p->dm_seat, self); - g_clear_object (&p->dm_seat); - } + g_clear_object (&p->dm_seat); if (seat != NULL) - { - p->dm_seat = g_object_ref (seat); - /*g_signal_connect (seat, "notify::has-actions-account", G_CALLBACK(on_notify_has_actions_account), self);*/ - } + p->dm_seat = g_object_ref (seat); } static void -- cgit v1.2.3 From 90c7f19eeaf0c89e40ddd59f00edbb0d7b1c0789 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:41:41 -0500 Subject: in backend-dbus/actions.c, create a separate cancellable for login1_manager s.t. new calls to set_login1_manager() will cancel any previous async calls pending on the old login1 manager object. --- src/backend-dbus/actions.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 1756a0f..c40d0c6 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -37,6 +37,7 @@ enum struct _IndicatorSessionActionsDbusPriv { GCancellable * cancellable; + GCancellable * login1_manager_cancellable; GSettings * lockdown_settings; GnomeScreenSaver * screen_saver; @@ -205,19 +206,26 @@ set_login1_manager (IndicatorSessionActionsDbus * self, { priv_t * p = self->priv; - g_clear_object (&p->login1_manager); + if (p->login1_manager != NULL) + { + g_cancellable_cancel (p->login1_manager_cancellable); + g_clear_object (&p->login1_manager_cancellable); + g_clear_object (&p->login1_manager); + } if (login1_manager != NULL) { + p->login1_manager_cancellable = g_cancellable_new (); + p->login1_manager = g_object_ref (login1_manager); login1_manager_call_can_suspend (p->login1_manager, - p->cancellable, + p->login1_manager_cancellable, on_can_suspend_ready, self); login1_manager_call_can_hibernate (p->login1_manager, - p->cancellable, + p->login1_manager_cancellable, on_can_hibernate_ready, self); } @@ -353,7 +361,11 @@ my_suspend (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_suspend (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_suspend (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } static void @@ -363,7 +375,11 @@ my_hibernate (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_hibernate (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_hibernate (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } /*** @@ -404,7 +420,11 @@ reboot_now (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_reboot (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_reboot (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } static void @@ -414,7 +434,11 @@ power_off_now (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_power_off (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_power_off (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } static void -- cgit v1.2.3 From 0b5f283691222c23599ab460bb5dad7a78378aa8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:46:00 -0500 Subject: in backend-dbus/actions.c, create a separate cancellable for dm_seat s.t. new calls to set_dm_seat() will cancel any previous async calls pending on the old DisplayManager seat object. --- src/backend-dbus/actions.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index c40d0c6..c095896 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -37,14 +37,15 @@ enum struct _IndicatorSessionActionsDbusPriv { GCancellable * cancellable; - GCancellable * login1_manager_cancellable; GSettings * lockdown_settings; GnomeScreenSaver * screen_saver; GnomeSessionManager * session_manager; Login1Manager * login1_manager; + GCancellable * login1_manager_cancellable; Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; + GCancellable * dm_seat_cancellable; Webcredentials * webcredentials; EndSessionDialog * end_session_dialog; @@ -124,10 +125,18 @@ set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * seat) { priv_t * p = self->priv; - g_clear_object (&p->dm_seat); + if (p->dm_seat != NULL) + { + g_cancellable_cancel (p->dm_seat_cancellable); + g_clear_object (&p->dm_seat); + g_clear_object (&p->dm_seat); + } if (seat != NULL) - p->dm_seat = g_object_ref (seat); + { + p->dm_seat = g_object_ref (seat); + p->dm_seat_cancellable = g_cancellable_new (); + } } static void @@ -570,7 +579,8 @@ my_switch_to_greeter (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); - display_manager_seat_call_switch_to_greeter (p->dm_seat, p->cancellable, + display_manager_seat_call_switch_to_greeter (p->dm_seat, + p->dm_seat_cancellable, NULL, NULL); } @@ -582,7 +592,7 @@ my_switch_to_guest (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); display_manager_seat_call_switch_to_guest (p->dm_seat, "", - p->cancellable, + p->dm_seat_cancellable, NULL, NULL); } @@ -594,7 +604,7 @@ my_switch_to_username (IndicatorSessionActions * self, const char * username) g_return_if_fail (p->dm_seat != NULL); display_manager_seat_call_switch_to_user (p->dm_seat, username, "", - p->cancellable, + p->dm_seat_cancellable, NULL, NULL); } -- cgit v1.2.3 From c9352cd0a8363e4508d19e66ccf373b2abb2b7d3 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 12 Jul 2013 02:05:35 -0500 Subject: If the Unity dialogs aren't available (such as in the greeter) but zenity is, use it to for confirmation dialogs: - add the implementation in actions.c - add actions.c to the i18n files list - sync the unit tests - suggest zenity in debian/control --- src/backend-dbus/actions.c | 314 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 261 insertions(+), 53 deletions(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index c095896..ed1e708 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -18,6 +18,7 @@ */ #include +#include #include "dbus-end-session-dialog.h" #include "dbus-login1-manager.h" @@ -39,6 +40,7 @@ struct _IndicatorSessionActionsDbusPriv GCancellable * cancellable; GSettings * lockdown_settings; + GSettings * indicator_settings; GnomeScreenSaver * screen_saver; GnomeSessionManager * session_manager; Login1Manager * login1_manager; @@ -48,6 +50,7 @@ struct _IndicatorSessionActionsDbusPriv GCancellable * dm_seat_cancellable; Webcredentials * webcredentials; EndSessionDialog * end_session_dialog; + char * zenity; gboolean can_suspend; gboolean can_hibernate; @@ -80,6 +83,44 @@ log_and_clear_error (GError ** err, const char * loc, const char * func) **** ***/ +typedef enum +{ + PROMPT_NONE, + PROMPT_WITH_ZENITY, + PROMPT_WITH_UNITY +} +prompt_status_t; + +static prompt_status_t +get_prompt_status (IndicatorSessionActionsDbus * self) +{ + prompt_status_t prompt = PROMPT_NONE; + const priv_t * p = self->priv; + + if (!g_settings_get_boolean (p->indicator_settings, "suppress-logout-restart-shutdown")) + { + /* can we use the Unity prompt? */ + if ((prompt == PROMPT_NONE) && p && p->end_session_dialog) + { + GDBusProxy * proxy = G_DBUS_PROXY (p->end_session_dialog); + char * name = g_dbus_proxy_get_name_owner (proxy); + if (name != NULL) + prompt = PROMPT_WITH_UNITY; + g_free (name); + } + + /* can we use zenity? */ + if ((prompt == PROMPT_NONE) && p && p->zenity) + prompt = PROMPT_WITH_ZENITY; + } + + return prompt; +} + +/*** +**** +***/ + static void on_seat_notify_multi_session (IndicatorSessionActionsDbus * self) { @@ -288,6 +329,7 @@ on_end_session_dialog_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->end_session_dialog = end_session_dialog; indicator_session_actions_notify_can_prompt (INDICATOR_SESSION_ACTIONS(gself)); + indicator_session_actions_notify_can_reboot (INDICATOR_SESSION_ACTIONS(gself)); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); @@ -310,7 +352,31 @@ my_can_logout (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return !g_settings_get_boolean (p->lockdown_settings, "disable-log-out"); + if (g_settings_get_boolean (p->indicator_settings, "suppress-logout-menuitem")) + return FALSE; + + if (g_settings_get_boolean (p->lockdown_settings, "disable-log-out")) + return FALSE; + + return TRUE; +} + +static gboolean +my_can_reboot (IndicatorSessionActions * actions) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS(actions); + priv_t * p = self->priv; + + if (g_settings_get_boolean (p->indicator_settings, "suppress-restart-menuitem")) + return FALSE; + + /* Shutdown and Restart are the same dialog prompt in Unity, + so disable the redundant 'Restart' menuitem in that mode */ + if (!g_settings_get_boolean (p->indicator_settings, "suppress-shutdown-menuitem")) + if (get_prompt_status(self) == PROMPT_WITH_UNITY) + return FALSE; + + return TRUE; } static gboolean @@ -341,18 +407,7 @@ my_can_hibernate (IndicatorSessionActions * self) static gboolean my_can_prompt (IndicatorSessionActions * self) { - gboolean can_prompt = FALSE; - const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - - if (p && p->end_session_dialog) - { - GDBusProxy * proxy = G_DBUS_PROXY (p->end_session_dialog); - char * name = g_dbus_proxy_get_name_owner (proxy); - can_prompt = name != NULL; - g_free (name); - } - - return can_prompt; + return get_prompt_status(INDICATOR_SESSION_ACTIONS_DBUS(self)) != PROMPT_NONE; } static gboolean @@ -396,50 +451,51 @@ my_hibernate (IndicatorSessionActions * self) ***/ static void -logout_now (IndicatorSessionActions * self, gboolean try_to_prompt) +logout_now (IndicatorSessionActionsDbus * self) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - const int type = try_to_prompt ? 0 : 1; + priv_t * p = self->priv; g_return_if_fail (p->session_manager != NULL); gnome_session_manager_call_logout (p->session_manager, - type, + 1, /* don't prompt */ p->cancellable, NULL, NULL); } static void -logout_now_with_prompt (IndicatorSessionActions * self) +on_reboot_response (GObject * o, + GAsyncResult * res, + gpointer unused G_GNUC_UNUSED) { - logout_now (self, TRUE); -} - -static void -logout_now_quietly (IndicatorSessionActions * self) -{ - logout_now (self, FALSE); + GError * err = NULL; + login1_manager_call_reboot_finish (LOGIN1_MANAGER(o), res, &err); + if (err != NULL) + { + g_warning ("Unable to reboot: %s", err->message); + g_error_free (err); + } } static void -reboot_now (IndicatorSessionActions * self) +reboot_now (IndicatorSessionActionsDbus * self) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + priv_t * p = self->priv; g_return_if_fail (p->login1_manager != NULL); login1_manager_call_reboot (p->login1_manager, FALSE, p->login1_manager_cancellable, - NULL, + on_reboot_response, NULL); } static void -power_off_now (IndicatorSessionActions * self) +power_off_now (IndicatorSessionActionsDbus * self) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + priv_t * p = self->priv; g_return_if_fail (p->login1_manager != NULL); @@ -477,7 +533,7 @@ on_open_end_session_dialog_ready (GObject * o, } static void -show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) +show_unity_end_session_dialog (IndicatorSessionActionsDbus * self, int type) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; gpointer o = p->end_session_dialog; @@ -485,7 +541,7 @@ show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) g_assert (o != NULL); - g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now_quietly), self); + g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now), self); g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(reboot_now), self); g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(power_off_now), self); g_signal_connect_swapped (o, "canceled", G_CALLBACK(on_end_session_dialog_canceled), self); @@ -497,34 +553,140 @@ show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) self); } -static void -my_logout (IndicatorSessionActions * self) -{ - if (my_can_prompt (self)) - show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_LOGOUT); +static gboolean +zenity_question (IndicatorSessionActionsDbus * self, + const char * icon_name, + const char * title, + const char * text, + const char * ok_label, + const char * cancel_label) +{ + char * command_line; + int exit_status; + gboolean confirmed; + + command_line = g_strdup_printf ("%s" + " --question" + " --icon-name=\"%s\"" + " --title=\"%s\"" + " --text=\"%s\"" + " --ok-label=\"%s\"" + " --cancel-label=\"%s\"" + " --no-wrap", + self->priv->zenity, + icon_name, + title, + text, + ok_label, + cancel_label); + + exit_status = -1; + if (!g_spawn_command_line_sync (command_line, NULL, NULL, &exit_status, NULL)) + { + /* Treat failure-to-prompt as user confirmation. + Otherwise how will the user ever log out? */ + confirmed = TRUE; + } else - logout_now_with_prompt (self); + { + confirmed = exit_status == 0; + } + + g_free (command_line); + return confirmed; } +static void +my_logout (IndicatorSessionActions * actions) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + switch (get_prompt_status (self)) + { + case PROMPT_WITH_UNITY: + show_unity_end_session_dialog (self, END_SESSION_TYPE_LOGOUT); + break; + + case PROMPT_NONE: + logout_now (self); + break; + + case PROMPT_WITH_ZENITY: + { + const char * primary = _("Are you sure you want to close all programs and log out?"); + const char * secondary = _("Some software updates won't be applied until the computer next restarts."); + char * text = g_strdup_printf ("%s\n \n%s", primary, secondary); + + gboolean confirmed = zenity_question (self, + "system-log-out", + _("Log Out"), + text, + _("Log Out"), + _("Cancel")); + + g_free (text); + + if (confirmed) + logout_now (self); + break; + } + } +} static void -my_reboot (IndicatorSessionActions * self) +my_reboot (IndicatorSessionActions * actions) { - if (my_can_prompt (self)) - show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); - else - reboot_now (self); + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + switch (get_prompt_status (self)) + { + case PROMPT_WITH_UNITY: + show_unity_end_session_dialog (self, END_SESSION_TYPE_REBOOT); + break; + + case PROMPT_NONE: + reboot_now (self); + break; + + case PROMPT_WITH_ZENITY: + if (zenity_question (self, + "system-restart", + _("Restart"), + _("Are you sure you want to close all programs and restart the computer?"), + _("Restart"), + _("Cancel"))) + reboot_now (self); + break; + } } static void -my_power_off (IndicatorSessionActions * self) +my_power_off (IndicatorSessionActions * actions) { - /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because - the latter adds lock & logout options in Unity... */ - if (my_can_prompt (self)) - show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); - else - power_off_now (self); + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + switch (get_prompt_status (self)) + { + case PROMPT_WITH_UNITY: + /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because + the latter adds lock & logout options in Unity... */ + show_unity_end_session_dialog (self, END_SESSION_TYPE_REBOOT); + break; + + case PROMPT_WITH_ZENITY: + if (zenity_question (self, + "system-shutdown", + _("Shut Down"), + _("Are you sure you want to close all programs and shut down the computer?"), + _("Shut Down"), + _("Cancel"))) + power_off_now (self); + break; + + case PROMPT_NONE: + power_off_now (self); + break; + } } /*** @@ -620,11 +782,32 @@ my_dispose (GObject * o) g_clear_object (&p->cancellable); } - g_clear_object (&p->lockdown_settings); + if (p->indicator_settings != NULL) + { + g_signal_handlers_disconnect_by_data (p->indicator_settings, self); + g_clear_object (&p->indicator_settings); + } + + if (p->lockdown_settings != NULL) + { + g_signal_handlers_disconnect_by_data (p->lockdown_settings, self); + g_clear_object (&p->lockdown_settings); + } + + if (p->webcredentials != NULL) + { + g_signal_handlers_disconnect_by_data (p->webcredentials, self); + g_clear_object (&p->webcredentials); + } + + if (p->end_session_dialog != NULL) + { + stop_listening_to_dialog (self); + g_clear_object (&p->end_session_dialog); + } + g_clear_object (&p->screen_saver); g_clear_object (&p->session_manager); - g_clear_object (&p->webcredentials); - g_clear_object (&p->end_session_dialog); set_dm_seat (self, NULL); set_login1_manager (self, NULL); set_login1_seat (self, NULL); @@ -632,6 +815,16 @@ my_dispose (GObject * o) G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); } +static void +my_finalize (GObject * o) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (o); + priv_t * p = self->priv; + + g_free (p->zenity); +} + + /*** **** GObject Boilerplate ***/ @@ -645,10 +838,12 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; + object_class->finalize = my_finalize; actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); actions_class->can_lock = my_can_lock; actions_class->can_logout = my_can_logout; + actions_class->can_reboot = my_can_reboot; actions_class->can_switch = my_can_switch; actions_class->can_suspend = my_can_suspend; actions_class->can_hibernate = my_can_hibernate; @@ -684,6 +879,8 @@ indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) p->seat_allows_activation = TRUE; self->priv = p; + p->zenity = g_find_program_in_path ("zenity"); + s = g_settings_new ("org.gnome.desktop.lockdown"); g_signal_connect_swapped (s, "changed::disable-lock-screen", G_CALLBACK(indicator_session_actions_notify_can_lock), self); @@ -693,6 +890,17 @@ indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) G_CALLBACK(indicator_session_actions_notify_can_switch), self); p->lockdown_settings = s; + s = g_settings_new ("com.canonical.indicator.session"); + g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(indicator_session_actions_notify_can_prompt), self); + g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(indicator_session_actions_notify_can_reboot), self); + g_signal_connect_swapped (s, "changed::suppress-restart-menuitem", + G_CALLBACK(indicator_session_actions_notify_can_reboot), self); + g_signal_connect_swapped (s, "changed::suppress-shutdown-menuitem", + G_CALLBACK(indicator_session_actions_notify_can_reboot), self); + p->indicator_settings = s; + gnome_screen_saver_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, "org.gnome.ScreenSaver", -- cgit v1.2.3 From a19955f3f81b1a5eb8fc928bc5dcf8a24bb6833f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 12 Jul 2013 07:42:07 -0500 Subject: add the online-accounts action and unit tests for it --- src/backend-dbus/actions.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index ed1e708..9030ca7 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -311,6 +311,9 @@ on_webcredentials_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gp g_signal_connect_swapped (webcredentials, "notify::error-status", G_CALLBACK(indicator_session_actions_notify_has_online_account_error), gself); + + if (webcredentials_get_error_status (webcredentials)) + indicator_session_actions_notify_has_online_account_error (gself); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); @@ -714,6 +717,12 @@ my_settings (IndicatorSessionActions * self G_GNUC_UNUSED) run_outside_app ("gnome-control-center"); } +static void +my_online_accounts (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("gnome-control-center credentials"); +} + static void my_about (IndicatorSessionActions * self G_GNUC_UNUSED) { @@ -855,6 +864,7 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl actions_class->reboot = my_reboot; actions_class->power_off = my_power_off; actions_class->settings = my_settings; + actions_class->online_accounts = my_online_accounts; actions_class->help = my_help; actions_class->about = my_about; actions_class->switch_to_screensaver = my_switch_to_screensaver; -- cgit v1.2.3 From 4759a380da77dd1f8746f298a5ae051319a70ddd Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 20 Aug 2013 08:42:24 -0500 Subject: when switching to the guest session, explicitly lock the current users's session --- src/backend-dbus/actions.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 9030ca7..17547f0 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -734,7 +734,7 @@ my_about (IndicatorSessionActions * self G_GNUC_UNUSED) ***/ static void -my_switch_to_screensaver (IndicatorSessionActions * self) +lock_current_session (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; @@ -743,6 +743,12 @@ my_switch_to_screensaver (IndicatorSessionActions * self) gnome_screen_saver_call_lock (p->screen_saver, p->cancellable, NULL, NULL); } +static void +my_switch_to_screensaver (IndicatorSessionActions * self) +{ + lock_current_session (self); +} + static void my_switch_to_greeter (IndicatorSessionActions * self) { @@ -750,6 +756,7 @@ my_switch_to_greeter (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); + /* show the greeter */ display_manager_seat_call_switch_to_greeter (p->dm_seat, p->dm_seat_cancellable, NULL, NULL); @@ -762,6 +769,8 @@ my_switch_to_guest (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); + lock_current_session (self); + display_manager_seat_call_switch_to_guest (p->dm_seat, "", p->dm_seat_cancellable, NULL, NULL); -- cgit v1.2.3 From e48d65866fa228929ddc545eac456635bf763501 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 20 Aug 2013 08:43:47 -0500 Subject: fix minor GCancellable memory leak noticed while fixing 1205273 --- src/backend-dbus/actions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 17547f0..2550fdb 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -169,7 +169,7 @@ set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * seat) if (p->dm_seat != NULL) { g_cancellable_cancel (p->dm_seat_cancellable); - g_clear_object (&p->dm_seat); + g_clear_object (&p->dm_seat_cancellable); g_clear_object (&p->dm_seat); } -- cgit v1.2.3 From 14964539aec0c91e39e3abdb70c08ad8d65824bb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 20 Aug 2013 08:52:54 -0500 Subject: copyediting: remove unnecessary comment that snuck into r406 --- src/backend-dbus/actions.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/backend-dbus/actions.c') diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 2550fdb..fcf850d 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -756,7 +756,6 @@ my_switch_to_greeter (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); - /* show the greeter */ display_manager_seat_call_switch_to_greeter (p->dm_seat, p->dm_seat_cancellable, NULL, NULL); -- cgit v1.2.3