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/CMakeLists.txt | 19 + src/Makefile.am | 207 ---- src/actions.c | 383 ++++++ src/actions.h | 129 ++ src/backend-dbus/CMakeLists.txt | 86 ++ src/backend-dbus/actions.c | 730 ++++++++++++ src/backend-dbus/actions.h | 73 ++ src/backend-dbus/backend-dbus.c | 117 ++ src/backend-dbus/backend-dbus.h | 38 + .../com.canonical.indicators.webcredentials.xml | 82 ++ src/backend-dbus/display-manager.xml | 30 + src/backend-dbus/guest.c | 570 +++++++++ src/backend-dbus/guest.h | 72 ++ src/backend-dbus/org.freedesktop.Accounts.User.xml | 744 ++++++++++++ src/backend-dbus/org.freedesktop.Accounts.xml | 194 ++++ .../org.freedesktop.ConsoleKit.Manager.xml | 353 ++++++ .../org.freedesktop.ConsoleKit.Seat.xml | 164 +++ .../org.freedesktop.ConsoleKit.Session.xml | 435 +++++++ src/backend-dbus/org.gnome.ScreenSaver.xml | 16 + .../org.gnome.SessionManager.EndSessionDialog.xml | 53 + src/backend-dbus/org.gnome.SessionManager.xml | 451 +++++++ src/backend-dbus/session-dbus.xml | 20 + src/backend-dbus/upower.xml | 309 +++++ src/backend-dbus/users.c | 810 +++++++++++++ src/backend-dbus/users.h | 71 ++ src/backend-dbus/utils.c | 399 +++++++ src/backend-dbus/utils.h | 53 + src/backend.h | 47 + src/dialog.c | 248 ---- src/dialog.h | 64 - src/display-manager.xml | 30 - src/gtk-logout-helper.c | 266 ----- src/guest.c | 190 +++ src/guest.h | 82 ++ src/indicator-session.c | 495 -------- src/main.c | 87 ++ src/online-accounts-mgr.c | 166 --- src/online-accounts-mgr.h | 50 - src/org.freedesktop.Accounts.User.xml | 744 ------------ src/org.freedesktop.Accounts.xml | 194 ---- src/org.freedesktop.ConsoleKit.Manager.xml | 353 ------ src/org.freedesktop.ConsoleKit.Seat.xml | 164 --- src/org.freedesktop.ConsoleKit.Session.xml | 435 ------- src/service.c | 1192 +++++++++++++++++++ src/service.h | 64 + src/session-dbus.c | 282 ----- src/session-dbus.h | 56 - src/session-dbus.xml | 20 - src/session-menu-mgr.c | 1226 -------------------- src/session-menu-mgr.h | 55 - src/session-service.c | 96 -- src/shared-names.h | 52 - src/upower.xml | 309 ----- src/user-widget.c | 292 ----- src/user-widget.h | 55 - src/users-service-dbus.c | 1044 ----------------- src/users-service-dbus.h | 97 -- src/users.c | 198 ++++ src/users.h | 146 +++ 59 files changed, 8407 insertions(+), 7000 deletions(-) create mode 100644 src/CMakeLists.txt delete mode 100644 src/Makefile.am create mode 100644 src/actions.c create mode 100644 src/actions.h create mode 100644 src/backend-dbus/CMakeLists.txt create mode 100644 src/backend-dbus/actions.c create mode 100644 src/backend-dbus/actions.h create mode 100644 src/backend-dbus/backend-dbus.c create mode 100644 src/backend-dbus/backend-dbus.h create mode 100644 src/backend-dbus/com.canonical.indicators.webcredentials.xml create mode 100644 src/backend-dbus/display-manager.xml create mode 100644 src/backend-dbus/guest.c create mode 100644 src/backend-dbus/guest.h create mode 100644 src/backend-dbus/org.freedesktop.Accounts.User.xml create mode 100644 src/backend-dbus/org.freedesktop.Accounts.xml create mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml create mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml create mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml create mode 100644 src/backend-dbus/org.gnome.ScreenSaver.xml create mode 100644 src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml create mode 100644 src/backend-dbus/org.gnome.SessionManager.xml create mode 100644 src/backend-dbus/session-dbus.xml create mode 100644 src/backend-dbus/upower.xml create mode 100644 src/backend-dbus/users.c create mode 100644 src/backend-dbus/users.h create mode 100644 src/backend-dbus/utils.c create mode 100644 src/backend-dbus/utils.h create mode 100644 src/backend.h delete mode 100644 src/dialog.c delete mode 100644 src/dialog.h delete mode 100644 src/display-manager.xml delete mode 100644 src/gtk-logout-helper.c create mode 100644 src/guest.c create mode 100644 src/guest.h delete mode 100644 src/indicator-session.c create mode 100644 src/main.c delete mode 100644 src/online-accounts-mgr.c delete mode 100644 src/online-accounts-mgr.h delete mode 100644 src/org.freedesktop.Accounts.User.xml delete mode 100644 src/org.freedesktop.Accounts.xml delete mode 100644 src/org.freedesktop.ConsoleKit.Manager.xml delete mode 100644 src/org.freedesktop.ConsoleKit.Seat.xml delete mode 100644 src/org.freedesktop.ConsoleKit.Session.xml create mode 100644 src/service.c create mode 100644 src/service.h delete mode 100644 src/session-dbus.c delete mode 100644 src/session-dbus.h delete mode 100644 src/session-dbus.xml delete mode 100644 src/session-menu-mgr.c delete mode 100644 src/session-menu-mgr.h delete mode 100644 src/session-service.c delete mode 100644 src/shared-names.h delete mode 100644 src/upower.xml delete mode 100644 src/user-widget.c delete mode 100644 src/user-widget.h delete mode 100644 src/users-service-dbus.c delete mode 100644 src/users-service-dbus.h create mode 100644 src/users.c create mode 100644 src/users.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..efa704c --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,19 @@ +add_subdirectory (backend-dbus) + +add_library (libindicatorsessionservice STATIC + actions.c + actions.h + guest.c + guest.h + service.c + service.h + users.c + users.h) +set_target_properties (libindicatorsessionservice PROPERTIES COMPILE_FLAGS " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") + +include_directories(${SERVICE_INCLUDE_DIRS}) +link_directories(${SERVICE_LIBRARY_DIRS}) + +add_executable (indicator-session-service main.c) +target_link_libraries (indicator-session-service libindicatorsessionservice backenddbus ${SERVICE_LIBRARIES} ${GCOV_LIBS}) + diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index bcc8652..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,207 +0,0 @@ -CLEANFILES = -EXTRA_DIST = - -libexec_PROGRAMS = \ - indicator-session-service - -if BUILD_GTKLOGOUTHELPER -libexec_PROGRAMS += \ - gtk-logout-helper -endif - -################### -# Indicator Stuff -################### - -CLEANFILES += .libs/*.gcda .libs/*.gcno *.gcda *.gcno - -sessionlibdir = $(INDICATORDIR) -sessionlib_LTLIBRARIES = libsession.la -libsession_la_SOURCES = \ - indicator-session.c \ - gen-session-dbus.xml.h \ - shared-names.h \ - user-widget.c \ - user-widget.h -libsession_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(COVERAGE_CFLAGS) \ - -Wall -Wunused \ - -DG_LOG_DOMAIN=\"Indicator-Session\" -libsession_la_LIBADD = $(APPLET_LIBS) -libsession_la_LDFLAGS = \ - $(COVERAGE_LDFLAGS) \ - -module -avoid-version - -dbus_display_manager_sources = \ - dbus-display-manager.c \ - dbus-display-manager.h - -$(dbus_display_manager_sources): display-manager.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-display-manager \ - $^ - -dbus_consolekit_manager_sources = \ - dbus-consolekit-manager.c \ - dbus-consolekit-manager.h - -$(dbus_consolekit_manager_sources): org.freedesktop.ConsoleKit.Manager.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-consolekit-manager \ - $^ - -dbus_consolekit_seat_sources = \ - dbus-consolekit-seat.c \ - dbus-consolekit-seat.h - -$(dbus_consolekit_seat_sources): org.freedesktop.ConsoleKit.Seat.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-consolekit-seat \ - $^ - -dbus_consolekit_session_sources = \ - dbus-consolekit-session.c \ - dbus-consolekit-session.h - -$(dbus_consolekit_session_sources): org.freedesktop.ConsoleKit.Session.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-consolekit-session \ - $^ - -dbus_accounts_sources = \ - dbus-accounts.c \ - dbus-accounts.h - -$(dbus_accounts_sources): org.freedesktop.Accounts.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-accounts \ - $^ - -dbus_user_sources = \ - dbus-user.c \ - dbus-user.h - -$(dbus_user_sources): org.freedesktop.Accounts.User.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-user \ - $^ - -dbus_upower_sources = \ - dbus-upower.c \ - dbus-upower.h - -$(dbus_upower_sources): upower.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-upower \ - --c-namespace DBus \ - $^ - -gen-%.xml.c: %.xml - @echo "Building $@ from $<" - @echo "const char * _$(subst -,_,$(subst .,_,$(basename $(notdir $<)))) = " > $@ - @sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@ - @echo ";" >> $@ - -gen-%.xml.h: %.xml - @echo "Building $@ from $<" - @echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $(notdir $<))));" > $@ - -################# -# Session Stuff -################# - -indicator_session_service_SOURCES = \ - $(dbus_accounts_sources) \ - $(dbus_consolekit_manager_sources) \ - $(dbus_consolekit_seat_sources) \ - $(dbus_consolekit_session_sources) \ - $(dbus_display_manager_sources) \ - $(dbus_upower_sources) \ - $(dbus_user_sources) \ - session-service.c \ - session-dbus.c \ - session-dbus.h \ - gen-session-dbus.xml.c \ - users-service-dbus.h \ - users-service-dbus.c \ - session-menu-mgr.h \ - session-menu-mgr.c \ - online-accounts-mgr.c \ - online-accounts-mgr.h - -indicator_session_service_CFLAGS = \ - $(SESSIONSERVICE_CFLAGS) \ - $(GCONF_CFLAGS) \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -Wall \ - -DG_LOG_DOMAIN=\"Indicator-Session\" \ - $(COVERAGE_CFLAGS) -indicator_session_service_LDADD = \ - $(SESSIONSERVICE_LIBS) \ - $(GCONF_LIBS) -indicator_session_service_LDFLAGS = \ - $(COVERAGE_LDFLAGS) - -################# -# GTK Logout Stuff -################# - -if BUILD_GTKLOGOUTHELPER -gtk_logout_helper_SOURCES = \ - $(dbus_consolekit_manager_sources) \ - gtk-logout-helper.c \ - dialog.c \ - dialog.h - -gtk_logout_helper_CFLAGS = \ - $(SESSIONSERVICE_CFLAGS) \ - $(GTKLOGOUTHELPER_CFLAGS) \ - $(GCONF_CFLAGS) \ - $(COVERAGE_CFLAGS) \ - -Wall \ - -DINDICATOR_ICONS_DIR="\"$(INDICATORICONSDIR)\"" - -gtk_logout_helper_LDADD = \ - $(SESSIONSERVICE_LIBS) \ - $(GTKLOGOUTHELPER_LIBS) \ - $(GCONF_LIBS) - -gtk_logout_helper_LDFLAGS = \ - $(COVERAGE_LDFLAGS) -endif - - -############### -# Other Stuff -############### - -BUILT_SOURCES = \ - $(dbus_accounts_sources) \ - $(dbus_consolekit_manager_sources) \ - $(dbus_consolekit_seat_sources) \ - $(dbus_consolekit_session_sources) \ - $(dbus_display_manager_sources) \ - $(dbus_upower_sources) \ - $(dbus_user_sources) \ - gen-session-dbus.xml.c \ - gen-session-dbus.xml.h - -EXTRA_DIST += \ - display-manager.xml \ - org.freedesktop.Accounts.User.xml \ - org.freedesktop.Accounts.xml \ - org.freedesktop.ConsoleKit.Manager.xml \ - org.freedesktop.ConsoleKit.Seat.xml \ - org.freedesktop.ConsoleKit.Session.xml \ - session-dbus.xml \ - upower.xml - -CLEANFILES += $(BUILT_SOURCES) diff --git a/src/actions.c b/src/actions.c new file mode 100644 index 0000000..788f418 --- /dev/null +++ b/src/actions.c @@ -0,0 +1,383 @@ + +/* + * 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 "actions.h" + +/*** +**** GObject Boilerplate +***/ + +G_DEFINE_TYPE (IndicatorSessionActions, indicator_session_actions, G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_CAN_SWITCH, + PROP_CAN_HIBERNATE, + PROP_CAN_SUSPEND, + PROP_CAN_LOCK, + PROP_CAN_LOGOUT, + PROP_CAN_PROMPT, + PROP_HAS_ONLINE_ACCOUNT_ERROR, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +static void +my_get_property (GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorSessionActions * self = INDICATOR_SESSION_ACTIONS (o); + + switch (property_id) + { + case PROP_CAN_SWITCH: + g_value_set_boolean (value, indicator_session_actions_can_switch (self)); + break; + + case PROP_CAN_HIBERNATE: + g_value_set_boolean (value, indicator_session_actions_can_hibernate (self)); + break; + + case PROP_CAN_SUSPEND: + g_value_set_boolean (value, indicator_session_actions_can_suspend (self)); + break; + + case PROP_CAN_LOCK: + g_value_set_boolean (value, indicator_session_actions_can_lock (self)); + break; + + case PROP_CAN_LOGOUT: + g_value_set_boolean (value, indicator_session_actions_can_logout (self)); + break; + + case PROP_CAN_PROMPT: + g_value_set_boolean (value, indicator_session_actions_can_prompt (self)); + break; + + case PROP_HAS_ONLINE_ACCOUNT_ERROR: + g_value_set_boolean (value, indicator_session_actions_has_online_account_error (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_class_init (IndicatorSessionActionsClass * klass) +{ + GObjectClass * object_class; + const GParamFlags flags = G_PARAM_READABLE | G_PARAM_STATIC_STRINGS; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = my_get_property; + + klass->can_lock = NULL; + klass->can_logout = NULL; + klass->can_switch = NULL; + klass->can_suspend = NULL; + klass->can_hibernate = NULL; + klass->has_online_account_error = NULL; + klass->logout = NULL; + klass->suspend = NULL; + klass->hibernate = NULL; + klass->restart = NULL; + klass->shutdown = NULL; + klass->switch_to_screensaver = NULL; + klass->switch_to_greeter = NULL; + klass->switch_to_guest = NULL; + klass->switch_to_username = NULL; + + /* properties */ + + properties[PROP_0] = NULL; + + properties[PROP_CAN_SWITCH] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_SWITCH, + "Can Switch Sessions", + "Whether or not the system services allow session switching", + TRUE, flags); + + properties[PROP_CAN_HIBERNATE] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE, + "Can Hibernate", + "Whether or not the system services allow the user to hibernate", + TRUE, flags); + + properties[PROP_CAN_SUSPEND] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND, + "Can Suspend", + "Whether or not the system services allow the user to suspend", + TRUE, flags); + + properties[PROP_CAN_LOCK] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_LOCK, + "Can Lock", + "Whether or not the system services allow the user to lock the screen", + TRUE, flags); + + properties[PROP_CAN_LOGOUT] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_LOGOUT, + "Can Logout", + "Whether or not the system services allow the user to logout", + TRUE, flags); + + properties[PROP_CAN_PROMPT] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT, + "Can Show End Session Dialog", + "Whether or not we can show an End Session dialog", + TRUE, flags); + + properties[PROP_HAS_ONLINE_ACCOUNT_ERROR] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_HAS_ONLINE_ACCOUNT_ERROR, + "Has Online Account Error", + "Whether or not an online account setting requires attention from the user", + FALSE, flags); + + g_object_class_install_properties (object_class, PROP_LAST, properties); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_init (IndicatorSessionActions * self G_GNUC_UNUSED) +{ +} + +/*** +**** +***/ + +gboolean +indicator_session_actions_can_lock (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_lock (self); +} + +gboolean +indicator_session_actions_can_logout (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_logout (self); +} + +gboolean +indicator_session_actions_can_switch (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_switch (self); +} + +gboolean +indicator_session_actions_can_suspend (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_suspend (self); +} + +gboolean +indicator_session_actions_can_hibernate (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_hibernate (self); +} + +gboolean +indicator_session_actions_can_prompt (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_prompt (self); +} + +gboolean +indicator_session_actions_has_online_account_error (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->has_online_account_error (self); +} + +/*** +**** +***/ + +void +indicator_session_actions_settings (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->settings (self); +} + +void +indicator_session_actions_logout (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->logout (self); +} + +void +indicator_session_actions_shutdown (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->shutdown (self); +} + +void +indicator_session_actions_help (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->help (self); +} + +void +indicator_session_actions_about (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->about (self); +} + +void +indicator_session_actions_restart (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->restart (self); +} + +void +indicator_session_actions_suspend (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->suspend (self); +} + +void +indicator_session_actions_hibernate (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->hibernate (self); +} + +void +indicator_session_actions_switch_to_screensaver (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->switch_to_screensaver (self); +} + +void +indicator_session_actions_switch_to_greeter (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->switch_to_greeter (self); +} + +void +indicator_session_actions_switch_to_guest (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->switch_to_guest (self); +} + +void +indicator_session_actions_switch_to_username (IndicatorSessionActions * self, + const gchar * username) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->switch_to_username (self, username); +} + +/*** +**** +***/ + +static void +notify_func (IndicatorSessionActions * self, int prop) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + g_debug ("%s %s emitting '%s' prop notify", G_STRLOC, G_STRFUNC, properties[prop]->name); + + g_object_notify_by_pspec (G_OBJECT(self), properties[prop]); +} + +void +indicator_session_actions_notify_can_lock (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_LOCK); +} + +void +indicator_session_actions_notify_can_logout (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_LOGOUT); +} + +void +indicator_session_actions_notify_can_switch (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_SWITCH); +} + +void +indicator_session_actions_notify_can_suspend (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_SUSPEND); +} + +void +indicator_session_actions_notify_can_hibernate (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_HIBERNATE); +} + +void +indicator_session_actions_notify_can_prompt (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_PROMPT); +} + +void +indicator_session_actions_notify_has_online_account_error (IndicatorSessionActions * self) +{ + notify_func (self, PROP_HAS_ONLINE_ACCOUNT_ERROR); +} diff --git a/src/actions.h b/src/actions.h new file mode 100644 index 0000000..e0d0ec5 --- /dev/null +++ b/src/actions.h @@ -0,0 +1,129 @@ +/* + * 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 . + */ + +#ifndef __INDICATOR_SESSION_ACTIONS_H__ +#define __INDICATOR_SESSION_ACTIONS_H__ + +#include +#include + +G_BEGIN_DECLS + +/* standard GObject macros */ +#define INDICATOR_TYPE_SESSION_ACTIONS (indicator_session_actions_get_type()) +#define INDICATOR_SESSION_ACTIONS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_ACTIONS, IndicatorSessionActions)) +#define INDICATOR_SESSION_ACTIONS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_ACTIONS, IndicatorSessionActionsClass)) +#define INDICATOR_SESSION_ACTIONS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_TYPE_SESSION_ACTIONS, IndicatorSessionActionsClass)) +#define INDICATOR_IS_SESSION_ACTIONS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_ACTIONS)) + +typedef struct _IndicatorSessionActions IndicatorSessionActions; +typedef struct _IndicatorSessionActionsClass IndicatorSessionActionsClass; + +/* property keys */ +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_LOCK "can-lock" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_LOGOUT "can-logout" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_SWITCH "can-switch" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND "can-suspend" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE "can-hibernate" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT "can-show-end-session-dialog" +#define INDICATOR_SESSION_ACTIONS_PROP_HAS_ONLINE_ACCOUNT_ERROR "has-online-account-error" + +/** + * A base class for invoking and getting state information on system actions. + * Use backend.h's get_backend() to get an instance. + */ +struct _IndicatorSessionActions +{ + /*< private >*/ + GObject parent; +}; + +struct _IndicatorSessionActionsClass +{ + GObjectClass parent_class; + + /* pure virtual functions */ + + gboolean (*can_lock) (IndicatorSessionActions * self); + gboolean (*can_logout) (IndicatorSessionActions * self); + gboolean (*can_switch) (IndicatorSessionActions * self); + gboolean (*can_suspend) (IndicatorSessionActions * self); + gboolean (*can_hibernate) (IndicatorSessionActions * self); + gboolean (*can_prompt) (IndicatorSessionActions * self); + gboolean (*has_online_account_error) (IndicatorSessionActions * self); + + void (*suspend) (IndicatorSessionActions * self); + void (*hibernate) (IndicatorSessionActions * self); + void (*logout) (IndicatorSessionActions * self); + void (*restart) (IndicatorSessionActions * self); + void (*shutdown) (IndicatorSessionActions * self); + void (*help) (IndicatorSessionActions * self); + void (*about) (IndicatorSessionActions * self); + void (*settings) (IndicatorSessionActions * self); + + void (*switch_to_greeter) (IndicatorSessionActions * self); + void (*switch_to_screensaver) (IndicatorSessionActions * self); + void (*switch_to_guest) (IndicatorSessionActions * self); + void (*switch_to_username) (IndicatorSessionActions * self, + const gchar * username); +}; + +/*** +**** +***/ + +GType indicator_session_actions_get_type (void); + +gboolean indicator_session_actions_can_lock (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_logout (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_switch (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_suspend (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_hibernate (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_prompt (IndicatorSessionActions * self); +gboolean indicator_session_actions_has_online_account_error (IndicatorSessionActions * self); + + +void indicator_session_actions_notify_can_lock (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_logout (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_switch (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_suspend (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_hibernate (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_prompt (IndicatorSessionActions * self); +void indicator_session_actions_notify_has_online_account_error (IndicatorSessionActions * self); + +void indicator_session_actions_lock (IndicatorSessionActions * self); +void indicator_session_actions_suspend (IndicatorSessionActions * self); +void indicator_session_actions_hibernate (IndicatorSessionActions * self); +void indicator_session_actions_logout (IndicatorSessionActions * self); +void indicator_session_actions_restart (IndicatorSessionActions * self); +void indicator_session_actions_shutdown (IndicatorSessionActions * self); + +void indicator_session_actions_help (IndicatorSessionActions * self); +void indicator_session_actions_about (IndicatorSessionActions * self); +void indicator_session_actions_settings (IndicatorSessionActions * self); + +void indicator_session_actions_switch_to_screensaver (IndicatorSessionActions * self); +void indicator_session_actions_switch_to_greeter (IndicatorSessionActions * self); +void indicator_session_actions_switch_to_guest (IndicatorSessionActions * self); +void indicator_session_actions_switch_to_username (IndicatorSessionActions * self, + const gchar * username); + +G_END_DECLS + +#endif /* __INDICATOR_SESSION_ACTIONS_H__ */ diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt new file mode 100644 index 0000000..a477cfe --- /dev/null +++ b/src/backend-dbus/CMakeLists.txt @@ -0,0 +1,86 @@ +# autogenerate source code files for our DBus proxies +function(gdbus_codegen XML_FILE INTERFACE_PREFIX SOURCE_PREFIX) + + set (SRC_C, ${SOURCE_PREFIX}.c) + set (SRC_H, ${SOURCE_PREFIX}.h) + + # check for the app + find_program (GDBUS_CODEGEN_EXECUTABLE NAMES gdbus-codegen DOC "gdbus-codegen executable") + if(NOT GDBUS_CODEGEN_EXECUTABLE) + message(FATAL_ERROR "Executable gdbus-codegen not found") + endif() + + # generate the code + add_custom_command ( + OUTPUT ${SOURCE_PREFIX}.c ${SOURCE_PREFIX}.h + COMMAND gdbus-codegen ARGS --interface-prefix ${INTERFACE_PREFIX} --generate-c-code ${SOURCE_PREFIX} ${CMAKE_CURRENT_SOURCE_DIR}/${XML_FILE} + DEPENDS ${XML_FILE}) + + # update our variables + set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_C}) + set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_H}) + set_property (SOURCE ${SRC_C} ${SRC_H} PROPERTY GENERATED) + + # cleanup + unset (SRC_C) + unset (SRC_H) + +endfunction(gdbus_codegen) +gdbus_codegen ("display-manager.xml" "org.freedesktop" "dbus-display-manager") +gdbus_codegen ("com.canonical.indicators.webcredentials.xml" "com.canonical.indicators" "dbus-webcredentials") +gdbus_codegen ("org.freedesktop.Accounts.xml" "org.freedesktop" "dbus-accounts") +gdbus_codegen ("org.freedesktop.Accounts.User.xml" "org.freedesktop" "dbus-user") +gdbus_codegen ("org.freedesktop.ConsoleKit.Manager.xml" "org.freedesktop" "dbus-consolekit-manager") +gdbus_codegen ("org.freedesktop.ConsoleKit.Seat.xml" "org.freedesktop" "dbus-consolekit-seat") +gdbus_codegen ("org.freedesktop.ConsoleKit.Session.xml" "org.freedesktop" "dbus-consolekit-session") +gdbus_codegen ("org.gnome.ScreenSaver.xml" "org" "gnome-screen-saver") +gdbus_codegen ("org.gnome.SessionManager.xml" "org" "gnome-session-manager") +gdbus_codegen ("org.gnome.SessionManager.EndSessionDialog.xml" "org.gnome.SessionManager" "dbus-end-session-dialog") +gdbus_codegen ("upower.xml" "org.freedesktop" "dbus-upower") + +# add warnings/coverage info on handwritten files +# but not the autogenerated ones... +set_source_files_properties (actions.c + backend-dbus.c + guest.c + users.c + utils.c + PROPERTIES COMPILE_FLAGS " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") + +# add the bin dir to our include path s.t. our code can find the autogenerated header files +include_directories (${CMAKE_CURRENT_BINARY_DIR} ${SERVICE_INCLUDE_DIRS}) + +add_library (backenddbus STATIC + gnome-screen-saver.c + gnome-screen-saver.h + gnome-session-manager.c + gnome-session-manager.h + dbus-display-manager.c + dbus-display-manager.h + dbus-consolekit-manager.c + dbus-consolekit-manager.h + dbus-consolekit-seat.c + dbus-consolekit-seat.h + dbus-consolekit-session.c + dbus-consolekit-session.h + dbus-accounts.c + dbus-accounts.h + dbus-upower.c + dbus-upower.h + dbus-user.c + dbus-user.h + dbus-webcredentials.c + dbus-webcredentials.h + dbus-end-session-dialog.c + dbus-end-session-dialog.h + actions.c + actions.h + backend-dbus.c + backend-dbus.h + guest.c + guest.h + users.c + users.h + utils.c + utils.h) + 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); +} diff --git a/src/backend-dbus/actions.h b/src/backend-dbus/actions.h new file mode 100644 index 0000000..997dd73 --- /dev/null +++ b/src/backend-dbus/actions.h @@ -0,0 +1,73 @@ +/* + * 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 . + */ + +#ifndef __INDICATOR_SESSION_ACTIONS_DBUS_H__ +#define __INDICATOR_SESSION_ACTIONS_DBUS_H__ + +#include +#include + +#include "../actions.h" /* parent class */ +#include "dbus-accounts.h" +#include "dbus-consolekit-manager.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-display-manager.h" + + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_ACTIONS_DBUS (indicator_session_actions_dbus_get_type()) +#define INDICATOR_SESSION_ACTIONS_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_ACTIONS_DBUS, IndicatorSessionActionsDbus)) +#define INDICATOR_SESSION_ACTIONS_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_ACTIONS_DBUS, IndicatorSessionActionsDbusClass)) +#define INDICATOR_IS_SESSION_ACTIONS_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_ACTIONS_DBUS)) + +typedef struct _IndicatorSessionActionsDbus IndicatorSessionActionsDbus; +typedef struct _IndicatorSessionActionsDbusPriv IndicatorSessionActionsDbusPriv; +typedef struct _IndicatorSessionActionsDbusClass IndicatorSessionActionsDbusClass; + +/** + * An implementation of IndicatorSessionActions that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionActionsDbus +{ + /*< private >*/ + IndicatorSessionActions parent; + IndicatorSessionActionsDbusPriv * priv; +}; + +struct _IndicatorSessionActionsDbusClass +{ + IndicatorSessionActionsClass parent_class; +}; + +GType indicator_session_actions_dbus_get_type (void); + +IndicatorSessionActions * indicator_session_actions_dbus_new (void); + +void indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, + ConsoleKitManager * ck_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * ck_seat); + + +G_END_DECLS + +#endif /* __INDICATOR_SESSION_ACTIONS_DBUS_H__ */ diff --git a/src/backend-dbus/backend-dbus.c b/src/backend-dbus/backend-dbus.c new file mode 100644 index 0000000..ea8f0ec --- /dev/null +++ b/src/backend-dbus/backend-dbus.c @@ -0,0 +1,117 @@ +/* + * 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 "actions.h" +#include "backend-dbus.h" +#include "guest.h" +#include "users.h" +#include "utils.h" + +struct dbus_world_data +{ + GCancellable * cancellable; + IndicatorSessionActionsDbus * actions; + IndicatorSessionUsersDbus * users; + IndicatorSessionGuestDbus * guest; +}; + +static void +on_proxies_ready (ConsoleKitManager * ck_manager, + Accounts * account_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * ck_seat, + ConsoleKitSession * ck_session, + AccountsUser * active_user G_GNUC_UNUSED, + const GError * error, + gpointer gdata) +{ + struct dbus_world_data * data = gdata; + + if (error == NULL) + { + if (data->actions != NULL) + indicator_session_actions_dbus_set_proxies (data->actions, + ck_manager, + dm_seat, + ck_seat); + + if (data->users != NULL) + indicator_session_users_dbus_set_proxies (data->users, + account_manager, + dm_seat, + ck_seat); + + if (data->guest != NULL) + indicator_session_guest_dbus_set_proxies (data->guest, + account_manager, + dm_seat, + ck_seat, + ck_session); + } + + g_free (data); +} + +/*** +**** +***/ + +void +backend_get (GCancellable * cancellable, + IndicatorSessionActions ** setme_actions, + IndicatorSessionUsers ** setme_users, + IndicatorSessionGuest ** setme_guest) +{ + struct dbus_world_data * data; + + data = g_new0 (struct dbus_world_data, 1); + + if (setme_actions != NULL) + { + IndicatorSessionActions * actions; + actions = indicator_session_actions_dbus_new (); + data->actions = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + *setme_actions = actions; + } + + if (setme_users != NULL) + { + IndicatorSessionUsers * users; + users = indicator_session_users_dbus_new (); + data->users = INDICATOR_SESSION_USERS_DBUS (users); + + *setme_users = users; + } + + if (setme_guest != NULL) + { + IndicatorSessionGuest * guest; + guest = indicator_session_guest_dbus_new (); + data->guest = INDICATOR_SESSION_GUEST_DBUS (guest); + + *setme_guest = guest; + } + + data->cancellable = g_object_ref (cancellable); + + indicator_session_util_get_session_proxies (on_proxies_ready, + data->cancellable, + data); +} diff --git a/src/backend-dbus/backend-dbus.h b/src/backend-dbus/backend-dbus.h new file mode 100644 index 0000000..daf6ac3 --- /dev/null +++ b/src/backend-dbus/backend-dbus.h @@ -0,0 +1,38 @@ +/* + * 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 . + */ + +#ifndef __INDICATOR_SESSION_BACKEND_DESKTOP_H__ +#define __INDICATOR_SESSION_BACKEND_DESKTOP_H__ + +#include /* GCancellable */ + +#include "../actions.h" +#include "../guest.h" +#include "../users.h" + +G_BEGIN_DECLS + +void backend_get (GCancellable * cancellable, + IndicatorSessionActions ** setme_actions, + IndicatorSessionUsers ** setme_users, + IndicatorSessionGuest ** setme_guest); + +G_END_DECLS + +#endif diff --git a/src/backend-dbus/com.canonical.indicators.webcredentials.xml b/src/backend-dbus/com.canonical.indicators.webcredentials.xml new file mode 100644 index 0000000..d215081 --- /dev/null +++ b/src/backend-dbus/com.canonical.indicators.webcredentials.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/display-manager.xml b/src/backend-dbus/display-manager.xml new file mode 100644 index 0000000..07b5f29 --- /dev/null +++ b/src/backend-dbus/display-manager.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c new file mode 100644 index 0000000..516ba00 --- /dev/null +++ b/src/backend-dbus/guest.c @@ -0,0 +1,570 @@ +/* + * 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-accounts.h" +#include "dbus-display-manager.h" +#include "dbus-user.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-manager.h" +#include "dbus-consolekit-session.h" + +#include "guest.h" + +struct _IndicatorSessionGuestDbusPriv +{ + GCancellable * cancellable; + + Accounts * accounts; + AccountsUser * guest; + DisplayManagerSeat * display_manager_seat; + + ConsoleKitSeat * seat; + ConsoleKitSession * active_session; + guint active_uid; + + gboolean guest_is_active; + gboolean guest_is_allowed; +}; + +typedef IndicatorSessionGuestDbusPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionGuestDbus, + indicator_session_guest_dbus, + INDICATOR_TYPE_SESSION_GUEST) + +/*** +**** +***/ + +static void +check_for_active_guest (IndicatorSessionGuestDbus * self) +{ + gboolean guest_is_active; + priv_t * p = self->priv; + + guest_is_active = (p->active_uid) + && (p->guest != NULL) + && (p->active_uid == accounts_user_get_uid (p->guest)); + + if (p->guest_is_active != guest_is_active) + { + p->guest_is_active = guest_is_active; + + indicator_session_guest_notify_active (INDICATOR_SESSION_GUEST(self)); + } +} + +static void +set_active_uid (IndicatorSessionGuestDbus * self, guint uid) +{ + self->priv->active_uid = uid; + + check_for_active_guest (self); +} + +static void +on_active_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + guint uid; + GError * err; + IndicatorSessionGuestDbus * self; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + uid = 0; + err = NULL; + self = INDICATOR_SESSION_GUEST_DBUS (gself); + console_kit_session_call_get_unix_user_finish (self->priv->active_session, &uid, res, &err); + + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + set_active_uid (self, uid); + } +} + + +static void +set_active_session (IndicatorSessionGuestDbus * self, + ConsoleKitSession * session) +{ + priv_t * p = self->priv; + + if (p->active_session != NULL) + { + g_debug ("%s %s active_session refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->active_session)->ref_count); + + g_clear_object (&p->active_session); + } + + if (session != NULL) + { + p->active_session = g_object_ref (session); + + console_kit_session_call_get_unix_user (session, + p->cancellable, + on_active_uid_ready, + self); + } +} + +static void +on_active_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + ConsoleKitSession * session; + + err = NULL; + session = console_kit_session_proxy_new_finish (res, &err); + + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + } + else + { + set_active_session (gself, session); + } + + g_clear_object (&session); +} + + +static void +on_active_session_changed (ConsoleKitSeat * seat G_GNUC_UNUSED, + const gchar * ssid, + IndicatorSessionGuestDbus * self) +{ + console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + ssid, + self->priv->cancellable, + on_active_session_proxy_ready, + self); +} + +static void +set_seat (IndicatorSessionGuestDbus * self, + ConsoleKitSeat * seat) +{ + priv_t * p = self->priv; + + if (p->seat != NULL) + { +g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)p->seat); + g_signal_handlers_disconnect_by_data (p->seat, self); +g_debug ("%s %s seat refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->seat)->ref_count); + + g_clear_object (&p->seat); + } + + if (seat != NULL) + { + p->seat = g_object_ref (seat); +g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)p->seat); + + g_signal_connect (seat, "active-session-changed", + G_CALLBACK(on_active_session_changed), self); + } +} + +/*** +**** +***/ + +static void +set_guest (IndicatorSessionGuestDbus * self, + AccountsUser * guest) +{ + priv_t * p = self->priv; + + if (p->guest != NULL) + { + g_debug ("%s %s guest refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->guest)->ref_count); + + g_clear_object (&p->guest); + } + + if (guest != NULL) + { + p->guest = g_object_ref (guest); + } + + g_debug ("%s %s guest proxy is now %p", G_STRLOC, G_STRFUNC, (void*)guest); + indicator_session_guest_notify_logged_in (INDICATOR_SESSION_GUEST(self)); + + check_for_active_guest (self); +} + +static void +on_user_deleted (IndicatorSessionGuestDbus * self, + const gchar * path) +{ + AccountsUser * guest = self->priv->guest; + g_debug ("%s %s %s", G_STRLOC, G_STRFUNC, path); + + if (guest != NULL) + if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (G_DBUS_PROXY(guest)))) + set_guest (self, NULL); +} + +static gboolean +is_guest (AccountsUser * user) +{ + /* a guest will look like this: + username:[guest-jjbEVV] realname:[Guest] system:[1] */ + return IS_ACCOUNTS_USER(user) + && accounts_user_get_system_account (user) + && !g_ascii_strcasecmp (accounts_user_get_real_name(user), "Guest"); +} + +static void +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer self) +{ + GError * err; + AccountsUser * user; + + err = NULL; + user = accounts_user_proxy_new_for_bus_finish (res, &err); + + if (err != NULL) + { + g_warning ("%s: %s", G_STRFUNC, err->message); + g_error_free (err); + } + else if (is_guest (user)) + { + g_debug ("%s %s got guest", G_STRLOC, G_STRFUNC); + set_guest (INDICATOR_SESSION_GUEST_DBUS(self), user); + } + + g_clear_object (&user); +} + +static void +create_user_proxy_for_path (IndicatorSessionGuestDbus * self, + const char * path) +{ + const char * name = "org.freedesktop.Accounts"; + const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + g_debug ("%s %s creating proxy for %s", G_STRLOC, G_STRFUNC, path); + + accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, path, + self->priv->cancellable, + on_user_proxy_ready, self); +} + +static void +on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar ** paths; + + err = NULL; + paths = NULL; + accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + int i; + + for (i=0; paths && paths[i]; ++i) + create_user_proxy_for_path (gself, paths[i]); + + g_strfreev (paths); + } +} + +static void +set_account_manager (IndicatorSessionGuestDbus * self, + Accounts * a) +{ + g_debug ("%s %s setting account manager to %p", G_STRLOC, G_STRFUNC, (void*)a); + + if (self->priv->accounts != NULL) + { +g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); + g_signal_handlers_disconnect_by_data (self->priv->accounts, self); +g_debug ("%s %s account manager refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->accounts)->ref_count); + g_clear_object (&self->priv->accounts); + } + + if (a != NULL) + { + self->priv->accounts = g_object_ref (a); + +g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); + g_signal_connect_swapped (a, "user-added", + G_CALLBACK(create_user_proxy_for_path), self); + + g_signal_connect_swapped (a, "user-deleted", + G_CALLBACK(on_user_deleted), self); + + accounts_call_list_cached_users (a, + self->priv->cancellable, + on_user_list_ready, + self); + } +} + +static void +set_guest_is_allowed (IndicatorSessionGuestDbus * self, gboolean guest_is_allowed) +{ + priv_t * p = self->priv; + g_debug ("%s %s guest_is_allowed: %d", G_STRLOC, G_STRFUNC, (int)guest_is_allowed); + + if (p->guest_is_allowed != guest_is_allowed) + { + p->guest_is_allowed = guest_is_allowed; + + indicator_session_guest_notify_allowed (INDICATOR_SESSION_GUEST (self)); + } +} + +static void +on_notify_has_guest_account (GObject * seat, GParamSpec * pspec G_GNUC_UNUSED, gpointer gself) +{ + set_guest_is_allowed (INDICATOR_SESSION_GUEST_DBUS (gself), + display_manager_seat_get_has_guest_account (DISPLAY_MANAGER_SEAT(seat))); +} + +static void +set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * seat) +{ + priv_t * p = self->priv; + + if (p->display_manager_seat != NULL) + { + g_signal_handlers_disconnect_by_data (p->display_manager_seat, self); + g_debug ("%s %s before we unref, dm seat's refcount is %d", G_STRLOC, G_STRFUNC, G_OBJECT(p->display_manager_seat)->ref_count); + g_clear_object (&p->display_manager_seat); + } + + if (seat != NULL) + { + p->display_manager_seat = g_object_ref (seat); + + g_signal_connect (seat, "notify::has-guest-account", G_CALLBACK(on_notify_has_guest_account), self); + + on_notify_has_guest_account (G_OBJECT(seat), NULL, self); + } +} + +#if 0 +static void +on_display_manager_seat_proxy_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + DisplayManagerSeat * seat; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + err = NULL; + seat = display_manager_seat_proxy_new_for_bus_finish (res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + set_display_manager_seat (INDICATOR_SESSION_GUEST_DBUS(gself), seat); + } + + g_clear_object (&seat); +} +#endif + +static void +on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC_UNUSED) +{ + GError * err; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + err = NULL; + display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } +} + +/*** +**** Virtual Functions +***/ + +static void +my_dispose (GObject * o) +{ + IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS (o); + + if (self->priv->cancellable != NULL) + { + g_cancellable_cancel (self->priv->cancellable); + g_clear_object (&self->priv->cancellable); + } + + set_seat (self, NULL); + set_active_session (self, NULL); + set_account_manager (self, NULL); + set_display_manager_seat (self, NULL); + g_clear_object (&self->priv->guest); + + G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + /*IndicatorSessionGuestDbus * u = INDICATOR_SESSION_GUEST_DBUS (o);*/ + + G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->finalize (o); +} + +static gboolean +my_is_allowed (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); + + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_allowed; +} + +static gboolean +my_is_logged_in (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); + + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest != NULL; +} + +static gboolean +my_is_active (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); + + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_active; +} + +static void +my_switch_to_guest (IndicatorSessionGuest * self) +{ + priv_t * p; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); + + p = INDICATOR_SESSION_GUEST_DBUS(self)->priv; + + if (p->display_manager_seat != NULL) + { + display_manager_seat_call_switch_to_guest (p->display_manager_seat, + "", + p->cancellable, + on_switch_to_guest_done, + self); + } +} + +/*** +**** GObject Boilerplate +***/ + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionGuestClass * guest_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + guest_class = INDICATOR_SESSION_GUEST_CLASS (klass); + guest_class->is_allowed = my_is_allowed; + guest_class->is_logged_in = my_is_logged_in; + guest_class->is_active = my_is_active; + guest_class->switch_to_guest = my_switch_to_guest; + + g_type_class_add_private (klass, sizeof (IndicatorSessionGuestDbusPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_dbus_init (IndicatorSessionGuestDbus * self) +{ + priv_t * p; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_GUEST_DBUS, + IndicatorSessionGuestDbusPriv); + p->cancellable = g_cancellable_new (); + self->priv = p; + +#if 0 + display_manager_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.DisplayManager", + g_getenv ("XDG_SEAT_PATH"), + self->priv->cancellable, + on_display_manager_seat_proxy_ready, + self); +#endif +} + +/*** +**** Public +***/ + +IndicatorSessionGuest * +indicator_session_guest_dbus_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_GUEST_DBUS, NULL); + + return INDICATOR_SESSION_GUEST (o); +} + +void +indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus * self, + Accounts * accounts, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * seat, + ConsoleKitSession * session) +{ + g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); + g_debug ("%s %s accounts %p seat %p session %p", G_STRLOC, G_STRFUNC, (void*)accounts, (void*)seat, (void*)session); + + set_account_manager (self, accounts); + set_display_manager_seat (self, dm_seat); + set_seat (self, seat); + set_active_session (self, session); +} diff --git a/src/backend-dbus/guest.h b/src/backend-dbus/guest.h new file mode 100644 index 0000000..03b6b28 --- /dev/null +++ b/src/backend-dbus/guest.h @@ -0,0 +1,72 @@ +/* + * 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 . + */ + +#ifndef __GUEST_DBUS_H__ +#define __GUEST_DBUS_H__ + +#include +#include + +#include "../guest.h" /* parent class */ +#include "dbus-accounts.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-display-manager.h" + + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_GUEST_DBUS (indicator_session_guest_dbus_get_type()) +#define INDICATOR_SESSION_GUEST_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_GUEST_DBUS, IndicatorSessionGuestDbus)) +#define INDICATOR_SESSION_GUEST_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_GUEST_DBUS, IndicatorSessionGuestDbusClass)) +#define INDICATOR_IS_SESSION_GUEST_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_GUEST_DBUS)) + +typedef struct _IndicatorSessionGuestDbus IndicatorSessionGuestDbus; +typedef struct _IndicatorSessionGuestDbusPriv IndicatorSessionGuestDbusPriv; +typedef struct _IndicatorSessionGuestDbusClass IndicatorSessionGuestDbusClass; + +/** + * An implementation of IndicatorSessionGuest that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionGuestDbus +{ + /*< private >*/ + IndicatorSessionGuest parent; + IndicatorSessionGuestDbusPriv * priv; +}; + +struct _IndicatorSessionGuestDbusClass +{ + IndicatorSessionGuestClass parent_class; +}; + +GType indicator_session_guest_dbus_get_type (void); + +IndicatorSessionGuest * indicator_session_guest_dbus_new (void); + +void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus *, + Accounts *, + DisplayManagerSeat *, + ConsoleKitSeat *, + ConsoleKitSession *); + +G_END_DECLS + +#endif diff --git a/src/backend-dbus/org.freedesktop.Accounts.User.xml b/src/backend-dbus/org.freedesktop.Accounts.User.xml new file mode 100644 index 0000000..53f54d4 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.Accounts.User.xml @@ -0,0 +1,744 @@ + + + + + + + + + + + The new username. + + + + + + + Sets the users username. Note that it is usually not allowed + to have multiple users with the same username. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the username of any user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new name, typically in the form "Firstname Lastname". + + + + + + + Sets the users real name. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own name + + + org.freedesktop.accounts.user-administration + To change the name of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new email address. + + + + + + + Sets the users email address. + + + Note that setting an email address in the AccountsService is + not the same as configuring a mail client. Mail clients might + default to email address that is configured here, though. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own email address + + + org.freedesktop.accounts.user-administration + To change the email address of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new language, as a locale specification like "de_DE.UTF-8". + + + + + + + Sets the users language. + + + The expectation is that display managers will start the + users session with this locale. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own language + + + org.freedesktop.accounts.user-administration + To change the language of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + + The new xsession to start (e.g. "gnome") + + + + + + + Sets the users x session. + + + The expectation is that display managers will log the user in to this + specified session, if available. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own language + + + org.freedesktop.accounts.user-administration + To change the language of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new location as a freeform string. + + + + + + + Sets the users location. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own location + + + org.freedesktop.accounts.user-administration + To change the location of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new homedir as an absolute path. + + + + + + + Sets the users home directory. + + + Note that changing the users home directory moves all the content + from the old location to the new one, and is potentially an + expensive operation. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the home directory of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new user shell. + + + + + + + Sets the users shell. + + + Note that setting the shell to a non-allowed program may + prevent the user from logging in. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the shell of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The absolute filename of a png file to use as the users icon. + + + + + + + Sets the users icon. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own icon + + + org.freedesktop.accounts.user-administration + To change the icon of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + Whether to lock or unlock the users account. + + + + + + + Locks or unlocks a users account. + + + Locking an account prevents the user from logging in. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To lock or unlock user accounts + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new account type, encoded as an integer: + + + 0 + Standard user + + + 1 + Administrator + + + + + + + + + Changes the users account type. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change an account type + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new password mode, encoded as an integer: + + + 0 + Regular password + + + 1 + Password must be set at next login + + + 2 + No password + + + + + + + + + Changes the users password mode. + + + Note that changing the password mode has the side-effect of + unlocking the account. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change a users password mode + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The crypted password. + + + + + + + The password hint. + + + + + + + Sets a new password for this user. + + + Note that setting a password has the side-effect of + unlocking the account. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the password of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + Whether to enable automatic login for this user. + + + + + + + Enables or disables automatic login for a user. + + + Note that usually only one user can have automatic login + enabled, so turning it on for a user will disable it for + the previously configured autologin user. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.set-login-option + To change the login screen configuration + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + The uid of the user. + + + + + + + + + + The username of the user. + + + + + + + + + + The users real name. + + + + + + + + + + The users account type, encoded as an integer: + + + 0 + Standard user + + + 1 + Administrator + + + + + + + + + + + + The users home directory. + + + + + + + + + + The users shell. + + + + + + + + + + The email address. + + + + + + + + + + The users language, as a locale specification like "de_DE.UTF-8". + + + + + + + + + + The users x session. + + + + + + + + + + The users location. + + + + + + + + + + How often the user has logged in. + + + + + + + + + + The filename of a png file containing the users icon. + + + + + + + + + + Whether the users account is locked. + + + + + + + + + + The password mode for the user account, encoded as an integer: + + + 0 + Regular password + + + 1 + Password must be set at next login + + + 2 + No password + + + + + + + + + + + + The password hint for the user. + + + + + + + + + + Whether automatic login is enabled for the user. + + + + + + + + + + Whether this is a 'system' account, like 'root' or 'nobody'. + System accounts should normally not appear in lists of + users, and ListCachedUsers will not include such accounts. + + + + + + + + + + Emitted when the user is changed. + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.Accounts.xml b/src/backend-dbus/org.freedesktop.Accounts.xml new file mode 100644 index 0000000..9c19761 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.Accounts.xml @@ -0,0 +1,194 @@ + + + + + + + + + + Object paths of cached users + + + + + + Lists users which have logged into the system locally before. + This is not meant to return an exhaustive list of all users. + It is possible for FindUserByName() + to return a user that's not on the list. + + + + + + + + + The uid to look up + + + Object path of user + + + + + + Finds a user by uid. + + + + if no user with the given uid exists + + + + + + + + The username to look up + + + Object path of user + + + + + + Finds a user by its username. + + + + if no user with the given username exists + + + + + + + + The username for the new user + + + + The real name for the new user + + + Object path of the new user + + + + The account type, encoded as an integer + + + + + + Creates a new user account. + + + The accountType argument can take the following values: + + + + 0 + Standard user + + + 1 + Administrator + + + 2 + Supervised user + + + + + The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + The uid to delete + + + Whether to remove the users files + + + + + + Deletes a user account. + + + + The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + Object path of the user that was added. + + + + + Emitted when a user is added. + + + + + + + + Object path of the user that was deleted. + + + + + Emitted when a user is deleted. + + + + + + + + Object path of the user that was changed. + + + + + Emitted when a user is changed. + + + + + + + + + + The version of the running daemon. + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml new file mode 100644 index 0000000..f903b55 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml @@ -0,0 +1,353 @@ + + + + + + + + + This method initiates a request to restart (ie. reboot) the computer system. + + + + + + + + + + + + + + This method initiates a request to stop (ie. shutdown) the computer system. + + + + + + + + + + + + + + The secret cookie that is used to identify the new session + + + + + This method requests that a new Session + be created for the calling process. The properties of this new Session are set automatically + from information collected about the calling process. + + This new session exists until the calling process disconnects from the system bus or + calls CloseSession(). + + It is the responsibility of the calling process to set the environment variable + XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only + be made available to child processes of the caller so that they may be identified + as members of this session. + + See this simple example: + + DBusError error; + DBusMessage *message; + DBusMessage *reply; + + message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + "OpenSession"); + if (message == NULL) { + goto out; + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connector->connection, + message, + -1, + &error); + if (reply == NULL) { + goto out; + } + + dbus_error_init (&error); + if (! dbus_message_get_args (reply, + &error, + DBUS_TYPE_STRING, &cookie, + DBUS_TYPE_INVALID)) { + goto out; + } + + + + OpenSessionWithParameters() + + + + + + + An array of sets of property names and values + + + + + The secret cookie that is used to identify the new session + + + + + This method requests that a new Session + be created for the calling process. The properties of this new Session are from the + parameters provided. + + This new session exists until the calling process disconnects from the system bus or + calls CloseSession(). + + It is the responsibility of the calling process to set the environment variable + XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only + be made available to child processes of the caller so that they may be identified + as members of this session. + + See the Session properties for a list of valid parameters. + + org.freedesktop.ConsoleKit.Session + This method is restricted to privileged users by D-Bus policy. + + + + + + + The secret cookie that is used to identify the session + + + + + Whether the session was successfully closed + + + + + This method is used to close the session identified by the supplied cookie. + + The session can only be closed by the same process that opened the session. + + + + + + + + + an array of Seat IDs + + + + + This gets a list of all the Seats + that are currently present on the system. + Each Seat ID is an D-Bus object path for the object that implements the + Seat interface. + + org.freedesktop.ConsoleKit.Seat + + + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently present on the system. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + org.freedesktop.ConsoleKit.Session + + + + + + + + The secret cookie that is used to identify the session + + + + + The object identifier for the current session + + + + + Returns the session ID that is associated with the specified cookie. + + + + + + + + + The POSIX process ID + + + + + The object identifier for the current session + + + + + Attempts to determine the session ID for the specified + POSIX process ID (pid). + + + + + + + + + The object identifier for the current session + + + + + Attempts to determine the session ID that the caller belongs to. + + See this example of using dbus-send: + + dbus-send --system --dest=org.freedesktop.ConsoleKit \ + --type=method_call --print-reply --reply-timeout=2000 \ + /org/freedesktop/ConsoleKit/Manager \ + org.freedesktop.ConsoleKit.Manager.GetCurrentSession + + + + + + + + + POSIX User identification + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently open for the specified user. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + + + + + + + User identification + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently open for the specified user. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + + + + + + + + The value of the system-idle-hint + + + + + Returns TRUE if the idle-hint + property of every open session is TRUE or if there are no open sessions. + + + + + + + + An ISO 8601 format date-type string + + + + + Returns an ISO 8601 date-time string that corresponds to + the time of the last change of the system-idle-hint. + + + + + + + + + The Seat ID for the added seat + + + + + Emitted when a Seat has been added to the system. + + + + + + + + The Seat ID for the removed seat + + + + + Emitted when a Seat has been removed from the system. + + + + + + + + The value of the system-idle-hint + + + + + Emitted when the value of the system-idle-hint has changed. + + + + + + diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml new file mode 100644 index 0000000..58c2ce7 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml @@ -0,0 +1,164 @@ + + + + + + + A seat is a collection of sessions and a set of hardware (usually at +least a keyboard and mouse). Only one session may be active on a +seat at a time. + + + + + + + Seat ID + + + + + Returns the ID for Seat. + + + + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently attached to this seat. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + + + + + + + an array of devices + + + + + This gets a list of all the devices + that are currently associated with this seat. + Each device is an D-Bus structure that represents + the device type and the device id. + + + + + + + + + Session ID + + + + + Gets the Session ID that is currently active on this Seat. + Returns NULL if there is no active session. + + + + + + + + TRUE if seat supports session activation + + + + Used to determine whether the seat supports session activation. + + + + + + + + + Session ID + + + + + Attempt to activate the specified session. In most + cases, if successful, this will cause the session to + become visible and take control of the hardware that is + associated with this seat. + + Activate() + + + + + + + Session ID + + + + + Emitted when the active session has changed. + + + + + + + Session ID + + + + + Emitted when a session has been added to the seat. + + + + + + + Session ID + + + + + Emitted when a session has been removed from the seat. + + + + + + + Device structure + + + + + Emitted when a device has been associated with the seat. + + + + + + + Device structure + + + + + Emitted when a device has been dissociated from the seat. + + + + + diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml new file mode 100644 index 0000000..b6e1cdb --- /dev/null +++ b/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml @@ -0,0 +1,435 @@ + + + + + + + Session objects represent and store information + related to a user session. + + The properties associated with the Session + specifically refer to the properties of the "session leader". + + + + + + + Session ID + + + + Returns the ID for Session. + + + + + + + Seat ID + + + + Returns the ID for the Seat the Session is + attached to. + + org.freedesktop.ConsoleKit.Seat + + + + + + Session type + + + + + Returns the type of the session. + Warning: we haven't yet defined the allowed values for this property. + It is probably best to avoid this until we do. + + + session-type + + + + + + User ID + + + + Returns the user that the session belongs to. + + + user + + + + + + POSIX User ID + + + + Returns the POSIX user ID that the session belongs to. + + unix-user + + + + + + The value of the X11 display + + + + Returns the value of the X11 DISPLAY for this session + if one is present. + + x11-display + + + + + + The value of the X11 display device + + + + Returns the value of the display device (aka TTY) that the + X11 display for the session is connected to. If there is no x11-display set then this value + is undefined. + + x11-display-device + + + + + + The value of the display device + + + + Returns the value of the display device (aka TTY) that the + session is connected to. + + display-device + + + + + + The remote host name + + + + Returns the value of the remote host name for the session. + + + remote-host-name + + + + + + The value of the native system login session ID + + + + Returns the value of the login session ID that the + underlying system uses to enforce session boundaries. If there is no login session ID + set then this value is an empty string. + + + + + + + TRUE if the session is active, otherwise FALSE + + + + Returns whether the session is active on the Seat that + it is attached to. + If the session is not attached to a seat this value is undefined. + + + active + + + + + + TRUE if the session is local, otherwise FALSE + + + + Returns whether the session is local + FIXME: we need to come up with a concrete definition for this value. + It was originally used as a way to identify XDMCP sessions that originate + from a remote system. + + + is-local + + + + + + An ISO 8601 format date-type string + + + + + Returns an ISO 8601 date-time string that corresponds to + the time that the session was opened. + + + + + + + + + + Attempt to activate the this session. In most + cases, if successful, this will cause the session to + become visible and become active on the seat that it + is attached to. + + Seat.ActivateSession() + + + + + + + This will cause a Lock + signal to be emitted for this session. + + + This method is restricted to privileged users by D-Bus policy. + Lock signal + + + + + + + This will cause an Unlock + signal to be emitted for this session. + + This can be used by login managers to unlock a session before it is + re-activated during fast-user-switching. + + + This method is restricted to privileged users by D-Bus policy. + Unlock signal + + + + + + + The value of the idle-hint + + + + + Gets the value of the idle-hint + property. + + + idle-hint + + + + + + An ISO 8601 format date-type string + + + + + Returns an ISO 8601 date-time string that corresponds to + the time of the last change of the idle-hint. + + + + + + + + + boolean value to set the idle-hint to + + + + + This may be used by the session to indicate that + it is idle. + + Use of this method is restricted to the user + that owns the session. + + + + + + + + TRUE if the session is active, otherwise FALSE + + + + + Emitted when the active property has changed. + + + + + + + the new value of idle-hint + + + + + Emitted when the idle-hint property has changed. + + + + + + + Emitted in response to a call to the Lock() method. + It is intended that the screensaver for the session should lock the screen in response to this signal. + + + + + + + Emitted in response to a call to the Unlock() method. + It is intended that the screensaver for the session should unlock the screen in response to this signal. + + + + + + + + The user assigned to the session. + + + + + + + The user assigned to the session. + + + + + + + + The type of the session. + Warning: we haven't yet defined the allowed values for this property. + It is probably best to avoid this until we do. + + + + + + + + The remote host name for the session. + + This will be set in situations where the session is + opened and controlled from a remote system. + + For example, this value will be set when the + session is created from an SSH or XDMCP connection. + + + + + + + + The display device (aka TTY) that the + session is connected to. + + + + + + + + Value of the X11 DISPLAY for this session + if one is present. + + + + + + + + + The display device (aka TTY) that the X11 display for the + session is connected to. If there is no x11-display set then + this value is undefined. + + + + + + + + + Whether the session is active on the Seat that + it is attached to. + If the session is not attached to a seat this value is undefined. + + + + + + + + + Whether the session is local + FIXME: we need to come up with a concrete definition for this value. + It was originally used as a way to identify XDMCP sessions that originate + from a remote system. + + + + + + + + + This is a hint used to indicate that the session may be idle. + + + For sessions with a x11-display set (ie. graphical + sessions), it is up to each session to delegate the + responsibility for updating this value. Typically, the + screensaver will set this. + + However, for non-graphical sessions with a display-device set + the Session object itself will periodically update this value based + on the activity detected on the display-device itself. + + + This should not be considered authoritative. + + + + + + + diff --git a/src/backend-dbus/org.gnome.ScreenSaver.xml b/src/backend-dbus/org.gnome.ScreenSaver.xml new file mode 100644 index 0000000..c21fdc5 --- /dev/null +++ b/src/backend-dbus/org.gnome.ScreenSaver.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml b/src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml new file mode 100644 index 0000000..5392de0 --- /dev/null +++ b/src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml @@ -0,0 +1,53 @@ + + + + + + + + + The type of dialog to show. + 0 for logout, 1 for shutdown, 2 for restart. + + + + + + + Timestamp of the user-initiated event which triggered + the call, or 0 if the call was not triggered by an event. + + + + + + + The number of seconds which the dialog should stay open + before automatic action is taken. + + + + + + + The object paths of all inhibitors that are registered + for the action. + + + + + + This function opens a dialog which asks the user for confirmation + of a logout, poweroff or reboot action. The dialog has a timeout + after which the action is automatically taken, and it should show + the inhibitors to the user. + + + + + + + + + + diff --git a/src/backend-dbus/org.gnome.SessionManager.xml b/src/backend-dbus/org.gnome.SessionManager.xml new file mode 100644 index 0000000..eb69180 --- /dev/null +++ b/src/backend-dbus/org.gnome.SessionManager.xml @@ -0,0 +1,451 @@ + + + + + + + + + + + The variable name + + + + + The value + + + + + Adds the variable name to the application launch environment with the specified value. May only be used during the Session Manager initialization phase. + + + + + + + + The locale category + + + + + The value + + + + + Reads the current state of the specific locale category. + + + + + + + + The error message + + + + + Whether the error should be treated as fatal + + + + + May be used by applications launched during the Session Manager initialization phase to indicate there was a problem. + + + + + + + + + + + The application identifier + + + + + Client startup identifier + + + + + The object path of the newly registered client + + + + + Register the caller as a Session Management client. + + + + + + + + + The object path of the client + + + + + Unregister the specified client from Session Management. + + + + + + + + + The application identifier + + + + + The toplevel X window identifier + + + + + The reason for the inhibit + + + + + Flags that specify what should be inhibited + + + + + The cookie + + + + + Proactively indicates that the calling application is performing an action that should not be interrupted and sets a reason to be displayed to the user when an interruption is about to take placea. + + + Applications should invoke this method when they begin an operation that + should not be interrupted, such as creating a CD or DVD. The types of actions + that may be blocked are specified by the flags parameter. When the application + completes the operation it should call Uninhibit() + or disconnect from the session bus. + + + Applications should not expect that they will always be able to block the + action. In most cases, users will be given the option to force the action + to take place. + + + Reasons should be short and to the point. + + + The flags parameter must include at least one of the following: + + + 1 + Inhibit logging out + + + 2 + Inhibit user switching + + + 4 + Inhibit suspending the session or computer + + + 8 + Inhibit the session being marked as idle + + + 16 + Inhibit auto-mounting removable media for the session + + + Values for flags may be bitwise or'ed together. + + + The returned cookie is used to uniquely identify this request. It should be used + as an argument to Uninhibit() in + order to remove the request. + + + + + + + + + + The cookie + + + + + Cancel a previous call to Inhibit() identified by the cookie. + + + + + + + + Flags that spefify what should be inhibited + + + + + Returns TRUE if any of the operations in the bitfield flags are inhibited + + + + + Determine if operation(s) specified by the flags + are currently inhibited. Flags are same as those accepted + by the + Inhibit() + method. + + + + + + + + an array of client IDs + + + + + This gets a list of all the Clients + that are currently known to the session manager. + Each Client ID is an D-Bus object path for the object that implements the + Client interface. + + org.gnome.SessionManager.Client + + + + + + + an array of inhibitor IDs + + + + + This gets a list of all the Inhibitors + that are currently known to the session manager. + Each Inhibitor ID is an D-Bus object path for the object that implements the + Inhibitor interface. + + org.gnome.SessionManager.Inhibitor + + + + + + + + The autostart condition string + + + + + True if condition is handled, false otherwise + + + + + Allows the caller to determine whether the session manager is + handling changes to the specified autostart condition. + + + + + + + + Request a shutdown dialog. + + + + + + + + Request a reboot dialog. + + + + + + + + True if shutdown is available to the user, false otherwise + + + + + Allows the caller to determine whether or not it's okay to show + a shutdown option in the UI + + + + + + + + The type of logout that is being requested + + + + + Request a logout dialog + + Allowed values for the mode parameter are: + + + 0 + Normal. + + + 1 + No confirmation inferface should be shown. + + + 2 + Forcefully logout. No confirmation will be shown and any inhibitors will be ignored. + + + Values for flags may be bitwise or'ed together. + + + + + + + + + True if the session has entered the Running phase, false otherwise + + + + + Allows the caller to determine whether the session manager + has entered the Running phase, in case the client missed the + SessionRunning signal. + + + + + + + + + + The object path for the added client + + + + + Emitted when a client has been added to the session manager. + + + + + + + + The object path for the removed client + + + + + Emitted when a client has been removed from the session manager. + + + + + + + + + The object path for the added inhibitor + + + + + Emitted when an inhibitor has been added to the session manager. + + + + + + + + The object path for the removed inhibitor + + + + + Emitted when an inhibitor has been removed from the session manager. + + + + + + + + + Indicates the session has entered the Running phase. + + + + + + + + Indicates the session is about to end. + + + + + + + + + + The name of the session that has been loaded. + + + + + + + + If true, the session is currently in the + foreground and available for user input. + + + + + + + + A bitmask of flags to indicate which actions + are inhibited. See the Inhibit() function's description + for a list of possible values. + + + + + + diff --git a/src/backend-dbus/session-dbus.xml b/src/backend-dbus/session-dbus.xml new file mode 100644 index 0000000..96e9837 --- /dev/null +++ b/src/backend-dbus/session-dbus.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/upower.xml b/src/backend-dbus/upower.xml new file mode 100644 index 0000000..18d5fbd --- /dev/null +++ b/src/backend-dbus/upower.xml @@ -0,0 +1,309 @@ + + + + + + + + The DeviceKit-power service is available via the system message + bus. To access the service, use + the org.freedesktop.UPower interface on + the /org/freedesktop/UPower object on + the D-Bus system bus service with the well-known + name org.freedesktop.UPower. + + + + +$ dbus-send --print-reply \ + --system \ + --dest=org.freedesktop.UPower \ + /org/freedesktop/UPower \ + org.freedesktop.UPower.EnumerateDevices + +method return sender=:1.386 -> dest=:1.451 reply_serial=2 + array [ + object path "/org/freedesktop/UPower/devices/line_power_AC" + object path "/org/freedesktop/UPower/devices/battery_BAT0" + ] + + + + + + + + + + + + An array of object paths for devices. + + + + + + Enumerate all power objects on the system. + + + + + + + + + + Object path of device that was added. + + + + + + Emitted when a device is added. + + + + + + + + + + Object path of device that was removed. + + + + + + Emitted when a device is removed. + + + + + + + + + + Object path of device that was changed. + + + + + + Emitted when a device changed. + + + + + + + + + + + + Emitted when one or more properties on the object changes. + + + + + + + + + + + + This signal is sent when the session is about to be suspended or + hibernated. + Session and system programs have one second to do anything required + before the sleep action is taken (such as sending out Avahi or + Jabber messages). + + + + + + + + + + + + This signal is sent when the session has just returned from + Suspend() or Hibernate(). + Session and system programs can then do anything required (such as + sending out Avahi or Jabber messages). + + + + + + + + + + + + + This method tells UPower that the Suspend() or Hibernate() method + is about to be called. + This allows UPower to emit the Suspending signal whilst + session activities are happening that have to be done before the + suspend process is started. + + + This method would typically be called by the session power + management daemon, before it locks the screen and waits for the + screen to fade to black. + The session power management component would then call Suspend() or + Hibernate() when these syncronous tasks have completed. + + + If this method is not called than nothing bad will happen and + Suspend() or Hibernate() will block for the required second. + + + + + + + + + + + + + Suspends the computer into a low power state. + System state is not preserved if the power is lost. + + + If AboutToRequestSleep() has not been called then UPower will send + the Sleeping() signal and block for one second. + + + If AboutToRequestSleep() has been called less than one second + before this method is called then UPower will block for the + remaining time to complete one second of delay. + + + + + + + + + + + TRUE if allowed, otherwise FALSE + + + + + Check if the caller has (or can get) the PolicyKit privilege to call + Suspend. + + + + + + + + + + + + + Hibernates the computer into a low power state. + System state is preserved if the power is lost. + + + If AboutToRequestSleep() has not been called then UPower will send + the Sleeping() signal and block for one second. + + + If AboutToRequestSleep() has been called less than one second + before this method is called then UPower will block for the + remaining time to complete one second of delay. + + + + + + + + + + + TRUE if allowed, otherwise FALSE + + + + + Check if the caller has (or can get) the PolicyKit privilege to call + Hibernate. + + + + + + + + + + Version of the running daemon, e.g. 002. + + + + + + Whether the system is able to suspend. + + + + + + Whether the system is able to hibernate. + + + + + + Indicates whether the system is running on battery power. + This property is provided for convenience. + + + + + + Indicates whether the system is running on battery power and if the battery is critically low. + This property is provided for convenience. + + + + + + + + Indicates if the laptop lid is closed where the display cannot be seen. + + + + + + + + + + If the system has a lid device. + + + + + + + + diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c new file mode 100644 index 0000000..4798d33 --- /dev/null +++ b/src/backend-dbus/users.c @@ -0,0 +1,810 @@ +/* + * 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 "dbus-accounts.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-consolekit-manager.h" +#include "dbus-user.h" + +#include "users.h" + +struct _IndicatorSessionUsersDbusPriv +{ + char * active_session_id; + + Accounts * accounts; + + DisplayManagerSeat * dm_seat; + + ConsoleKitSeat * seat_proxy; + + /* user's dbus object path -> AccountsUser* */ + GHashTable * path_to_user; + + /* uint32 user-id --> user's dbus object path */ + GHashTable * uid_to_user_path; + + /* uint32 user-id --> hashset of ssid strings */ + GHashTable * uid_to_sessions; + + /* ssid string --> uint32 user-id */ + GHashTable * session_to_uid; + + GCancellable * cancellable; +}; + +typedef IndicatorSessionUsersDbusPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionUsersDbus, + indicator_session_users_dbus, + INDICATOR_TYPE_SESSION_USERS) + +/*** +**** +***/ + +static void create_user_proxy_for_path (IndicatorSessionUsersDbus * self, + const char * path); + +static void create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, + const char * ssid); + +static void +emit_user_changed_for_path (IndicatorSessionUsersDbus * self, const char * path) +{ + AccountsUser * user = g_hash_table_lookup (self->priv->path_to_user, path); + + if (user && !accounts_user_get_system_account (user)) + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), path); +} + +static void +emit_user_changed_for_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + const char * path; + + if ((path = g_hash_table_lookup (self->priv->uid_to_user_path, GUINT_TO_POINTER(uid)))) + emit_user_changed_for_path (self, path); +} + +/*** +**** ACCOUNT MANAGER / USER TRACKING +***/ + +/* called when a user proxy gets the 'Changed' signal */ +static void +on_user_changed (AccountsUser * user, gpointer gself) +{ + /* Accounts.User doesn't update properties in the standard way, + * so create a new proxy to pull in the new properties. + * The older proxy is freed when it's removed from our path_to_user hash */ + const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); + create_user_proxy_for_path (gself, path); +} + +static void +track_user (IndicatorSessionUsersDbus * self, + AccountsUser * user) +{ + priv_t * p; + const char * path; + gboolean already_had_user; + + p = self->priv; + + path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); + already_had_user = g_hash_table_contains (p->path_to_user, path); + + g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); + g_hash_table_insert (p->path_to_user, g_strdup(path), user); + + if (already_had_user) + { + emit_user_changed_for_path (self, path); + } + else + { + const guint uid = (guint) accounts_user_get_uid (user); + + g_hash_table_insert (p->uid_to_user_path, + GUINT_TO_POINTER(uid), + g_strdup(path)); + + if (!accounts_user_get_system_account (user)) + indicator_session_users_added (INDICATOR_SESSION_USERS(self), path); + } +} + +static void +untrack_user (IndicatorSessionUsersDbus * self, + const gchar * path) +{ + g_hash_table_remove (self->priv->path_to_user, path); + + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), path); +} + + +static void +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer self) +{ + GError * err; + AccountsUser * user; + + err = NULL; + user = accounts_user_proxy_new_for_bus_finish (res, &err); + if (err != NULL) + { + g_warning ("%s: %s", G_STRFUNC, err->message); + g_error_free (err); + } + else + { + track_user (self, user); + } +} + +static void +create_user_proxy_for_path (IndicatorSessionUsersDbus * self, + const char * path) +{ + const char * name = "org.freedesktop.Accounts"; + const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + + accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, path, + self->priv->cancellable, + on_user_proxy_ready, self); +} + +static void +on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar ** paths; + + err = NULL; + paths = NULL; + accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + int i; + + for (i=0; paths && paths[i]; ++i) + create_user_proxy_for_path (gself, paths[i]); + + g_strfreev (paths); + } +} + +static void +set_account_manager (IndicatorSessionUsersDbus * self, Accounts * a) +{ + priv_t * p = self->priv; + + if (p->accounts != NULL) + { + g_signal_handlers_disconnect_by_data (p->accounts, self); + g_clear_object (&p->accounts); + } + + if (a != NULL) + { + p->accounts = g_object_ref (a); + + accounts_call_list_cached_users (a, + self->priv->cancellable, + on_user_list_ready, + self); + + g_signal_connect_swapped (a, "user-added", + G_CALLBACK(create_user_proxy_for_path), self); + + g_signal_connect_swapped (a, "user-deleted", + G_CALLBACK(untrack_user), self); + } +} + +#if 0 +static void +create_accounts_proxy (IndicatorSessionUsersDbus * self) +{ + const char * name = "org.freedesktop.Accounts"; + const char * path = "/org/freedesktop/Accounts"; + GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + + accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, path, + self->priv->cancellable, + on_accounts_proxy_ready, self); +} +#endif + +/** + * SEAT / SESSION TRACKING + * + * There are two simple goals here: + * + * 1. Keep track of how many GUI sessions each user has + * so that we can set the 'is_logged_in' flag correctly + * + * 2. Also track which is the current session, + * so that we can compare it to those GUI sessions to + * set the 'is_current_session' flag correctly. + * + * Now that you know the goals, these steps may make more sense: + * + * 1. create a ConsoleKitManager proxy + * 2. ask it for the current session + * 3. create a corresponding Session proxy + * 4. ask that Session proxy for its seat + * 5. create a corresponding Seat proxy + * 6. connect to that seat's session-added / session-removed signals + * 7. ask the seat for a list of its current sessions + * 8. create corresponding Session proxies + * 9. of them, look for the GUI sessions by checking their X11 properties + * 10. for each GUI session, get the corresponding uid + * 11. use the information to update our uid <--> GUI sessions tables + */ + +static void +track_session (IndicatorSessionUsersDbus * self, + const char * ssid, + guint uid) +{ + gpointer uid_key; + GHashTable * sessions; + + uid_key = GUINT_TO_POINTER (uid); + sessions = g_hash_table_lookup (self->priv->uid_to_sessions, uid_key); + if (sessions == NULL) + { + sessions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_hash_table_insert (self->priv->uid_to_sessions, uid_key, sessions); + } + + g_hash_table_add (sessions, g_strdup (ssid)); + g_hash_table_insert (self->priv->session_to_uid, g_strdup(ssid), uid_key); + + g_debug ("%s %s now tracking ssid:%s uid:%u. uid has %u tracked ssids.", + G_STRLOC, G_STRFUNC, ssid, uid, g_hash_table_size (sessions)); + + emit_user_changed_for_uid (self, uid); +} + +static void +untrack_session (IndicatorSessionUsersDbus * self, + const char * ssid) +{ + gpointer uidptr; + priv_t * p = self->priv; + + if (g_hash_table_lookup_extended (p->session_to_uid, ssid, NULL, &uidptr)) + { + const guint uid = GPOINTER_TO_UINT (uidptr); + GHashTable * sessions = g_hash_table_lookup (p->uid_to_sessions, uidptr); + + g_hash_table_remove (p->session_to_uid, ssid); + g_hash_table_remove (sessions, ssid); + g_debug ("%s %s not tracking ssid:%s uid:%u. uid has %u tracked ssids.", + G_STRLOC, G_STRFUNC, ssid, uid, + sessions ? g_hash_table_size (sessions) : 0); + + emit_user_changed_for_uid (self, uid); + } +} + +static void +on_session_proxy_uid_ready (GObject * o, + GAsyncResult * res, + gpointer gself) +{ + guint uid; + GError * err; + ConsoleKitSession * session = CONSOLE_KIT_SESSION (o); + + uid = 0; + err = NULL; + console_kit_session_call_get_unix_user_finish (session, &uid, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else if (uid) + { + const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(session)); + track_session (gself, path, uid); + } + + g_object_unref (o); +} + +static void +on_session_x11_display_ready (GObject * o, + GAsyncResult * res, + gpointer gself) +{ + priv_t * p; + GError * err; + gchar * gui; + ConsoleKitSession * session; + + p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; + + err = NULL; + gui = NULL; + session = CONSOLE_KIT_SESSION (o); + console_kit_session_call_get_x11_display_finish (session, &gui, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + gboolean is_gui_session; + + is_gui_session = gui && *gui; + + if (!is_gui_session) + g_clear_object (&session); + else + console_kit_session_call_get_unix_user (session, + p->cancellable, + on_session_proxy_uid_ready, + gself); + + g_free (gui); + } +} + +static void +on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + ConsoleKitSession * session; + + err = NULL; + session = console_kit_session_proxy_new_finish (res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else if (session != NULL) + { + priv_t * p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; + + console_kit_session_call_get_x11_display (session, + p->cancellable, + on_session_x11_display_ready, + gself); + } +} + +static void +create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, + const char * ssid) +{ + const char * name = "org.freedesktop.ConsoleKit"; + GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + + console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, ssid, + self->priv->cancellable, + on_session_proxy_ready, self); +} + +static void +on_session_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar ** sessions; + + err = NULL; + sessions = NULL; + console_kit_seat_call_get_sessions_finish (CONSOLE_KIT_SEAT(o), + &sessions, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + int i; + + for (i=0; sessions && sessions[i]; i++) + create_session_proxy_for_ssid (gself, sessions[i]); + + g_strfreev (sessions); + } +} + +static inline guint +get_uid_for_session (IndicatorSessionUsersDbus * self, const char * ssid) +{ + guint uid = 0; + gpointer value; + + if (ssid != NULL) + if ((value = g_hash_table_lookup (self->priv->session_to_uid, ssid))) + uid = GPOINTER_TO_UINT (value); + + return uid; +} + +/* it's a live session if username is 'ubuntu' and uid is 999 */ +static gboolean +is_live_ssid (IndicatorSessionUsersDbus * self, const char * ssid) +{ + priv_t * p; + guint uid; + + p = INDICATOR_SESSION_USERS_DBUS (self)->priv; + uid = get_uid_for_session (self, ssid); + + if (uid == 999) + { + const char * path; + AccountsUser * user = NULL; + + if ((path = g_hash_table_lookup (p->uid_to_user_path, GUINT_TO_POINTER (uid)))) + user = g_hash_table_lookup (p->path_to_user, path); + + return (user != NULL) && !g_strcmp0 (accounts_user_get_user_name(user), "ubuntu"); + } + + return FALSE; +} + + +static void +set_active_session (IndicatorSessionUsersDbus * self, const char * ssid) +{ + priv_t * p = self->priv; + const guint old_uid = get_uid_for_session (self, p->active_session_id); + const guint new_uid = get_uid_for_session (self, ssid); + const gboolean old_live = is_live_ssid (self, p->active_session_id); + const gboolean new_live = is_live_ssid (self, ssid); + + g_debug ("%s %s changing active_session_id from '%s' to '%s'", + G_STRLOC, G_STRFUNC, p->active_session_id, ssid); + g_free (p->active_session_id); + p->active_session_id = g_strdup (ssid); + + if (old_uid != new_uid) + { + emit_user_changed_for_uid (self, old_uid); + emit_user_changed_for_uid (self, new_uid); + } + + if (old_live != new_live) + { + indicator_session_users_notify_is_live_session (INDICATOR_SESSION_USERS(self)); + } +} + +static void +on_seat_active_session_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar * ssid; + ConsoleKitSeat * seat; + + err = NULL; + ssid = NULL; + seat = CONSOLE_KIT_SEAT (o); + console_kit_seat_call_get_active_session_finish (seat, &ssid, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else if (ssid != NULL) + { + set_active_session (INDICATOR_SESSION_USERS_DBUS(gself), ssid); + g_free (ssid); + } +} + +static void +set_seat (IndicatorSessionUsersDbus * self, ConsoleKitSeat * seat) +{ + priv_t * p = self->priv; + + if (p->seat_proxy != NULL) + { + g_signal_handlers_disconnect_by_data (p->seat_proxy, self); + g_clear_object (&p->seat_proxy); + } + + if (seat != NULL) + { + p->seat_proxy = g_object_ref (seat); + + /* ask the seat for a list of all the sessions */ + console_kit_seat_call_get_sessions (seat, + p->cancellable, + on_session_list_ready, + self); + + /* ask the seat for the name of the active session */ + console_kit_seat_call_get_active_session (p->seat_proxy, + p->cancellable, + on_seat_active_session_ready, + self); + + /* listen for session changes in this seat */ + g_signal_connect_swapped (seat, "session-added", + G_CALLBACK(create_session_proxy_for_ssid),self); + g_signal_connect_swapped (seat, "session-removed", + G_CALLBACK(untrack_session), self); + g_signal_connect_swapped (seat, "active-session-changed", + G_CALLBACK(set_active_session), self); + } +} + +/*** +**** +***/ + +static void +set_dm_seat (IndicatorSessionUsersDbus * self, DisplayManagerSeat * dm_seat) +{ + priv_t * p = self->priv; + + g_clear_object (&p->dm_seat); + + if (dm_seat != NULL) + p->dm_seat = g_object_ref (dm_seat); +} + +static void +activate_username (IndicatorSessionUsersDbus * self, const char * username) +{ + priv_t * p = self->priv; + const char * session = ""; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_user (p->dm_seat, username, session, + p->cancellable, NULL, NULL); +} + +/*** +**** +***/ + +static void +my_dispose (GObject * o) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + priv_t * p = self->priv; + + if (p->cancellable) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + + set_seat (self, NULL); + set_dm_seat (self, NULL); + set_account_manager (self, NULL); + + g_clear_pointer (&p->path_to_user, g_hash_table_destroy); + g_clear_pointer (&p->session_to_uid, g_hash_table_destroy); + g_clear_pointer (&p->uid_to_sessions, g_hash_table_destroy); + g_clear_pointer (&p->uid_to_user_path, g_hash_table_destroy); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + IndicatorSessionUsersDbus * u = INDICATOR_SESSION_USERS_DBUS (o); + + g_free (u->priv->active_session_id); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->finalize (o); +} + +static void +my_activate_user (IndicatorSessionUsers * users, const char * key) +{ + priv_t * p; + const char * username = 0; + + p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + if (p != 0) + { + AccountsUser * au = g_hash_table_lookup (p->path_to_user, key); + + if (au != NULL) + username = accounts_user_get_user_name (au); + } + + if (username != 0) + activate_username (INDICATOR_SESSION_USERS_DBUS(users), username); + else + g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, key); +} + +static gboolean +my_is_live_session (IndicatorSessionUsers * users) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); + + return is_live_ssid (self, self->priv->active_session_id); +} + +static GStrv +my_get_keys (IndicatorSessionUsers * users) +{ + int i; + priv_t * p; + gchar ** keys; + GHashTableIter iter; + gpointer path; + gpointer user; + + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); + p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + + i = 0; + keys = g_new (gchar*, g_hash_table_size(p->path_to_user)+1); + g_hash_table_iter_init (&iter, p->path_to_user); + while (g_hash_table_iter_next (&iter, &path, &user)) + if (!accounts_user_get_system_account (user)) + keys[i++] = g_strdup (path); + keys[i] = NULL; + + return keys; +} + +static IndicatorSessionUser * +my_get_user (IndicatorSessionUsers * users, const gchar * key) +{ + priv_t * p; + AccountsUser * au; + IndicatorSessionUser * ret = NULL; + + p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + + au = g_hash_table_lookup (p->path_to_user, key); + if (au && !accounts_user_get_system_account(au)) + { + const guint uid = (guint) accounts_user_get_uid (au); + GHashTable * s; + + ret = g_new0 (IndicatorSessionUser, 1); + + s = g_hash_table_lookup (p->uid_to_sessions, GUINT_TO_POINTER(uid)); + if (s == NULL) + { + ret->is_logged_in = FALSE; + ret->is_current_user = FALSE; + } + else + { + ret->is_logged_in = g_hash_table_size (s) > 0; + ret->is_current_user = g_hash_table_contains (s, p->active_session_id); + } + + ret->uid = uid; + ret->user_name = g_strdup (accounts_user_get_user_name (au)); + ret->real_name = g_strdup (accounts_user_get_real_name (au)); + ret->icon_file = g_strdup (accounts_user_get_icon_file (au)); + ret->login_frequency = accounts_user_get_login_frequency (au); + } + + return ret; +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionUsersClass * users_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + users_class = INDICATOR_SESSION_USERS_CLASS (klass); + users_class->is_live_session = my_is_live_session; + users_class->get_keys = my_get_keys; + users_class->get_user = my_get_user; + users_class->activate_user = my_activate_user; + + g_type_class_add_private (klass, sizeof (IndicatorSessionUsersDbusPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) +{ + priv_t * p; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_USERS_DBUS, + IndicatorSessionUsersDbusPriv); + self->priv = p; + p->cancellable = g_cancellable_new (); + + p->path_to_user = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_object_unref); + + p->uid_to_user_path = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, g_free); + + p->session_to_uid = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + + p->uid_to_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, + (GDestroyNotify)g_hash_table_destroy); + +#if 0 + console_kit_manager_proxy_new_for_bus ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + p->cancellable, + on_console_kit_manager_proxy_ready, + self); +#endif +} + +/*** +**** Public +***/ + +IndicatorSessionUsers * +indicator_session_users_dbus_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_USERS_DBUS, NULL); + + return INDICATOR_SESSION_USERS (o); +} + +void +indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus * self, + Accounts * accounts, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * seat) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS_DBUS (self)); + + set_account_manager (self, accounts); + set_seat (self, seat); + set_dm_seat (self, dm_seat); +} diff --git a/src/backend-dbus/users.h b/src/backend-dbus/users.h new file mode 100644 index 0000000..ff1e0ad --- /dev/null +++ b/src/backend-dbus/users.h @@ -0,0 +1,71 @@ +/* + * 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 . + */ + +#ifndef __USERS_DBUS_H__ +#define __USERS_DBUS_H__ + +#include +#include + +#include "../users.h" /* parent class */ +#include "dbus-accounts.h" +#include "dbus-consolekit-seat.h" +#include "dbus-display-manager.h" + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_USERS_DBUS (indicator_session_users_dbus_get_type()) +#define INDICATOR_SESSION_USERS_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_USERS_DBUS, IndicatorSessionUsersDbus)) +#define INDICATOR_SESSION_USERS_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_USERS_DBUS, IndicatorSessionUsersDbusClass)) +#define INDICATOR_IS_SESSION_USERS_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_USERS_DBUS)) + +typedef struct _IndicatorSessionUsersDbus IndicatorSessionUsersDbus; +typedef struct _IndicatorSessionUsersDbusPriv IndicatorSessionUsersDbusPriv; +typedef struct _IndicatorSessionUsersDbusClass IndicatorSessionUsersDbusClass; + +/** + * An implementation of IndicatorSessionUsers that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionUsersDbus +{ + /*< private >*/ + IndicatorSessionUsers parent; + IndicatorSessionUsersDbusPriv * priv; +}; + +struct _IndicatorSessionUsersDbusClass +{ + IndicatorSessionUsersClass parent_class; +}; + +GType indicator_session_users_dbus_get_type (void); + +IndicatorSessionUsers * indicator_session_users_dbus_new (void); + +void indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus *, + Accounts *, + DisplayManagerSeat *, + ConsoleKitSeat *); + + + +G_END_DECLS + +#endif diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c new file mode 100644 index 0000000..86a5e5a --- /dev/null +++ b/src/backend-dbus/utils.c @@ -0,0 +1,399 @@ +/* + * 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 "utils.h" + +/*** +**** indicator_session_util_get_session_proxies() +***/ + +struct session_proxy_data +{ + ConsoleKitManager * ck_manager; + Accounts * account_manager; + DisplayManagerSeat * dm_seat; + + ConsoleKitSeat * current_seat; + ConsoleKitSession * current_session; + AccountsUser * active_user; + + GCancellable * cancellable; + GError * error; + int pending; + + indicator_session_util_session_proxies_func callback; + gpointer user_data; +}; + +static void +session_proxy_data_free (struct session_proxy_data * data) +{ + g_clear_object (&data->ck_manager); + g_clear_object (&data->account_manager); + g_clear_object (&data->dm_seat); + + g_clear_object (&data->current_seat); + g_clear_object (&data->current_session); + g_clear_object (&data->active_user); + + g_clear_object (&data->cancellable); + g_clear_error (&data->error); + + g_free (data); +} + +static void +finish_callback (struct session_proxy_data * data) +{ + g_assert (data != NULL); + g_debug ("%s %s: pending is %d", G_STRLOC, G_STRFUNC, (data->pending-1)); + + if (!--data->pending) + { + data->callback (data->ck_manager, + data->account_manager, + data->dm_seat, + data->current_seat, + data->current_session, + data->active_user, + data->error, + data->user_data); + + session_proxy_data_free (data); + } +} + +static void +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + data->active_user = accounts_user_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else + { + g_debug ("%s %s user proxy is %p", G_STRLOC, G_STRFUNC, (void*)data->active_user); + } + + finish_callback (data); +} + +static void +on_user_path_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + char * path = NULL; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + accounts_call_find_user_by_id_finish (data->account_manager, &path, res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (path != NULL) + { + g_debug ("%s %s user path is %s", G_STRLOC, G_STRFUNC, path); + ++data->pending; + accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.Accounts", + path, + data->cancellable, + on_user_proxy_ready, + data); + } + + finish_callback (data); + g_free (path); +} + +static void +on_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + guint uid = 0; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + console_kit_session_call_get_unix_user_finish (data->current_session, &uid, res, &data->error); + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (uid) + { + g_debug ("%s %s uid is %u", G_STRLOC, G_STRFUNC, uid); + ++data->pending; + accounts_call_find_user_by_id (data->account_manager, + uid, + data->cancellable, + on_user_path_ready, + data); + } + + finish_callback (data); +} + +static void +on_seat_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + data->current_seat = console_kit_seat_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + + finish_callback (data); +} + +static void +on_sid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + char * sid = NULL; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + console_kit_session_call_get_seat_id_finish (data->current_session, &sid, res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (sid != NULL) + { + g_debug ("%s %s sid is %s", G_STRLOC, G_STRFUNC, sid); + ++data->pending; + console_kit_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + sid, + data->cancellable, + on_seat_proxy_ready, + data); + } + + finish_callback (data); + g_free (sid); +} + +static void +on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + data->current_session = console_kit_session_proxy_new_finish (res, &data->error); + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else + { + ++data->pending; + console_kit_session_call_get_seat_id (data->current_session, + data->cancellable, + on_sid_ready, + data); + + ++data->pending; + console_kit_session_call_get_unix_user (data->current_session, + data->cancellable, + on_uid_ready, + data); + } + + finish_callback (data); +} + +static void +on_current_session_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + char * ssid = NULL; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + ssid = NULL; + console_kit_manager_call_get_current_session_finish (data->ck_manager, + &ssid, res, + &data->error); + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (ssid) + { + g_debug ("%s %s ssid is %s", G_STRLOC, G_STRFUNC, ssid); + data->pending++; + console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + ssid, + data->cancellable, + on_session_proxy_ready, + data); + + } + + finish_callback (data); + g_free (ssid); +} + +static void +on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) +{ + DisplayManagerSeat * seat; + struct session_proxy_data * data = gdata; + + seat = display_manager_seat_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (seat != NULL) + { + data->dm_seat = g_object_ref (seat); + } + + finish_callback (data); + g_clear_object (&seat); +} + +static void +on_console_kit_manager_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) +{ + ConsoleKitManager * mgr; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + if (data->error == NULL) + { + mgr = console_kit_manager_proxy_new_for_bus_finish (res, &data->error); + g_debug ("%s %s mgr is %p, err is %p", G_STRLOC, G_STRFUNC, (void*)mgr, (void*)data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else + { + data->ck_manager = mgr; + + data->pending++; + console_kit_manager_call_get_current_session (mgr, + data->cancellable, + on_current_session_ready, + data); + + } + } + + finish_callback (data); +} + +static void +on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + if (data->error == NULL) + { + data->account_manager = accounts_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + + finish_callback (data); +} + +/** + * Getting all the proxies we want is kind of a pain -- + * especially without blocking (ie, using _sync() funcs) -- + * so it's farmed out to this wrapper utility. + * + * 1. in this func, start getting the ConsoleKit and Accounts proxies + * 2. when the accounts proxy is ready, stash it in data.account_manager + * 3. when the ck manager proxy is ready, stash it in data.ck_manager and + * ask it for the current session's ssid + * 4. when the ssid is ready, start getting a proxy for it + * 5. when the session's proxy is ready, stash it in data.current_session + * and ask it for both the current seat's sid and the active user's uid + * 6. When the current seat's sid is ready, start getting a proxy for it + * 7. When the current seat's proxy is ready, stash it in data.current_seat + * 8. when the active user's uid is ready, ask data.account_manager for the path + * 9. when the user path is ready, start getting an Accounts.User proxy for it + * 10. when the Accounts.User proxy is read, stash it in data.active_user + * + * When everything is done, or if there's an error, invoke the data.callback + */ +void +indicator_session_util_get_session_proxies ( + indicator_session_util_session_proxies_func func, + GCancellable * cancellable, + gpointer user_data) +{ + struct session_proxy_data * data; + + data = g_new0 (struct session_proxy_data, 1); + data->callback = func; + data->user_data = user_data; + data->cancellable = g_object_ref (cancellable); + + data->pending++; + accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.Accounts", + "/org/freedesktop/Accounts", + data->cancellable, + on_accounts_proxy_ready, data); + + data->pending++; + console_kit_manager_proxy_new_for_bus ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + data->cancellable, + on_console_kit_manager_proxy_ready, data); + + data->pending++; + display_manager_seat_proxy_new_for_bus ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.DisplayManager", + g_getenv ("XDG_SEAT_PATH"), + data->cancellable, + on_display_manager_seat_proxy_ready, data); + +} diff --git a/src/backend-dbus/utils.h b/src/backend-dbus/utils.h new file mode 100644 index 0000000..b4f26c3 --- /dev/null +++ b/src/backend-dbus/utils.h @@ -0,0 +1,53 @@ +/* + * 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 . + */ + +#ifndef __DBUS_UTILS_H__ +#define __DBUS_UTILS_H__ + +#include +#include + +#include "dbus-accounts.h" +#include "dbus-display-manager.h" +#include "dbus-user.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-consolekit-manager.h" + +typedef void (*indicator_session_util_session_proxies_func)( + ConsoleKitManager * ck_manager, + Accounts * account_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * current_ck_seat, + ConsoleKitSession * current_ck_session, + AccountsUser * active_user, + const GError * error, + gpointer user_data); + +/** + * Both users-dbus and guest-dbus need some of these proxies. + * Getting them all involves a lot of steps, so instead of repeating + * ourselves, the common dbus steps are extracted to this func. + */ +void indicator_session_util_get_session_proxies ( + indicator_session_util_session_proxies_func func, + GCancellable * cancellable, + gpointer user_data); + +#endif diff --git a/src/backend.h b/src/backend.h new file mode 100644 index 0000000..2df215d --- /dev/null +++ b/src/backend.h @@ -0,0 +1,47 @@ +/* + * 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 . + */ + +#ifndef __INDICATOR_SESSION_BACKEND_H__ +#define __INDICATOR_SESSION_BACKEND_H__ + +#include /* GCancellable */ + +#include "actions.h" +#include "guest.h" +#include "users.h" + +G_BEGIN_DECLS + +/** + * Gets instances of the backend abstract base classes. + * These are how IndicatorSystemService knows what's happening on the system. + * + * This function isn't defined in libindicatorsessionservice. + * Instead, one of two implementations is statically linked at build time: + * one for production in libbackenddbus (in src/backend-dbus/) or + * one for testing in libbackendmock (in tests/). + */ +void backend_get (GCancellable * cancellable, + IndicatorSessionActions ** setme_actions, + IndicatorSessionUsers ** setme_users, + IndicatorSessionGuest ** setme_guest); + +G_END_DECLS + +#endif diff --git a/src/dialog.c b/src/dialog.c deleted file mode 100644 index eb91f57..0000000 --- a/src/dialog.c +++ /dev/null @@ -1,248 +0,0 @@ -/* -A dialog to ask the user about the various logout options that -are available. - -Copyright 2010 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 . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "dbus-consolekit-manager.h" -#include "dialog.h" - -/* Strings */ - -static const gchar * title_strings[LOGOUT_DIALOG_TYPE_CNT] = { - /* LOGOUT_DIALOG_LOGOUT, */ NC_("title", "Log Out"), - /* LOGOUT_DIALOG_RESTART, */ NC_("title", "Restart"), - /* LOGOUT_DIALOG_SHUTDOWN, */ NC_("title", "Shut Down") -}; - -static const gchar * body_strings[LOGOUT_DIALOG_TYPE_CNT] = { - /* LOGOUT_DIALOG_LOGOUT, */ N_("Are you sure you want to close all programs and log out of the computer?"), - /* LOGOUT_DIALOG_RESTART, */ N_("Are you sure you want to close all programs and restart the computer?"), - /* LOGOUT_DIALOG_SHUTDOWN, */ N_("Are you sure you want to close all programs and shut down the computer?") -}; - -static const gchar * button_strings[LOGOUT_DIALOG_TYPE_CNT] = { - /* LOGOUT_DIALOG_LOGOUT, */ NC_("button", "Log Out"), - /* LOGOUT_DIALOG_RESTART, */ NC_("button", "Restart"), - /* LOGOUT_DIALOG_SHUTDOWN, */ NC_("button", "Shut Down") -}; - -/* TRANSLATORS: These strings have an ellipsis so that the user knows - they are also going to get a password dialog to do the action. */ -static const gchar * button_auth_strings[LOGOUT_DIALOG_TYPE_CNT] = { - /* LOGOUT_DIALOG_LOGOUT, */ NC_("button auth", "Log Out"), - /* LOGOUT_DIALOG_RESTART, */ NC_("button auth", "Restart…"), - /* LOGOUT_DIALOG_SHUTDOWN, */ NC_("button auth", "Shut Down…") -}; - -/* TRANSLATORS: This button appears on the logout dialog when - there are updates that require restart. It will do a restart - in place of a log out. */ -static const gchar * restart_updates = N_("Restart Instead"); -static const gchar * restart_auth = N_("Restart Instead…"); -static const gchar * body_logout_update = N_("Some software updates won’t apply until the computer next restarts."); - -static const gchar * icon_strings[LOGOUT_DIALOG_TYPE_CNT] = { - /* LOGOUT_DIALOG_LOGOUT, */ "system-log-out", - /* LOGOUT_DIALOG_RESTART, */ "system-restart", - /* LOGOUT_DIALOG_SHUTDOWN, */ "system-shutdown" -}; - - - -typedef struct _LogoutDialogPrivate LogoutDialogPrivate; -struct _LogoutDialogPrivate { - guint type; -}; - -#define LOGOUT_DIALOG_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), LOGOUT_DIALOG_TYPE, LogoutDialogPrivate)) - -static void logout_dialog_class_init (LogoutDialogClass *klass); -static void logout_dialog_init (LogoutDialog *self); -static void logout_dialog_dispose (GObject *object); -static void logout_dialog_finalize (GObject *object); - -G_DEFINE_TYPE (LogoutDialog, logout_dialog, GTK_TYPE_MESSAGE_DIALOG); - -static void -logout_dialog_class_init (LogoutDialogClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (LogoutDialogPrivate)); - - object_class->dispose = logout_dialog_dispose; - object_class->finalize = logout_dialog_finalize; - - return; -} - -static void -logout_dialog_init (LogoutDialog *self) -{ - - return; -} - -static void -logout_dialog_dispose (GObject *object) -{ - - - G_OBJECT_CLASS (logout_dialog_parent_class)->dispose (object); - return; -} - -static void -logout_dialog_finalize (GObject *object) -{ - - - G_OBJECT_CLASS (logout_dialog_parent_class)->finalize (object); - return; -} - -/* Checks for updates that would signal that a restart is - required for them to apply */ -static gboolean -check_restart_required (void) -{ - return g_file_test("/var/run/reboot-required", G_FILE_TEST_EXISTS); -} - -/* Checks with console kit to see if we can do what we want */ -static gboolean -ck_check_allowed (LogoutDialogType type) -{ - gboolean allowed = TRUE; - - ConsoleKitManager * ck_proxy = console_kit_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - NULL, - NULL); - if (ck_proxy != NULL) - { - switch (type) { - case LOGOUT_DIALOG_TYPE_RESTART: - console_kit_manager_call_can_restart_sync (ck_proxy, &allowed, NULL, NULL); - break; - case LOGOUT_DIALOG_TYPE_SHUTDOWN: - console_kit_manager_call_can_stop_sync (ck_proxy, &allowed, NULL, NULL); - break; - default: - break; - } - - g_object_unref(ck_proxy); - } - - return allowed; -} - -LogoutDialog * -logout_dialog_new (LogoutDialogType type) -{ - GtkWidget * image = gtk_image_new_from_icon_name(icon_strings[type], GTK_ICON_SIZE_DIALOG); - gtk_widget_show(image); - - LogoutDialog * dialog = LOGOUT_DIALOG(g_object_new(LOGOUT_DIALOG_TYPE, - /* Window */ - "icon-name", icon_strings[type], - "modal", TRUE, - "resizable", FALSE, - "title", g_dpgettext2 (NULL, "title", title_strings[type]), - "window-position", GTK_WIN_POS_CENTER_ALWAYS, - /* Message Dialog */ - "buttons", GTK_BUTTONS_NONE, - "image", image, - "message-type", GTK_MESSAGE_OTHER, - "text", _(body_strings[type]), - NULL)); - - gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); - - gboolean allowed = FALSE; - if (type == LOGOUT_DIALOG_TYPE_LOG_OUT) { - allowed = ck_check_allowed(LOGOUT_DIALOG_TYPE_RESTART); - } else { - allowed = ck_check_allowed(type); - } - - gboolean restart_required = FALSE; - if (type == LOGOUT_DIALOG_TYPE_LOG_OUT) { - restart_required = check_restart_required(); - } - - const gchar * button_text; - if (allowed) { - button_text = g_dpgettext2 (NULL, "button", button_strings[type]); - } else { - button_text = g_dpgettext2 (NULL, "button auth", button_auth_strings[type]); - } - - if (restart_required) { - const gchar * restart_req; - if (allowed) { - restart_req = restart_updates; - } else { - restart_req = restart_auth; - } - - g_object_set(dialog, "secondary-text", _(body_logout_update), NULL); - - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - _(restart_req), GTK_RESPONSE_HELP, - _("Cancel"), GTK_RESPONSE_CANCEL, - button_text, GTK_RESPONSE_OK, - NULL); - } else { - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - _("Cancel"), GTK_RESPONSE_CANCEL, - button_text, GTK_RESPONSE_OK, - NULL); - } - - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); - - /* The following is a workaround to fix an issue in GtkMessageDialog - in which the user can tab through the text in addition to - the buttons. */ - GtkWidget *message_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog)); - GList *children = gtk_container_get_children(GTK_CONTAINER(message_area)); - GList *l; - - for (l = children; l != NULL; l = g_list_next (l)) - { - GtkWidget *child = l->data; - gtk_widget_set_can_focus(child, FALSE); - } - - g_list_free (children); - - return dialog; -} diff --git a/src/dialog.h b/src/dialog.h deleted file mode 100644 index 18a55a7..0000000 --- a/src/dialog.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -A dialog to ask the user about the various logout options that -are available. - -Copyright 2010 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 __LOGOUT_DIALOG_H__ -#define __LOGOUT_DIALOG_H__ - -#include -#include - -#include - -G_BEGIN_DECLS - -#define LOGOUT_DIALOG_TYPE (logout_dialog_get_type ()) -#define LOGOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LOGOUT_DIALOG_TYPE, LogoutDialog)) -#define LOGOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LOGOUT_DIALOG_TYPE, LogoutDialogClass)) -#define IS_LOGOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LOGOUT_DIALOG_TYPE)) -#define IS_LOGOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LOGOUT_DIALOG_TYPE)) -#define LOGOUT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LOGOUT_DIALOG_TYPE, LogoutDialogClass)) - -typedef enum _LogoutDialogType LogoutDialogType; -enum _LogoutDialogType { - LOGOUT_DIALOG_TYPE_LOG_OUT, - LOGOUT_DIALOG_TYPE_RESTART, - LOGOUT_DIALOG_TYPE_SHUTDOWN, - LOGOUT_DIALOG_TYPE_CNT -}; - -typedef struct _LogoutDialog LogoutDialog; -typedef struct _LogoutDialogClass LogoutDialogClass; - -struct _LogoutDialogClass { - GtkMessageDialogClass parent_class; -}; - -struct _LogoutDialog { - GtkMessageDialog parent; -}; - -GType logout_dialog_get_type (void); -LogoutDialog * logout_dialog_new (LogoutDialogType type); - -G_END_DECLS - -#endif diff --git a/src/display-manager.xml b/src/display-manager.xml deleted file mode 100644 index 07b5f29..0000000 --- a/src/display-manager.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gtk-logout-helper.c b/src/gtk-logout-helper.c deleted file mode 100644 index 55db630..0000000 --- a/src/gtk-logout-helper.c +++ /dev/null @@ -1,266 +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 - 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 "config.h" - -#include -#include -#include /* textdomain(), bindtextdomain() */ -#include -#include "dialog.h" -#include "shared-names.h" - -static GVariant * -call_console_kit (const gchar *method, GVariant *parameters, GError **error) -{ - GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, error); - if (!bus) - { - g_variant_unref (parameters); - return NULL; - } - - GVariant *result = g_dbus_connection_call_sync(bus, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager", - method, - parameters, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - error); - g_object_unref (bus); - - return result; -} - -static void -consolekit_fallback (LogoutDialogType action) -{ - GError * error = NULL; - GVariant *result = NULL; - - g_debug("Falling back to using ConsoleKit for action"); - - switch (action) { - case LOGOUT_DIALOG_TYPE_LOG_OUT: - g_warning("Unable to fallback to ConsoleKit for logout as it's a session issue. We need some sort of session handler."); - break; - case LOGOUT_DIALOG_TYPE_SHUTDOWN: - g_debug("Telling ConsoleKit to 'Stop'"); - result = call_console_kit ("Stop", g_variant_new ("()"), &error); - break; - case LOGOUT_DIALOG_TYPE_RESTART: - g_debug("Telling ConsoleKit to 'Restart'"); - result = call_console_kit ("Restart", g_variant_new ("()"), &error); - break; - default: - g_warning("Unknown action"); - break; - } - - if (!result) { - if (error != NULL) { - g_warning ("ConsoleKit action failed: %s", error->message); - } else { - g_warning ("ConsoleKit action failed: unknown error"); - } - - consolekit_fallback(action); - } - else - g_variant_unref (result); - g_clear_error (&error); - - return; -} - -static GVariant * -call_gnome_session (const gchar *method, GVariant *parameters, GError **error) -{ - GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, error); - if (!bus) - { - g_variant_unref (parameters); - return NULL; - } - - GVariant *result = g_dbus_connection_call_sync(bus, - "org.gnome.SessionManager", - "/org/gnome/SessionManager", - "org.gnome.SessionManager", - method, - parameters, - NULL, - G_DBUS_CALL_FLAGS_NONE, - G_MAXINT, - NULL, - error); - g_object_unref (bus); - - return result; -} - -static void -session_action (LogoutDialogType action) -{ - GError * error = NULL; - GVariant *result = NULL; - - if (action == LOGOUT_DIALOG_TYPE_LOG_OUT) { - g_debug("Asking Session manager to 'Logout'"); - result = call_gnome_session ("Logout", g_variant_new ("(u)", 1), &error); - } else if (action == LOGOUT_DIALOG_TYPE_SHUTDOWN) { - g_debug("Asking Session manager to 'RequestShutdown'"); - result = call_gnome_session ("RequestShutdown", g_variant_new ("()"), &error); - } else if (action == LOGOUT_DIALOG_TYPE_RESTART) { - g_debug("Asking Session manager to 'RequestReboot'"); - result = call_gnome_session ("RequestReboot", g_variant_new ("()"), &error); - } else { - g_warning ("Unknown session action"); - } - - if (!result) { - if (error != NULL) { - g_warning ("SessionManager action failed: %s", error->message); - } else { - g_warning ("SessionManager action failed: unknown error"); - } - - consolekit_fallback(action); - } - else - g_variant_unref (result); - g_clear_error (&error); - - return; -} - -static LogoutDialogType type = LOGOUT_DIALOG_TYPE_LOG_OUT; - -static gboolean -option_logout (const gchar * arg, const gchar * value, gpointer data, GError * error) -{ - type = LOGOUT_DIALOG_TYPE_LOG_OUT; - g_debug("Dialog type: logout"); - return TRUE; -} - -static gboolean -option_shutdown (const gchar * arg, const gchar * value, gpointer data, GError * error) -{ - type = LOGOUT_DIALOG_TYPE_SHUTDOWN; - g_debug("Dialog type: shutdown"); - return TRUE; -} - -static gboolean -option_restart (const gchar * arg, const gchar * value, gpointer data, GError * error) -{ - type = LOGOUT_DIALOG_TYPE_RESTART; - g_debug("Dialog type: restart"); - return TRUE; -} - -static GOptionEntry options[] = { - {"logout", 'l', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, option_logout, "Log out of the current session", NULL}, - {"shutdown", 's', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, option_shutdown, "Switch off the entire system", NULL}, - {"restart", 'r', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, option_restart, "Restart the system", NULL}, - - {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[]) -{ - gtk_init(&argc, &argv); - - /* Setting up i18n and gettext. Apparently, we need - all of these. */ - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - - GError * error = NULL; - GOptionContext * context = g_option_context_new(" - logout of the current session"); - g_option_context_add_main_entries(context, options, "gtk-logout-helper"); - g_option_context_add_group(context, gtk_get_option_group(TRUE)); - g_option_context_set_help_enabled(context, TRUE); - - if (!g_option_context_parse(context, &argc, &argv, &error)) { - g_debug("Option parsing failed: %s", error->message); - g_error_free(error); - return 1; - } - - /* Init some theme/icon stuff */ - gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), - INDICATOR_ICONS_DIR); - - GtkWidget * dialog = NULL; - if (!suppress_confirmations()) { - g_debug("Showing dialog to ask for user confirmation"); - dialog = GTK_WIDGET(logout_dialog_new(type)); - } - - if (dialog != NULL) { - GtkResponseType response = gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_hide(dialog); - - if (response == GTK_RESPONSE_OK) { - g_debug("Dialog return response: 'okay'"); - } else if (response == GTK_RESPONSE_HELP) { - g_debug("Dialog return response: 'help'"); - } else { - g_debug("Dialog return response: %d", response); - } - - if (response == GTK_RESPONSE_HELP) { - type = LOGOUT_DIALOG_TYPE_RESTART; - response = GTK_RESPONSE_OK; - } - - if (response != GTK_RESPONSE_OK) { - g_debug("Final response was not okay, quiting"); - return 0; - } - } - - session_action(type); - g_debug("Finished action, quiting"); - - return 0; -} diff --git a/src/guest.c b/src/guest.c new file mode 100644 index 0000000..bcbd384 --- /dev/null +++ b/src/guest.c @@ -0,0 +1,190 @@ +/* + * 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 "guest.h" + +G_DEFINE_TYPE (IndicatorSessionGuest, + indicator_session_guest, + G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_ALLOWED, + PROP_LOGGED_IN, + PROP_ACTIVE, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +static void +my_get_property (GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorSessionGuest * self = INDICATOR_SESSION_GUEST (o); + + switch (property_id) + { + case PROP_ALLOWED: + g_value_set_boolean (value, indicator_session_guest_is_allowed (self)); + break; + + case PROP_LOGGED_IN: + g_value_set_boolean (value, indicator_session_guest_is_logged_in (self)); + break; + + case PROP_ACTIVE: + g_value_set_boolean (value, indicator_session_guest_is_active (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +my_dispose (GObject *object) +{ + G_OBJECT_CLASS (indicator_session_guest_parent_class)->dispose (object); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_class_init (IndicatorSessionGuestClass * klass) +{ + GObjectClass * object_class; + const GParamFlags flags = G_PARAM_READABLE | G_PARAM_STATIC_STRINGS; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = my_get_property; + object_class->dispose = my_dispose; + + klass->is_allowed = NULL; + klass->is_logged_in = NULL; + klass->is_active = NULL; + klass->switch_to_guest = NULL; + + properties[PROP_0] = NULL; + + properties[PROP_ALLOWED] = + g_param_spec_boolean (INDICATOR_SESSION_GUEST_PROPERTY_ALLOWED, + "Is Allowed", + "Whether or not a Guest user is allowed", + FALSE, flags); + + properties[PROP_LOGGED_IN] = + g_param_spec_boolean (INDICATOR_SESSION_GUEST_PROPERTY_LOGGED_IN, + "Is Logged In", + "Whether or not the Guest account is logged in", + FALSE, flags); + + properties[PROP_ACTIVE] = + g_param_spec_boolean (INDICATOR_SESSION_GUEST_PROPERTY_ACTIVE, + "Is Active", + "If the Guest account has the current session", + FALSE, flags); + + g_object_class_install_properties (object_class, PROP_LAST, properties); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_init (IndicatorSessionGuest *self G_GNUC_UNUSED) +{ +} + +/*** +**** +***/ + +gboolean +indicator_session_guest_is_active (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST (self), FALSE); + + return INDICATOR_SESSION_GUEST_GET_CLASS (self)->is_active (self); +} + +gboolean +indicator_session_guest_is_allowed (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST (self), FALSE); + + return INDICATOR_SESSION_GUEST_GET_CLASS (self)->is_allowed (self); +} + +gboolean +indicator_session_guest_is_logged_in (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST (self), FALSE); + + return INDICATOR_SESSION_GUEST_GET_CLASS (self)->is_logged_in (self); +} + +/*** +**** +***/ +static void +notify_func (IndicatorSessionGuest * self, int prop) +{ + g_return_if_fail (INDICATOR_IS_SESSION_GUEST (self)); + + g_debug ("%s %s emitting '%s' prop notify", G_STRLOC, G_STRFUNC, properties[prop]->name); + + g_object_notify_by_pspec (G_OBJECT(self), properties[prop]); +} + +void +indicator_session_guest_notify_active (IndicatorSessionGuest * self) +{ + notify_func (self, PROP_ACTIVE); +} + +void +indicator_session_guest_notify_allowed (IndicatorSessionGuest * self) +{ + notify_func (self, PROP_ALLOWED); +} + +void +indicator_session_guest_notify_logged_in (IndicatorSessionGuest * self) +{ + notify_func (self, PROP_LOGGED_IN); +} + +/*** +**** +***/ + +void +indicator_session_guest_switch_to_guest (IndicatorSessionGuest * self) +{ + gboolean allowed; + + g_return_if_fail (INDICATOR_IS_SESSION_GUEST (self)); + + g_object_get (self, INDICATOR_SESSION_GUEST_PROPERTY_ALLOWED, &allowed, NULL); + g_return_if_fail (allowed); + + INDICATOR_SESSION_GUEST_GET_CLASS (self)->switch_to_guest (self); +} + diff --git a/src/guest.h b/src/guest.h new file mode 100644 index 0000000..30947d5 --- /dev/null +++ b/src/guest.h @@ -0,0 +1,82 @@ +/* + * 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 . + */ + +#ifndef __GUEST_H__ +#define __GUEST_H__ + +#include +#include + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_GUEST (indicator_session_guest_get_type()) +#define INDICATOR_SESSION_GUEST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_GUEST, IndicatorSessionGuest)) +#define INDICATOR_SESSION_GUEST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_GUEST, IndicatorSessionGuestClass)) +#define INDICATOR_SESSION_GUEST_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_TYPE_SESSION_GUEST, IndicatorSessionGuestClass)) +#define INDICATOR_IS_SESSION_GUEST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_GUEST)) + +typedef struct _IndicatorSessionGuest IndicatorSessionGuest; +typedef struct _IndicatorSessionGuestClass IndicatorSessionGuestClass; + +GType indicator_session_guest_get_type (void); + +/** + * A base class for getting state information about the system's guest user. + * Use backend.h's get_backend() to get an instance. + */ +struct _IndicatorSessionGuest +{ + /*< private >*/ + GObject parent; +}; + +/* properties */ +#define INDICATOR_SESSION_GUEST_PROPERTY_ALLOWED "guest-is-allowed" +#define INDICATOR_SESSION_GUEST_PROPERTY_LOGGED_IN "guest-is-logged-in" +#define INDICATOR_SESSION_GUEST_PROPERTY_ACTIVE "guest-is-active-session" + +struct _IndicatorSessionGuestClass +{ + GObjectClass parent_class; + + /* virtual functions */ + gboolean (* is_allowed) (IndicatorSessionGuest * self); + gboolean (* is_logged_in) (IndicatorSessionGuest * self); + gboolean (* is_active) (IndicatorSessionGuest * self); + void (* switch_to_guest) (IndicatorSessionGuest * self); +}; + +gboolean indicator_session_guest_is_allowed (IndicatorSessionGuest * self); +gboolean indicator_session_guest_is_logged_in (IndicatorSessionGuest * self); +gboolean indicator_session_guest_is_active (IndicatorSessionGuest * self); + +void indicator_session_guest_switch_to_guest (IndicatorSessionGuest * self); + +/** + * Emit 'notify' signals for the corresponding properties. + * These functions should only be called by IndicatorSessionGuest implementations. + */ +void indicator_session_guest_notify_allowed (IndicatorSessionGuest * self); +void indicator_session_guest_notify_logged_in (IndicatorSessionGuest * self); +void indicator_session_guest_notify_active (IndicatorSessionGuest * self); + + +G_END_DECLS + +#endif diff --git a/src/indicator-session.c b/src/indicator-session.c deleted file mode 100644 index 431292e..0000000 --- a/src/indicator-session.c +++ /dev/null @@ -1,495 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -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 -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 . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "shared-names.h" -#include "user-widget.h" - -#define INDICATOR_SESSION_TYPE (indicator_session_get_type ()) -#define INDICATOR_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SESSION_TYPE, IndicatorSession)) -#define INDICATOR_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_SESSION_TYPE, IndicatorSessionClass)) -#define IS_INDICATOR_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_SESSION_TYPE)) -#define IS_INDICATOR_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_SESSION_TYPE)) -#define INDICATOR_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_SESSION_TYPE, IndicatorSessionClass)) - -typedef struct _IndicatorSession IndicatorSession; -typedef struct _IndicatorSessionClass IndicatorSessionClass; - -struct _IndicatorSessionClass -{ - IndicatorObjectClass parent_class; -}; - -struct _IndicatorSession -{ - IndicatorObject parent; - IndicatorServiceManager * service; - IndicatorObjectEntry entry; - GCancellable * service_proxy_cancel; - GDBusProxy * service_proxy; - GSettings * settings; - DbusmenuClient * menu_client; - GtkIconTheme * icon_theme; -}; - -GType indicator_session_get_type (void); - -/* Indicator stuff */ -INDICATOR_SET_VERSION -INDICATOR_SET_TYPE(INDICATOR_SESSION_TYPE) - -/* Prototypes */ -static gboolean new_user_item (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data); -static void on_menu_layout_updated (DbusmenuClient * client, IndicatorSession * session); -static void indicator_session_update_icon_callback (GtkWidget * widget, gpointer callback_data); -static void indicator_session_update_icon_and_a11y (IndicatorSession * self); -static void indicator_session_update_users_label (IndicatorSession* self, - const gchar* name); -static void service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data); -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 indicator_session_class_init (IndicatorSessionClass *klass); -static void indicator_session_init (IndicatorSession *self); -static void indicator_session_dispose (GObject *object); -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 -indicator_session_class_init (IndicatorSessionClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = indicator_session_dispose; - object_class->finalize = indicator_session_finalize; - - IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); - io_class->get_entries = indicator_session_get_entries; - io_class->get_location = indicator_session_get_location; - return; -} - -static void -indicator_session_init (IndicatorSession *self) -{ - self->settings = g_settings_new ("com.canonical.indicator.session"); - - /* Now let's fire these guys up. */ - self->service = indicator_service_manager_new_version(INDICATOR_SESSION_DBUS_NAME, - INDICATOR_SESSION_DBUS_VERSION); - g_signal_connect (G_OBJECT(self->service), - INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, - G_CALLBACK(service_connection_cb), self); - - self->entry.name_hint = PACKAGE; - self->entry.label = GTK_LABEL (gtk_label_new ("User Name")); - self->entry.image = GTK_IMAGE (gtk_image_new()); - self->entry.menu = GTK_MENU (dbusmenu_gtkmenu_new(INDICATOR_SESSION_DBUS_NAME, - INDICATOR_SESSION_DBUS_OBJECT)); - /* We need to check if the current icon theme has the hard coded icons. - * If not, we'll fall back to a standard icon */ - self->icon_theme = gtk_icon_theme_get_default(); - g_signal_connect(G_OBJECT(self->icon_theme), - "changed", - G_CALLBACK(indicator_session_update_icon_callback), self); - - indicator_session_update_icon_and_a11y (self); - g_settings_bind (self->settings, "show-real-name-on-panel", - self->entry.label, "visible", - G_SETTINGS_BIND_GET); - - /* show-real-name-on-panel affects the a11y string */ - g_signal_connect_swapped (self->settings, - "notify::show-real-name-on-panel", - G_CALLBACK(indicator_session_update_icon_and_a11y), - self); - - 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 - self->menu_client = DBUSMENU_CLIENT(dbusmenu_gtkmenu_get_client(DBUSMENU_GTKMENU(self->entry.menu))); - g_signal_connect (self->menu_client, "layout-updated", - G_CALLBACK(on_menu_layout_updated), self); - - dbusmenu_client_add_type_handler (self->menu_client, - USER_ITEM_TYPE, - new_user_item); - dbusmenu_gtkclient_set_accel_group (DBUSMENU_GTKCLIENT(self->menu_client), - gtk_accel_group_new()); -} - -static void -indicator_session_dispose (GObject *object) -{ - IndicatorSession * self = INDICATOR_SESSION(object); - - g_clear_object (&self->settings); - g_clear_object (&self->service); - g_clear_object (&self->service_proxy); - - if (self->service_proxy_cancel != NULL) - { - g_cancellable_cancel(self->service_proxy_cancel); - g_clear_object (&self->service_proxy_cancel); - } - - g_clear_object (&self->entry.menu); - - G_OBJECT_CLASS (indicator_session_parent_class)->dispose (object); -} - -static void -indicator_session_finalize (GObject *object) -{ - - G_OBJECT_CLASS (indicator_session_parent_class)->finalize (object); - return; -} - -static GList* -indicator_session_get_entries (IndicatorObject* obj) -{ - g_return_val_if_fail(IS_INDICATOR_SESSION(obj), NULL); - - IndicatorSession* self = INDICATOR_SESSION (obj); - return g_list_append (NULL, &self->entry); -} - -static guint -indicator_session_get_location (IndicatorObject * io, - IndicatorObjectEntry * entry) -{ - return 0; -} - -/* callback for the service manager state of being */ -static void -service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data) -{ - IndicatorSession * self = INDICATOR_SESSION (user_data); - - if (connected) { - if (self->service_proxy != NULL){ - // Its a reconnect ! - // Fetch synchronisation data and return (proxy is still legit) - g_dbus_proxy_call (self->service_proxy, - "GetUserRealName", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - user_real_name_get_cb, - 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, - NULL, - INDICATOR_SESSION_DBUS_NAME, - INDICATOR_SESSION_SERVICE_DBUS_OBJECT, - INDICATOR_SESSION_SERVICE_DBUS_IFACE, - self->service_proxy_cancel, - service_proxy_cb, - self); - } - return; -} - - -static void -service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) -{ - GError * error = NULL; - - IndicatorSession * self = INDICATOR_SESSION(user_data); - g_return_if_fail(self != NULL); - - GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); - - g_clear_object (&self->service_proxy_cancel); - - if (error != NULL) { - g_warning("Could not grab DBus proxy for %s: %s", INDICATOR_SESSION_DBUS_NAME, error->message); - g_error_free(error); - return; - } - - /* Okay, we're good to grab the proxy at this point, we're - sure that it's ours. */ - 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", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - user_real_name_get_cb, - user_data); - return; -} - - -static gboolean -new_user_item (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data) -{ - g_return_val_if_fail (DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail (DBUSMENU_IS_GTKCLIENT(client), FALSE); - - GtkWidget * user_item = user_widget_new (newitem); - - GtkMenuItem *user_widget = GTK_MENU_ITEM(user_item); - - dbusmenu_gtkclient_newitem_base (DBUSMENU_GTKCLIENT(client), - newitem, - user_widget, - parent); - - g_debug ("%s (\"%s\")", __func__, - dbusmenu_menuitem_property_get (newitem, - USER_ITEM_PROP_NAME)); - return TRUE; -} - -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 = g_dbus_proxy_call_finish(self->service_proxy, res, &error); - - 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 */ -static void -receive_signal (GDBusProxy * proxy, - gchar * sender_name, - gchar * signal_name, - GVariant * parameters, - gpointer user_data) -{ - IndicatorSession * self = INDICATOR_SESSION(user_data); - - if (!g_strcmp0(signal_name, "UserRealNameUpdated")) - { - const gchar * username = NULL; - g_variant_get (parameters, "(&s)", &username); - indicator_session_update_users_label (self, username); - } -} - -static void -indicator_session_update_users_label (IndicatorSession * self, - const gchar * name) -{ - gtk_label_set_text (self->entry.label, name ? name : ""); -} - -/*** -**** Disposition -***/ - -enum -{ - DISPOSITION_NORMAL, - DISPOSITION_INFO, - DISPOSITION_WARNING, - DISPOSITION_ALERT -}; - -static void -indicator_session_update_a11y_from_disposition (IndicatorSession * indicator, - int disposition) -{ - gchar * a11y; - const gchar * username = gtk_label_get_text (indicator->entry.label); - const gboolean need_attn = disposition != DISPOSITION_NORMAL; - const gboolean show_name = g_settings_get_boolean (indicator->settings, - "show-real-name-on-panel"); - - if (show_name && need_attn) - /* Translators: the name of the menu ("System"), followed by the user's name, - followed by a hint that an item in this menu requires an action from the user */ - a11y = g_strdup_printf (_("System %s (Attention Required)"), username); - else if (show_name) - /* Translators: the name of the menu ("System"), followed by the user's name */ - a11y = g_strdup_printf (_("System %s"), username); - else if (need_attn) - a11y = g_strdup (_("System (Attention Required)")); - else - a11y = g_strdup (_("System")); - - g_debug (G_STRLOC" setting a11y to \"%s\"", a11y); - g_clear_pointer (&indicator->entry.accessible_desc, g_free); - indicator->entry.accessible_desc = a11y; - g_signal_emit (indicator, - INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, - 0, - &indicator->entry); -} - -static void -indicator_session_update_icon_from_disposition (IndicatorSession * indicator, - int disposition) -{ - const gchar * icon; - - if (disposition == DISPOSITION_NORMAL) - icon = ICON_DEFAULT; - else if (disposition == DISPOSITION_INFO) - icon = ICON_INFO; - else - icon = ICON_ALERT; - - if (gtk_icon_theme_has_icon (indicator->icon_theme, icon) == FALSE) - icon = "gtk-missing-image"; - - g_debug (G_STRLOC" setting icon to \"%s\"", icon); - gtk_image_set_from_icon_name (GTK_IMAGE(indicator->entry.image), - icon, - GTK_ICON_SIZE_BUTTON); -} - -static int -calculate_disposition (IndicatorSession * indicator) -{ - GList * l; - DbusmenuMenuitem * root = dbusmenu_client_get_root (indicator->menu_client); - GList * children = dbusmenu_menuitem_get_children (root); - int ret = DISPOSITION_NORMAL; - - for (l=children; l!=NULL; l=l->next) - { - int val; - const gchar * key = DBUSMENU_MENUITEM_PROP_DISPOSITION; - const gchar * val_str = dbusmenu_menuitem_property_get (l->data, key); - - if (!g_strcmp0 (val_str, DBUSMENU_MENUITEM_DISPOSITION_ALERT)) - val = DISPOSITION_ALERT; - else if (!g_strcmp0 (val_str, DBUSMENU_MENUITEM_DISPOSITION_WARNING)) - val = DISPOSITION_WARNING; - else if (!g_strcmp0 (val_str, DBUSMENU_MENUITEM_DISPOSITION_INFORMATIVE)) - val = DISPOSITION_INFO; - else - val = DISPOSITION_NORMAL; - - if (ret < val) - ret = val; - } - - return ret; -} - -static void -indicator_session_update_icon_callback (GtkWidget * widget, gpointer callback_data) -{ - indicator_session_update_icon_and_a11y ((IndicatorSession *)callback_data); -} - -static void -indicator_session_update_icon_and_a11y (IndicatorSession * indicator) -{ - const int disposition = calculate_disposition (indicator); - indicator_session_update_a11y_from_disposition (indicator, disposition); - indicator_session_update_icon_from_disposition (indicator, disposition); -} - -static void -on_menuitem_property_changed (DbusmenuMenuitem * mi, - gchar * property, - GValue * value, - gpointer indicator) -{ - if (!g_strcmp0 (property, DBUSMENU_MENUITEM_PROP_DISPOSITION)) - indicator_session_update_icon_and_a11y (indicator); -} - -static void -on_menu_layout_updated (DbusmenuClient * client, IndicatorSession * session) -{ - GList * l; - DbusmenuMenuitem * root = dbusmenu_client_get_root (client); - GList * children = dbusmenu_menuitem_get_children (root); - static GQuark tag = 0; - - if (G_UNLIKELY (tag == 0)) - { - tag = g_quark_from_static_string ("x-tagged-by-indicator-session"); - } - - for (l=children; l!=NULL; l=l->next) - { - if (g_object_get_qdata (l->data, tag) == NULL) - { - g_object_set_qdata (l->data, tag, GINT_TO_POINTER(1)); - g_signal_connect (l->data, "property-changed", G_CALLBACK(on_menuitem_property_changed), session); - } - } -} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..ff5997b --- /dev/null +++ b/src/main.c @@ -0,0 +1,87 @@ +/* + * 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 /* exit() */ + +#include +#include + +#include "service.h" + +/*** +**** +***/ + +static gboolean replace = FALSE; + +static void +parse_command_line (int * argc, char *** argv) +{ + GError * error; + GOptionContext * option_context; + + static GOptionEntry entries[] = + { + { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, "Replace the currently-running service", NULL }, + { NULL } + }; + + error = NULL; + option_context = g_option_context_new ("- indicator-session service"); + g_option_context_add_main_entries (option_context, entries, GETTEXT_PACKAGE); + if (!g_option_context_parse (option_context, argc, argv, &error)) + { + g_print ("option parsing failed: %s\n", error->message); + g_error_free (error); + exit (EXIT_FAILURE); + } + + g_option_context_free (option_context); +} + +/*** +**** +***/ + +int +main (int argc, char ** argv) +{ + GMainLoop * loop; + IndicatorSessionService * service; + + signal (SIGPIPE, SIG_IGN); + + /* boilerplate i18n */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); + + parse_command_line (&argc, &argv); + + /* run */ + service = indicator_session_service_new (replace); + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + /* cleanup */ + g_clear_object (&service); + g_main_loop_unref (loop); + return 0; +} diff --git a/src/online-accounts-mgr.c b/src/online-accounts-mgr.c deleted file mode 100644 index 4abba00..0000000 --- a/src/online-accounts-mgr.c +++ /dev/null @@ -1,166 +0,0 @@ -/* -Copyright 2012 Canonical Ltd. - -Authors: - Alberto Mardegan - -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 "online-accounts-mgr.h" - -#include - -struct _OnlineAccountsMgr -{ - GObject parent_instance; - GDBusProxy *proxy; - DbusmenuMenuitem *menu_item; -}; - -#define ONLINE_ACCOUNTS_OBJECT_PATH "/com/canonical/indicators/webcredentials" -#define ONLINE_ACCOUNTS_BUS_NAME "com.canonical.indicators.webcredentials" -#define ONLINE_ACCOUNTS_INTERFACE ONLINE_ACCOUNTS_BUS_NAME - -G_DEFINE_TYPE (OnlineAccountsMgr, online_accounts_mgr, G_TYPE_OBJECT); - -static void -update_disposition (OnlineAccountsMgr *self, GVariant *error_status_prop) -{ - gboolean error_status; - - error_status = g_variant_get_boolean (error_status_prop); - dbusmenu_menuitem_property_set (self->menu_item, - DBUSMENU_MENUITEM_PROP_DISPOSITION, - error_status ? - DBUSMENU_MENUITEM_DISPOSITION_ALERT : - DBUSMENU_MENUITEM_DISPOSITION_NORMAL); -} - -static void -on_properties_changed (GDBusProxy *proxy, - GVariant *changed_properties, - GStrv invalidated_properties, - OnlineAccountsMgr *self) -{ - if (g_variant_n_children (changed_properties) > 0) { - GVariantIter *iter; - const gchar *key; - GVariant *value; - - g_variant_get (changed_properties, "a{sv}", &iter); - while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) { - if (g_strcmp0 (key, "ErrorStatus") == 0) { - update_disposition (self, value); - } - } - g_variant_iter_free (iter); - } -} - -static void -on_menu_item_activated (DbusmenuMenuitem *menu_item, - guint timestamp, - OnlineAccountsMgr *self) -{ - GError *error = NULL; - - if (!g_spawn_command_line_async("gnome-control-center credentials", &error)) - { - g_warning("Unable to show control center: %s", error->message); - g_error_free(error); - } -} - -static void -online_accounts_mgr_init (OnlineAccountsMgr *self) -{ - GError *error = NULL; - GVariant *error_status_prop; - - self->menu_item = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (self->menu_item, - DBUSMENU_MENUITEM_PROP_TYPE, - DBUSMENU_CLIENT_TYPES_DEFAULT); - dbusmenu_menuitem_property_set (self->menu_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Online Accounts\342\200\246")); - g_signal_connect (self->menu_item, - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (on_menu_item_activated), - self); - - self->proxy = - g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - ONLINE_ACCOUNTS_BUS_NAME, - ONLINE_ACCOUNTS_OBJECT_PATH, - ONLINE_ACCOUNTS_INTERFACE, - NULL, - &error); - if (G_UNLIKELY (error != NULL)) { - g_warning ("Couldn't create online_accounts proxy: %s", error->message); - g_clear_error (&error); - return; - } - - g_signal_connect (self->proxy, "g-properties-changed", - G_CALLBACK (on_properties_changed), self); - - error_status_prop = - g_dbus_proxy_get_cached_property (self->proxy, "ErrorStatus"); - if (error_status_prop != NULL) { - update_disposition (self, error_status_prop); - g_variant_unref (error_status_prop); - } -} - -static void -online_accounts_mgr_dispose (GObject *object) -{ - OnlineAccountsMgr *self = ONLINE_ACCOUNTS_MGR (object); - - if (self->proxy != NULL) { - g_object_unref (self->proxy); - self->proxy = NULL; - } - - if (self->menu_item != NULL) { - g_object_unref (self->menu_item); - self->menu_item = NULL; - } - - G_OBJECT_CLASS (online_accounts_mgr_parent_class)->dispose (object); -} - -static void -online_accounts_mgr_class_init (OnlineAccountsMgrClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->dispose = online_accounts_mgr_dispose; -} - -OnlineAccountsMgr *online_accounts_mgr_new () -{ - return g_object_new (ONLINE_ACCOUNTS_TYPE_MGR, NULL); -} - -DbusmenuMenuitem *online_accounts_mgr_get_menu_item (OnlineAccountsMgr *self) -{ - g_return_val_if_fail (ONLINE_ACCOUNTS_IS_MGR (self), NULL); - return self->menu_item; -} diff --git a/src/online-accounts-mgr.h b/src/online-accounts-mgr.h deleted file mode 100644 index 16c0461..0000000 --- a/src/online-accounts-mgr.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2012 Canonical Ltd. - -Authors: - Alberto Mardegan - -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 _ONLINE_ACCOUNTS_MGR_H_ -#define _ONLINE_ACCOUNTS_MGR_H_ - -#include -#include - -G_BEGIN_DECLS - -#define ONLINE_ACCOUNTS_TYPE_MGR (online_accounts_mgr_get_type ()) -#define ONLINE_ACCOUNTS_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ONLINE_ACCOUNTS_TYPE_MGR, OnlineAccountsMgr)) -#define ONLINE_ACCOUNTS_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ONLINE_ACCOUNTS_TYPE_MGR, OnlineAccountsMgrClass)) -#define ONLINE_ACCOUNTS_IS_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ONLINE_ACCOUNTS_TYPE_MGR)) -#define ONLINE_ACCOUNTS_IS_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ONLINE_ACCOUNTS_TYPE_MGR)) -#define ONLINE_ACCOUNTS_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ONLINE_ACCOUNTS_TYPE_MGR, OnlineAccountsMgrClass)) - -typedef struct _OnlineAccountsMgrClass OnlineAccountsMgrClass; -typedef struct _OnlineAccountsMgr OnlineAccountsMgr; - -struct _OnlineAccountsMgrClass -{ - GObjectClass parent_class; -}; - -GType online_accounts_mgr_get_type (void) G_GNUC_CONST; -OnlineAccountsMgr *online_accounts_mgr_new (void); - -DbusmenuMenuitem *online_accounts_mgr_get_menu_item (OnlineAccountsMgr *self); - -G_END_DECLS - -#endif /* _ONLINE_ACCOUNTS_MGR_H_ */ diff --git a/src/org.freedesktop.Accounts.User.xml b/src/org.freedesktop.Accounts.User.xml deleted file mode 100644 index 53f54d4..0000000 --- a/src/org.freedesktop.Accounts.User.xml +++ /dev/null @@ -1,744 +0,0 @@ - - - - - - - - - - - The new username. - - - - - - - Sets the users username. Note that it is usually not allowed - to have multiple users with the same username. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the username of any user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new name, typically in the form "Firstname Lastname". - - - - - - - Sets the users real name. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own name - - - org.freedesktop.accounts.user-administration - To change the name of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new email address. - - - - - - - Sets the users email address. - - - Note that setting an email address in the AccountsService is - not the same as configuring a mail client. Mail clients might - default to email address that is configured here, though. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own email address - - - org.freedesktop.accounts.user-administration - To change the email address of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new language, as a locale specification like "de_DE.UTF-8". - - - - - - - Sets the users language. - - - The expectation is that display managers will start the - users session with this locale. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own language - - - org.freedesktop.accounts.user-administration - To change the language of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - - The new xsession to start (e.g. "gnome") - - - - - - - Sets the users x session. - - - The expectation is that display managers will log the user in to this - specified session, if available. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own language - - - org.freedesktop.accounts.user-administration - To change the language of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new location as a freeform string. - - - - - - - Sets the users location. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own location - - - org.freedesktop.accounts.user-administration - To change the location of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new homedir as an absolute path. - - - - - - - Sets the users home directory. - - - Note that changing the users home directory moves all the content - from the old location to the new one, and is potentially an - expensive operation. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the home directory of a user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new user shell. - - - - - - - Sets the users shell. - - - Note that setting the shell to a non-allowed program may - prevent the user from logging in. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the shell of a user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The absolute filename of a png file to use as the users icon. - - - - - - - Sets the users icon. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own icon - - - org.freedesktop.accounts.user-administration - To change the icon of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - Whether to lock or unlock the users account. - - - - - - - Locks or unlocks a users account. - - - Locking an account prevents the user from logging in. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To lock or unlock user accounts - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new account type, encoded as an integer: - - - 0 - Standard user - - - 1 - Administrator - - - - - - - - - Changes the users account type. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change an account type - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new password mode, encoded as an integer: - - - 0 - Regular password - - - 1 - Password must be set at next login - - - 2 - No password - - - - - - - - - Changes the users password mode. - - - Note that changing the password mode has the side-effect of - unlocking the account. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change a users password mode - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The crypted password. - - - - - - - The password hint. - - - - - - - Sets a new password for this user. - - - Note that setting a password has the side-effect of - unlocking the account. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the password of a user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - Whether to enable automatic login for this user. - - - - - - - Enables or disables automatic login for a user. - - - Note that usually only one user can have automatic login - enabled, so turning it on for a user will disable it for - the previously configured autologin user. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.set-login-option - To change the login screen configuration - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - The uid of the user. - - - - - - - - - - The username of the user. - - - - - - - - - - The users real name. - - - - - - - - - - The users account type, encoded as an integer: - - - 0 - Standard user - - - 1 - Administrator - - - - - - - - - - - - The users home directory. - - - - - - - - - - The users shell. - - - - - - - - - - The email address. - - - - - - - - - - The users language, as a locale specification like "de_DE.UTF-8". - - - - - - - - - - The users x session. - - - - - - - - - - The users location. - - - - - - - - - - How often the user has logged in. - - - - - - - - - - The filename of a png file containing the users icon. - - - - - - - - - - Whether the users account is locked. - - - - - - - - - - The password mode for the user account, encoded as an integer: - - - 0 - Regular password - - - 1 - Password must be set at next login - - - 2 - No password - - - - - - - - - - - - The password hint for the user. - - - - - - - - - - Whether automatic login is enabled for the user. - - - - - - - - - - Whether this is a 'system' account, like 'root' or 'nobody'. - System accounts should normally not appear in lists of - users, and ListCachedUsers will not include such accounts. - - - - - - - - - - Emitted when the user is changed. - - - - - - - diff --git a/src/org.freedesktop.Accounts.xml b/src/org.freedesktop.Accounts.xml deleted file mode 100644 index 9c19761..0000000 --- a/src/org.freedesktop.Accounts.xml +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - Object paths of cached users - - - - - - Lists users which have logged into the system locally before. - This is not meant to return an exhaustive list of all users. - It is possible for FindUserByName() - to return a user that's not on the list. - - - - - - - - - The uid to look up - - - Object path of user - - - - - - Finds a user by uid. - - - - if no user with the given uid exists - - - - - - - - The username to look up - - - Object path of user - - - - - - Finds a user by its username. - - - - if no user with the given username exists - - - - - - - - The username for the new user - - - - The real name for the new user - - - Object path of the new user - - - - The account type, encoded as an integer - - - - - - Creates a new user account. - - - The accountType argument can take the following values: - - - - 0 - Standard user - - - 1 - Administrator - - - 2 - Supervised user - - - - - The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - The uid to delete - - - Whether to remove the users files - - - - - - Deletes a user account. - - - - The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - Object path of the user that was added. - - - - - Emitted when a user is added. - - - - - - - - Object path of the user that was deleted. - - - - - Emitted when a user is deleted. - - - - - - - - Object path of the user that was changed. - - - - - Emitted when a user is changed. - - - - - - - - - - The version of the running daemon. - - - - - - - diff --git a/src/org.freedesktop.ConsoleKit.Manager.xml b/src/org.freedesktop.ConsoleKit.Manager.xml deleted file mode 100644 index f903b55..0000000 --- a/src/org.freedesktop.ConsoleKit.Manager.xml +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - - - - This method initiates a request to restart (ie. reboot) the computer system. - - - - - - - - - - - - - - This method initiates a request to stop (ie. shutdown) the computer system. - - - - - - - - - - - - - - The secret cookie that is used to identify the new session - - - - - This method requests that a new Session - be created for the calling process. The properties of this new Session are set automatically - from information collected about the calling process. - - This new session exists until the calling process disconnects from the system bus or - calls CloseSession(). - - It is the responsibility of the calling process to set the environment variable - XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only - be made available to child processes of the caller so that they may be identified - as members of this session. - - See this simple example: - - DBusError error; - DBusMessage *message; - DBusMessage *reply; - - message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager", - "OpenSession"); - if (message == NULL) { - goto out; - } - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connector->connection, - message, - -1, - &error); - if (reply == NULL) { - goto out; - } - - dbus_error_init (&error); - if (! dbus_message_get_args (reply, - &error, - DBUS_TYPE_STRING, &cookie, - DBUS_TYPE_INVALID)) { - goto out; - } - - - - OpenSessionWithParameters() - - - - - - - An array of sets of property names and values - - - - - The secret cookie that is used to identify the new session - - - - - This method requests that a new Session - be created for the calling process. The properties of this new Session are from the - parameters provided. - - This new session exists until the calling process disconnects from the system bus or - calls CloseSession(). - - It is the responsibility of the calling process to set the environment variable - XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only - be made available to child processes of the caller so that they may be identified - as members of this session. - - See the Session properties for a list of valid parameters. - - org.freedesktop.ConsoleKit.Session - This method is restricted to privileged users by D-Bus policy. - - - - - - - The secret cookie that is used to identify the session - - - - - Whether the session was successfully closed - - - - - This method is used to close the session identified by the supplied cookie. - - The session can only be closed by the same process that opened the session. - - - - - - - - - an array of Seat IDs - - - - - This gets a list of all the Seats - that are currently present on the system. - Each Seat ID is an D-Bus object path for the object that implements the - Seat interface. - - org.freedesktop.ConsoleKit.Seat - - - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently present on the system. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - org.freedesktop.ConsoleKit.Session - - - - - - - - The secret cookie that is used to identify the session - - - - - The object identifier for the current session - - - - - Returns the session ID that is associated with the specified cookie. - - - - - - - - - The POSIX process ID - - - - - The object identifier for the current session - - - - - Attempts to determine the session ID for the specified - POSIX process ID (pid). - - - - - - - - - The object identifier for the current session - - - - - Attempts to determine the session ID that the caller belongs to. - - See this example of using dbus-send: - - dbus-send --system --dest=org.freedesktop.ConsoleKit \ - --type=method_call --print-reply --reply-timeout=2000 \ - /org/freedesktop/ConsoleKit/Manager \ - org.freedesktop.ConsoleKit.Manager.GetCurrentSession - - - - - - - - - POSIX User identification - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently open for the specified user. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - User identification - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently open for the specified user. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - - The value of the system-idle-hint - - - - - Returns TRUE if the idle-hint - property of every open session is TRUE or if there are no open sessions. - - - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time of the last change of the system-idle-hint. - - - - - - - - - The Seat ID for the added seat - - - - - Emitted when a Seat has been added to the system. - - - - - - - - The Seat ID for the removed seat - - - - - Emitted when a Seat has been removed from the system. - - - - - - - - The value of the system-idle-hint - - - - - Emitted when the value of the system-idle-hint has changed. - - - - - - diff --git a/src/org.freedesktop.ConsoleKit.Seat.xml b/src/org.freedesktop.ConsoleKit.Seat.xml deleted file mode 100644 index 58c2ce7..0000000 --- a/src/org.freedesktop.ConsoleKit.Seat.xml +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - A seat is a collection of sessions and a set of hardware (usually at -least a keyboard and mouse). Only one session may be active on a -seat at a time. - - - - - - - Seat ID - - - - - Returns the ID for Seat. - - - - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently attached to this seat. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - an array of devices - - - - - This gets a list of all the devices - that are currently associated with this seat. - Each device is an D-Bus structure that represents - the device type and the device id. - - - - - - - - - Session ID - - - - - Gets the Session ID that is currently active on this Seat. - Returns NULL if there is no active session. - - - - - - - - TRUE if seat supports session activation - - - - Used to determine whether the seat supports session activation. - - - - - - - - - Session ID - - - - - Attempt to activate the specified session. In most - cases, if successful, this will cause the session to - become visible and take control of the hardware that is - associated with this seat. - - Activate() - - - - - - - Session ID - - - - - Emitted when the active session has changed. - - - - - - - Session ID - - - - - Emitted when a session has been added to the seat. - - - - - - - Session ID - - - - - Emitted when a session has been removed from the seat. - - - - - - - Device structure - - - - - Emitted when a device has been associated with the seat. - - - - - - - Device structure - - - - - Emitted when a device has been dissociated from the seat. - - - - - diff --git a/src/org.freedesktop.ConsoleKit.Session.xml b/src/org.freedesktop.ConsoleKit.Session.xml deleted file mode 100644 index b6e1cdb..0000000 --- a/src/org.freedesktop.ConsoleKit.Session.xml +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - - Session objects represent and store information - related to a user session. - - The properties associated with the Session - specifically refer to the properties of the "session leader". - - - - - - - Session ID - - - - Returns the ID for Session. - - - - - - - Seat ID - - - - Returns the ID for the Seat the Session is - attached to. - - org.freedesktop.ConsoleKit.Seat - - - - - - Session type - - - - - Returns the type of the session. - Warning: we haven't yet defined the allowed values for this property. - It is probably best to avoid this until we do. - - - session-type - - - - - - User ID - - - - Returns the user that the session belongs to. - - - user - - - - - - POSIX User ID - - - - Returns the POSIX user ID that the session belongs to. - - unix-user - - - - - - The value of the X11 display - - - - Returns the value of the X11 DISPLAY for this session - if one is present. - - x11-display - - - - - - The value of the X11 display device - - - - Returns the value of the display device (aka TTY) that the - X11 display for the session is connected to. If there is no x11-display set then this value - is undefined. - - x11-display-device - - - - - - The value of the display device - - - - Returns the value of the display device (aka TTY) that the - session is connected to. - - display-device - - - - - - The remote host name - - - - Returns the value of the remote host name for the session. - - - remote-host-name - - - - - - The value of the native system login session ID - - - - Returns the value of the login session ID that the - underlying system uses to enforce session boundaries. If there is no login session ID - set then this value is an empty string. - - - - - - - TRUE if the session is active, otherwise FALSE - - - - Returns whether the session is active on the Seat that - it is attached to. - If the session is not attached to a seat this value is undefined. - - - active - - - - - - TRUE if the session is local, otherwise FALSE - - - - Returns whether the session is local - FIXME: we need to come up with a concrete definition for this value. - It was originally used as a way to identify XDMCP sessions that originate - from a remote system. - - - is-local - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time that the session was opened. - - - - - - - - - - Attempt to activate the this session. In most - cases, if successful, this will cause the session to - become visible and become active on the seat that it - is attached to. - - Seat.ActivateSession() - - - - - - - This will cause a Lock - signal to be emitted for this session. - - - This method is restricted to privileged users by D-Bus policy. - Lock signal - - - - - - - This will cause an Unlock - signal to be emitted for this session. - - This can be used by login managers to unlock a session before it is - re-activated during fast-user-switching. - - - This method is restricted to privileged users by D-Bus policy. - Unlock signal - - - - - - - The value of the idle-hint - - - - - Gets the value of the idle-hint - property. - - - idle-hint - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time of the last change of the idle-hint. - - - - - - - - - boolean value to set the idle-hint to - - - - - This may be used by the session to indicate that - it is idle. - - Use of this method is restricted to the user - that owns the session. - - - - - - - - TRUE if the session is active, otherwise FALSE - - - - - Emitted when the active property has changed. - - - - - - - the new value of idle-hint - - - - - Emitted when the idle-hint property has changed. - - - - - - - Emitted in response to a call to the Lock() method. - It is intended that the screensaver for the session should lock the screen in response to this signal. - - - - - - - Emitted in response to a call to the Unlock() method. - It is intended that the screensaver for the session should unlock the screen in response to this signal. - - - - - - - - The user assigned to the session. - - - - - - - The user assigned to the session. - - - - - - - - The type of the session. - Warning: we haven't yet defined the allowed values for this property. - It is probably best to avoid this until we do. - - - - - - - - The remote host name for the session. - - This will be set in situations where the session is - opened and controlled from a remote system. - - For example, this value will be set when the - session is created from an SSH or XDMCP connection. - - - - - - - - The display device (aka TTY) that the - session is connected to. - - - - - - - - Value of the X11 DISPLAY for this session - if one is present. - - - - - - - - - The display device (aka TTY) that the X11 display for the - session is connected to. If there is no x11-display set then - this value is undefined. - - - - - - - - - Whether the session is active on the Seat that - it is attached to. - If the session is not attached to a seat this value is undefined. - - - - - - - - - Whether the session is local - FIXME: we need to come up with a concrete definition for this value. - It was originally used as a way to identify XDMCP sessions that originate - from a remote system. - - - - - - - - - This is a hint used to indicate that the session may be idle. - - - For sessions with a x11-display set (ie. graphical - sessions), it is up to each session to delegate the - responsibility for updating this value. Typically, the - screensaver will set this. - - However, for non-graphical sessions with a display-device set - the Session object itself will periodically update this value based - on the activity detected on the display-device itself. - - - This should not be considered authoritative. - - - - - - - diff --git a/src/service.c b/src/service.c new file mode 100644 index 0000000..1345681 --- /dev/null +++ b/src/service.c @@ -0,0 +1,1192 @@ +/* + * 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 +#include + +#include "backend.h" +#include "service.h" + +/* FIXME: remove -test */ +#define BUS_NAME "com.canonical.indicator.session-test" +#define BUS_PATH "/com/canonical/indicator/session" + +#define ICON_DEFAULT "system-devices-panel" +#define ICON_INFO "system-devices-panel-information" +#define ICON_ALERT "system-devices-panel-alert" + +G_DEFINE_TYPE (IndicatorSessionService, + indicator_session_service, + G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_REPLACE, + PROP_MAX_USERS, + PROP_LAST +}; + +static GParamSpec * properties[PROP_LAST]; + +enum +{ + SECTION_HEADER = (1<<0), + SECTION_ADMIN = (1<<1), + SECTION_SETTINGS = (1<<2), + SECTION_SWITCH = (1<<3), + SECTION_SESSION = (1<<4) +}; + +enum +{ + FORM_DESKTOP, + FORM_GREETER, + N_FORMS +}; + +static const char * const menu_names[N_FORMS] = +{ + "desktop", + "desktop_greeter" +}; + +struct FormMenuInfo +{ + /* the root level -- the header is the only child of this */ + GMenu * menu; + + /* parent of the sections. This is the header's submenu */ + GMenu * submenu; + + guint export_id; +}; + +struct _IndicatorSessionServicePrivate +{ + guint own_id; + guint max_users; + IndicatorSessionUsers * backend_users; + IndicatorSessionGuest * backend_guest; + IndicatorSessionActions * backend_actions; + GSettings * indicator_settings; + GSettings * keybinding_settings; + GSimpleActionGroup * actions; + guint actions_export_id; + struct FormMenuInfo menus[N_FORMS]; + GSimpleAction * header_action; + GSimpleAction * user_switcher_action; + GSimpleAction * guest_switcher_action; + GHashTable * users; + guint rebuild_id; + int rebuild_flags; + GDBusConnection * conn; + + gboolean replace; +}; + +typedef IndicatorSessionServicePrivate priv_t; + +static const char * get_current_real_name (IndicatorSessionService * self); + +/*** +**** +***/ + +static void rebuild_now (IndicatorSessionService * self, int section); +static void rebuild_soon (IndicatorSessionService * self, int section); + +static inline void +rebuild_header_soon (IndicatorSessionService * self) +{ + rebuild_soon (self, SECTION_HEADER); +} +static inline void +rebuild_switch_section_soon (IndicatorSessionService * self) +{ + rebuild_soon (self, SECTION_SWITCH); +} +static inline void +rebuild_session_section_soon (IndicatorSessionService * self) +{ + rebuild_soon (self, SECTION_SESSION); +} +static inline void +rebuild_settings_section_soon (IndicatorSessionService * self) +{ + rebuild_soon (self, SECTION_SETTINGS); +} + +/*** +**** +***/ + +static void +update_header_action (IndicatorSessionService * self) +{ + gchar * a11y; + gboolean need_attn; + gboolean show_name; + GVariant * variant; + const gchar * real_name; + const gchar * label; + const gchar * iconstr; + const priv_t * const p = self->priv; + + g_return_if_fail (p->header_action != NULL); + + if (indicator_session_actions_has_online_account_error (p->backend_actions)) + { + need_attn = TRUE; + iconstr = ICON_ALERT; + } + else + { + need_attn = FALSE; + iconstr = ICON_DEFAULT; + } + + show_name = g_settings_get_boolean (p->indicator_settings, + "show-real-name-on-panel"); + + real_name = get_current_real_name (self); + label = show_name && real_name ? real_name : ""; + + if (*label && need_attn) + { + /* Translators: the name of the menu ("System"), then the user's name, + then a hint that something in this menu requires user attention */ + a11y = g_strdup_printf (_("System, %s (Attention Required)"), real_name); + } + else if (*label) + { + /* Translators: the name of the menu ("System"), then the user's name */ + a11y = g_strdup_printf (_("System, %s"), label); + } + else if (need_attn) + { + a11y = g_strdup (_("System (Attention Required)")); + } + else + { + a11y = g_strdup (_("System")); + } + + variant = g_variant_new ("(sssb)", label, iconstr, a11y, TRUE); + g_simple_action_set_state (p->header_action, variant); + g_free (a11y); +} + +/*** +**** USERS +***/ + +static GMenuModel * create_switch_section (IndicatorSessionService * self); + +static void +add_user (IndicatorSessionService * self, const gchar * key) +{ + IndicatorSessionUser * u; + + /* update our user table */ + u = indicator_session_users_get_user (self->priv->backend_users, key); + g_hash_table_insert (self->priv->users, g_strdup(key), u); + + /* enqueue rebuilds for the affected sections */ + rebuild_switch_section_soon (self); + if (u->is_current_user) + rebuild_header_soon (self); +} + +static void +on_user_added (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, + const char * key, + gpointer gself) +{ + add_user (INDICATOR_SESSION_SERVICE(gself), key); +} + +static void +on_user_changed (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, + const char * key, + gpointer gself) +{ + add_user (INDICATOR_SESSION_SERVICE(gself), key); +} + +static void +on_user_removed (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, + const char * key, + gpointer gself) +{ + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (gself); + g_return_if_fail (self != NULL); + + /* update our user table */ + g_hash_table_remove (self->priv->users, key); + + /* enqueue rebuilds for the affected sections */ + rebuild_switch_section_soon (self); +} + +static const char * +get_current_real_name (IndicatorSessionService * self) +{ + GHashTableIter iter; + gpointer key, value; + + /* is it the guest? */ + if (indicator_session_guest_is_active (self->priv->backend_guest)) + return _("Guest"); + + /* is it a user? */ + g_hash_table_iter_init (&iter, self->priv->users); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + IndicatorSessionUser * user = value; + if (user->is_current_user) + return user->real_name; + } + + return ""; +} + +/*** +**** +***/ + +static GMenuModel * +create_admin_section (void) +{ + GMenu * menu; + GMenuItem * item; + + menu = g_menu_new (); + + item = g_menu_item_new (_("About This Computer"), "indicator.about"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + + item = g_menu_item_new (_("Ubuntu Help"), "indicator.help"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + + return G_MENU_MODEL (menu); +} + +static GMenuModel * +create_settings_section (IndicatorSessionService * self) +{ + GMenu * menu; + GMenuItem * item; + priv_t * p = self->priv; + + menu = g_menu_new (); + + item = g_menu_item_new (_("System Settings\342\200\246"), "indicator.settings"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + + if (indicator_session_actions_has_online_account_error (p->backend_actions)) + { + item = g_menu_item_new (_("Online Accounts\342\200\246"), "indicator.online-accounts"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + return G_MENU_MODEL (menu); +} + +/** + * The switch-to-guest action's state is a dictionary with these entries: + * - "is-active" (boolean) + * - "is-logged-in" (boolean) + */ +static GVariant * +create_guest_switcher_state (IndicatorSessionService * self) +{ + GVariant * val; + GVariantBuilder * b; + IndicatorSessionGuest * const g = self->priv->backend_guest; + + b = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + val = g_variant_new_boolean (indicator_session_guest_is_active (g)); + g_variant_builder_add (b, "{sv}", "is-active", val); + val = g_variant_new_boolean (indicator_session_guest_is_logged_in (g)); + g_variant_builder_add (b, "{sv}", "is-logged-in", val); + return g_variant_builder_end (b); +} + +/** + * The switch-to-user action's state is a dictionary with these entries: + * - "active-user" (username string) + * - "logged-in-users" (array of username strings) + */ +static GVariant * +create_user_switcher_state (IndicatorSessionService * self) +{ + GVariantBuilder * a; + GVariantBuilder * b; + GVariant * val; + GHashTableIter ht_iter; + gpointer ht_key, ht_value; + const char * current_user; + + current_user = ""; + a = g_variant_builder_new (G_VARIANT_TYPE("as")); + g_hash_table_iter_init (&ht_iter, self->priv->users); + while (g_hash_table_iter_next (&ht_iter, &ht_key, &ht_value)) + { + const IndicatorSessionUser * u = ht_value; + + if (u->is_current_user) + current_user = u->user_name; + + if (u->is_logged_in) + g_variant_builder_add (a, "s", u->user_name); + } + + b = g_variant_builder_new (G_VARIANT_TYPE("a{sv}")); + val = g_variant_new_string (current_user); + g_variant_builder_add (b, "{sv}", "active-user", val); + val = g_variant_builder_end (a); + g_variant_builder_add (b, "{sv}", "logged-in-users", val); + return g_variant_builder_end (b); +} + +static void +update_switch_actions (IndicatorSessionService * self) +{ + g_simple_action_set_state (self->priv->guest_switcher_action, + create_guest_switcher_state (self)); + + g_simple_action_set_state (self->priv->user_switcher_action, + create_user_switcher_state (self)); +} + +static gboolean +use_ellipsis (IndicatorSessionService * self) +{ + /* does the backend support confirmation prompts? */ + if (!indicator_session_actions_can_prompt (self->priv->backend_actions)) + return FALSE; + + /* has the user disabled prompts? */ + if (g_settings_get_boolean (self->priv->indicator_settings, + "suppress-logout-restart-shutdown")) + return FALSE; + + return TRUE; +} + +/* lower index == more useful. + When there are too many users for the menu, + we use this to decide which to cull. */ +static int +compare_users_by_usefulness (gconstpointer ga, gconstpointer gb) +{ + const IndicatorSessionUser * a = *(const IndicatorSessionUser**)ga; + const IndicatorSessionUser * b = *(const IndicatorSessionUser**)gb; + + if (a->is_current_user != b->is_current_user) + return a->is_current_user ? -1 : 1; + + if (a->is_logged_in != b->is_logged_in) + return a->is_logged_in ? -1 : 1; + + if (a->login_frequency != b->login_frequency) + return a->login_frequency > b->login_frequency ? -1 : 1; + + return 0; +} + +/* sorting them for display in the menu */ +static int +compare_users_by_label (gconstpointer ga, gconstpointer gb) +{ + int i; + const IndicatorSessionUser * a = *(const IndicatorSessionUser**)ga; + const IndicatorSessionUser * b = *(const IndicatorSessionUser**)gb; + + if ((i = g_strcmp0 (a->real_name, b->real_name))) + return i; + + return g_strcmp0 (a->user_name, b->user_name); +} + +static GMenuModel * +create_switch_section (IndicatorSessionService * self) +{ + gchar * str; + GMenu * menu; + GMenuItem * item; + guint i; + gpointer guser; + GHashTableIter iter; + GPtrArray * users; + const priv_t * const p = self->priv; + const gboolean ellipsis = use_ellipsis (self); + + menu = g_menu_new (); + + /* lockswitch */ + if (indicator_session_users_is_live_session (p->backend_users)) + { + const char * action = "indicator.switch-to-screensaver"; + item = g_menu_item_new (_("Start Screen Saver"), action); + } + else if (indicator_session_guest_is_active (p->backend_guest)) + { + const char * action = "indicator.switch-to-greeter"; + item = g_menu_item_new (ellipsis ? _("Switch Account\342\200\246") + : _("Switch Account"), action); + } + else if (g_hash_table_size (p->users) == 1) + { + const char * action = "indicator.switch-to-greeter"; + item = g_menu_item_new (ellipsis ? _("Lock\342\200\246") + : _("Lock"), action); + } + else + { + const char * action = "indicator.switch-to-greeter"; + item = g_menu_item_new (ellipsis ? _("Lock/Switch Account\342\200\246") + : _("Lock/Switch Account"), action); + } + str = g_settings_get_string (p->keybinding_settings, "screensaver"); + g_menu_item_set_attribute (item, "accel", "s", str); + g_free (str); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + + if (indicator_session_guest_is_allowed (p->backend_guest)) + { + item = g_menu_item_new (_("Guest Session"), "indicator.switch-to-guest"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + /* build an array of all the users we know of */ + users = g_ptr_array_new (); + g_hash_table_iter_init (&iter, p->users); + while (g_hash_table_iter_next (&iter, NULL, &guser)) + g_ptr_array_add (users, guser); + + /* if there are too many users, cull out the less interesting ones */ + if (users->len > p->max_users) + { + g_ptr_array_sort (users, compare_users_by_usefulness); + g_ptr_array_set_size (users, p->max_users); + } + + /* sort the users by name */ + g_ptr_array_sort (users, compare_users_by_label); + + /* add the users */ + for (i=0; ilen; ++i) + { + const IndicatorSessionUser * u = g_ptr_array_index (users, i); + item = g_menu_item_new (u->real_name, NULL); + g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + /* cleanup */ + g_ptr_array_free (users, TRUE); + return G_MENU_MODEL (menu); +} + +static GMenuModel * +create_session_section (IndicatorSessionService * self) +{ + GMenu * menu; + GMenuItem * item; + const priv_t * const p = self->priv; + GSettings * const s = p->indicator_settings; + const gboolean ellipsis = use_ellipsis (self); + + menu = g_menu_new (); + + if (indicator_session_actions_can_logout (p->backend_actions) && !g_settings_get_boolean (s, "suppress-logout-menuitem")) + { + item = g_menu_item_new (ellipsis ? _("Log Out\342\200\246") + : _("Log Out"), "indicator.logout"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + if (indicator_session_actions_can_suspend (p->backend_actions)) + { + item = g_menu_item_new (_("Suspend"), "indicator.suspend"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + if (indicator_session_actions_can_hibernate (p->backend_actions)) + { + item = g_menu_item_new (_("Hibernate"), "indicator.hibernate"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + if (!g_settings_get_boolean (s, "suppress-restart-menuitem")) + { + item = g_menu_item_new (ellipsis ? _("Restart\342\200\246") + : _("Restart"), "indicator.restart"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + if (!g_settings_get_boolean (s, "suppress-shutdown-menuitem")) + { + item = g_menu_item_new (ellipsis ? _("Shutdown\342\200\246") + : _("Shutdown"), "indicator.shutdown"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + return G_MENU_MODEL (menu); +} + +static void +create_menu (IndicatorSessionService * self, int form_factor) +{ + GMenu * menu; + GMenu * submenu; + GMenuItem * header; + GMenuModel * sections[16]; + int i; + int n = 0; + + g_assert (0<=form_factor && form_factorpriv->menus[form_factor].menu == NULL); + + if (form_factor == FORM_DESKTOP) + { + sections[n++] = create_admin_section (); + sections[n++] = create_settings_section (self); + sections[n++] = create_switch_section (self); + sections[n++] = create_session_section (self); + } + else if (form_factor == FORM_GREETER) + { + sections[n++] = create_session_section (self); + } + + /* add sections to the submenu */ + submenu = g_menu_new (); + for (i=0; ipriv->menus[form_factor].menu = menu; + self->priv->menus[form_factor].submenu = submenu; +} + +/*** +**** GActions +***/ + +static IndicatorSessionActions * +get_backend_actions (gpointer gself) +{ + return INDICATOR_SESSION_SERVICE(gself)->priv->backend_actions; +} + +static void +on_about_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_about (get_backend_actions(gself)); +} + +static void +on_help_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_help (get_backend_actions(gself)); +} + +static void +on_settings_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_settings (get_backend_actions(gself)); +} + +static void +on_logout_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_logout (get_backend_actions(gself)); +} + +static void +on_suspend_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_suspend (get_backend_actions(gself)); +} + +static void +on_hibernate_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_hibernate (get_backend_actions(gself)); +} + +static void +on_restart_activated (GSimpleAction * action G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_restart (get_backend_actions(gself)); +} + +static void +on_shutdown_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_shutdown (get_backend_actions(gself)); +} + +static void +on_guest_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_switch_to_guest (get_backend_actions(gself)); +} + +static void +on_screensaver_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_switch_to_screensaver (get_backend_actions(gself)); +} + +static void +on_greeter_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_switch_to_greeter (get_backend_actions(gself)); +} + +static void +on_user_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param, + gpointer gself) +{ + const char * username = g_variant_get_string (param, NULL); + indicator_session_actions_switch_to_username (get_backend_actions(gself), + username); +} + +static void +init_gactions (IndicatorSessionService * self) +{ + GVariant * v; + GSimpleAction * a; + priv_t * p = self->priv; + + GActionEntry entries[] = { + { "about", on_about_activated }, + { "help", on_help_activated }, + { "settings", on_settings_activated }, + { "logout", on_logout_activated }, + { "suspend", on_suspend_activated }, + { "hibernate", on_hibernate_activated }, + { "restart", on_restart_activated }, + { "shutdown", on_shutdown_activated }, + { "switch-to-screensaver", on_screensaver_activated }, + { "switch-to-greeter", on_greeter_activated } + }; + + p->actions = g_simple_action_group_new (); + + g_action_map_add_action_entries (G_ACTION_MAP(p->actions), + entries, + G_N_ELEMENTS(entries), + self); + + /* add switch-to-guest action */ + v = create_guest_switcher_state (self); + a = g_simple_action_new_stateful ("switch-to-guest", NULL, v); + g_signal_connect (a, "activate", G_CALLBACK(on_guest_activated), self); + g_simple_action_group_insert (p->actions, G_ACTION(a)); + p->guest_switcher_action = a; + + /* add switch-to-user action... parameter is the uesrname */ + v = create_user_switcher_state (self); + a = g_simple_action_new_stateful ("switch-to-user", G_VARIANT_TYPE_STRING, v); + g_signal_connect (a, "activate", G_CALLBACK(on_user_activated), self); + g_simple_action_group_insert (p->actions, G_ACTION(a)); + p->user_switcher_action = a; + + /* add the header action */ + v = g_variant_new ("(sssb)", "label", ICON_DEFAULT, "a11y", TRUE); + a = g_simple_action_new_stateful ("_header", NULL, v); + g_simple_action_group_insert (p->actions, G_ACTION(a)); + p->header_action = a; + + rebuild_now (self, SECTION_HEADER); +} + +/*** +**** +***/ + +static void +replace_section (GMenu * parent, int pos, GMenuModel * new_section) +{ + g_menu_remove (parent, pos); + g_menu_insert_section (parent, pos, NULL, new_section); + g_object_unref (G_OBJECT(new_section)); +} + +static void +rebuild_now (IndicatorSessionService * self, int sections) +{ + priv_t * p = self->priv; + struct FormMenuInfo * desktop = &p->menus[FORM_DESKTOP]; + struct FormMenuInfo * greeter = &p->menus[FORM_GREETER]; + + if (sections & SECTION_HEADER) + { + update_header_action (self); + } + + if (sections & SECTION_ADMIN) + { + replace_section (desktop->submenu, 0, create_admin_section()); + } + + if (sections & SECTION_SETTINGS) + { + replace_section (desktop->submenu, 1, create_settings_section(self)); + } + + if (sections & SECTION_SWITCH) + { + replace_section (desktop->submenu, 2, create_switch_section(self)); + update_switch_actions (self); + } + + if (sections & SECTION_SESSION) + { + replace_section (desktop->submenu, 3, create_session_section(self)); + replace_section (greeter->submenu, 0, create_session_section(self)); + } +} + +static int +rebuild_timeout_func (IndicatorSessionService * self) +{ + priv_t * p = self->priv; + rebuild_now (self, p->rebuild_flags); + p->rebuild_flags = 0; + p->rebuild_id = 0; + return G_SOURCE_REMOVE; +} + +static void +rebuild_soon (IndicatorSessionService * self, int section) +{ + priv_t * p = self->priv; + + p->rebuild_flags |= section; + + if (p->rebuild_id == 0) + { + static const int REBUILD_INTERVAL_MSEC = 500; + + p->rebuild_id = g_timeout_add (REBUILD_INTERVAL_MSEC, + (GSourceFunc)rebuild_timeout_func, + self); + } +} + +/*** +**** GDBus +***/ + +static void +on_bus_acquired (GDBusConnection * connection, + const gchar * name, + gpointer gself) +{ + int i; + guint id; + GError * err = NULL; + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE(gself); + priv_t * p = self->priv; + + g_debug ("bus acquired: %s", name); + + p->conn = g_object_ref (G_OBJECT (connection)); + + /* export the actions */ + if ((id = g_dbus_connection_export_action_group (connection, + BUS_PATH, + G_ACTION_GROUP (p->actions), + &err))) + { + p->actions_export_id = id; + } + else + { + g_warning ("cannot export action group: %s", err->message); + g_clear_error (&err); + } + + /* export the menus */ + for (i=0; imenus[i]; + + if (menu->menu == NULL) + create_menu (self, i); + + if ((id = g_dbus_connection_export_menu_model (connection, + path, + G_MENU_MODEL (menu->menu), + &err))) + { + menu->export_id = id; + } + else + { + g_warning ("cannot export %s menu: %s", menu_names[i], err->message); + g_clear_error (&err); + } + + g_free (path); + } +} + +static void +unexport (IndicatorSessionService * self) +{ + int i; + priv_t * p = self->priv; + + /* unexport the menus */ + for (i=0; ipriv->menus[i].export_id; + + if (*id) + { + g_dbus_connection_unexport_menu_model (p->conn, *id); + *id = 0; + } + } + + /* unexport the actions */ + if (p->actions_export_id) + { + g_dbus_connection_unexport_action_group (p->conn, p->actions_export_id); + p->actions_export_id = 0; + } +} + +static void +on_name_lost (GDBusConnection * connection G_GNUC_UNUSED, + const gchar * name, + gpointer gself) +{ + g_debug ("%s %s name lost %s", G_STRLOC, G_STRFUNC, name); + + unexport (INDICATOR_SESSION_SERVICE (gself)); +} + +/*** +**** +***/ + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_service_init (IndicatorSessionService * self) +{ + int i; + GStrv keys; + priv_t * p; + gpointer gp; + + /* init our priv pointer */ + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_SERVICE, + IndicatorSessionServicePrivate); + p->indicator_settings = g_settings_new ("com.canonical.indicator.session"); + p->keybinding_settings = g_settings_new ("org.gnome.settings-daemon.plugins.media-keys"); + self->priv = p; + + /* init the backend objects */ + backend_get (g_cancellable_new (), &p->backend_actions, + &p->backend_users, + &p->backend_guest); + + /* init our key-to-User table */ + p->users = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify)indicator_session_user_free); + keys = indicator_session_users_get_keys (p->backend_users); + for (i=0; keys && keys[i]; ++i) + add_user (self, keys[i]); + g_strfreev (keys); + + init_gactions (self); + + /* watch for changes in backend_users */ + gp = p->backend_users; + g_signal_connect (gp, INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED, + G_CALLBACK(on_user_added), self); + g_signal_connect (gp, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, + G_CALLBACK(on_user_changed), self); + g_signal_connect (gp, INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED, + G_CALLBACK(on_user_removed), self); + g_signal_connect_swapped (gp, "notify::is-live-session", + G_CALLBACK(rebuild_switch_section_soon), self); + + /* watch for changes in backend_guest */ + gp = p->backend_guest; + g_signal_connect_swapped (gp, "notify::guest-is-active-session", + G_CALLBACK(rebuild_header_soon), self); + g_signal_connect_swapped (gp, "notify", + G_CALLBACK(rebuild_switch_section_soon), self); + + /* watch for updates in backend_actions */ + gp = p->backend_actions; + g_signal_connect_swapped (gp, "notify", + G_CALLBACK(rebuild_switch_section_soon), self); + g_signal_connect_swapped (gp, "notify", + G_CALLBACK(rebuild_session_section_soon), self); + g_signal_connect_swapped (gp, "notify::has-online-account-error", + G_CALLBACK(rebuild_header_soon), self); + g_signal_connect_swapped (gp, "notify::has-online-account-error", + G_CALLBACK(rebuild_settings_section_soon), self); + + /* watch for changes in the indicator's settings */ + gp = p->indicator_settings; + g_signal_connect_swapped (gp, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(rebuild_switch_section_soon), self); + g_signal_connect_swapped (gp, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(rebuild_session_section_soon), self); + g_signal_connect_swapped (gp, "changed::suppress-logout-menuitem", + G_CALLBACK(rebuild_session_section_soon), self); + g_signal_connect_swapped (gp, "changed::suppress-restart-menuitem", + G_CALLBACK(rebuild_session_section_soon), self); + g_signal_connect_swapped (gp, "changed::suppress-shutdown-menuitem", + G_CALLBACK(rebuild_session_section_soon), self); + g_signal_connect_swapped (gp, "changed::show-real-name-on-panel", + G_CALLBACK(rebuild_header_soon), self); + + /* watch for changes to the lock keybinding */ + gp = p->keybinding_settings; + g_signal_connect_swapped (gp, "changed::screensaver", + G_CALLBACK(rebuild_switch_section_soon), self); +} + +static void +my_constructed (GObject * o) +{ + GBusNameOwnerFlags owner_flags; + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE(o); + + /* own the name in constructed() instead of init() so that + we'll know the value of the 'replace' property */ + owner_flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; + if (self->priv->replace) + owner_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; + + self->priv->own_id = g_bus_own_name (G_BUS_TYPE_SESSION, + BUS_NAME, + owner_flags, + on_bus_acquired, + NULL, + on_name_lost, + self, + NULL); +} + +/*** +**** GObject plumbing: properties +***/ + +static void +my_get_property (GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (o); + + switch (property_id) + { + case PROP_REPLACE: + g_value_set_boolean (value, self->priv->replace); + break; + + case PROP_MAX_USERS: + g_value_set_uint (value, self->priv->max_users); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +my_set_property (GObject * o, + guint property_id, + const GValue * value G_GNUC_UNUSED, + GParamSpec * pspec) +{ + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (o); + + switch (property_id) + { + case PROP_REPLACE: + self->priv->replace = g_value_get_boolean (value); + break; + + case PROP_MAX_USERS: + self->priv->max_users = g_value_get_uint (value); + rebuild_switch_section_soon (self); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +/*** +**** GObject plumbing: life cycle +***/ + +static void +my_dispose (GObject * o) +{ + int i; + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE(o); + priv_t * p = self->priv; + + unexport (self); + + if (p->rebuild_id) + { + g_source_remove (p->rebuild_id); + p->rebuild_id = 0; + } + + if (p->own_id) + { + g_bus_unown_name (p->own_id); + p->own_id = 0; + } + + g_clear_pointer (&p->users, g_hash_table_destroy); + g_clear_object (&p->backend_users); + g_clear_object (&p->backend_guest); + g_clear_object (&p->backend_actions); + g_clear_object (&p->indicator_settings); + g_clear_object (&p->keybinding_settings); + g_clear_object (&p->actions); + + for (i=0; imenus[i].menu); + + g_clear_object (&p->header_action); + g_clear_object (&p->user_switcher_action); + g_clear_object (&p->guest_switcher_action); + g_clear_object (&p->conn); + + G_OBJECT_CLASS (indicator_session_service_parent_class)->dispose (o); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_service_class_init (IndicatorSessionServiceClass * klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = my_dispose; + object_class->constructed = my_constructed; + object_class->get_property = my_get_property; + object_class->set_property = my_set_property; + + g_type_class_add_private (klass, sizeof (IndicatorSessionServicePrivate)); + + properties[PROP_0] = NULL; + + properties[PROP_REPLACE] = g_param_spec_boolean ("replace", + "Replace Service", + "Replace existing service", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_MAX_USERS] = g_param_spec_uint ("max-users", + "Max Users", + "Max visible users", + 0, INT_MAX, 12, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, PROP_LAST, properties); +} + +IndicatorSessionService * +indicator_session_service_new (gboolean replace) +{ + GObject * o = g_object_new (INDICATOR_TYPE_SESSION_SERVICE, + "replace", replace, + NULL); + + return INDICATOR_SESSION_SERVICE (o); +} diff --git a/src/service.h b/src/service.h new file mode 100644 index 0000000..2a78855 --- /dev/null +++ b/src/service.h @@ -0,0 +1,64 @@ +/* + * 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 . + */ + +#ifndef __INDICATOR_SESSION_SERVICE_H__ +#define __INDICATOR_SESSION_SERVICE_H__ + +#include +#include + +G_BEGIN_DECLS + +/* standard GObject macros */ +#define INDICATOR_TYPE_SESSION_SERVICE (indicator_session_service_get_type()) +#define INDICATOR_SESSION_SERVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_SERVICE, IndicatorSessionService)) +#define INDICATOR_SESSION_SERVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_SERVICE, IndicatorSessionServiceClass)) +#define INDICATOR_SESSION_SERVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_TYPE_SESSION_SERVICE, IndicatorSessionServiceClass)) +#define INDICATOR_IS_SESSION_SERVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_SERVICE)) + +typedef struct _IndicatorSessionService IndicatorSessionService; +typedef struct _IndicatorSessionServiceClass IndicatorSessionServiceClass; +typedef struct _IndicatorSessionServicePrivate IndicatorSessionServicePrivate; + +/** + * The Indicator Session Service. + */ +struct _IndicatorSessionService +{ + /*< private >*/ + GObject parent; + IndicatorSessionServicePrivate * priv; +}; + +struct _IndicatorSessionServiceClass +{ + GObjectClass parent_class; +}; + +/*** +**** +***/ + +GType indicator_session_service_get_type (void); + +IndicatorSessionService * indicator_session_service_new (gboolean replace); + +G_END_DECLS + +#endif /* __INDICATOR_SESSION_SERVICE_H__ */ diff --git a/src/session-dbus.c b/src/session-dbus.c deleted file mode 100644 index 4ece444..0000000 --- a/src/session-dbus.c +++ /dev/null @@ -1,282 +0,0 @@ -/* -The Dbus object on the bus for the indicator. - -Copyright 2010 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 -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 . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "session-dbus.h" -#include "shared-names.h" - -static GVariant * get_users_real_name (SessionDbus * service); -static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data); -static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data); - -#include "gen-session-dbus.xml.h" - -typedef struct _SessionDbusPrivate SessionDbusPrivate; -struct _SessionDbusPrivate { - gchar * name; - GDBusConnection * bus; - GCancellable * bus_cancel; - guint dbus_registration; -}; - -/* GDBus Stuff */ -static GDBusNodeInfo * node_info = NULL; -static GDBusInterfaceInfo * interface_info = NULL; -static GDBusInterfaceVTable interface_table = { - method_call: bus_method_call, - get_property: NULL, /* No properties */ - set_property: NULL /* No properties */ -}; - -#define SESSION_DBUS_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), SESSION_DBUS_TYPE, SessionDbusPrivate)) - -static void session_dbus_class_init (SessionDbusClass *klass); -static void session_dbus_init (SessionDbus *self); -static void session_dbus_dispose (GObject *object); -static void session_dbus_finalize (GObject *object); - -G_DEFINE_TYPE (SessionDbus, session_dbus, G_TYPE_OBJECT); - -static void -session_dbus_class_init (SessionDbusClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (SessionDbusPrivate)); - - object_class->dispose = session_dbus_dispose; - object_class->finalize = session_dbus_finalize; - - /* Setting up the DBus interfaces */ - if (node_info == NULL) { - GError * error = NULL; - - node_info = g_dbus_node_info_new_for_xml(_session_dbus, &error); - if (error != NULL) { - g_error("Unable to parse Session Service Interface description: %s", error->message); - g_error_free(error); - } - } - - if (interface_info == NULL) { - interface_info = g_dbus_node_info_lookup_interface(node_info, INDICATOR_SESSION_SERVICE_DBUS_IFACE); - - if (interface_info == NULL) { - g_error("Unable to find interface '" INDICATOR_SESSION_SERVICE_DBUS_IFACE "'"); - } - } - - return; -} - -static void -session_dbus_init (SessionDbus *self) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(self); - - priv->name = NULL; - priv->bus = NULL; - priv->bus_cancel = NULL; - priv->dbus_registration = 0; - - priv->bus_cancel = g_cancellable_new(); - g_bus_get(G_BUS_TYPE_SESSION, - priv->bus_cancel, - bus_get_cb, - self); - - return; -} - -static void -bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data) -{ - GError * error = NULL; - GDBusConnection * connection = g_bus_get_finish(res, &error); - - if (error != NULL) { - g_error("OMG! Unable to get a connection to DBus: %s", error->message); - g_error_free(error); - return; - } - - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(user_data); - - g_warn_if_fail(priv->bus == NULL); - priv->bus = connection; - - if (priv->bus_cancel != NULL) { - g_object_unref(priv->bus_cancel); - priv->bus_cancel = NULL; - } - - /* Now register our object on our new connection */ - priv->dbus_registration = g_dbus_connection_register_object(priv->bus, - INDICATOR_SESSION_SERVICE_DBUS_OBJECT, - interface_info, - &interface_table, - user_data, - NULL, - &error); - - if (error != NULL) { - g_error("Unable to register the object to DBus: %s", error->message); - g_error_free(error); - return; - } - - return; -} - -/* A method has been called from our dbus inteface. Figure out what it - is and dispatch it. */ -static void -bus_method_call (GDBusConnection * connection, const gchar * sender, - const gchar * path, const gchar * interface, - const gchar * method, GVariant * params, - GDBusMethodInvocation * invocation, gpointer user_data) -{ - SessionDbus * service = SESSION_DBUS (user_data); - - GVariant * retval = NULL; - - if (g_strcmp0(method, "GetUserRealName") == 0) { - retval = get_users_real_name (service); - } - else { - g_warning("Calling method '%s' on the indicator service and it's unknown", method); - } - g_dbus_method_invocation_return_value(invocation, retval); - return; -} - -static void -session_dbus_dispose (GObject *object) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(object); - - if (priv->dbus_registration != 0) { - g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration); - /* Don't care if it fails, there's nothing we can do */ - priv->dbus_registration = 0; - } - - if (priv->bus != NULL) { - g_object_unref(priv->bus); - priv->bus = NULL; - } - - if (priv->bus_cancel != NULL) { - g_cancellable_cancel(priv->bus_cancel); - g_object_unref(priv->bus_cancel); - priv->bus_cancel = NULL; - } - - G_OBJECT_CLASS (session_dbus_parent_class)->dispose (object); - return; -} - -static void -session_dbus_finalize (GObject *object) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(object); - - g_clear_pointer (&priv->name, g_free); - - G_OBJECT_CLASS (session_dbus_parent_class)->finalize (object); - return; -} - -static GVariant * -get_users_real_name (SessionDbus * service) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(service); - return g_variant_new ("(s)", priv->name ? priv->name : ""); -} - -SessionDbus * -session_dbus_new (void) -{ - return SESSION_DBUS(g_object_new(SESSION_DBUS_TYPE, NULL)); -} - -void -session_dbus_set_name (SessionDbus * session, const gchar * name) -{ -} - -void -session_dbus_set_users_real_name (SessionDbus * session, const gchar * name) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session); - GError * error = NULL; - - g_free (priv->name); - priv->name = g_strdup(name); - - if (priv->bus != NULL) { - g_dbus_connection_emit_signal (priv->bus, - NULL, - INDICATOR_SESSION_SERVICE_DBUS_OBJECT, - INDICATOR_SESSION_SERVICE_DBUS_IFACE, - "UserRealNameUpdated", - g_variant_new ("(s)", priv->name, NULL), - &error); - - if (error != NULL) { - g_warning("Unable to send UserRealNameUpdated signal: %s", error->message); - g_error_free(error); - return; - } - } - return; -} - -void session_dbus_restart_required (SessionDbus* session) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session); - GError * error = NULL; - - if (priv->bus != NULL) { - g_debug("About to send RebootRequired signal"); - - g_dbus_connection_emit_signal (priv->bus, - NULL, - INDICATOR_SESSION_SERVICE_DBUS_OBJECT, - INDICATOR_SESSION_SERVICE_DBUS_IFACE, - "RestartRequired", - NULL, - &error); - - if (error != NULL) { - g_warning("Unable to send reboot-required signal: %s", error->message); - g_error_free(error); - } - } - -} diff --git a/src/session-dbus.h b/src/session-dbus.h deleted file mode 100644 index 7520f06..0000000 --- a/src/session-dbus.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -The Dbus object on the bus for the indicator. - -Copyright 2010 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 __SESSION_DBUS_H__ -#define __SESSION_DBUS_H__ - -#include -#include - -G_BEGIN_DECLS - -#define SESSION_DBUS_TYPE (session_dbus_get_type ()) -#define SESSION_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SESSION_DBUS_TYPE, SessionDbus)) -#define SESSION_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SESSION_DBUS_TYPE, SessionDbusClass)) -#define IS_SESSION_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SESSION_DBUS_TYPE)) -#define IS_SESSION_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SESSION_DBUS_TYPE)) -#define SESSION_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SESSION_DBUS_TYPE, SessionDbusClass)) - -typedef struct _SessionDbus SessionDbus; -typedef struct _SessionDbusClass SessionDbusClass; - -struct _SessionDbusClass { - GObjectClass parent_class; - void (*icon_updated) (SessionDbus * session, gchar * icon, gpointer user_data); -}; - -struct _SessionDbus { - GObject parent; -}; - -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_restart_required (SessionDbus* session); -G_END_DECLS - -#endif diff --git a/src/session-dbus.xml b/src/session-dbus.xml deleted file mode 100644 index 96e9837..0000000 --- a/src/session-dbus.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/src/session-menu-mgr.c b/src/session-menu-mgr.c deleted file mode 100644 index b618135..0000000 --- a/src/session-menu-mgr.c +++ /dev/null @@ -1,1226 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - 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 -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 "config.h" - -#include -#include /* geteuid(), getpwuid() */ - -#include -#include - -#include -#include - -#include "dbus-upower.h" -#include "session-menu-mgr.h" -#include "shared-names.h" -#include "users-service-dbus.h" -#include "online-accounts-mgr.h" - -#define DEBUG_SHOW_ALL FALSE - -#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 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" -#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" -#endif - -/** - * 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, - SWITCHER_MODE_NONE -} -SwitcherMode; - -/** - * 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 the - * UsersServiceDBus facade class. - */ -struct _SessionMenuMgr -{ - GObject parent_instance; - - DbusmenuMenuitem * top_mi; - DbusmenuMenuitem * screensaver_mi; - DbusmenuMenuitem * lock_mi; - DbusmenuMenuitem * lock_switch_mi; - DbusmenuMenuitem * guest_mi; - DbusmenuMenuitem * online_accounts_mi; - DbusmenuMenuitem * logout_mi; - DbusmenuMenuitem * suspend_mi; - DbusmenuMenuitem * hibernate_mi; - DbusmenuMenuitem * restart_mi; - DbusmenuMenuitem * shutdown_mi; - - GSList * user_menuitems; - gint user_menuitem_index; - - GSettings * lockdown_settings; - 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; - UsersServiceDbus * users_dbus_facade; - OnlineAccountsMgr * online_accounts_mgr; -}; - -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 *); - -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 (AccountsUser *); -static void action_func_spawn_async (const char * cmd); - -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_user_logged_in_changed (UsersServiceDbus *, - AccountsUser *, - SessionMenuMgr *); - -/** -*** GObject init / dispose -**/ - -G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); - -static void -session_menu_mgr_init (SessionMenuMgr *mgr) -{ - mgr->top_mi = dbusmenu_menuitem_new (); - - /* Lockdown settings */ - GSettings * s = g_settings_new ("org.gnome.desktop.lockdown"); - 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); - 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_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 */ - 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 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); - 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); - - /* Online accounts menu item */ - mgr->online_accounts_mgr = online_accounts_mgr_new (); -} - -static void -session_menu_mgr_dispose (GObject *object) -{ - 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_clear_object (&mgr->top_mi); - g_clear_object (&mgr->session_dbus); - g_clear_object (&mgr->online_accounts_mgr); - - g_slist_free (mgr->user_menuitems); - mgr->user_menuitems = NULL; - - G_OBJECT_CLASS (session_menu_mgr_parent_class)->dispose (object); -} - -static void -session_menu_mgr_class_init (SessionMenuMgrClass * klass) -{ - GObjectClass* object_class = G_OBJECT_CLASS (klass); - object_class->dispose = session_menu_mgr_dispose; -} - -/*** -**** UPower Proxy: -**** -**** 1. While bootstrapping, we invoke the AllowSuspend and AllowHibernate -**** 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. -**** -***/ - -static void -on_upower_properties_changed (SessionMenuMgr * mgr) -{ - gboolean need_refresh = FALSE; - - if (mgr->upower_proxy != NULL) - { - gboolean b; - - /* suspend */ - b = dbus_upower_get_can_suspend (mgr->upower_proxy); - if (mgr->can_suspend != b) - { - mgr->can_suspend = b; - need_refresh = TRUE; - } - - /* hibernate */ - b = dbus_upower_get_can_hibernate (mgr->upower_proxy); - if (mgr->can_hibernate != b) - { - mgr->can_hibernate = b; - need_refresh = TRUE; - } - } - - if (need_refresh) - { - update_session_menuitems (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; - mgr->upower_proxy = dbus_upower_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - UPOWER_ADDRESS, - UPOWER_PATH, - NULL, - &error); - if (error != NULL) - { - g_warning ("Error creating upower proxy: %s", error->message); - g_clear_error (&error); - } - else - { - 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); - } - - g_signal_connect_swapped (mgr->upower_proxy, "changed", - G_CALLBACK(on_upower_properties_changed), mgr); - } -} - -/*** -**** 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 || DEBUG_SHOW_ALL); -} - -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; -} - -static void -check_online_accounts_status (SessionMenuMgr * mgr, DbusmenuMenuitem * mi) -{ - const gchar *disposition; - gboolean on_alert; - - disposition = - dbusmenu_menuitem_property_get (mi, DBUSMENU_MENUITEM_PROP_DISPOSITION); - on_alert = g_strcmp0 (disposition, DBUSMENU_MENUITEM_DISPOSITION_ALERT) == 0; - - mi_set_visible (mi, on_alert); -} - -static void -on_online_accounts_changed (SessionMenuMgr * mgr, const gchar * property, - GVariant *value, DbusmenuMenuitem *mi) -{ - if (g_strcmp0 (property, DBUSMENU_MENUITEM_PROP_DISPOSITION) == 0) - { - check_online_accounts_status(mgr, 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->top_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->top_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->top_mi, mi); - - mi = mi_new (_("System Settings\342\200\246")); - mi_set_visible (mi, show_settings); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), - CMD_SYSTEM_SETTINGS); - - mi = mgr->online_accounts_mi = - online_accounts_mgr_get_menu_item (mgr->online_accounts_mgr); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, - G_CALLBACK(on_online_accounts_changed), - mgr); - check_online_accounts_status (mgr, mi); - - mi = mi_new_separator (); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - } -} - -/*** -**** Session Menuitems -**** -***/ - -static void -update_session_menuitems (SessionMenuMgr * mgr) -{ - gboolean v; - GSettings * s = mgr->indicator_settings; - - v = !mgr->greeter_mode - && !is_this_live_session() - && !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); - - v = mgr->can_suspend - && mgr->allow_suspend; - mi_set_visible (mgr->suspend_mi, v); - - v = mgr->can_hibernate - && mgr->allow_hibernate; - mi_set_visible (mgr->hibernate_mi, v); - - 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); -} - -/* 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) -{ - const gboolean confirm_needed = !g_settings_get_boolean ( - mgr->indicator_settings, - "suppress-logout-restart-shutdown"); - - mi_set_label (mgr->logout_mi, confirm_needed ? _("Log Out\342\200\246") - : _("Log Out")); - - mi_set_label (mgr->shutdown_mi, confirm_needed ? _("Shut Down\342\200\246") - : _("Shut Down")); - - mi_set_label (mgr->restart_mi, confirm_needed ? _("Restart\342\200\246") - : _("Restart")); -} - -static void -build_session_menuitems (SessionMenuMgr* mgr) -{ - DbusmenuMenuitem * mi; - - mi = mgr->logout_mi = mi_new (_("Log Out\342\200\246")); - dbusmenu_menuitem_child_append (mgr->top_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->top_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->top_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->top_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 (_("Shut Down\342\200\246")); - dbusmenu_menuitem_child_append (mgr->top_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 */ - -static GQuark -get_menuitem_quark (void) -{ - static GQuark q = 0; - - if (G_UNLIKELY(!q)) - { - q = g_quark_from_static_string ("menuitem"); - } - - return q; -} - -static DbusmenuMenuitem* -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_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) -{ - static GQuark q = 0; - - if (G_UNLIKELY(!q)) - { - q = g_quark_from_static_string ("name-collision"); - } - - return q; -} - -static gboolean -user_has_name_collision (AccountsUser * u) -{ - return g_object_get_qdata (G_OBJECT(u), get_collision_quark()) != NULL; -} - -static void -user_set_name_collision (AccountsUser * u, gboolean b) -{ - g_object_set_qdata (G_OBJECT(u), get_collision_quark(), GINT_TO_POINTER(b)); -} - -/*** -**** -***/ - -static void -on_guest_logged_in_changed (UsersServiceDbus * usd, - SessionMenuMgr * mgr) -{ - 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, - 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 ("%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 -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; - } - - 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)); - - if (!gstr->len) - g_string_assign (gstr, 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 -{ - gpointer instance; - gulong handler_id; -} -SignalHandlerData; - -/* when a user menuitem is destroyed, - it should stop listening for its UserAccount's property changes */ -static void -on_user_menuitem_destroyed (SignalHandlerData * data) -{ - g_signal_handler_disconnect (data->instance, data->handler_id); - g_free (data); -} - -static DbusmenuMenuitem* -user_menuitem_new (AccountsUser * user, SessionMenuMgr * mgr) -{ - DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - mi_set_type (mi, USER_ITEM_TYPE); - - /* 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 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, - is_current_user); - - /* 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; -} - -/* for sorting AccountsUsers from most to least frequently used */ -static gint -compare_users_by_login_frequency (gconstpointer a, gconstpointer 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; -} - -/* for sorting AccountsUsers alphabetically */ -static gint -compare_users_by_username (gconstpointer ga, gconstpointer gb) -{ - AccountsUser * a = ACCOUNTS_USER(ga); - AccountsUser * b = ACCOUNTS_USER(gb); - - 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 */ - { - user_set_name_collision (a, TRUE); - user_set_name_collision (b, TRUE); - } - - return ret; -} - -static gboolean -is_user_switching_allowed (SessionMenuMgr * mgr) -{ - /* maybe it's locked down */ - if (g_settings_get_boolean (mgr->lockdown_settings, "disable-user-switching")) - { - return FALSE; - } - - /* maybe the seat doesn't support activation */ - if (!users_service_dbus_can_activate_session (mgr->users_dbus_facade)) - { - return FALSE; - } - - return TRUE; -} - -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; - const char * current_real_name = NULL; - - /** - *** Start Screen Saver - *** Switch Account... - *** Lock - *** Lock / Switch Account... - **/ - - const SwitcherMode mode = get_switcher_mode (mgr); - - mi = mgr->screensaver_mi = mi_new (_("Start Screen Saver")); - mi_set_visible (mi, mode == SWITCHER_MODE_SCREENSAVER); - dbusmenu_menuitem_child_add_position (mgr->top_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, mode == SWITCHER_MODE_SWITCH); - dbusmenu_menuitem_child_add_position (mgr->top_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, mode == SWITCHER_MODE_LOCK); - dbusmenu_menuitem_child_add_position (mgr->top_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, mode == SWITCHER_MODE_SWITCH_OR_LOCK); - dbusmenu_menuitem_child_add_position (mgr->top_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 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, !is_guest && guest_allowed); - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, _("Guest Session")); - dbusmenu_menuitem_child_add_position (mgr->top_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); - - if (guest_allowed && is_guest) - { - current_real_name = _("Guest"); - } - - /*** - **** Users - ***/ - - /* if we can switch to another user account, show them here */ - 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) - { - 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) - { - 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; - for (i=0, u=users; inext, i++) - { - AccountsUser * user = u->data; - DbusmenuMenuitem * mi = user_menuitem_new (user, mgr); - dbusmenu_menuitem_child_add_position (mgr->top_mi, mi, pos++); - items = g_slist_prepend (items, mi); - } - } - - g_list_free (users); - - /* separator */ - if (mode != SWITCHER_MODE_SCREENSAVER && !is_guest && guest_allowed) - { - mi = mi_new_separator (); - dbusmenu_menuitem_child_add_position (mgr->top_mi, mi, pos++); - items = g_slist_prepend (items, mi); - } - - if (current_real_name != NULL) - { - session_dbus_set_users_real_name (mgr->session_dbus, - current_real_name); - } - - update_screensaver_shortcut (mgr); - mgr->user_menuitems = items; -} - -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->top_mi, l->data); - } - g_slist_free (mgr->user_menuitems); - mgr->user_menuitems = NULL; - - /* add fresh user menuitems */ - if (!mgr->greeter_mode) - { - build_user_menuitems (mgr); - } -} - -/*** -**** Actions! -***/ - -static void -action_func_spawn_async (const char * cmd) -{ - GError * error = NULL; - - g_debug ("%s calling \"%s\"", G_STRFUNC, cmd); - g_spawn_command_line_async (cmd, &error); - - if (error != NULL) - { - g_warning ("Unable to execute \"%s\": %s", cmd, error->message); - g_clear_error (&error); - } -} - -/* Calling "Lock" locks the screen & goes to black. - Calling "SimulateUserActivity" afterwards shows the Lock Screen. */ -static void -lock_helper (SessionMenuMgr * mgr, gboolean show_lock_screen) -{ - if (!g_settings_get_boolean (mgr->lockdown_settings, "disable-lock-screen")) - { - 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); - } -} - -static void -action_func_lock (SessionMenuMgr * mgr) -{ - lock_helper (mgr, FALSE); -} - -static void -action_func_switch_to_lockscreen (SessionMenuMgr * mgr) -{ - lock_helper (mgr, TRUE); -} - -static void -action_func_switch_to_greeter (SessionMenuMgr * mgr) -{ - action_func_lock (mgr); - users_service_dbus_show_greeter (mgr->users_dbus_facade); -} - -static void -action_func_switch_to_user (AccountsUser * user) -{ - SessionMenuMgr * mgr = user_get_mgr (user); - - g_return_if_fail (mgr != NULL); - - if (g_strcmp0 (g_get_user_name(), accounts_user_get_user_name(user)) != 0) - { - action_func_lock (mgr); - users_service_dbus_activate_user_session (mgr->users_dbus_facade, user); - } -} - -static void -action_func_switch_to_guest (SessionMenuMgr * mgr) -{ - action_func_lock (mgr); - users_service_dbus_activate_guest_session (mgr->users_dbus_facade); -} - -static void -action_func_suspend (SessionMenuMgr * mgr) -{ - GError * error = NULL; - - dbus_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); - } -} - -static void -action_func_hibernate (SessionMenuMgr * mgr) -{ - GError * error = NULL; - - dbus_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); - } -} - -/*** -**** -***/ - -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; -} - -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) -{ - 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_NONE; - } - 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 /* 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); - - /* 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; -} - - -/*** -**** -***/ - -SessionMenuMgr* -session_menu_mgr_new (SessionDbus * session_dbus, - gboolean greeter_mode) -{ - SessionMenuMgr* mgr = g_object_new (SESSION_TYPE_MENU_MGR, NULL); - mgr->greeter_mode = greeter_mode; - mgr->session_dbus = g_object_ref (session_dbus); - build_admin_menuitems (mgr); - const guint n = g_list_length (dbusmenu_menuitem_get_children (mgr->top_mi)); - mgr->user_menuitem_index = n; - update_user_menuitems (mgr); - build_session_menuitems (mgr); - - /* After we have the session menu items built we can look to - align them with UPower */ - on_upower_properties_changed (mgr); - - return mgr; -} - -/** - * session_menu_mgr_get_menu: - * - * Returns: (transfer none): the manager's menu. - */ -DbusmenuMenuitem * -session_menu_mgr_get_menu (SessionMenuMgr * mgr) -{ - g_return_val_if_fail (IS_SESSION_MENU_MGR(mgr), NULL); - - return mgr->top_mi; -} diff --git a/src/session-menu-mgr.h b/src/session-menu-mgr.h deleted file mode 100644 index 5a173e1..0000000 --- a/src/session-menu-mgr.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - 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 -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 _SESSION_MENU_MGR_H_ -#define _SESSION_MENU_MGR_H_ - -#include - -#include "session-dbus.h" - -G_BEGIN_DECLS - -#define SESSION_TYPE_MENU_MGR (session_menu_mgr_get_type ()) -#define SESSION_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SESSION_TYPE_MENU_MGR, SessionMenuMgr)) -#define SESSION_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SESSION_TYPE_MENU_MGR, SessionMenuMgrClass)) -#define IS_SESSION_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SESSION_TYPE_MENU_MGR)) -#define IS_SESSION_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SESSION_TYPE_MENU_MGR)) -#define SESSION_MENU_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SESSION_TYPE_MENU_MGR, SessionMenuMgrClass)) - -typedef struct _SessionMenuMgrClass SessionMenuMgrClass; -typedef struct _SessionMenuMgr SessionMenuMgr; - -struct _SessionMenuMgrClass -{ - GObjectClass parent_class; -}; - -GType session_menu_mgr_get_type (void) G_GNUC_CONST; - -SessionMenuMgr* session_menu_mgr_new (SessionDbus * session_dbus, - gboolean greeter_mode); - -DbusmenuMenuitem* session_menu_mgr_get_menu (SessionMenuMgr * mgr); - - -G_END_DECLS - -#endif /* _SESSION_MENU_MGR_H_ */ diff --git a/src/session-service.c b/src/session-service.c deleted file mode 100644 index 13438d3..0000000 --- a/src/session-service.c +++ /dev/null @@ -1,96 +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 - Christoph Korn - Cody Russell - 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 -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 "config.h" - -#include -#include - -#include -#include -#include - -#include - -#include - -#include - -#include "session-dbus.h" -#include "session-menu-mgr.h" -#include "shared-names.h" -#include "users-service-dbus.h" - -static SessionDbus * session_dbus = NULL; -static GMainLoop * mainloop = NULL; - - -/* 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); - } -} - -static inline gboolean -is_greeter_mode (void) -{ - return !g_strcmp0 (g_getenv ("INDICATOR_GREETER_MODE"), "1"); -} - -/* Main, is well, main. It brings everything up and throws - us into the mainloop of no return. */ -int -main (int argc, char ** argv) -{ - /* 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, - G_CALLBACK(service_shutdown), NULL); - - session_dbus = session_dbus_new(); - - SessionMenuMgr * menu_mgr = session_menu_mgr_new (session_dbus, is_greeter_mode()); - DbusmenuServer* server = dbusmenu_server_new (INDICATOR_SESSION_DBUS_OBJECT); - dbusmenu_server_set_root (server, session_menu_mgr_get_menu (menu_mgr)); - - mainloop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(mainloop); - - return 0; -} - diff --git a/src/shared-names.h b/src/shared-names.h deleted file mode 100644 index c08f98a..0000000 --- a/src/shared-names.h +++ /dev/null @@ -1,52 +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__ - -#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 ICON_DEFAULT "system-devices-panel" -#define ICON_INFO "system-devices-panel-information" -#define ICON_ALERT "system-devices-panel-alert" - -/* 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/upower.xml b/src/upower.xml deleted file mode 100644 index 18d5fbd..0000000 --- a/src/upower.xml +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - The DeviceKit-power service is available via the system message - bus. To access the service, use - the org.freedesktop.UPower interface on - the /org/freedesktop/UPower object on - the D-Bus system bus service with the well-known - name org.freedesktop.UPower. - - - - -$ dbus-send --print-reply \ - --system \ - --dest=org.freedesktop.UPower \ - /org/freedesktop/UPower \ - org.freedesktop.UPower.EnumerateDevices - -method return sender=:1.386 -> dest=:1.451 reply_serial=2 - array [ - object path "/org/freedesktop/UPower/devices/line_power_AC" - object path "/org/freedesktop/UPower/devices/battery_BAT0" - ] - - - - - - - - - - - - An array of object paths for devices. - - - - - - Enumerate all power objects on the system. - - - - - - - - - - Object path of device that was added. - - - - - - Emitted when a device is added. - - - - - - - - - - Object path of device that was removed. - - - - - - Emitted when a device is removed. - - - - - - - - - - Object path of device that was changed. - - - - - - Emitted when a device changed. - - - - - - - - - - - - Emitted when one or more properties on the object changes. - - - - - - - - - - - - This signal is sent when the session is about to be suspended or - hibernated. - Session and system programs have one second to do anything required - before the sleep action is taken (such as sending out Avahi or - Jabber messages). - - - - - - - - - - - - This signal is sent when the session has just returned from - Suspend() or Hibernate(). - Session and system programs can then do anything required (such as - sending out Avahi or Jabber messages). - - - - - - - - - - - - - This method tells UPower that the Suspend() or Hibernate() method - is about to be called. - This allows UPower to emit the Suspending signal whilst - session activities are happening that have to be done before the - suspend process is started. - - - This method would typically be called by the session power - management daemon, before it locks the screen and waits for the - screen to fade to black. - The session power management component would then call Suspend() or - Hibernate() when these syncronous tasks have completed. - - - If this method is not called than nothing bad will happen and - Suspend() or Hibernate() will block for the required second. - - - - - - - - - - - - - Suspends the computer into a low power state. - System state is not preserved if the power is lost. - - - If AboutToRequestSleep() has not been called then UPower will send - the Sleeping() signal and block for one second. - - - If AboutToRequestSleep() has been called less than one second - before this method is called then UPower will block for the - remaining time to complete one second of delay. - - - - - - - - - - - TRUE if allowed, otherwise FALSE - - - - - Check if the caller has (or can get) the PolicyKit privilege to call - Suspend. - - - - - - - - - - - - - Hibernates the computer into a low power state. - System state is preserved if the power is lost. - - - If AboutToRequestSleep() has not been called then UPower will send - the Sleeping() signal and block for one second. - - - If AboutToRequestSleep() has been called less than one second - before this method is called then UPower will block for the - remaining time to complete one second of delay. - - - - - - - - - - - TRUE if allowed, otherwise FALSE - - - - - Check if the caller has (or can get) the PolicyKit privilege to call - Hibernate. - - - - - - - - - - Version of the running daemon, e.g. 002. - - - - - - Whether the system is able to suspend. - - - - - - Whether the system is able to hibernate. - - - - - - Indicates whether the system is running on battery power. - This property is provided for convenience. - - - - - - Indicates whether the system is running on battery power and if the battery is critically low. - This property is provided for convenience. - - - - - - - - Indicates if the laptop lid is closed where the display cannot be seen. - - - - - - - - - - If the system has a lid device. - - - - - - - - diff --git a/src/user-widget.c b/src/user-widget.c deleted file mode 100644 index 79b87b0..0000000 --- a/src/user-widget.c +++ /dev/null @@ -1,292 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - Mirco Müller - 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 . -*/ - -#ifdef HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -#include "shared-names.h" -#include "user-widget.h" - - -typedef struct _UserWidgetPrivate UserWidgetPrivate; - -struct _UserWidgetPrivate -{ - DbusmenuMenuitem* twin_item; - GtkWidget* user_image; - GtkWidget* user_name; - GtkWidget* container; - GtkWidget* tick_icon; - gboolean logged_in; - gboolean sessions_active; -}; - -#define USER_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), USER_WIDGET_TYPE, UserWidgetPrivate)) - -/* Prototypes */ -static void user_widget_class_init (UserWidgetClass *klass); -static void user_widget_init (UserWidget *self); -static void user_widget_dispose (GObject *object); -static void user_widget_finalize (GObject *object); - -static void user_widget_set_twin_item (UserWidget* self, - DbusmenuMenuitem* twin_item); - -static gboolean user_widget_primitive_draw_cb_gtk_3 (GtkWidget *image, - cairo_t* cr, - gpointer user_data); - -G_DEFINE_TYPE (UserWidget, user_widget, GTK_TYPE_MENU_ITEM); - -static void -user_widget_class_init (UserWidgetClass *klass) -{ - GObjectClass * gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (UserWidgetPrivate)); - - gobject_class->dispose = user_widget_dispose; - gobject_class->finalize = user_widget_finalize; -} - -static void -user_widget_init (UserWidget *self) -{ - self->priv = USER_WIDGET_GET_PRIVATE(self); - - UserWidgetPrivate * priv = self->priv; - - priv->user_image = NULL; - priv->user_name = NULL; - priv->logged_in = FALSE; - priv->sessions_active = FALSE; - priv->container = NULL; - priv->tick_icon = NULL; - - // Create the UI elements. - priv->user_image = gtk_image_new (); - gtk_misc_set_alignment(GTK_MISC(priv->user_image), 0.0, 0.0); - - priv->user_name = gtk_label_new (NULL); - - priv->container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); - - priv->tick_icon = gtk_image_new_from_icon_name ("account-logged-in", - GTK_ICON_SIZE_MENU); - gtk_misc_set_alignment(GTK_MISC(priv->tick_icon), 1.0, 0.5); - - // Pack it together - gtk_box_pack_start (GTK_BOX (priv->container), - priv->user_image, - FALSE, - FALSE, - 0); - gtk_box_pack_start (GTK_BOX (priv->container), - priv->user_name, - FALSE, - FALSE, - 3); - gtk_box_pack_end (GTK_BOX(priv->container), - priv->tick_icon, - FALSE, - FALSE, 5); - - gtk_widget_show_all (priv->container); - gtk_container_add (GTK_CONTAINER (self), priv->container); - gtk_widget_show_all (priv->tick_icon); - gtk_widget_set_no_show_all (priv->tick_icon, TRUE); - gtk_widget_hide (priv->tick_icon); - - - // Fetch the drawing context. - g_signal_connect_after (GTK_WIDGET(self), "draw", - G_CALLBACK(user_widget_primitive_draw_cb_gtk_3), - GTK_WIDGET(self)); -} - -static void -user_widget_dispose (GObject *object) -{ - G_OBJECT_CLASS (user_widget_parent_class)->dispose (object); -} - -// TODO tidy up image and name -static void -user_widget_finalize (GObject *object) -{ - G_OBJECT_CLASS (user_widget_parent_class)->finalize (object); -} - - -/*****************************************************************/ - -// TODO handle drawing of green check mark -static gboolean -user_widget_primitive_draw_cb_gtk_3 (GtkWidget *widget, - cairo_t* cr, - gpointer user_data) -{ - g_return_val_if_fail(IS_USER_WIDGET(user_data), FALSE); - UserWidget* meta = USER_WIDGET(user_data); - UserWidgetPrivate * priv = USER_WIDGET_GET_PRIVATE(meta); - - // Draw dot only when user is the current user. - if (dbusmenu_menuitem_property_get_bool (priv->twin_item, USER_ITEM_PROP_IS_CURRENT_USER)) - { - gdouble x, y; - GtkStyle * style = gtk_widget_get_style (widget); - - GtkAllocation allocation; - gtk_widget_get_allocation (widget, &allocation); - x = allocation.x + 13; - y = allocation.height / 2; - - cairo_arc (cr, x, y, 3.0, 0.0, 2 * G_PI); - - cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0, - style->fg[gtk_widget_get_state(widget)].green/65535.0, - style->fg[gtk_widget_get_state(widget)].blue/65535.0); - cairo_fill (cr); - } - - return FALSE; -} - -/*** -**** -***/ - -static void -update_icon (UserWidget * self, DbusmenuMenuitem * mi) -{ - gboolean updated = FALSE; - GtkImage * image = GTK_IMAGE(self->priv->user_image); - - /* first try the menuitem's icon property */ - const gchar * icon_name = dbusmenu_menuitem_property_get (mi, USER_ITEM_PROP_ICON); - if (icon_name != NULL) - { - int width = 18; /* arbitrary default values */ - int height = 18; - GError * err = NULL; - GdkPixbuf * pixbuf = NULL; - - /* load the image */ - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height); - pixbuf = gdk_pixbuf_new_from_file_at_size (icon_name, width, height, &err); - if (err == NULL) - { - gtk_image_set_from_pixbuf (image, pixbuf); - g_object_unref (pixbuf); - updated = TRUE; - } - else - { - g_warning ("Couldn't load the image \"%s\": %s", icon_name, err->message); - g_clear_error (&err); - } - } - - /* as a fallback, use the default user icon */ - if (!updated) - { - gtk_image_set_from_icon_name (image, - USER_ITEM_ICON_DEFAULT, - GTK_ICON_SIZE_MENU); - } -} - -static void -update_logged_in (UserWidget * self, DbusmenuMenuitem * mi) -{ - const gboolean b = dbusmenu_menuitem_property_get_bool (mi, USER_ITEM_PROP_LOGGED_IN); - - g_debug ("User \"%s\" %s active sessions", - dbusmenu_menuitem_property_get (mi, USER_ITEM_PROP_NAME), - b ? "has" : "doesn't have"); - - gtk_widget_set_visible (self->priv->tick_icon, b); -} - -static void -update_name (UserWidget * self, DbusmenuMenuitem * mi) -{ - gtk_label_set_label (GTK_LABEL(self->priv->user_name), - dbusmenu_menuitem_property_get (mi, USER_ITEM_PROP_NAME)); -} - -static void -user_widget_property_update (DbusmenuMenuitem * mi, - const gchar * property, - GVariant * value, - UserWidget * self) -{ - g_return_if_fail (IS_USER_WIDGET (self)); - - if (!g_strcmp0 (property, USER_ITEM_PROP_LOGGED_IN)) - { - update_logged_in (self, mi); - } - else if (!g_strcmp0 (property, USER_ITEM_PROP_ICON)) - { - update_icon (self, mi); - } - else if (!g_strcmp0 (property, USER_ITEM_PROP_NAME)) - { - update_name (self, mi); - } - else - { - g_debug ("%s FIXME: unhandled property change %s", G_STRFUNC, property); - } -} - -static void -user_widget_set_twin_item (UserWidget * self, DbusmenuMenuitem * mi) -{ - self->priv->twin_item = mi; - - update_icon (self, mi); - update_name (self, mi); - update_logged_in (self, mi); - - g_signal_connect (G_OBJECT(mi), "property-changed", - G_CALLBACK(user_widget_property_update), self); -} - - /** - * user_widget_new: - * @item: the #DbusmenuMenuitem this widget will render. - * - * Returns: (transfer full): a new #UserWidget. - **/ -GtkWidget* -user_widget_new (DbusmenuMenuitem *item) -{ - GtkWidget* widget = g_object_new(USER_WIDGET_TYPE, NULL); - user_widget_set_twin_item ( USER_WIDGET(widget), item ); - return widget; -} diff --git a/src/user-widget.h b/src/user-widget.h deleted file mode 100644 index 0953e6c..0000000 --- a/src/user-widget.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - 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 -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 __USER_WIDGET_H__ -#define __USER_WIDGET_H__ - -#include -#include - -G_BEGIN_DECLS - -#define USER_WIDGET_TYPE (user_widget_get_type ()) -#define USER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), USER_WIDGET_TYPE, UserWidget)) -#define USER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), USER_WIDGET_TYPE, UserWidgetClass)) -#define IS_USER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), USER_WIDGET_TYPE)) -#define IS_USER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), USER_WIDGET_TYPE)) -#define USER_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), USER_WIDGET_TYPE, UserWidgetClass)) - -typedef struct _UserWidget UserWidget; -typedef struct _UserWidgetClass UserWidgetClass; -typedef struct _UserWidgetPrivate UserWidgetPrivate; - -struct _UserWidgetClass -{ - GtkMenuItemClass parent_class; -}; - -struct _UserWidget -{ - /*< private >*/ - GtkMenuItem parent; - UserWidgetPrivate * priv; -}; - -GType user_widget_get_type (void) G_GNUC_CONST; -GtkWidget* user_widget_new(DbusmenuMenuitem *twin_item); - -G_END_DECLS - -#endif diff --git a/src/users-service-dbus.c b/src/users-service-dbus.c deleted file mode 100644 index f12f47c..0000000 --- a/src/users-service-dbus.c +++ /dev/null @@ -1,1044 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */ -/* - * Copyright 2009 Canonical Ltd. - * - * Authors: - * Cody Russell - * 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 . - */ - -#ifdef HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -#include /* getpwuid() */ - -#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" -#define CK_SESSION_IFACE "org.freedesktop.ConsoleKit.Session" - -/** -*** -**/ - -static void update_user_list (UsersServiceDbus * self); - -static gchar* get_seat (UsersServiceDbus * service); - -static void on_user_added (Accounts * o, - const gchar * user_object_path, - UsersServiceDbus * service); - -static void on_user_deleted (Accounts * o, - const gchar * user_object_path, - UsersServiceDbus * service); - -static void on_session_added (ConsoleKitSeat * seat, - const gchar * ssid, - UsersServiceDbus * service); - -static void on_session_removed (ConsoleKitSeat * seat, - const gchar * ssid, - UsersServiceDbus * service); - -static void on_session_list (ConsoleKitSeat * seat, - GAsyncResult * result, - UsersServiceDbus * service); - -/*** -**** Priv Struct -***/ - -struct _UsersServiceDbusPrivate -{ - gchar * seat; - gchar * guest_ssid; - - /* ssid -> AccountsUser lookup */ - GHashTable * sessions; - - /* user object path -> AccountsUser lookup */ - GHashTable * users; - - GCancellable * cancellable; - ConsoleKitSeat * seat_proxy; - ConsoleKitManager * ck_manager_proxy; - Accounts * accounts_proxy; -}; - -/*** -**** GObject -***/ - -enum -{ - USER_LIST_CHANGED, - USER_LOGGED_IN_CHANGED, - GUEST_LOGGED_IN_CHANGED, - N_SIGNALS -}; - -static guint signals[N_SIGNALS] = { 0 }; - -G_DEFINE_TYPE (UsersServiceDbus, users_service_dbus, G_TYPE_OBJECT); - -static void -users_service_dbus_dispose (GObject *object) -{ - UsersServiceDbusPrivate * priv = USERS_SERVICE_DBUS(object)->priv; - - g_clear_object (&priv->accounts_proxy); - g_clear_object (&priv->seat_proxy); - g_clear_object (&priv->ck_manager_proxy); - - if (priv->cancellable != NULL) - { - g_cancellable_cancel (priv->cancellable); - g_clear_object (&priv->cancellable); - } - - if (priv->users != NULL) - { - g_hash_table_destroy (priv->users); - priv->users = NULL; - } - - if (priv->sessions != NULL) - { - g_hash_table_destroy (priv->sessions); - priv->sessions = NULL; - } - - G_OBJECT_CLASS (users_service_dbus_parent_class)->dispose (object); -} - -static void -users_service_dbus_finalize (GObject *object) -{ - UsersServiceDbusPrivate * priv = USERS_SERVICE_DBUS(object)->priv; - - g_free (priv->guest_ssid); - g_free (priv->seat); - - G_OBJECT_CLASS (users_service_dbus_parent_class)->finalize (object); -} - -static void -users_service_dbus_class_init (UsersServiceDbusClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (UsersServiceDbusPrivate)); - - object_class->dispose = users_service_dbus_dispose; - object_class->finalize = users_service_dbus_finalize; - - signals[USER_LIST_CHANGED] = g_signal_new ( - "user-list-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UsersServiceDbusClass, user_list_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[USER_LOGGED_IN_CHANGED] = g_signal_new ( - "user-logged-in-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UsersServiceDbusClass, user_logged_in_changed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - signals[GUEST_LOGGED_IN_CHANGED] = g_signal_new ( - "guest-logged-in-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UsersServiceDbusClass, guest_logged_in_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -users_service_dbus_init (UsersServiceDbus *self) -{ - GError * error = NULL; - - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - USERS_SERVICE_DBUS_TYPE, - UsersServiceDbusPrivate); - - UsersServiceDbusPrivate * p = self->priv; - - p->cancellable = g_cancellable_new (); - - /* ssid -> AccountsUser */ - p->sessions = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - /* user object path -> AccountsUser */ - p->users = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - /** - *** create the consolekit manager proxy... - **/ - - p->ck_manager_proxy = console_kit_manager_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - NULL, - &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_clear_error (&error); - } - - p->seat = get_seat (self); - - /** - *** create the consolekit seat proxy... - **/ - - if (p->seat != NULL) - { - ConsoleKitSeat * proxy = console_kit_seat_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.ConsoleKit", - p->seat, - NULL, - &error); - - if (error != NULL) - { - g_warning ("Failed to connect to the ConsoleKit seat: %s", error->message); - g_clear_error (&error); - } - else - { - g_signal_connect (proxy, "session-added", - G_CALLBACK (on_session_added), self); - g_signal_connect (proxy, "session-removed", - G_CALLBACK (on_session_removed), self); - console_kit_seat_call_get_sessions (proxy, p->cancellable, - (GAsyncReadyCallback)on_session_list, self); - p->seat_proxy = proxy; - } - } - - /** - *** create the accounts manager proxy... - **/ - - Accounts * proxy = accounts_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.Accounts", - "/org/freedesktop/Accounts", - NULL, - &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } - else - { - g_signal_connect (proxy, "user-added", G_CALLBACK(on_user_added), self); - g_signal_connect (proxy, "user-deleted", G_CALLBACK(on_user_deleted), self); - p->accounts_proxy = proxy; - update_user_list (self); - } -} - -/*** -**** -***/ - -static void -emit_user_list_changed (UsersServiceDbus * self) -{ - g_signal_emit (self, signals[USER_LIST_CHANGED], 0); -} - -static void -emit_user_login_changed (UsersServiceDbus * self, AccountsUser * user) -{ - g_signal_emit (self, signals[USER_LOGGED_IN_CHANGED], 0, user); -} - -static void -emit_guest_login_changed (UsersServiceDbus * self) -{ - g_signal_emit (self, signals[GUEST_LOGGED_IN_CHANGED], 0); -} - -/*** -**** -***/ - -static ConsoleKitSession* -create_consolekit_session_proxy (const char * ssid) -{ - GError * error = NULL; - - ConsoleKitSession * p = console_kit_session_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - CK_ADDR, - ssid, - NULL, - &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - - return p; -} - -static gchar * -get_seat_from_session_proxy (ConsoleKitSession * session_proxy) -{ - gchar * seat = NULL; - - GError * error = NULL; - console_kit_session_call_get_seat_id_sync (session_proxy, - &seat, - NULL, - &error); - if (error != NULL) - { - g_debug ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - - return seat; -} - -static gchar * -get_seat (UsersServiceDbus *service) -{ - gchar * seat = NULL; - gchar * ssid = NULL; - GError * error = NULL; - UsersServiceDbusPrivate * priv = service->priv; - - console_kit_manager_call_get_current_session_sync (priv->ck_manager_proxy, - &ssid, - NULL, - &error); - - if (error != NULL) - { - g_debug ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - else - { - ConsoleKitSession * session = create_consolekit_session_proxy (ssid); - - if (session != NULL) - { - seat = get_seat_from_session_proxy (session); - g_object_unref (session); - } - } - - return seat; -} - -/*** -**** AccountsUser add-ons for tracking sessions -***/ - -static GHashTable* -user_get_sessions_hashset (AccountsUser * user) -{ - static GQuark q = 0; - - if (G_UNLIKELY(!q)) - { - q = g_quark_from_static_string ("sessions"); - } - - GObject * o = G_OBJECT (user); - GHashTable * h = g_object_get_qdata (o, q); - if (h == NULL) - { - h = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - g_object_set_qdata_full (o, q, h, (GDestroyNotify)g_hash_table_destroy); - } - - return h; -} - -static void -user_add_session (AccountsUser * user, const char * ssid) -{ - g_hash_table_add (user_get_sessions_hashset(user), g_strdup(ssid)); -} - -static void -user_remove_session (AccountsUser * user, const char * ssid) -{ - g_hash_table_remove (user_get_sessions_hashset(user), ssid); -} - -static guint -user_count_sessions (AccountsUser * user) -{ - return g_hash_table_size (user_get_sessions_hashset(user)); -} - -/*** -**** Users -***/ - -/* adds this user session to the user's and service's session tables */ -static void -add_user_session (UsersServiceDbus * service, - AccountsUser * user, - const gchar * ssid) -{ - ConsoleKitSession * session_proxy = create_consolekit_session_proxy (ssid); - if (session_proxy != NULL) - { - UsersServiceDbusPrivate * priv = service->priv; - gchar * seat = get_seat_from_session_proxy (session_proxy); - - /* is this session in our seat? */ - if (seat && priv->seat && !g_strcmp0 (seat, priv->seat)) - { - /* does this session have a display? */ - gchar * display = NULL; - console_kit_session_call_get_x11_display_sync (session_proxy, - &display, - NULL, NULL); - const gboolean has_display = display && *display; - g_free (display); - - if (has_display) - { - const gchar * username = accounts_user_get_user_name (user); - g_debug ("%s adding %s's session '%s' to our tables", - G_STRLOC, username, ssid); - - g_hash_table_insert (priv->sessions, - g_strdup (ssid), - g_object_ref (user)); - - user_add_session (user, ssid); - } - } - - g_free (seat); - g_object_unref (session_proxy); - } -} - -/* calls add_user_session() for each of this user's sessions */ -static void -add_user_sessions (UsersServiceDbus *self, AccountsUser * user) -{ - const guint64 uid = accounts_user_get_uid (user); - const char * username = accounts_user_get_user_name (user); - g_debug ("%s adding %s (%i)", G_STRLOC, username, (int)uid); - - GError * error = NULL; - gchar ** sessions = NULL; - console_kit_manager_call_get_sessions_for_unix_user_sync ( - self->priv->ck_manager_proxy, - uid, - &sessions, - NULL, - &error); - - if (error != NULL) - { - g_debug ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - else if (sessions != NULL) - { - int i; - - for (i=0; sessions[i]; i++) - { - const char * const ssid = sessions[i]; - g_debug ("%s adding %s's session %s", G_STRLOC, username, ssid); - add_user_session (self, user, ssid); - } - - g_strfreev (sessions); - } -} - -/* returns true if this property is one we use */ -static gboolean -is_interesting_user_property (const char * key) -{ - return !g_strcmp0 (key, "IconFile") - || !g_strcmp0 (key, "LoginFrequency") - || !g_strcmp0 (key, "RealName") - || !g_strcmp0 (key, "Uid") - || !g_strcmp0 (key, "UserName"); -} - -static void -sync_user_properties (GDBusProxy * source, GDBusProxy * target) -{ - gchar ** keys = g_dbus_proxy_get_cached_property_names (source); - - if (keys != NULL) - { - int i; - GVariantBuilder builder; - gboolean changed = FALSE; - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); - - for (i=0; keys[i]; i++) - { - const gchar * const key = keys[i]; - - if (is_interesting_user_property (key)) - { - GVariant * oldval = g_dbus_proxy_get_cached_property (target, key); - GVariant * newval = g_dbus_proxy_get_cached_property (source, key); - - /* all the properties we're interested in are - basic types safe for g_variant_compare()... */ - g_assert (g_variant_type_is_basic(g_variant_get_type(newval))); - - if (g_variant_compare (oldval, newval)) - { - changed = TRUE; - g_dbus_proxy_set_cached_property (target, key, newval); - g_variant_builder_add (&builder, "{sv}", key, newval); - } - - g_variant_unref (newval); - g_variant_unref (oldval); - } - } - - if (changed) - { - g_signal_emit_by_name (target, "g-properties-changed", g_variant_builder_end(&builder), keys); - } - - g_variant_builder_clear (&builder); - g_strfreev (keys); - } -} - -/** - * The AccountsUserProxy's properties aren't being updated automatically - * for some reason... the only update we get is the 'changed' signal. - * This function is a workaround to update our User object's properties. - */ -static void -on_user_changed (AccountsUser * user, UsersServiceDbus * service) -{ - AccountsUser * tmp = accounts_user_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.Accounts", - g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)), - NULL, - NULL); - if (tmp != NULL) - { - sync_user_properties (G_DBUS_PROXY(tmp), G_DBUS_PROXY(user)); - g_object_unref (tmp); - } -} - -static void -add_user_from_object_path (UsersServiceDbus * self, - const char * user_object_path) -{ - GError * error = NULL; - - AccountsUser * user = accounts_user_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.Accounts", - user_object_path, - NULL, - &error); - - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_clear_error (&error); - } - else - { - AccountsUser * prev = g_hash_table_lookup (self->priv->users, user_object_path); - - if (prev != NULL) /* we've already got this user... sync its properties */ - { - sync_user_properties (G_DBUS_PROXY(user), G_DBUS_PROXY(prev)); - g_object_unref (user); - user = prev; - } - else /* ooo, we got a new user */ - { - g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); - g_hash_table_insert (self->priv->users, g_strdup(user_object_path), user); - } - - add_user_sessions (self, user); - } -} - - -/* asks org.freedesktop.Accounts for a list of users and - * calls add_user_from_object_path() on each of those users */ -static void -update_user_list (UsersServiceDbus *self) -{ - g_return_if_fail(IS_USERS_SERVICE_DBUS(self)); - - GError * error = NULL; - char ** object_paths = NULL; - UsersServiceDbusPrivate * priv = self->priv; - - accounts_call_list_cached_users_sync (priv->accounts_proxy, - &object_paths, - NULL, - &error); - - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } - else if (object_paths != NULL) - { - gint i; - - for (i=0; object_paths[i] != NULL; ++i) - { - add_user_from_object_path (self, object_paths[i]); - } - - emit_user_list_changed (self); - - g_strfreev (object_paths); - } - - g_debug ("%s finished updating the user list", G_STRLOC); -} - -static void -on_user_added (Accounts * o G_GNUC_UNUSED, - const gchar * user_path G_GNUC_UNUSED, - UsersServiceDbus * service) -{ - /* 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 - org.freedesktop.Accounts for a fresh list of users - because it filters out special cases. */ - update_user_list (service); -} - -static void -on_user_deleted (Accounts * o G_GNUC_UNUSED, - const gchar * user_path, - UsersServiceDbus * service) -{ - AccountsUser * user = g_hash_table_lookup (service->priv->users, user_path); - - if (user != NULL) - { - GObject * o = g_object_ref (G_OBJECT(user)); - g_hash_table_remove (service->priv->users, user_path); - emit_user_list_changed (service); - g_object_unref (o); - } -} - -static AccountsUser * -find_user_from_username (UsersServiceDbus * self, - const gchar * username) -{ - AccountsUser * match = NULL; - - g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), match); - - gpointer user; - GHashTableIter iter; - g_hash_table_iter_init (&iter, self->priv->users); - while (!match && g_hash_table_iter_next (&iter, NULL, &user)) - { - if (!g_strcmp0 (username, accounts_user_get_user_name (user))) - { - match = user; - } - } - - return match; -} - -/*** -**** Sessions -***/ - -static void -on_session_removed (ConsoleKitSeat * seat_proxy, - const gchar * ssid, - UsersServiceDbus * service) -{ - g_return_if_fail (IS_USERS_SERVICE_DBUS (service)); - - UsersServiceDbusPrivate * priv = service->priv; - g_debug ("%s %s() session removed %s", G_STRLOC, G_STRFUNC, ssid); - - if (!g_strcmp0 (ssid, priv->guest_ssid)) - { - g_debug ("%s removing guest session %s", G_STRLOC, ssid); - g_clear_pointer (&priv->guest_ssid, g_free); - emit_guest_login_changed (service); - } - else - { - AccountsUser * user = g_hash_table_lookup (priv->sessions, ssid); - if (user == NULL) - { - g_debug ("%s we're not tracking ssid %s", G_STRLOC, ssid); - } - else - { - GObject * o = g_object_ref (G_OBJECT(user)); - g_hash_table_remove (service->priv->users, ssid); - user_remove_session (user, ssid); - emit_user_login_changed (service, user); - g_object_unref (o); - } - } -} - -static gchar* -get_unix_username_from_ssid (UsersServiceDbus * self, - const gchar * ssid) -{ - gchar * username = NULL; - - ConsoleKitSession * session_proxy = create_consolekit_session_proxy (ssid); - if (session_proxy != NULL) - { - guint uid = 0; - GError * error = NULL; - console_kit_session_call_get_unix_user_sync (session_proxy, - &uid, - NULL, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_clear_error (&error); - } - else - { - errno = 0; - const struct passwd * pwent = getpwuid (uid); - if (pwent == NULL) - { - g_warning ("Failed to lookup user id %d: %s", (int)uid, g_strerror(errno)); - } - else - { - username = g_strdup (pwent->pw_name); - } - } - - g_object_unref (session_proxy); - } - - return username; -} - -static gboolean -is_guest_username (const char * username) -{ - if (!g_strcmp0 (username, "guest")) - return TRUE; - - if (username && g_str_has_prefix (username, "guest-")) - return TRUE; - - return FALSE; -} - -/* If the new session belongs to 'guest', update our guest_ssid. - Otherwise, call add_user_session() to update our session tables */ -static void -on_session_added (ConsoleKitSeat * seat_proxy G_GNUC_UNUSED, - const gchar * ssid, - UsersServiceDbus * service) -{ - g_return_if_fail (IS_USERS_SERVICE_DBUS(service)); - - gchar * username = get_unix_username_from_ssid (service, ssid); - g_debug ("%s %s() username %s has new session %s", G_STRLOC, G_STRFUNC, username, ssid); - - if (is_guest_username (username)) - { - /* handle guest as a special case -- it's not in the GDM - user tables and there isn't be an AccountsUser for it */ - g_debug("Found guest session: %s", ssid); - g_free (service->priv->guest_ssid); - service->priv->guest_ssid = g_strdup (ssid); - emit_guest_login_changed (service); - } - else - { - AccountsUser * user = find_user_from_username (service, username); - - if (user != NULL) - { - add_user_session (service, user, ssid); - emit_user_login_changed (service, user); - } - } - - g_free (username); -} - -/* Receives a list of sessions and calls on_session_added() for each of them */ -static void -on_session_list (ConsoleKitSeat * seat_proxy, - GAsyncResult * result, - UsersServiceDbus * self) -{ - GError * error = NULL; - gchar ** sessions = NULL; - g_debug ("%s bootstrapping the session list", G_STRLOC); - - console_kit_seat_call_get_sessions_finish (seat_proxy, - &sessions, - result, - &error); - - if (error != NULL) - { - g_debug ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - else if (sessions != NULL) - { - int i; - - for (i=0; sessions[i]; i++) - { - g_debug ("%s adding initial session '%s'", G_STRLOC, sessions[i]); - on_session_added (seat_proxy, sessions[i], self); - } - - g_strfreev (sessions); - } - - g_debug ("%s done bootstrapping the session list", G_STRLOC); -} - -static DisplayManagerSeat * -create_display_proxy (UsersServiceDbus * self) -{ - const gchar * const seat = g_getenv ("XDG_SEAT_PATH"); - g_debug ("%s creating a DisplayManager proxy for seat %s", G_STRLOC, seat); - - GError * error = NULL; - DisplayManagerSeat * p = display_manager_seat_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.DisplayManager", - seat, - NULL, - &error); - - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - - return p; -} - -/*** -**** Public API -***/ - -/** - * users_service_dbus_get_user_list: - * - * Returns: (transfer container): a list of AccountsUser objects - */ -GList * -users_service_dbus_get_user_list (UsersServiceDbus * self) -{ - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), NULL); - - return g_hash_table_get_values (self->priv->users); -} - -/** - * users_service_dbus_show_greeter: - * - * Ask the Display Mnaager to switch to the greeter screen. - */ -void -users_service_dbus_show_greeter (UsersServiceDbus * self) -{ - DisplayManagerSeat * dp; - - g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); - - dp = create_display_proxy (self); - if (dp != NULL) - { - display_manager_seat_call_switch_to_greeter_sync (dp, NULL, NULL); - g_clear_object (&dp); - } -} - -/** - * users_service_dbus_activate_guest_session: - * - * Activates the guest account. - */ -void -users_service_dbus_activate_guest_session (UsersServiceDbus * self) -{ - DisplayManagerSeat * dp; - - g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); - - dp = create_display_proxy (self); - if (dp != NULL) - { - display_manager_seat_call_switch_to_guest_sync (dp, "", NULL, NULL); - g_clear_object (&dp); - } -} - -/** - * users_service_dbus_activate_user_session: - * - * Activates a specific user. - */ -void -users_service_dbus_activate_user_session (UsersServiceDbus * self, - AccountsUser * user) -{ - DisplayManagerSeat * dp; - - g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); - - dp = create_display_proxy (self); - if (dp != NULL) - { - const char * const username = accounts_user_get_user_name (user); - display_manager_seat_call_switch_to_user_sync (dp, username, "", NULL, NULL); - g_clear_object (&dp); - } -} - -/** - * users_service_dbus_guest_session_enabled: - * - * Tells whether or not guest sessions are allowed. - */ -gboolean -users_service_dbus_guest_session_enabled (UsersServiceDbus * self) -{ - DisplayManagerSeat * dp; - gboolean enabled = FALSE; - - g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), enabled); - - dp = create_display_proxy (self); - if (dp != NULL) - { - enabled = display_manager_seat_get_has_guest_account (dp); - g_clear_object (&dp); - } - - return enabled; -} - -gboolean -users_service_dbus_can_activate_session (UsersServiceDbus * self) -{ - gboolean can_activate = FALSE; - - g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), can_activate); - - GError * error = NULL; - console_kit_seat_call_can_activate_sessions_sync (self->priv->seat_proxy, - &can_activate, - NULL, - &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - - return can_activate; -} - -gboolean -users_service_dbus_is_guest_logged_in (UsersServiceDbus * self) -{ - g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), FALSE); - - return self->priv->guest_ssid != NULL; -} - -gboolean -users_service_dbus_is_user_logged_in (UsersServiceDbus * self, - AccountsUser * user) -{ - g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), FALSE); - g_return_val_if_fail (IS_ACCOUNTS_USER(user), FALSE); - - return user_count_sessions (user) > 0; -} diff --git a/src/users-service-dbus.h b/src/users-service-dbus.h deleted file mode 100644 index 0f082c3..0000000 --- a/src/users-service-dbus.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2009 Canonical Ltd. - * - * Authors: - * Cody Russell - * 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 . - */ - -#ifndef __USERS_SERVICE_DBUS_H__ -#define __USERS_SERVICE_DBUS_H__ - -#include -#include - -#include "dbus-user.h" /* for AccountsUser */ - -G_BEGIN_DECLS - -#define USERS_SERVICE_DBUS_TYPE (users_service_dbus_get_type ()) -#define USERS_SERVICE_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), USERS_SERVICE_DBUS_TYPE, UsersServiceDbus)) -#define IS_USERS_SERVICE_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), USERS_SERVICE_DBUS_TYPE)) - -typedef struct _UsersServiceDbus UsersServiceDbus; -typedef struct _UsersServiceDbusClass UsersServiceDbusClass; -typedef struct _UsersServiceDbusPrivate UsersServiceDbusPrivate; - -/** - * A facade class which interacts with multiple DBus services to - * track info which is useful to the interactor's user menu: - * - * 1. A list of users to add to the user menu. - * - * Each user is an AccountsUser object, which is a GDBusProxy - * to an org.freedesktop.Accounts.User object. - * - * We initially build this list by calling org.freedesktop.Accounts' - * GetCachedUsers method. We also monitor o.f.Accounts' UserAdded - * and UserDeleted and update the list accordingly. - * - * 2. Track which users currently have X sessions. - * This is used for the menuitems' USER_ITEM_PROP_LOGGED_IN property. - * - * We initially build this list by calling org.freedesktop.ConsoleKit.Seat's - * GetDevices method. We also monitor the seat for SessionAdded and - * SessionRemoved and update the list accordingly. - * - * 3. Provide an API for user switching and guest sessions. - * These are typically pass-through functions to GDBusProxies. - * - */ -struct _UsersServiceDbus -{ - /*< private >*/ - GObject parent; - UsersServiceDbusPrivate * priv; -}; - -struct _UsersServiceDbusClass -{ - GObjectClass parent_class; - - /* Signals */ - void (* user_list_changed) (UsersServiceDbus*, gpointer); - void (* user_logged_in_changed) (UsersServiceDbus*, AccountsUser*, gpointer); - void (* guest_logged_in_changed) (UsersServiceDbus*, gpointer); -}; - -GType users_service_dbus_get_type (void) G_GNUC_CONST; - -GList * users_service_dbus_get_user_list (UsersServiceDbus * self); - -gboolean users_service_dbus_is_guest_logged_in (UsersServiceDbus * self); -gboolean users_service_dbus_is_user_logged_in (UsersServiceDbus * self, - AccountsUser * user); - -void users_service_dbus_show_greeter (UsersServiceDbus * self); -gboolean users_service_dbus_guest_session_enabled (UsersServiceDbus * self); -gboolean users_service_dbus_can_activate_session (UsersServiceDbus * self); -void users_service_dbus_activate_guest_session (UsersServiceDbus * self); -void users_service_dbus_activate_user_session (UsersServiceDbus * self, - AccountsUser * user); - -G_END_DECLS - -#endif diff --git a/src/users.c b/src/users.c new file mode 100644 index 0000000..4b9c0ad --- /dev/null +++ b/src/users.c @@ -0,0 +1,198 @@ +/* + * 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 "users.h" + +/* signals enum */ +enum +{ + USER_ADDED, + USER_REMOVED, + USER_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (IndicatorSessionUsers, indicator_session_users, G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_IS_LIVE_SESSION, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +static void +my_get_property (GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorSessionUsers * self = INDICATOR_SESSION_USERS (o); + + switch (property_id) + { + case PROP_IS_LIVE_SESSION: + g_value_set_boolean (value, indicator_session_users_is_live_session (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_class_init (IndicatorSessionUsersClass * klass) +{ + GObjectClass * object_class; + const GParamFlags flags = G_PARAM_READABLE | G_PARAM_STATIC_STRINGS; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = my_get_property; + + signals[USER_ADDED] = g_signal_new (INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_added), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + signals[USER_REMOVED] = g_signal_new (INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_removed), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + signals[USER_CHANGED] = g_signal_new (INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_changed), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + + properties[PROP_IS_LIVE_SESSION] = + g_param_spec_boolean (INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION, + "Is Live Session", + "Whether or this is a 'live session', such as booting from a live CD", + FALSE, flags); + + g_object_class_install_properties (object_class, PROP_LAST, properties); + +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_init (IndicatorSessionUsers * self G_GNUC_UNUSED) +{ +} + +/*** +**** Virtual Functions +***/ + +GStrv +indicator_session_users_get_keys (IndicatorSessionUsers * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS (self), NULL); + + return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_keys (self); +} + +IndicatorSessionUser * +indicator_session_users_get_user (IndicatorSessionUsers * self, + const char * key) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS (self), NULL); + + return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_user (self, key); +} + +void +indicator_session_users_activate_user (IndicatorSessionUsers * self, + const char * key) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); + + INDICATOR_SESSION_USERS_GET_CLASS (self)->activate_user (self, key); +} + +gboolean +indicator_session_users_is_live_session (IndicatorSessionUsers * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS (self), FALSE); + + return INDICATOR_SESSION_USERS_GET_CLASS (self)->is_live_session (self); +} + +void +indicator_session_user_free (IndicatorSessionUser * user) +{ + g_return_if_fail (user != NULL); + + g_free (user->real_name); + g_free (user->user_name); + g_free (user->icon_file); + g_free (user); +} + +/*** +**** Signal Convenience +***/ + +void +indicator_session_users_added (IndicatorSessionUsers * self, const char * key) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); + + g_signal_emit (self, signals[USER_ADDED], 0, key); +} + +void +indicator_session_users_removed (IndicatorSessionUsers * self, const char * key) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); + + g_signal_emit (self, signals[USER_REMOVED], 0, key); +} + +void +indicator_session_users_changed (IndicatorSessionUsers * self, const char * key) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); + + g_signal_emit (self, signals[USER_CHANGED], 0, key); +} + +void +indicator_session_users_notify_is_live_session (IndicatorSessionUsers * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_IS_LIVE_SESSION]); +} + diff --git a/src/users.h b/src/users.h new file mode 100644 index 0000000..31ee39e --- /dev/null +++ b/src/users.h @@ -0,0 +1,146 @@ +/* + * 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 . + */ + +#ifndef __USERS_H__ +#define __USERS_H__ + +#include +#include + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_USERS (indicator_session_users_get_type()) +#define INDICATOR_SESSION_USERS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_USERS, IndicatorSessionUsers)) +#define INDICATOR_SESSION_USERS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_USERS, IndicatorSessionUsersClass)) +#define INDICATOR_SESSION_USERS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_TYPE_SESSION_USERS, IndicatorSessionUsersClass)) +#define INDICATOR_IS_SESSION_USERS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_USERS)) + + +typedef struct _IndicatorSessionUser IndicatorSessionUser; +typedef struct _IndicatorSessionUsers IndicatorSessionUsers; +typedef struct _IndicatorSessionUsersClass IndicatorSessionUsersClass; + +/** + * A base class for monitoring the system's users and active sessions. + * Use backend.h's get_backend() to get an instance. + */ +struct _IndicatorSessionUsers +{ + /*< private >*/ + GObject parent; +}; + +struct _IndicatorSessionUser +{ + gboolean is_current_user; + gboolean is_logged_in; + guint uid; + guint64 login_frequency; + gchar * user_name; + gchar * real_name; + gchar * icon_file; +}; + +/* signal keys */ +#define INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED "user-added" +#define INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED "user-removed" +#define INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED "user-changed" + +/* property keys */ +#define INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION "is-live-session" + +struct _IndicatorSessionUsersClass +{ + GObjectClass parent_class; + + /* signals */ + + void (* user_added) (IndicatorSessionUsers * self, + const gchar * key); + + void (* user_removed) (IndicatorSessionUsers * self, + const gchar * key); + + void (* user_changed) (IndicatorSessionUsers * self, + const gchar * key); + + + /* pure virtual functions */ + + gboolean (* is_live_session) (IndicatorSessionUsers * self); + + + GStrv (* get_keys) (IndicatorSessionUsers * self); + + IndicatorSessionUser * (* get_user) (IndicatorSessionUsers * self, + const gchar * key); + + void ( * activate_user) (IndicatorSessionUsers * self, + const gchar * key); +}; + +/*** +**** +***/ + +GType indicator_session_users_get_type (void); + +/* emits the "user-added" signal */ +void indicator_session_users_added (IndicatorSessionUsers * self, + const gchar * key); + +/* emits the "user-removed" signal */ +void indicator_session_users_removed (IndicatorSessionUsers * self, + const gchar * key); + +/* emits the "user-changed" signal */ +void indicator_session_users_changed (IndicatorSessionUsers * self, + const gchar * key); + +/* notify listeners of a change to the 'is-live-session' property */ +void indicator_session_users_notify_is_live_session (IndicatorSessionUsers * self); + + + +/*** +**** +***/ + +gboolean indicator_session_users_is_live_session (IndicatorSessionUsers * users); + +/* get a list of user keys */ +GStrv indicator_session_users_get_keys (IndicatorSessionUsers * users); + +/* get information about a particular user. + call indicator_session_user_free() when done with the returned struct. */ +IndicatorSessionUser * +indicator_session_users_get_user (IndicatorSessionUsers * users, + const gchar * key); + +/* frees a IndicatorSessionUser struct */ +void indicator_session_user_free (IndicatorSessionUser * user); + +/* activate to a different session */ +void indicator_session_users_activate_user (IndicatorSessionUsers * self, + const char * key); + + +G_END_DECLS + +#endif -- cgit v1.2.3 From ca4b40ade7f432d98c21ac499a0de63244b1c3cc Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 23 Mar 2013 10:04:13 -0500 Subject: use pete woods' hud cmake code for the build.sh script to check for Ninja and to move the gdbus-codegen macros into a resuable file in the cmake/ directory. --- src/backend-dbus/CMakeLists.txt | 115 +++++++++++++++------------------------- 1 file changed, 44 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index a477cfe..dd928cc 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -1,86 +1,59 @@ -# autogenerate source code files for our DBus proxies -function(gdbus_codegen XML_FILE INTERFACE_PREFIX SOURCE_PREFIX) +set(BACKEND_GENERATED_SOURCES +) - set (SRC_C, ${SOURCE_PREFIX}.c) - set (SRC_H, ${SOURCE_PREFIX}.h) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-display-manager + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/display-manager.xml) - # check for the app - find_program (GDBUS_CODEGEN_EXECUTABLE NAMES gdbus-codegen DOC "gdbus-codegen executable") - if(NOT GDBUS_CODEGEN_EXECUTABLE) - message(FATAL_ERROR "Executable gdbus-codegen not found") - endif() +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-webcredentials + com.canonical.indicators + ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicators.webcredentials.xml) - # generate the code - add_custom_command ( - OUTPUT ${SOURCE_PREFIX}.c ${SOURCE_PREFIX}.h - COMMAND gdbus-codegen ARGS --interface-prefix ${INTERFACE_PREFIX} --generate-c-code ${SOURCE_PREFIX} ${CMAKE_CURRENT_SOURCE_DIR}/${XML_FILE} - DEPENDS ${XML_FILE}) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-accounts + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Accounts.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-user + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Accounts.User.xml) - # update our variables - set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_C}) - set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_H}) - set_property (SOURCE ${SRC_C} ${SRC_H} PROPERTY GENERATED) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-manager + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Manager.xml) - # cleanup - unset (SRC_C) - unset (SRC_H) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-seat + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Seat.xml) -endfunction(gdbus_codegen) -gdbus_codegen ("display-manager.xml" "org.freedesktop" "dbus-display-manager") -gdbus_codegen ("com.canonical.indicators.webcredentials.xml" "com.canonical.indicators" "dbus-webcredentials") -gdbus_codegen ("org.freedesktop.Accounts.xml" "org.freedesktop" "dbus-accounts") -gdbus_codegen ("org.freedesktop.Accounts.User.xml" "org.freedesktop" "dbus-user") -gdbus_codegen ("org.freedesktop.ConsoleKit.Manager.xml" "org.freedesktop" "dbus-consolekit-manager") -gdbus_codegen ("org.freedesktop.ConsoleKit.Seat.xml" "org.freedesktop" "dbus-consolekit-seat") -gdbus_codegen ("org.freedesktop.ConsoleKit.Session.xml" "org.freedesktop" "dbus-consolekit-session") -gdbus_codegen ("org.gnome.ScreenSaver.xml" "org" "gnome-screen-saver") -gdbus_codegen ("org.gnome.SessionManager.xml" "org" "gnome-session-manager") -gdbus_codegen ("org.gnome.SessionManager.EndSessionDialog.xml" "org.gnome.SessionManager" "dbus-end-session-dialog") -gdbus_codegen ("upower.xml" "org.freedesktop" "dbus-upower") +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-session + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Session.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES gnome-screen-saver + org + ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.ScreenSaver.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES gnome-session-manager + org + ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.SessionManager.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-end-session-dialog + org.gnome.SessionManager + ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.SessionManager.EndSessionDialog.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-upower + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/upower.xml) + +set (SOURCES actions.c backend-dbus.c guest.c users.c utils.c) # add warnings/coverage info on handwritten files # but not the autogenerated ones... -set_source_files_properties (actions.c - backend-dbus.c - guest.c - users.c - utils.c +set_source_files_properties (${SOURCES} PROPERTIES COMPILE_FLAGS " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") # add the bin dir to our include path s.t. our code can find the autogenerated header files include_directories (${CMAKE_CURRENT_BINARY_DIR} ${SERVICE_INCLUDE_DIRS}) -add_library (backenddbus STATIC - gnome-screen-saver.c - gnome-screen-saver.h - gnome-session-manager.c - gnome-session-manager.h - dbus-display-manager.c - dbus-display-manager.h - dbus-consolekit-manager.c - dbus-consolekit-manager.h - dbus-consolekit-seat.c - dbus-consolekit-seat.h - dbus-consolekit-session.c - dbus-consolekit-session.h - dbus-accounts.c - dbus-accounts.h - dbus-upower.c - dbus-upower.h - dbus-user.c - dbus-user.h - dbus-webcredentials.c - dbus-webcredentials.h - dbus-end-session-dialog.c - dbus-end-session-dialog.h - actions.c - actions.h - backend-dbus.c - backend-dbus.h - guest.c - guest.h - users.c - users.h - utils.c - utils.h) +add_library (backenddbus STATIC ${SOURCES} ${BACKEND_GENERATED_SOURCES}) -- cgit v1.2.3 From 4a8c2566e3114cb30e0c79b48859e5325c1f448b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 25 Mar 2013 15:06:43 -0500 Subject: remove unused session-dbus.xml; this is a leftover from the GTK+ indicator --- src/backend-dbus/session-dbus.xml | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/backend-dbus/session-dbus.xml (limited to 'src') diff --git a/src/backend-dbus/session-dbus.xml b/src/backend-dbus/session-dbus.xml deleted file mode 100644 index 96e9837..0000000 --- a/src/backend-dbus/session-dbus.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From 4bc93061f407194434de187ea55a0317af4b71ac Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 26 Mar 2013 15:52:55 -0500 Subject: remove unnecessary G_GNUC_UNUSED --- src/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 1345681..8e2921e 100644 --- a/src/service.c +++ b/src/service.c @@ -1082,7 +1082,7 @@ my_get_property (GObject * o, static void my_set_property (GObject * o, guint property_id, - const GValue * value G_GNUC_UNUSED, + const GValue * value, GParamSpec * pspec) { IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (o); -- cgit v1.2.3 From 066872fb191ba3b79d1387a10f0b8be948d2d488 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 09:49:09 -0500 Subject: remove unnecessary signal (SIGPIPE, SIG_IGN) --- src/main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index ff5997b..17b50b4 100644 --- a/src/main.c +++ b/src/main.c @@ -66,8 +66,6 @@ main (int argc, char ** argv) GMainLoop * loop; IndicatorSessionService * service; - signal (SIGPIPE, SIG_IGN); - /* boilerplate i18n */ setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); -- cgit v1.2.3 From d87fb5d14091b22eaf6226dc8f9656bd6d514571 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 10:10:17 -0500 Subject: where appropriate, use g_menu_append() to save a few lines. --- src/service.c | 62 +++++++++++++---------------------------------------------- 1 file changed, 13 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 8e2921e..e62250e 100644 --- a/src/service.c +++ b/src/service.c @@ -277,18 +277,10 @@ static GMenuModel * create_admin_section (void) { GMenu * menu; - GMenuItem * item; menu = g_menu_new (); - - item = g_menu_item_new (_("About This Computer"), "indicator.about"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - - item = g_menu_item_new (_("Ubuntu Help"), "indicator.help"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - + g_menu_append (menu, _("About This Computer"), "indicator.about"); + g_menu_append (menu, _("Ubuntu Help"), "indicator.help"); return G_MENU_MODEL (menu); } @@ -296,21 +288,12 @@ static GMenuModel * create_settings_section (IndicatorSessionService * self) { GMenu * menu; - GMenuItem * item; priv_t * p = self->priv; menu = g_menu_new (); - - item = g_menu_item_new (_("System Settings\342\200\246"), "indicator.settings"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - + g_menu_append (menu, _("System Settings\342\200\246"), "indicator.settings"); if (indicator_session_actions_has_online_account_error (p->backend_actions)) - { - item = g_menu_item_new (_("Online Accounts\342\200\246"), "indicator.online-accounts"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - } + g_menu_append (menu, _("Online Accounts\342\200\246"), "indicator.online-accounts"); return G_MENU_MODEL (menu); } @@ -478,11 +461,7 @@ create_switch_section (IndicatorSessionService * self) g_object_unref (G_OBJECT(item)); if (indicator_session_guest_is_allowed (p->backend_guest)) - { - item = g_menu_item_new (_("Guest Session"), "indicator.switch-to-guest"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - } + g_menu_append (menu, _("Guest Session"), "indicator.switch-to-guest"); /* build an array of all the users we know of */ users = g_ptr_array_new (); @@ -519,7 +498,6 @@ static GMenuModel * create_session_section (IndicatorSessionService * self) { GMenu * menu; - GMenuItem * item; const priv_t * const p = self->priv; GSettings * const s = p->indicator_settings; const gboolean ellipsis = use_ellipsis (self); @@ -528,40 +506,26 @@ create_session_section (IndicatorSessionService * self) if (indicator_session_actions_can_logout (p->backend_actions) && !g_settings_get_boolean (s, "suppress-logout-menuitem")) { - item = g_menu_item_new (ellipsis ? _("Log Out\342\200\246") - : _("Log Out"), "indicator.logout"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); + const char * label = ellipsis ? _("Log Out\342\200\246") : _("Log Out"); + g_menu_append (menu, label, "indicator.logout"); } if (indicator_session_actions_can_suspend (p->backend_actions)) - { - item = g_menu_item_new (_("Suspend"), "indicator.suspend"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - } + g_menu_append (menu, _("Suspend"), "indicator.suspend"); if (indicator_session_actions_can_hibernate (p->backend_actions)) - { - item = g_menu_item_new (_("Hibernate"), "indicator.hibernate"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - } + g_menu_append (menu, _("Hibernate"), "indicator.hibernate"); if (!g_settings_get_boolean (s, "suppress-restart-menuitem")) { - item = g_menu_item_new (ellipsis ? _("Restart\342\200\246") - : _("Restart"), "indicator.restart"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); + const char * label = ellipsis ? _("Restart\342\200\246") : _("Restart"); + g_menu_append (menu, label, "indicator.restart"); } if (!g_settings_get_boolean (s, "suppress-shutdown-menuitem")) { - item = g_menu_item_new (ellipsis ? _("Shutdown\342\200\246") - : _("Shutdown"), "indicator.shutdown"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); + const char * label = ellipsis ? _("Shutdown\342\200\246") : _("Shutdown"); + g_menu_append (menu, label, "indicator.shutdown"); } return G_MENU_MODEL (menu); -- cgit v1.2.3 From 033cc134729679757e96715e32e0d517143ef49e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 10:26:20 -0500 Subject: add a small comment explaining replace_section() --- src/service.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index e62250e..2206621 100644 --- a/src/service.c +++ b/src/service.c @@ -741,8 +741,13 @@ init_gactions (IndicatorSessionService * self) **** ***/ +/** + * A small helper function for rebuild_now(). + * - removes the previous section + * - adds and unrefs the new section + */ static void -replace_section (GMenu * parent, int pos, GMenuModel * new_section) +rebuild_section (GMenu * parent, int pos, GMenuModel * new_section) { g_menu_remove (parent, pos); g_menu_insert_section (parent, pos, NULL, new_section); @@ -763,24 +768,24 @@ rebuild_now (IndicatorSessionService * self, int sections) if (sections & SECTION_ADMIN) { - replace_section (desktop->submenu, 0, create_admin_section()); + rebuild_section (desktop->submenu, 0, create_admin_section()); } if (sections & SECTION_SETTINGS) { - replace_section (desktop->submenu, 1, create_settings_section(self)); + rebuild_section (desktop->submenu, 1, create_settings_section(self)); } if (sections & SECTION_SWITCH) { - replace_section (desktop->submenu, 2, create_switch_section(self)); + rebuild_section (desktop->submenu, 2, create_switch_section(self)); update_switch_actions (self); } if (sections & SECTION_SESSION) { - replace_section (desktop->submenu, 3, create_session_section(self)); - replace_section (greeter->submenu, 0, create_session_section(self)); + rebuild_section (desktop->submenu, 3, create_session_section(self)); + rebuild_section (greeter->submenu, 0, create_session_section(self)); } } -- cgit v1.2.3 From d79745bdb2e9bbd02e162a5209de9f227d1dbbc3 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 10:29:50 -0500 Subject: in rebuild_soon(), add a comment explaining the 500 msec interval --- src/service.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/service.c b/src/service.c index 2206621..2a10290 100644 --- a/src/service.c +++ b/src/service.c @@ -808,6 +808,10 @@ rebuild_soon (IndicatorSessionService * self, int section) if (p->rebuild_id == 0) { + /* Change events seem to come over the bus in small bursts. This msec + value is an arbitrary number that tries to be large enough to fold + multiple events into a single rebuild, but small enough that the + user won't notice any lag. */ static const int REBUILD_INTERVAL_MSEC = 500; p->rebuild_id = g_timeout_add (REBUILD_INTERVAL_MSEC, -- cgit v1.2.3 From 67218e58889b101ceb5a50bcb40c37045fb2855d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:13:03 -0500 Subject: indicator-session-service should exit when it loses ownership of its name on the bus. --- src/main.c | 9 +++++++++ src/service.c | 23 ++++++++++++++++++++++- src/service.h | 7 +++++++ 3 files changed, 38 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 17b50b4..4511fce 100644 --- a/src/main.c +++ b/src/main.c @@ -60,6 +60,13 @@ parse_command_line (int * argc, char *** argv) **** ***/ +static void +on_name_lost (gpointer instance, gpointer loop) +{ + g_debug ("exiting: service couldn't acquire or lost ownership of busname"); + g_main_loop_quit ((GMainLoop*)loop); +} + int main (int argc, char ** argv) { @@ -76,6 +83,8 @@ main (int argc, char ** argv) /* run */ service = indicator_session_service_new (replace); loop = g_main_loop_new (NULL, FALSE); + g_signal_connect (service, INDICATOR_SESSION_SERVICE_SIGNAL_NAME_LOST, + G_CALLBACK(on_name_lost), loop); g_main_loop_run (loop); /* cleanup */ diff --git a/src/service.c b/src/service.c index 2a10290..bcd88ff 100644 --- a/src/service.c +++ b/src/service.c @@ -37,6 +37,15 @@ G_DEFINE_TYPE (IndicatorSessionService, indicator_session_service, G_TYPE_OBJECT) +/* signals enum */ +enum +{ + NAME_LOST, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + enum { PROP_0, @@ -910,9 +919,13 @@ on_name_lost (GDBusConnection * connection G_GNUC_UNUSED, const gchar * name, gpointer gself) { + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (gself); + g_debug ("%s %s name lost %s", G_STRLOC, G_STRFUNC, name); - unexport (INDICATOR_SESSION_SERVICE (gself)); + unexport (self); + + g_signal_emit (self, signals[NAME_LOST], 0, NULL); } /*** @@ -1133,6 +1146,14 @@ indicator_session_service_class_init (IndicatorSessionServiceClass * klass) g_type_class_add_private (klass, sizeof (IndicatorSessionServicePrivate)); + signals[NAME_LOST] = g_signal_new (INDICATOR_SESSION_SERVICE_SIGNAL_NAME_LOST, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorSessionServiceClass, name_lost), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + properties[PROP_0] = NULL; properties[PROP_REPLACE] = g_param_spec_boolean ("replace", diff --git a/src/service.h b/src/service.h index 2a78855..3fad6bf 100644 --- a/src/service.h +++ b/src/service.h @@ -36,6 +36,9 @@ typedef struct _IndicatorSessionService IndicatorSessionService; typedef struct _IndicatorSessionServiceClass IndicatorSessionServiceClass; typedef struct _IndicatorSessionServicePrivate IndicatorSessionServicePrivate; +/* signal keys */ +#define INDICATOR_SESSION_SERVICE_SIGNAL_NAME_LOST "name-lost" + /** * The Indicator Session Service. */ @@ -49,6 +52,10 @@ struct _IndicatorSessionService struct _IndicatorSessionServiceClass { GObjectClass parent_class; + + /* signals */ + + void (* name_lost)(IndicatorSessionService * self); }; /*** -- cgit v1.2.3 From 348a5c53f4ca0d1ee197bc0822f0c8d712cd8972 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:19:05 -0500 Subject: in indicator_session_service_init(), don't leak a GCancellable --- src/service.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index bcd88ff..14d41cd 100644 --- a/src/service.c +++ b/src/service.c @@ -108,6 +108,7 @@ struct _IndicatorSessionServicePrivate guint rebuild_id; int rebuild_flags; GDBusConnection * conn; + GCancellable * cancellable; gboolean replace; }; @@ -950,9 +951,10 @@ indicator_session_service_init (IndicatorSessionService * self) self->priv = p; /* init the backend objects */ - backend_get (g_cancellable_new (), &p->backend_actions, - &p->backend_users, - &p->backend_guest); + p->cancellable = g_cancellable_new (); + backend_get (p->cancellable, &p->backend_actions, + &p->backend_users, + &p->backend_guest); /* init our key-to-User table */ p->users = g_hash_table_new_full (g_str_hash, @@ -1102,6 +1104,12 @@ my_dispose (GObject * o) unexport (self); + if (p->cancellable != NULL) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + if (p->rebuild_id) { g_source_remove (p->rebuild_id); -- cgit v1.2.3 From 75d79800ffbc0bdc8598b2b34164c4dabc9888c8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:25:13 -0500 Subject: in the service's dispose() function, unown the busname before unexporting the actions and menus. --- src/service.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 14d41cd..9a4e561 100644 --- a/src/service.c +++ b/src/service.c @@ -1102,6 +1102,12 @@ my_dispose (GObject * o) IndicatorSessionService * self = INDICATOR_SESSION_SERVICE(o); priv_t * p = self->priv; + if (p->own_id) + { + g_bus_unown_name (p->own_id); + p->own_id = 0; + } + unexport (self); if (p->cancellable != NULL) @@ -1116,12 +1122,6 @@ my_dispose (GObject * o) p->rebuild_id = 0; } - if (p->own_id) - { - g_bus_unown_name (p->own_id); - p->own_id = 0; - } - g_clear_pointer (&p->users, g_hash_table_destroy); g_clear_object (&p->backend_users); g_clear_object (&p->backend_guest); -- cgit v1.2.3 From 6ff4e525b7f1a090450b3ff40cff082888250323 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:33:20 -0500 Subject: remove #if 0 code --- src/backend-dbus/guest.c | 34 ---------------------------------- src/backend-dbus/users.c | 26 -------------------------- 2 files changed, 60 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 516ba00..1559aa8 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -379,30 +379,6 @@ set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * } } -#if 0 -static void -on_display_manager_seat_proxy_ready (GObject * o, GAsyncResult * res, gpointer gself) -{ - GError * err; - DisplayManagerSeat * seat; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - err = NULL; - seat = display_manager_seat_proxy_new_for_bus_finish (res, &err); - if (err != NULL) - { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - g_error_free (err); - } - else - { - set_display_manager_seat (INDICATOR_SESSION_GUEST_DBUS(gself), seat); - } - - g_clear_object (&seat); -} -#endif - static void on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC_UNUSED) { @@ -529,16 +505,6 @@ indicator_session_guest_dbus_init (IndicatorSessionGuestDbus * self) IndicatorSessionGuestDbusPriv); p->cancellable = g_cancellable_new (); self->priv = p; - -#if 0 - display_manager_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.DisplayManager", - g_getenv ("XDG_SEAT_PATH"), - self->priv->cancellable, - on_display_manager_seat_proxy_ready, - self); -#endif } /*** diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 4798d33..34e0c97 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -229,21 +229,6 @@ set_account_manager (IndicatorSessionUsersDbus * self, Accounts * a) } } -#if 0 -static void -create_accounts_proxy (IndicatorSessionUsersDbus * self) -{ - const char * name = "org.freedesktop.Accounts"; - const char * path = "/org/freedesktop/Accounts"; - GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - - accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, path, - self->priv->cancellable, - on_accounts_proxy_ready, self); -} -#endif - /** * SEAT / SESSION TRACKING * @@ -771,17 +756,6 @@ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) p->uid_to_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_hash_table_destroy); - -#if 0 - console_kit_manager_proxy_new_for_bus ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - p->cancellable, - on_console_kit_manager_proxy_ready, - self); -#endif } /*** -- cgit v1.2.3 From 29befc58e1f1fd61d4d6d1a6db024d32182f7488 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:41:22 -0500 Subject: g_object_unref doesn't need a G_OBJECT() cast --- src/service.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 9a4e561..2e42bd0 100644 --- a/src/service.c +++ b/src/service.c @@ -468,7 +468,7 @@ create_switch_section (IndicatorSessionService * self) g_menu_item_set_attribute (item, "accel", "s", str); g_free (str); g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); + g_object_unref (item); if (indicator_session_guest_is_allowed (p->backend_guest)) g_menu_append (menu, _("Guest Session"), "indicator.switch-to-guest"); @@ -496,7 +496,7 @@ create_switch_section (IndicatorSessionService * self) item = g_menu_item_new (u->real_name, NULL); g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name); g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); + g_object_unref (item); } /* cleanup */ @@ -571,19 +571,19 @@ create_menu (IndicatorSessionService * self, int form_factor) for (i=0; ipriv->menus[form_factor].menu = menu; self->priv->menus[form_factor].submenu = submenu; @@ -761,7 +761,7 @@ rebuild_section (GMenu * parent, int pos, GMenuModel * new_section) { g_menu_remove (parent, pos); g_menu_insert_section (parent, pos, NULL, new_section); - g_object_unref (G_OBJECT(new_section)); + g_object_unref (new_section); } static void -- cgit v1.2.3 From 460b015be860290cf06e9e08a99a51c52c770717 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 12:24:58 -0500 Subject: better documentation for indicator_session_users_get_keys() and indicator_session_users_get_user() --- src/users.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/users.h b/src/users.h index 31ee39e..f2d7404 100644 --- a/src/users.h +++ b/src/users.h @@ -124,11 +124,21 @@ void indicator_session_users_notify_is_live_session (IndicatorSessionUsers * sel gboolean indicator_session_users_is_live_session (IndicatorSessionUsers * users); -/* get a list of user keys */ +/** + * Get a list of user keys. + * + * Return value: (transfer full): a NULL-terminated array of user keys. + * Free with g_strfreev() when done. + */ GStrv indicator_session_users_get_keys (IndicatorSessionUsers * users); -/* get information about a particular user. - call indicator_session_user_free() when done with the returned struct. */ +/** + * Get information about a particular user. + * + * Return value: (transfer full): an IndicatorSessionUser struct + * populated with information about the specified user. + * Free with indicator_session_user_free() when done. + */ IndicatorSessionUser * indicator_session_users_get_user (IndicatorSessionUsers * users, const gchar * key); -- cgit v1.2.3 From 6729218076bdfebfc5b5c48742abb72a3a899314 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 12:30:14 -0500 Subject: refer to profiles as profiles instead of forms. --- src/service.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 2e42bd0..d912176 100644 --- a/src/service.c +++ b/src/service.c @@ -67,18 +67,18 @@ enum enum { - FORM_DESKTOP, - FORM_GREETER, - N_FORMS + PROFILE_DESKTOP, + PROFILE_GREETER, + N_PROFILES }; -static const char * const menu_names[N_FORMS] = +static const char * const menu_names[N_PROFILES] = { "desktop", "desktop_greeter" }; -struct FormMenuInfo +struct ProfileMenuInfo { /* the root level -- the header is the only child of this */ GMenu * menu; @@ -100,7 +100,7 @@ struct _IndicatorSessionServicePrivate GSettings * keybinding_settings; GSimpleActionGroup * actions; guint actions_export_id; - struct FormMenuInfo menus[N_FORMS]; + struct ProfileMenuInfo menus[N_PROFILES]; GSimpleAction * header_action; GSimpleAction * user_switcher_action; GSimpleAction * guest_switcher_action; @@ -542,7 +542,7 @@ create_session_section (IndicatorSessionService * self) } static void -create_menu (IndicatorSessionService * self, int form_factor) +create_menu (IndicatorSessionService * self, int profile) { GMenu * menu; GMenu * submenu; @@ -551,17 +551,17 @@ create_menu (IndicatorSessionService * self, int form_factor) int i; int n = 0; - g_assert (0<=form_factor && form_factorpriv->menus[form_factor].menu == NULL); + g_assert (0<=profile && profilepriv->menus[profile].menu == NULL); - if (form_factor == FORM_DESKTOP) + if (profile == PROFILE_DESKTOP) { sections[n++] = create_admin_section (); sections[n++] = create_settings_section (self); sections[n++] = create_switch_section (self); sections[n++] = create_session_section (self); } - else if (form_factor == FORM_GREETER) + else if (profile == PROFILE_GREETER) { sections[n++] = create_session_section (self); } @@ -585,8 +585,8 @@ create_menu (IndicatorSessionService * self, int form_factor) g_menu_append_item (menu, header); g_object_unref (header); - self->priv->menus[form_factor].menu = menu; - self->priv->menus[form_factor].submenu = submenu; + self->priv->menus[profile].menu = menu; + self->priv->menus[profile].submenu = submenu; } /*** @@ -768,8 +768,8 @@ static void rebuild_now (IndicatorSessionService * self, int sections) { priv_t * p = self->priv; - struct FormMenuInfo * desktop = &p->menus[FORM_DESKTOP]; - struct FormMenuInfo * greeter = &p->menus[FORM_GREETER]; + struct ProfileMenuInfo * desktop = &p->menus[PROFILE_DESKTOP]; + struct ProfileMenuInfo * greeter = &p->menus[PROFILE_GREETER]; if (sections & SECTION_HEADER) { @@ -864,10 +864,10 @@ on_bus_acquired (GDBusConnection * connection, } /* export the menus */ - for (i=0; imenus[i]; + struct ProfileMenuInfo * menu = &p->menus[i]; if (menu->menu == NULL) create_menu (self, i); @@ -896,7 +896,7 @@ unexport (IndicatorSessionService * self) priv_t * p = self->priv; /* unexport the menus */ - for (i=0; ipriv->menus[i].export_id; @@ -1130,7 +1130,7 @@ my_dispose (GObject * o) g_clear_object (&p->keybinding_settings); g_clear_object (&p->actions); - for (i=0; imenus[i].menu); g_clear_object (&p->header_action); -- cgit v1.2.3 From 2babf3e334649031a4e8fff308358f6974ceb155 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 23 May 2013 18:48:56 -0400 Subject: Set x-canonical-type for user and guest menu items --- src/service.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index d912176..59728d1 100644 --- a/src/service.c +++ b/src/service.c @@ -471,7 +471,15 @@ create_switch_section (IndicatorSessionService * self) g_object_unref (item); if (indicator_session_guest_is_allowed (p->backend_guest)) - g_menu_append (menu, _("Guest Session"), "indicator.switch-to-guest"); + { + GMenuItem *item; + + item = g_menu_item_new (_("Guest Session"), "indicator.switch-to-guest"); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "indicator.guest-menu-item"); + g_menu_append_item (menu, item); + + g_object_unref (item); + } /* build an array of all the users we know of */ users = g_ptr_array_new (); @@ -495,6 +503,7 @@ create_switch_section (IndicatorSessionService * self) const IndicatorSessionUser * u = g_ptr_array_index (users, i); item = g_menu_item_new (u->real_name, NULL); g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "indicator.user-menu-item"); g_menu_append_item (menu, item); g_object_unref (item); } -- cgit v1.2.3 From a4c536391abbd2057ddbcd8d0bc83a9e67de3273 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Jun 2013 18:16:25 -0500 Subject: in service.c, remove unnecesssary locale #include --- src/service.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index d912176..7852adf 100644 --- a/src/service.c +++ b/src/service.c @@ -17,8 +17,6 @@ * with this program. If not, see . */ -#include - #include #include -- 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 +++---------- src/backend-dbus/guest.c | 30 ++++++++++++++++-------------- src/backend-dbus/users.c | 28 +++++++++++++++++++++------- src/backend-dbus/utils.c | 28 ++++++++++++++++++---------- 4 files changed, 58 insertions(+), 41 deletions(-) (limited to 'src') 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; diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 1559aa8..317152d 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -95,7 +95,9 @@ on_active_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gse if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -140,7 +142,10 @@ on_active_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gp if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + + g_error_free (err); } else { @@ -253,7 +258,9 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, if (err != NULL) { - g_warning ("%s: %s", G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s: %s", G_STRFUNC, err->message); + g_error_free (err); } else if (is_guest (user)) @@ -290,7 +297,9 @@ on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -389,7 +398,9 @@ on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } } @@ -418,14 +429,6 @@ my_dispose (GObject * o) G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); } -static void -my_finalize (GObject * o) -{ - /*IndicatorSessionGuestDbus * u = INDICATOR_SESSION_GUEST_DBUS (o);*/ - - G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->finalize (o); -} - static gboolean my_is_allowed (IndicatorSessionGuest * self) { @@ -483,7 +486,6 @@ indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; - object_class->finalize = my_finalize; guest_class = INDICATOR_SESSION_GUEST_CLASS (klass); guest_class->is_allowed = my_is_allowed; diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 34e0c97..6d9ada6 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -154,7 +154,9 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, user = accounts_user_proxy_new_for_bus_finish (res, &err); if (err != NULL) { - g_warning ("%s: %s", G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s: %s", G_STRFUNC, err->message); + g_error_free (err); } else @@ -187,7 +189,9 @@ on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -317,7 +321,9 @@ on_session_proxy_uid_ready (GObject * o, console_kit_session_call_get_unix_user_finish (session, &uid, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else if (uid) @@ -347,7 +353,9 @@ on_session_x11_display_ready (GObject * o, console_kit_session_call_get_x11_display_finish (session, &gui, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -378,7 +386,9 @@ on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer session = console_kit_session_proxy_new_finish (res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else if (session != NULL) @@ -417,7 +427,9 @@ on_session_list_ready (GObject * o, GAsyncResult * res, gpointer gself) &sessions, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -508,7 +520,9 @@ on_seat_active_session_ready (GObject * o, GAsyncResult * res, gpointer gself) console_kit_seat_call_get_active_session_finish (seat, &ssid, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else if (ssid != NULL) diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index 86a5e5a..c8abc2b 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -91,7 +91,8 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else { @@ -112,7 +113,8 @@ on_user_path_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdat if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (path != NULL) { @@ -141,7 +143,8 @@ on_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) console_kit_session_call_get_unix_user_finish (data->current_session, &uid, res, &data->error); if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (uid) { @@ -165,7 +168,7 @@ on_seat_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gda data->current_seat = console_kit_seat_proxy_new_for_bus_finish (res, &data->error); - if (data->error != NULL) + if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); finish_callback (data); @@ -182,7 +185,8 @@ on_sid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (sid != NULL) { @@ -210,7 +214,8 @@ on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer data->current_session = console_kit_session_proxy_new_finish (res, &data->error); if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else { @@ -243,7 +248,8 @@ on_current_session_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointe &data->error); if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (ssid) { @@ -275,7 +281,8 @@ on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (seat != NULL) { @@ -302,7 +309,8 @@ on_console_kit_manager_proxy_ready (GObject * o G_GNUC_UNUSED, if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else { @@ -330,7 +338,7 @@ on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer { data->account_manager = accounts_proxy_new_for_bus_finish (res, &data->error); - if (data->error != NULL) + if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } -- cgit v1.2.3 From 4df0aceb48e9b3d6c77f6e06c7acde89747ff878 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Jun 2013 18:27:08 -0500 Subject: use the production dbus name --- src/service.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 7852adf..862028b 100644 --- a/src/service.c +++ b/src/service.c @@ -23,8 +23,7 @@ #include "backend.h" #include "service.h" -/* FIXME: remove -test */ -#define BUS_NAME "com.canonical.indicator.session-test" +#define BUS_NAME "com.canonical.indicator.session" #define BUS_PATH "/com/canonical/indicator/session" #define ICON_DEFAULT "system-devices-panel" -- cgit v1.2.3 From fab2853f35eb108988b5ddb16cd9f6e43de79773 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 20 Jun 2013 13:54:41 -0500 Subject: remove the --replace command-line argument and property as we're using upstart for that --- src/main.c | 42 +++++------------------------------------- src/service.c | 41 +++-------------------------------------- src/service.h | 2 +- 3 files changed, 9 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 4511fce..8df5e60 100644 --- a/src/main.c +++ b/src/main.c @@ -29,46 +29,16 @@ **** ***/ -static gboolean replace = FALSE; - -static void -parse_command_line (int * argc, char *** argv) -{ - GError * error; - GOptionContext * option_context; - - static GOptionEntry entries[] = - { - { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, "Replace the currently-running service", NULL }, - { NULL } - }; - - error = NULL; - option_context = g_option_context_new ("- indicator-session service"); - g_option_context_add_main_entries (option_context, entries, GETTEXT_PACKAGE); - if (!g_option_context_parse (option_context, argc, argv, &error)) - { - g_print ("option parsing failed: %s\n", error->message); - g_error_free (error); - exit (EXIT_FAILURE); - } - - g_option_context_free (option_context); -} - -/*** -**** -***/ - static void on_name_lost (gpointer instance, gpointer loop) { - g_debug ("exiting: service couldn't acquire or lost ownership of busname"); - g_main_loop_quit ((GMainLoop*)loop); + g_warning ("exiting: service couldn't acquire, or lost ownership of, busname"); + + g_main_loop_quit (loop); } int -main (int argc, char ** argv) +main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) { GMainLoop * loop; IndicatorSessionService * service; @@ -78,10 +48,8 @@ main (int argc, char ** argv) bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); textdomain (GETTEXT_PACKAGE); - parse_command_line (&argc, &argv); - /* run */ - service = indicator_session_service_new (replace); + service = indicator_session_service_new (); loop = g_main_loop_new (NULL, FALSE); g_signal_connect (service, INDICATOR_SESSION_SERVICE_SIGNAL_NAME_LOST, G_CALLBACK(on_name_lost), loop); diff --git a/src/service.c b/src/service.c index 862028b..83bfeaa 100644 --- a/src/service.c +++ b/src/service.c @@ -46,7 +46,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_0, - PROP_REPLACE, PROP_MAX_USERS, PROP_LAST }; @@ -106,8 +105,6 @@ struct _IndicatorSessionServicePrivate int rebuild_flags; GDBusConnection * conn; GCancellable * cancellable; - - gboolean replace; }; typedef IndicatorSessionServicePrivate priv_t; @@ -1013,23 +1010,10 @@ indicator_session_service_init (IndicatorSessionService * self) gp = p->keybinding_settings; g_signal_connect_swapped (gp, "changed::screensaver", G_CALLBACK(rebuild_switch_section_soon), self); -} - -static void -my_constructed (GObject * o) -{ - GBusNameOwnerFlags owner_flags; - IndicatorSessionService * self = INDICATOR_SESSION_SERVICE(o); - - /* own the name in constructed() instead of init() so that - we'll know the value of the 'replace' property */ - owner_flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; - if (self->priv->replace) - owner_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; self->priv->own_id = g_bus_own_name (G_BUS_TYPE_SESSION, BUS_NAME, - owner_flags, + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, on_bus_acquired, NULL, on_name_lost, @@ -1051,10 +1035,6 @@ my_get_property (GObject * o, switch (property_id) { - case PROP_REPLACE: - g_value_set_boolean (value, self->priv->replace); - break; - case PROP_MAX_USERS: g_value_set_uint (value, self->priv->max_users); break; @@ -1074,10 +1054,6 @@ my_set_property (GObject * o, switch (property_id) { - case PROP_REPLACE: - self->priv->replace = g_value_get_boolean (value); - break; - case PROP_MAX_USERS: self->priv->max_users = g_value_get_uint (value); rebuild_switch_section_soon (self); @@ -1145,7 +1121,6 @@ indicator_session_service_class_init (IndicatorSessionServiceClass * klass) GObjectClass * object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; - object_class->constructed = my_constructed; object_class->get_property = my_get_property; object_class->set_property = my_set_property; @@ -1161,14 +1136,6 @@ indicator_session_service_class_init (IndicatorSessionServiceClass * klass) properties[PROP_0] = NULL; - properties[PROP_REPLACE] = g_param_spec_boolean ("replace", - "Replace Service", - "Replace existing service", - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - properties[PROP_MAX_USERS] = g_param_spec_uint ("max-users", "Max Users", "Max visible users", @@ -1181,11 +1148,9 @@ indicator_session_service_class_init (IndicatorSessionServiceClass * klass) } IndicatorSessionService * -indicator_session_service_new (gboolean replace) +indicator_session_service_new (void) { - GObject * o = g_object_new (INDICATOR_TYPE_SESSION_SERVICE, - "replace", replace, - NULL); + GObject * o = g_object_new (INDICATOR_TYPE_SESSION_SERVICE, NULL); return INDICATOR_SESSION_SERVICE (o); } diff --git a/src/service.h b/src/service.h index 3fad6bf..fa870e5 100644 --- a/src/service.h +++ b/src/service.h @@ -64,7 +64,7 @@ struct _IndicatorSessionServiceClass GType indicator_session_service_get_type (void); -IndicatorSessionService * indicator_session_service_new (gboolean replace); +IndicatorSessionService * indicator_session_service_new (void); G_END_DECLS -- cgit v1.2.3 From 6def7fceae5ea55e6d44ede05146f6a95add317c Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 20 Jun 2013 17:31:07 -0500 Subject: install .schema.xml and indicator-session-service in the right places. --- src/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index efa704c..7b65629 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ set_target_properties (libindicatorsessionservice PROPERTIES COMPILE_FLAGS " -g include_directories(${SERVICE_INCLUDE_DIRS}) link_directories(${SERVICE_LIBRARY_DIRS}) -add_executable (indicator-session-service main.c) -target_link_libraries (indicator-session-service libindicatorsessionservice backenddbus ${SERVICE_LIBRARIES} ${GCOV_LIBS}) - +set (SERVICE_EXEC "indicator-session-service") +add_executable (${SERVICE_EXEC} main.c) +target_link_libraries (${SERVICE_EXEC} libindicatorsessionservice backenddbus ${SERVICE_LIBRARIES} ${GCOV_LIBS}) +install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${PROJECT_LIBEXECDIR}) -- cgit v1.2.3 From f6ab8644d81f403b0264e126e9631a00dd578418 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 23 Jun 2013 18:26:25 -0500 Subject: add icon support to user menuitems --- src/service.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/service.c b/src/service.c index 4a62bd1..ede3a9f 100644 --- a/src/service.c +++ b/src/service.c @@ -498,6 +498,16 @@ create_switch_section (IndicatorSessionService * self) item = g_menu_item_new (u->real_name, NULL); g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name); g_menu_item_set_attribute (item, "x-canonical-type", "s", "indicator.user-menu-item"); + + if (u->icon_file != NULL) + { + GFile * file = g_file_new_for_path (u->icon_file); + GIcon * icon = g_file_icon_new (file); + g_menu_item_set_attribute_value (item, G_MENU_ATTRIBUTE_ICON, g_icon_serialize (icon)); + g_clear_object (&icon); + g_clear_object (&file); + } + g_menu_append_item (menu, item); g_object_unref (item); } -- cgit v1.2.3 From d7bb2123f7afffd93524110b4174ad855043f57d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:14:32 -0500 Subject: add replace consolekit xml files with login1; update build files --- src/backend-dbus/CMakeLists.txt | 24 +- .../org.freedesktop.ConsoleKit.Manager.xml | 353 ----------------- .../org.freedesktop.ConsoleKit.Seat.xml | 164 -------- .../org.freedesktop.ConsoleKit.Session.xml | 435 --------------------- .../org.freedesktop.login1.Manager.xml | 199 ++++++++++ src/backend-dbus/org.freedesktop.login1.Seat.xml | 21 + .../org.freedesktop.login1.Session.xml | 49 +++ src/backend-dbus/org.freedesktop.login1.User.xml | 56 +++ src/backend-dbus/upower.xml | 309 --------------- 9 files changed, 337 insertions(+), 1273 deletions(-) delete mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml delete mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml delete mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.Manager.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.Seat.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.Session.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.User.xml delete mode 100644 src/backend-dbus/upower.xml (limited to 'src') diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index dd928cc..58d7b6a 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -3,7 +3,7 @@ set(BACKEND_GENERATED_SOURCES add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-display-manager org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/display-manager.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.DisplayManager.Seat) add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-webcredentials com.canonical.indicators @@ -17,17 +17,21 @@ add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-user org.freedesktop ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Accounts.User.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-manager +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-manager org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Manager.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Manager.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-seat +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-seat org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Seat.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Seat.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-session +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-session org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Session.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Session.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-user + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.User.xml) add_gdbus_codegen (BACKEND_GENERATED_SOURCES gnome-screen-saver org @@ -41,11 +45,7 @@ add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-end-session-dialog org.gnome.SessionManager ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.SessionManager.EndSessionDialog.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-upower - org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/upower.xml) - -set (SOURCES actions.c backend-dbus.c guest.c users.c utils.c) +set (SOURCES actions.c guest.c users.c backend-dbus.c utils.c) # add warnings/coverage info on handwritten files # but not the autogenerated ones... diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml deleted file mode 100644 index f903b55..0000000 --- a/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - - - - This method initiates a request to restart (ie. reboot) the computer system. - - - - - - - - - - - - - - This method initiates a request to stop (ie. shutdown) the computer system. - - - - - - - - - - - - - - The secret cookie that is used to identify the new session - - - - - This method requests that a new Session - be created for the calling process. The properties of this new Session are set automatically - from information collected about the calling process. - - This new session exists until the calling process disconnects from the system bus or - calls CloseSession(). - - It is the responsibility of the calling process to set the environment variable - XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only - be made available to child processes of the caller so that they may be identified - as members of this session. - - See this simple example: - - DBusError error; - DBusMessage *message; - DBusMessage *reply; - - message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager", - "OpenSession"); - if (message == NULL) { - goto out; - } - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connector->connection, - message, - -1, - &error); - if (reply == NULL) { - goto out; - } - - dbus_error_init (&error); - if (! dbus_message_get_args (reply, - &error, - DBUS_TYPE_STRING, &cookie, - DBUS_TYPE_INVALID)) { - goto out; - } - - - - OpenSessionWithParameters() - - - - - - - An array of sets of property names and values - - - - - The secret cookie that is used to identify the new session - - - - - This method requests that a new Session - be created for the calling process. The properties of this new Session are from the - parameters provided. - - This new session exists until the calling process disconnects from the system bus or - calls CloseSession(). - - It is the responsibility of the calling process to set the environment variable - XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only - be made available to child processes of the caller so that they may be identified - as members of this session. - - See the Session properties for a list of valid parameters. - - org.freedesktop.ConsoleKit.Session - This method is restricted to privileged users by D-Bus policy. - - - - - - - The secret cookie that is used to identify the session - - - - - Whether the session was successfully closed - - - - - This method is used to close the session identified by the supplied cookie. - - The session can only be closed by the same process that opened the session. - - - - - - - - - an array of Seat IDs - - - - - This gets a list of all the Seats - that are currently present on the system. - Each Seat ID is an D-Bus object path for the object that implements the - Seat interface. - - org.freedesktop.ConsoleKit.Seat - - - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently present on the system. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - org.freedesktop.ConsoleKit.Session - - - - - - - - The secret cookie that is used to identify the session - - - - - The object identifier for the current session - - - - - Returns the session ID that is associated with the specified cookie. - - - - - - - - - The POSIX process ID - - - - - The object identifier for the current session - - - - - Attempts to determine the session ID for the specified - POSIX process ID (pid). - - - - - - - - - The object identifier for the current session - - - - - Attempts to determine the session ID that the caller belongs to. - - See this example of using dbus-send: - - dbus-send --system --dest=org.freedesktop.ConsoleKit \ - --type=method_call --print-reply --reply-timeout=2000 \ - /org/freedesktop/ConsoleKit/Manager \ - org.freedesktop.ConsoleKit.Manager.GetCurrentSession - - - - - - - - - POSIX User identification - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently open for the specified user. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - User identification - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently open for the specified user. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - - The value of the system-idle-hint - - - - - Returns TRUE if the idle-hint - property of every open session is TRUE or if there are no open sessions. - - - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time of the last change of the system-idle-hint. - - - - - - - - - The Seat ID for the added seat - - - - - Emitted when a Seat has been added to the system. - - - - - - - - The Seat ID for the removed seat - - - - - Emitted when a Seat has been removed from the system. - - - - - - - - The value of the system-idle-hint - - - - - Emitted when the value of the system-idle-hint has changed. - - - - - - diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml deleted file mode 100644 index 58c2ce7..0000000 --- a/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - A seat is a collection of sessions and a set of hardware (usually at -least a keyboard and mouse). Only one session may be active on a -seat at a time. - - - - - - - Seat ID - - - - - Returns the ID for Seat. - - - - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently attached to this seat. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - an array of devices - - - - - This gets a list of all the devices - that are currently associated with this seat. - Each device is an D-Bus structure that represents - the device type and the device id. - - - - - - - - - Session ID - - - - - Gets the Session ID that is currently active on this Seat. - Returns NULL if there is no active session. - - - - - - - - TRUE if seat supports session activation - - - - Used to determine whether the seat supports session activation. - - - - - - - - - Session ID - - - - - Attempt to activate the specified session. In most - cases, if successful, this will cause the session to - become visible and take control of the hardware that is - associated with this seat. - - Activate() - - - - - - - Session ID - - - - - Emitted when the active session has changed. - - - - - - - Session ID - - - - - Emitted when a session has been added to the seat. - - - - - - - Session ID - - - - - Emitted when a session has been removed from the seat. - - - - - - - Device structure - - - - - Emitted when a device has been associated with the seat. - - - - - - - Device structure - - - - - Emitted when a device has been dissociated from the seat. - - - - - diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml deleted file mode 100644 index b6e1cdb..0000000 --- a/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - - Session objects represent and store information - related to a user session. - - The properties associated with the Session - specifically refer to the properties of the "session leader". - - - - - - - Session ID - - - - Returns the ID for Session. - - - - - - - Seat ID - - - - Returns the ID for the Seat the Session is - attached to. - - org.freedesktop.ConsoleKit.Seat - - - - - - Session type - - - - - Returns the type of the session. - Warning: we haven't yet defined the allowed values for this property. - It is probably best to avoid this until we do. - - - session-type - - - - - - User ID - - - - Returns the user that the session belongs to. - - - user - - - - - - POSIX User ID - - - - Returns the POSIX user ID that the session belongs to. - - unix-user - - - - - - The value of the X11 display - - - - Returns the value of the X11 DISPLAY for this session - if one is present. - - x11-display - - - - - - The value of the X11 display device - - - - Returns the value of the display device (aka TTY) that the - X11 display for the session is connected to. If there is no x11-display set then this value - is undefined. - - x11-display-device - - - - - - The value of the display device - - - - Returns the value of the display device (aka TTY) that the - session is connected to. - - display-device - - - - - - The remote host name - - - - Returns the value of the remote host name for the session. - - - remote-host-name - - - - - - The value of the native system login session ID - - - - Returns the value of the login session ID that the - underlying system uses to enforce session boundaries. If there is no login session ID - set then this value is an empty string. - - - - - - - TRUE if the session is active, otherwise FALSE - - - - Returns whether the session is active on the Seat that - it is attached to. - If the session is not attached to a seat this value is undefined. - - - active - - - - - - TRUE if the session is local, otherwise FALSE - - - - Returns whether the session is local - FIXME: we need to come up with a concrete definition for this value. - It was originally used as a way to identify XDMCP sessions that originate - from a remote system. - - - is-local - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time that the session was opened. - - - - - - - - - - Attempt to activate the this session. In most - cases, if successful, this will cause the session to - become visible and become active on the seat that it - is attached to. - - Seat.ActivateSession() - - - - - - - This will cause a Lock - signal to be emitted for this session. - - - This method is restricted to privileged users by D-Bus policy. - Lock signal - - - - - - - This will cause an Unlock - signal to be emitted for this session. - - This can be used by login managers to unlock a session before it is - re-activated during fast-user-switching. - - - This method is restricted to privileged users by D-Bus policy. - Unlock signal - - - - - - - The value of the idle-hint - - - - - Gets the value of the idle-hint - property. - - - idle-hint - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time of the last change of the idle-hint. - - - - - - - - - boolean value to set the idle-hint to - - - - - This may be used by the session to indicate that - it is idle. - - Use of this method is restricted to the user - that owns the session. - - - - - - - - TRUE if the session is active, otherwise FALSE - - - - - Emitted when the active property has changed. - - - - - - - the new value of idle-hint - - - - - Emitted when the idle-hint property has changed. - - - - - - - Emitted in response to a call to the Lock() method. - It is intended that the screensaver for the session should lock the screen in response to this signal. - - - - - - - Emitted in response to a call to the Unlock() method. - It is intended that the screensaver for the session should unlock the screen in response to this signal. - - - - - - - - The user assigned to the session. - - - - - - - The user assigned to the session. - - - - - - - - The type of the session. - Warning: we haven't yet defined the allowed values for this property. - It is probably best to avoid this until we do. - - - - - - - - The remote host name for the session. - - This will be set in situations where the session is - opened and controlled from a remote system. - - For example, this value will be set when the - session is created from an SSH or XDMCP connection. - - - - - - - - The display device (aka TTY) that the - session is connected to. - - - - - - - - Value of the X11 DISPLAY for this session - if one is present. - - - - - - - - - The display device (aka TTY) that the X11 display for the - session is connected to. If there is no x11-display set then - this value is undefined. - - - - - - - - - Whether the session is active on the Seat that - it is attached to. - If the session is not attached to a seat this value is undefined. - - - - - - - - - Whether the session is local - FIXME: we need to come up with a concrete definition for this value. - It was originally used as a way to identify XDMCP sessions that originate - from a remote system. - - - - - - - - - This is a hint used to indicate that the session may be idle. - - - For sessions with a x11-display set (ie. graphical - sessions), it is up to each session to delegate the - responsibility for updating this value. Typically, the - screensaver will set this. - - However, for non-graphical sessions with a display-device set - the Session object itself will periodically update this value based - on the activity detected on the display-device itself. - - - This should not be considered authoritative. - - - - - - - diff --git a/src/backend-dbus/org.freedesktop.login1.Manager.xml b/src/backend-dbus/org.freedesktop.login1.Manager.xml new file mode 100644 index 0000000..91da5f2 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.Manager.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.login1.Seat.xml b/src/backend-dbus/org.freedesktop.login1.Seat.xml new file mode 100644 index 0000000..b73f724 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.Seat.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.login1.Session.xml b/src/backend-dbus/org.freedesktop.login1.Session.xml new file mode 100644 index 0000000..24a6fac --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.Session.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.login1.User.xml b/src/backend-dbus/org.freedesktop.login1.User.xml new file mode 100644 index 0000000..8253706 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.User.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/upower.xml b/src/backend-dbus/upower.xml deleted file mode 100644 index 18d5fbd..0000000 --- a/src/backend-dbus/upower.xml +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - The DeviceKit-power service is available via the system message - bus. To access the service, use - the org.freedesktop.UPower interface on - the /org/freedesktop/UPower object on - the D-Bus system bus service with the well-known - name org.freedesktop.UPower. - - - - -$ dbus-send --print-reply \ - --system \ - --dest=org.freedesktop.UPower \ - /org/freedesktop/UPower \ - org.freedesktop.UPower.EnumerateDevices - -method return sender=:1.386 -> dest=:1.451 reply_serial=2 - array [ - object path "/org/freedesktop/UPower/devices/line_power_AC" - object path "/org/freedesktop/UPower/devices/battery_BAT0" - ] - - - - - - - - - - - - An array of object paths for devices. - - - - - - Enumerate all power objects on the system. - - - - - - - - - - Object path of device that was added. - - - - - - Emitted when a device is added. - - - - - - - - - - Object path of device that was removed. - - - - - - Emitted when a device is removed. - - - - - - - - - - Object path of device that was changed. - - - - - - Emitted when a device changed. - - - - - - - - - - - - Emitted when one or more properties on the object changes. - - - - - - - - - - - - This signal is sent when the session is about to be suspended or - hibernated. - Session and system programs have one second to do anything required - before the sleep action is taken (such as sending out Avahi or - Jabber messages). - - - - - - - - - - - - This signal is sent when the session has just returned from - Suspend() or Hibernate(). - Session and system programs can then do anything required (such as - sending out Avahi or Jabber messages). - - - - - - - - - - - - - This method tells UPower that the Suspend() or Hibernate() method - is about to be called. - This allows UPower to emit the Suspending signal whilst - session activities are happening that have to be done before the - suspend process is started. - - - This method would typically be called by the session power - management daemon, before it locks the screen and waits for the - screen to fade to black. - The session power management component would then call Suspend() or - Hibernate() when these syncronous tasks have completed. - - - If this method is not called than nothing bad will happen and - Suspend() or Hibernate() will block for the required second. - - - - - - - - - - - - - Suspends the computer into a low power state. - System state is not preserved if the power is lost. - - - If AboutToRequestSleep() has not been called then UPower will send - the Sleeping() signal and block for one second. - - - If AboutToRequestSleep() has been called less than one second - before this method is called then UPower will block for the - remaining time to complete one second of delay. - - - - - - - - - - - TRUE if allowed, otherwise FALSE - - - - - Check if the caller has (or can get) the PolicyKit privilege to call - Suspend. - - - - - - - - - - - - - Hibernates the computer into a low power state. - System state is preserved if the power is lost. - - - If AboutToRequestSleep() has not been called then UPower will send - the Sleeping() signal and block for one second. - - - If AboutToRequestSleep() has been called less than one second - before this method is called then UPower will block for the - remaining time to complete one second of delay. - - - - - - - - - - - TRUE if allowed, otherwise FALSE - - - - - Check if the caller has (or can get) the PolicyKit privilege to call - Hibernate. - - - - - - - - - - Version of the running daemon, e.g. 002. - - - - - - Whether the system is able to suspend. - - - - - - Whether the system is able to hibernate. - - - - - - Indicates whether the system is running on battery power. - This property is provided for convenience. - - - - - - Indicates whether the system is running on battery power and if the battery is critically low. - This property is provided for convenience. - - - - - - - - Indicates if the laptop lid is closed where the display cannot be seen. - - - - - - - - - - If the system has a lid device. - - - - - - - - -- cgit v1.2.3 From 463ed782d3f2480126cb11d3e18630e275526d9e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:16:43 -0500 Subject: update which proxies the dbus utils helper creates --- src/backend-dbus/backend-dbus.c | 34 ++-- src/backend-dbus/utils.c | 384 ++++++++-------------------------------- src/backend-dbus/utils.h | 16 +- 3 files changed, 96 insertions(+), 338 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/backend-dbus.c b/src/backend-dbus/backend-dbus.c index ea8f0ec..547c6ab 100644 --- a/src/backend-dbus/backend-dbus.c +++ b/src/backend-dbus/backend-dbus.c @@ -31,38 +31,36 @@ struct dbus_world_data IndicatorSessionGuestDbus * guest; }; -static void -on_proxies_ready (ConsoleKitManager * ck_manager, +static void +on_proxies_ready (Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * display_manager_seat, Accounts * account_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * ck_seat, - ConsoleKitSession * ck_session, - AccountsUser * active_user G_GNUC_UNUSED, - const GError * error, + GCancellable * cancellable, gpointer gdata) { struct dbus_world_data * data = gdata; - if (error == NULL) + if (!g_cancellable_is_cancelled (cancellable)) { if (data->actions != NULL) indicator_session_actions_dbus_set_proxies (data->actions, - ck_manager, - dm_seat, - ck_seat); + login1_manager, + login1_seat, + display_manager_seat); if (data->users != NULL) indicator_session_users_dbus_set_proxies (data->users, - account_manager, - dm_seat, - ck_seat); + login1_manager, + login1_seat, + display_manager_seat, + account_manager); if (data->guest != NULL) indicator_session_guest_dbus_set_proxies (data->guest, - account_manager, - dm_seat, - ck_seat, - ck_session); + login1_manager, + login1_seat, + display_manager_seat); } g_free (data); diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index c8abc2b..25ac7c3 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -25,346 +25,100 @@ struct session_proxy_data { - ConsoleKitManager * ck_manager; - Accounts * account_manager; + Login1Manager * login1_manager; + Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; - - ConsoleKitSeat * current_seat; - ConsoleKitSession * current_session; - AccountsUser * active_user; + Accounts * account_manager; GCancellable * cancellable; - GError * error; int pending; indicator_session_util_session_proxies_func callback; gpointer user_data; }; -static void -session_proxy_data_free (struct session_proxy_data * data) -{ - g_clear_object (&data->ck_manager); - g_clear_object (&data->account_manager); - g_clear_object (&data->dm_seat); - - g_clear_object (&data->current_seat); - g_clear_object (&data->current_session); - g_clear_object (&data->active_user); - - g_clear_object (&data->cancellable); - g_clear_error (&data->error); - - g_free (data); -} static void -finish_callback (struct session_proxy_data * data) +on_proxy_ready_impl (struct session_proxy_data * data, + gsize member_offset, + GError * err, + gpointer proxy) { - g_assert (data != NULL); - g_debug ("%s %s: pending is %d", G_STRLOC, G_STRFUNC, (data->pending-1)); - - if (!--data->pending) + if (err != NULL) { - data->callback (data->ck_manager, - data->account_manager, - data->dm_seat, - data->current_seat, - data->current_session, - data->active_user, - data->error, - data->user_data); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - session_proxy_data_free (data); - } -} - -static void -on_user_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer gdata) -{ - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - data->active_user = accounts_user_proxy_new_for_bus_finish (res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + g_error_free (err); } else { - g_debug ("%s %s user proxy is %p", G_STRLOC, G_STRFUNC, (void*)data->active_user); - } - - finish_callback (data); -} - -static void -on_user_path_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - char * path = NULL; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - accounts_call_find_user_by_id_finish (data->account_manager, &path, res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (path != NULL) - { - g_debug ("%s %s user path is %s", G_STRLOC, G_STRFUNC, path); - ++data->pending; - accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.Accounts", - path, - data->cancellable, - on_user_proxy_ready, - data); + *((gpointer*)G_STRUCT_MEMBER_P(data, member_offset)) = proxy; } - finish_callback (data); - g_free (path); -} - -static void -on_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - guint uid = 0; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - console_kit_session_call_get_unix_user_finish (data->current_session, &uid, res, &data->error); - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (uid) - { - g_debug ("%s %s uid is %u", G_STRLOC, G_STRFUNC, uid); - ++data->pending; - accounts_call_find_user_by_id (data->account_manager, - uid, - data->cancellable, - on_user_path_ready, - data); - } - - finish_callback (data); -} - -static void -on_seat_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - data->current_seat = console_kit_seat_proxy_new_for_bus_finish (res, &data->error); - - if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - - finish_callback (data); -} - -static void -on_sid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - char * sid = NULL; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - console_kit_session_call_get_seat_id_finish (data->current_session, &sid, res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (sid != NULL) - { - g_debug ("%s %s sid is %s", G_STRLOC, G_STRFUNC, sid); - ++data->pending; - console_kit_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - sid, - data->cancellable, - on_seat_proxy_ready, - data); - } - - finish_callback (data); - g_free (sid); -} - -static void -on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - data->current_session = console_kit_session_proxy_new_finish (res, &data->error); - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else + if (!--data->pending) { - ++data->pending; - console_kit_session_call_get_seat_id (data->current_session, - data->cancellable, - on_sid_ready, - data); + data->callback (data->login1_manager, + data->login1_seat, + data->dm_seat, + data->account_manager, + data->cancellable, + data->user_data); - ++data->pending; - console_kit_session_call_get_unix_user (data->current_session, - data->cancellable, - on_uid_ready, - data); + g_clear_object (&data->login1_manager); + g_clear_object (&data->login1_seat); + g_clear_object (&data->dm_seat); + g_clear_object (&data->account_manager); + g_clear_object (&data->cancellable); + g_free (data); } - - finish_callback (data); } - + static void -on_current_session_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - char * ssid = NULL; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - ssid = NULL; - console_kit_manager_call_get_current_session_finish (data->ck_manager, - &ssid, res, - &data->error); - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (ssid) - { - g_debug ("%s %s ssid is %s", G_STRLOC, G_STRFUNC, ssid); - data->pending++; - console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - ssid, - data->cancellable, - on_session_proxy_ready, - data); - - } - - finish_callback (data); - g_free (ssid); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, dm_seat); + GError * err = NULL; + gpointer proxy = display_manager_seat_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } static void -on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer gdata) +on_login1_seat_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - DisplayManagerSeat * seat; - struct session_proxy_data * data = gdata; - - seat = display_manager_seat_proxy_new_for_bus_finish (res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (seat != NULL) - { - data->dm_seat = g_object_ref (seat); - } - - finish_callback (data); - g_clear_object (&seat); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, login1_seat); + GError * err = NULL; + gpointer proxy = login1_seat_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } static void -on_console_kit_manager_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer gdata) +on_login1_manager_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - ConsoleKitManager * mgr; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - if (data->error == NULL) - { - mgr = console_kit_manager_proxy_new_for_bus_finish (res, &data->error); - g_debug ("%s %s mgr is %p, err is %p", G_STRLOC, G_STRFUNC, (void*)mgr, (void*)data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else - { - data->ck_manager = mgr; - - data->pending++; - console_kit_manager_call_get_current_session (mgr, - data->cancellable, - on_current_session_ready, - data); - - } - } - - finish_callback (data); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, login1_manager); + GError * err = NULL; + gpointer proxy = login1_manager_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } static void -on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - if (data->error == NULL) - { - data->account_manager = accounts_proxy_new_for_bus_finish (res, &data->error); - - if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - - finish_callback (data); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, account_manager); + GError * err = NULL; + gpointer proxy = accounts_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } -/** - * Getting all the proxies we want is kind of a pain -- - * especially without blocking (ie, using _sync() funcs) -- - * so it's farmed out to this wrapper utility. - * - * 1. in this func, start getting the ConsoleKit and Accounts proxies - * 2. when the accounts proxy is ready, stash it in data.account_manager - * 3. when the ck manager proxy is ready, stash it in data.ck_manager and - * ask it for the current session's ssid - * 4. when the ssid is ready, start getting a proxy for it - * 5. when the session's proxy is ready, stash it in data.current_session - * and ask it for both the current seat's sid and the active user's uid - * 6. When the current seat's sid is ready, start getting a proxy for it - * 7. When the current seat's proxy is ready, stash it in data.current_seat - * 8. when the active user's uid is ready, ask data.account_manager for the path - * 9. when the user path is ready, start getting an Accounts.User proxy for it - * 10. when the Accounts.User proxy is read, stash it in data.active_user - * - * When everything is done, or if there's an error, invoke the data.callback - */ +/* helper utility to get the dbus proxies used by the backend-dbus classes */ void indicator_session_util_get_session_proxies ( indicator_session_util_session_proxies_func func, @@ -372,12 +126,30 @@ indicator_session_util_get_session_proxies ( gpointer user_data) { struct session_proxy_data * data; + char * seat_path; data = g_new0 (struct session_proxy_data, 1); data->callback = func; data->user_data = user_data; data->cancellable = g_object_ref (cancellable); + data->pending++; + login1_manager_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.login1", + "/org/freedesktop/login1", + data->cancellable, + on_login1_manager_ready, data); + + data->pending++; + seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); + login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.login1", + seat_path, + data->cancellable, + on_login1_seat_ready, + data); data->pending++; accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, @@ -386,15 +158,6 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_accounts_proxy_ready, data); - data->pending++; - console_kit_manager_proxy_new_for_bus ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - data->cancellable, - on_console_kit_manager_proxy_ready, data); - data->pending++; display_manager_seat_proxy_new_for_bus ( G_BUS_TYPE_SYSTEM, @@ -404,4 +167,5 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_display_manager_seat_proxy_ready, data); + g_free (seat_path); } diff --git a/src/backend-dbus/utils.h b/src/backend-dbus/utils.h index b4f26c3..802dd5e 100644 --- a/src/backend-dbus/utils.h +++ b/src/backend-dbus/utils.h @@ -25,19 +25,15 @@ #include "dbus-accounts.h" #include "dbus-display-manager.h" -#include "dbus-user.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" -#include "dbus-consolekit-manager.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" typedef void (*indicator_session_util_session_proxies_func)( - ConsoleKitManager * ck_manager, + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * display_manager_seat, Accounts * account_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * current_ck_seat, - ConsoleKitSession * current_ck_session, - AccountsUser * active_user, - const GError * error, + GCancellable * cancellable, gpointer user_data); /** -- cgit v1.2.3 From d3fe504ae1f9936c508bfd95427767833044811a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:20:08 -0500 Subject: in IndicatorSessionGuest, update to login1 --- src/backend-dbus/guest.c | 466 ++++++++++++++++------------------------------- src/backend-dbus/guest.h | 14 +- 2 files changed, 164 insertions(+), 316 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 317152d..fcb3604 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -19,28 +19,18 @@ #include -#include "dbus-accounts.h" -#include "dbus-display-manager.h" -#include "dbus-user.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-manager.h" -#include "dbus-consolekit-session.h" - #include "guest.h" struct _IndicatorSessionGuestDbusPriv { GCancellable * cancellable; - Accounts * accounts; - AccountsUser * guest; - DisplayManagerSeat * display_manager_seat; - - ConsoleKitSeat * seat; - ConsoleKitSession * active_session; - guint active_uid; + Login1Manager * login1_manager; + Login1Seat * login1_seat; + DisplayManagerSeat * dm_seat; gboolean guest_is_active; + gboolean guest_is_logged_in; gboolean guest_is_allowed; }; @@ -55,143 +45,41 @@ G_DEFINE_TYPE (IndicatorSessionGuestDbus, ***/ static void -check_for_active_guest (IndicatorSessionGuestDbus * self) +set_guest_is_allowed_flag (IndicatorSessionGuestDbus * self, gboolean b) { - gboolean guest_is_active; priv_t * p = self->priv; - guest_is_active = (p->active_uid) - && (p->guest != NULL) - && (p->active_uid == accounts_user_get_uid (p->guest)); - - if (p->guest_is_active != guest_is_active) - { - p->guest_is_active = guest_is_active; - - indicator_session_guest_notify_active (INDICATOR_SESSION_GUEST(self)); - } -} - -static void -set_active_uid (IndicatorSessionGuestDbus * self, guint uid) -{ - self->priv->active_uid = uid; - - check_for_active_guest (self); -} - -static void -on_active_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) -{ - guint uid; - GError * err; - IndicatorSessionGuestDbus * self; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - uid = 0; - err = NULL; - self = INDICATOR_SESSION_GUEST_DBUS (gself); - console_kit_session_call_get_unix_user_finish (self->priv->active_session, &uid, res, &err); - - if (err != NULL) + if (p->guest_is_allowed != b) { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + p->guest_is_allowed = b; - g_error_free (err); - } - else - { - set_active_uid (self, uid); + indicator_session_guest_notify_allowed (INDICATOR_SESSION_GUEST (self)); } } - static void -set_active_session (IndicatorSessionGuestDbus * self, - ConsoleKitSession * session) +set_guest_is_logged_in_flag (IndicatorSessionGuestDbus * self, gboolean b) { priv_t * p = self->priv; - if (p->active_session != NULL) + if (p->guest_is_logged_in != b) { - g_debug ("%s %s active_session refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->active_session)->ref_count); + p->guest_is_logged_in = b; - g_clear_object (&p->active_session); - } - - if (session != NULL) - { - p->active_session = g_object_ref (session); - - console_kit_session_call_get_unix_user (session, - p->cancellable, - on_active_uid_ready, - self); + indicator_session_guest_notify_logged_in (INDICATOR_SESSION_GUEST (self)); } } static void -on_active_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) -{ - GError * err; - ConsoleKitSession * session; - - err = NULL; - session = console_kit_session_proxy_new_finish (res, &err); - - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - - g_error_free (err); - } - else - { - set_active_session (gself, session); - } - - g_clear_object (&session); -} - - -static void -on_active_session_changed (ConsoleKitSeat * seat G_GNUC_UNUSED, - const gchar * ssid, - IndicatorSessionGuestDbus * self) -{ - console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - ssid, - self->priv->cancellable, - on_active_session_proxy_ready, - self); -} - -static void -set_seat (IndicatorSessionGuestDbus * self, - ConsoleKitSeat * seat) +set_guest_is_active_flag (IndicatorSessionGuestDbus * self, gboolean b) { priv_t * p = self->priv; - if (p->seat != NULL) + if (p->guest_is_active != b) { -g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)p->seat); - g_signal_handlers_disconnect_by_data (p->seat, self); -g_debug ("%s %s seat refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->seat)->ref_count); + p->guest_is_active = b; - g_clear_object (&p->seat); - } - - if (seat != NULL) - { - p->seat = g_object_ref (seat); -g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)p->seat); - - g_signal_connect (seat, "active-session-changed", - G_CALLBACK(on_active_session_changed), self); + indicator_session_guest_notify_active (INDICATOR_SESSION_GUEST(self)); } } @@ -199,63 +87,21 @@ g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)p->sea **** ***/ +/* walk the sessions to see if guest is logged in or active */ static void -set_guest (IndicatorSessionGuestDbus * self, - AccountsUser * guest) -{ - priv_t * p = self->priv; - - if (p->guest != NULL) - { - g_debug ("%s %s guest refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->guest)->ref_count); - - g_clear_object (&p->guest); - } - - if (guest != NULL) - { - p->guest = g_object_ref (guest); - } - - g_debug ("%s %s guest proxy is now %p", G_STRLOC, G_STRFUNC, (void*)guest); - indicator_session_guest_notify_logged_in (INDICATOR_SESSION_GUEST(self)); - - check_for_active_guest (self); -} - -static void -on_user_deleted (IndicatorSessionGuestDbus * self, - const gchar * path) -{ - AccountsUser * guest = self->priv->guest; - g_debug ("%s %s %s", G_STRLOC, G_STRFUNC, path); - - if (guest != NULL) - if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (G_DBUS_PROXY(guest)))) - set_guest (self, NULL); -} - -static gboolean -is_guest (AccountsUser * user) -{ - /* a guest will look like this: - username:[guest-jjbEVV] realname:[Guest] system:[1] */ - return IS_ACCOUNTS_USER(user) - && accounts_user_get_system_account (user) - && !g_ascii_strcasecmp (accounts_user_get_real_name(user), "Guest"); -} - -static void -on_user_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer self) +on_login1_manager_session_list_ready (GObject * o, + GAsyncResult * res, + gpointer gself) { + GVariant * sessions; GError * err; - AccountsUser * user; + sessions = NULL; err = NULL; - user = accounts_user_proxy_new_for_bus_finish (res, &err); - + login1_manager_call_list_sessions_finish (LOGIN1_MANAGER(o), + &sessions, + res, + &err); if (err != NULL) { if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -263,139 +109,141 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else if (is_guest (user)) + else { - g_debug ("%s %s got guest", G_STRLOC, G_STRFUNC); - set_guest (INDICATOR_SESSION_GUEST_DBUS(self), user); + const gchar * const current_seat_id = g_getenv ("XDG_SEAT"); + const gchar * const current_session_id = g_getenv ("XDG_SESSION_ID"); + gboolean is_logged_in = FALSE; + gboolean is_active = FALSE; + const gchar * session_id = NULL; + guint32 uid = 0; + const gchar * user_name = NULL; + const gchar * seat_id = NULL; + const gchar * path = NULL; + GVariantIter iter; + + g_variant_iter_init (&iter, sessions); + while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, + &uid, + &user_name, + &seat_id, + &path)) + { + gboolean is_current_session; + gboolean is_guest; + + is_current_session = !g_strcmp0 (current_seat_id, seat_id) + && !g_strcmp0 (current_session_id, session_id); + + is_guest = g_str_has_prefix (user_name, "guest-") + && (uid < 1000); + + if (is_guest) + { + is_logged_in = TRUE; + + is_active = is_current_session; + } + } + + set_guest_is_logged_in_flag (gself, is_logged_in); + set_guest_is_active_flag (gself, is_active); + + g_variant_unref (sessions); } - - g_clear_object (&user); -} - -static void -create_user_proxy_for_path (IndicatorSessionGuestDbus * self, - const char * path) -{ - const char * name = "org.freedesktop.Accounts"; - const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - g_debug ("%s %s creating proxy for %s", G_STRLOC, G_STRFUNC, path); - - accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, path, - self->priv->cancellable, - on_user_proxy_ready, self); } static void -on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +update_session_list (IndicatorSessionGuestDbus * self) { - GError * err; - gchar ** paths; - - err = NULL; - paths = NULL; - accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + priv_t * p = self->priv; - g_error_free (err); - } - else + if (p->login1_manager != NULL) { - int i; - - for (i=0; paths && paths[i]; ++i) - create_user_proxy_for_path (gself, paths[i]); - - g_strfreev (paths); + login1_manager_call_list_sessions (p->login1_manager, + p->cancellable, + on_login1_manager_session_list_ready, + self); } } static void -set_account_manager (IndicatorSessionGuestDbus * self, - Accounts * a) +set_login1_manager (IndicatorSessionGuestDbus * self, + Login1Manager * login1_manager) { - g_debug ("%s %s setting account manager to %p", G_STRLOC, G_STRFUNC, (void*)a); + priv_t * p = self->priv; - if (self->priv->accounts != NULL) + if (p->login1_manager != NULL) { -g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); - g_signal_handlers_disconnect_by_data (self->priv->accounts, self); -g_debug ("%s %s account manager refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->accounts)->ref_count); - g_clear_object (&self->priv->accounts); + g_signal_handlers_disconnect_by_data (p->login1_manager, self); + + g_clear_object (&p->login1_manager); } - if (a != NULL) + if (login1_manager != NULL) { - self->priv->accounts = g_object_ref (a); - -g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); - g_signal_connect_swapped (a, "user-added", - G_CALLBACK(create_user_proxy_for_path), self); - - g_signal_connect_swapped (a, "user-deleted", - G_CALLBACK(on_user_deleted), self); + p->login1_manager = g_object_ref (login1_manager); - accounts_call_list_cached_users (a, - self->priv->cancellable, - on_user_list_ready, - self); + g_signal_connect_swapped (login1_manager, "session-new", + G_CALLBACK(update_session_list), self); + g_signal_connect_swapped (login1_manager, "session-removed", + G_CALLBACK(update_session_list), self); + update_session_list (self); } } static void -set_guest_is_allowed (IndicatorSessionGuestDbus * self, gboolean guest_is_allowed) +update_guest_allowed (IndicatorSessionGuestDbus * self) { priv_t * p = self->priv; - g_debug ("%s %s guest_is_allowed: %d", G_STRLOC, G_STRFUNC, (int)guest_is_allowed); - - if (p->guest_is_allowed != guest_is_allowed) - { - p->guest_is_allowed = guest_is_allowed; - indicator_session_guest_notify_allowed (INDICATOR_SESSION_GUEST (self)); - } -} + gboolean allowed = p->login1_seat + && login1_seat_get_can_multi_session (p->login1_seat); -static void -on_notify_has_guest_account (GObject * seat, GParamSpec * pspec G_GNUC_UNUSED, gpointer gself) -{ - set_guest_is_allowed (INDICATOR_SESSION_GUEST_DBUS (gself), - display_manager_seat_get_has_guest_account (DISPLAY_MANAGER_SEAT(seat))); + set_guest_is_allowed_flag (self, allowed); } static void -set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * seat) +set_login1_seat (IndicatorSessionGuestDbus * self, + Login1Seat * login1_seat) { priv_t * p = self->priv; - if (p->display_manager_seat != NULL) + if (p->login1_seat != NULL) { - g_signal_handlers_disconnect_by_data (p->display_manager_seat, self); - g_debug ("%s %s before we unref, dm seat's refcount is %d", G_STRLOC, G_STRFUNC, G_OBJECT(p->display_manager_seat)->ref_count); - g_clear_object (&p->display_manager_seat); + g_signal_handlers_disconnect_by_data (p->login1_seat, self); + g_clear_object (&p->login1_seat); } - if (seat != NULL) + if (login1_seat != NULL) { - p->display_manager_seat = g_object_ref (seat); + p->login1_seat = g_object_ref (login1_seat); - g_signal_connect (seat, "notify::has-guest-account", G_CALLBACK(on_notify_has_guest_account), self); + g_signal_connect_swapped (login1_seat, "notify::active-session", + G_CALLBACK(update_session_list), self); + update_session_list (self); - on_notify_has_guest_account (G_OBJECT(seat), NULL, self); + g_signal_connect_swapped (login1_seat, "notify::can-multi-session", + G_CALLBACK(update_guest_allowed), self); + update_guest_allowed (self); } } +/*** +**** +***/ + static void -on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC_UNUSED) +on_switch_to_guest_done (GObject * o, + GAsyncResult * res, + gpointer unused G_GNUC_UNUSED) { GError * err; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); err = NULL; - display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), res, &err); + display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), + res, + &err); if (err != NULL) { if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -405,30 +253,35 @@ on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC } } -/*** -**** Virtual Functions -***/ - static void -my_dispose (GObject * o) +my_switch_to_guest (IndicatorSessionGuest * guest) { - IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS (o); + IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS(guest); - if (self->priv->cancellable != NULL) - { - g_cancellable_cancel (self->priv->cancellable); - g_clear_object (&self->priv->cancellable); - } + g_return_if_fail (self != NULL); + g_return_if_fail (self->priv->dm_seat != NULL); - set_seat (self, NULL); - set_active_session (self, NULL); - set_account_manager (self, NULL); - set_display_manager_seat (self, NULL); - g_clear_object (&self->priv->guest); + display_manager_seat_call_switch_to_guest (self->priv->dm_seat, + "", + self->priv->cancellable, + on_switch_to_guest_done, + self); +} - G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); +static void +set_display_manager_seat (IndicatorSessionGuestDbus * self, + DisplayManagerSeat * dm_seat) +{ + g_clear_object (&self->priv->dm_seat); + + if (dm_seat != NULL) + self->priv->dm_seat = g_object_ref (dm_seat); } +/*** +**** IndiatorSessionGuest Virtual Functions +***/ + static gboolean my_is_allowed (IndicatorSessionGuest * self) { @@ -442,7 +295,7 @@ my_is_logged_in (IndicatorSessionGuest * self) { g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); - return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest != NULL; + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_logged_in; } static gboolean @@ -453,32 +306,33 @@ my_is_active (IndicatorSessionGuest * self) return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_active; } +/*** +**** GObject Virtual Functions +***/ + static void -my_switch_to_guest (IndicatorSessionGuest * self) +my_dispose (GObject * o) { - priv_t * p; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); - - p = INDICATOR_SESSION_GUEST_DBUS(self)->priv; + IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS (o); - if (p->display_manager_seat != NULL) + if (self->priv->cancellable != NULL) { - display_manager_seat_call_switch_to_guest (p->display_manager_seat, - "", - p->cancellable, - on_switch_to_guest_done, - self); + g_cancellable_cancel (self->priv->cancellable); + g_clear_object (&self->priv->cancellable); } + + set_login1_seat (self, NULL); + set_login1_manager (self, NULL); + set_display_manager_seat (self, NULL); + + G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); } /*** -**** GObject Boilerplate +**** Instantiation ***/ static void -/* cppcheck-suppress unusedFunction */ indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) { GObjectClass * object_class; @@ -497,7 +351,6 @@ indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) } static void -/* cppcheck-suppress unusedFunction */ indicator_session_guest_dbus_init (IndicatorSessionGuestDbus * self) { priv_t * p; @@ -523,16 +376,13 @@ indicator_session_guest_dbus_new (void) void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus * self, - Accounts * accounts, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * seat, - ConsoleKitSession * session) + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * dm_seat) { g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); - g_debug ("%s %s accounts %p seat %p session %p", G_STRLOC, G_STRFUNC, (void*)accounts, (void*)seat, (void*)session); - set_account_manager (self, accounts); + set_login1_manager (self, login1_manager); + set_login1_seat (self, login1_seat); set_display_manager_seat (self, dm_seat); - set_seat (self, seat); - set_active_session (self, session); } diff --git a/src/backend-dbus/guest.h b/src/backend-dbus/guest.h index 03b6b28..aca5588 100644 --- a/src/backend-dbus/guest.h +++ b/src/backend-dbus/guest.h @@ -24,9 +24,8 @@ #include #include "../guest.h" /* parent class */ -#include "dbus-accounts.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" #include "dbus-display-manager.h" @@ -61,11 +60,10 @@ GType indicator_session_guest_dbus_get_type (void); IndicatorSessionGuest * indicator_session_guest_dbus_new (void); -void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus *, - Accounts *, - DisplayManagerSeat *, - ConsoleKitSeat *, - ConsoleKitSession *); +void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus * self, + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * display_manager_seat); G_END_DECLS -- cgit v1.2.3 From df6db45c1bf1ca1e678e8f19974f48c4ead2b06e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:20:23 -0500 Subject: in IndicatorSessionUsers, update to login1 --- src/backend-dbus/users.c | 813 +++++++++++++++++++++-------------------------- src/backend-dbus/users.h | 8 +- 2 files changed, 370 insertions(+), 451 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 6d9ada6..4466ede 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -17,35 +17,28 @@ * with this program. If not, see . */ -#include "dbus-accounts.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" -#include "dbus-consolekit-manager.h" #include "dbus-user.h" #include "users.h" struct _IndicatorSessionUsersDbusPriv { - char * active_session_id; - - Accounts * accounts; - + Login1Manager * login1_manager; + Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; + Accounts * accounts; - ConsoleKitSeat * seat_proxy; - - /* user's dbus object path -> AccountsUser* */ - GHashTable * path_to_user; + /* hash table of int uids to AccountsUser* */ + GHashTable * uid_to_account; - /* uint32 user-id --> user's dbus object path */ - GHashTable * uid_to_user_path; + /* a hashset of int uids of users who are logged in */ + GHashTable * logins; - /* uint32 user-id --> hashset of ssid strings */ - GHashTable * uid_to_sessions; + /* the user-id of the owner of the active session */ + guint active_uid; - /* ssid string --> uint32 user-id */ - GHashTable * session_to_uid; + /* true if this is a live session */ + gboolean is_live; GCancellable * cancellable; }; @@ -60,41 +53,176 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ -static void create_user_proxy_for_path (IndicatorSessionUsersDbus * self, - const char * path); +static const gchar * +get_public_key_for_uid (guint uid) +{ + static char buf[16]; + g_snprintf (buf, sizeof(buf), "%u", uid); + return buf; +} + +static void +emit_user_added (IndicatorSessionUsersDbus * self, guint uid) +{ + const gchar * const public_key = get_public_key_for_uid (uid); + indicator_session_users_added (INDICATOR_SESSION_USERS(self), public_key); +} + +static void +emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) +{ + const gchar * const public_key = get_public_key_for_uid (uid); + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), public_key); +} + +static void +emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) +{ + const gchar * const public_key = get_public_key_for_uid (uid); + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), public_key); +} -static void create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, - const char * ssid); +/*** +**** +***/ static void -emit_user_changed_for_path (IndicatorSessionUsersDbus * self, const char * path) +set_is_live_session_flag (IndicatorSessionUsersDbus * self, gboolean b) { - AccountsUser * user = g_hash_table_lookup (self->priv->path_to_user, path); + priv_t * p = self->priv; + + if (p->is_live != b) + { + p->is_live = b; - if (user && !accounts_user_get_system_account (user)) - indicator_session_users_changed (INDICATOR_SESSION_USERS(self), path); + indicator_session_users_notify_is_live_session (INDICATOR_SESSION_USERS (self)); + } } static void -emit_user_changed_for_uid (IndicatorSessionUsersDbus * self, guint uid) +set_active_uid (IndicatorSessionUsersDbus * self, guint uid) { - const char * path; + priv_t * p = self->priv; + + g_message ("%s %s setting active uid to %u", G_STRLOC, G_STRFUNC, uid); + + if (p->active_uid != uid) + { + const guint old_uid = p->active_uid; - if ((path = g_hash_table_lookup (self->priv->uid_to_user_path, GUINT_TO_POINTER(uid)))) - emit_user_changed_for_path (self, path); + p->active_uid = uid; + + if (old_uid) + emit_user_changed (self, old_uid); + + if (uid) + emit_user_changed (self, uid); + } +} + +static void +set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) +{ + GHashTable * old_logins = self->priv->logins; + gpointer key; + GHashTableIter iter; + + self->priv->logins = logins; + + /* fire 'user changed' event for users who logged out */ + g_hash_table_iter_init (&iter, old_logins); + while ((g_hash_table_iter_next (&iter, &key, NULL))) + if (!g_hash_table_contains (logins, key)) + emit_user_changed (self, GPOINTER_TO_INT(key)); + + /* fire 'user changed' event for users who logged in */ + g_hash_table_iter_init (&iter, logins); + while ((g_hash_table_iter_next (&iter, &key, NULL))) + if (!g_hash_table_contains (old_logins, key)) + emit_user_changed (self, GPOINTER_TO_INT(key)); + + g_hash_table_destroy (old_logins); } /*** -**** ACCOUNT MANAGER / USER TRACKING +**** ***/ +static GQuark +get_connection_list_quark (void) +{ + static GQuark q = 0; + + if (G_UNLIKELY (q == 0)) + q = g_quark_from_static_string ("connection-ids"); + + return q; +} + +static void +object_unref_and_disconnect (gpointer instance) +{ + GSList * l; + GSList * ids; + const GQuark q = get_connection_list_quark (); + + ids = g_object_steal_qdata (G_OBJECT(instance), q); + for (l=ids; l!=NULL; l=l->next) + { + gulong * handler_id = l->data; + g_signal_handler_disconnect (instance, *handler_id); + g_free (handler_id); + } + + g_slist_free (ids); +} + +static void +object_add_connection (GObject * o, gulong connection_id) +{ + const GQuark q = get_connection_list_quark (); + GSList * ids; + gulong * ptr; + + ptr = g_new (gulong, 1); + *ptr = connection_id; + + ids = g_object_steal_qdata (o, q); + ids = g_slist_prepend (ids, ptr); + g_object_set_qdata (o, q, ids); +} + +/*** +**** +***/ + +static AccountsUser * +get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + priv_t * p = self->priv; + + return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); +} + +static AccountsUser * +get_user_for_public_key (IndicatorSessionUsersDbus * self, const char * public_key) +{ + return get_user_for_uid (self, g_ascii_strtoull (public_key, NULL, 10)); +} + +/*** +**** User Account Tracking +***/ + +static void create_user_proxy_for_path (IndicatorSessionUsersDbus *, const char *); + /* called when a user proxy gets the 'Changed' signal */ static void on_user_changed (AccountsUser * user, gpointer gself) { /* Accounts.User doesn't update properties in the standard way, * so create a new proxy to pull in the new properties. - * The older proxy is freed when it's removed from our path_to_user hash */ + * The older proxy is freed when it's replaced in our accounts hash */ const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); create_user_proxy_for_path (gself, path); } @@ -103,32 +231,24 @@ static void track_user (IndicatorSessionUsersDbus * self, AccountsUser * user) { - priv_t * p; - const char * path; + priv_t * p = self->priv; + const guint32 uid = accounts_user_get_uid (user); + const gpointer uid_key = GUINT_TO_POINTER (uid); gboolean already_had_user; + gulong id; - p = self->priv; - - path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); - already_had_user = g_hash_table_contains (p->path_to_user, path); + already_had_user = g_hash_table_contains (p->uid_to_account, uid_key); - g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); - g_hash_table_insert (p->path_to_user, g_strdup(path), user); + id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); + object_add_connection (G_OBJECT(user), id); + g_hash_table_insert (p->uid_to_account, uid_key, user); - if (already_had_user) - { - emit_user_changed_for_path (self, path); - } - else + if (!accounts_user_get_system_account (user)) { - const guint uid = (guint) accounts_user_get_uid (user); - - g_hash_table_insert (p->uid_to_user_path, - GUINT_TO_POINTER(uid), - g_strdup(path)); - - if (!accounts_user_get_system_account (user)) - indicator_session_users_added (INDICATOR_SESSION_USERS(self), path); + if (already_had_user) + emit_user_changed (self, uid); + else + emit_user_added (self, uid); } } @@ -136,14 +256,28 @@ static void untrack_user (IndicatorSessionUsersDbus * self, const gchar * path) { - g_hash_table_remove (self->priv->path_to_user, path); + guint uid; + gpointer key; + gpointer val; + GHashTableIter iter; + priv_t * p = self->priv; - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), path); -} + uid = 0; + g_hash_table_iter_init (&iter, p->uid_to_account); + while (!uid && g_hash_table_iter_next (&iter, &key, &val)) + if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (val))) + uid = GPOINTER_TO_UINT (key); + + if (uid) + { + g_hash_table_remove (p->uid_to_account, GUINT_TO_POINTER(uid)); + emit_user_removed (self, uid); + } +} static void -on_user_proxy_ready (GObject * o G_GNUC_UNUSED, +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer self) { @@ -169,15 +303,15 @@ static void create_user_proxy_for_path (IndicatorSessionUsersDbus * self, const char * path) { - const char * name = "org.freedesktop.Accounts"; - const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, path, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.Accounts", + path, self->priv->cancellable, on_user_proxy_ready, self); } +/* create user proxies for everything in Account's user-list */ static void on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) { @@ -233,348 +367,143 @@ set_account_manager (IndicatorSessionUsersDbus * self, Accounts * a) } } -/** - * SEAT / SESSION TRACKING - * - * There are two simple goals here: - * - * 1. Keep track of how many GUI sessions each user has - * so that we can set the 'is_logged_in' flag correctly - * - * 2. Also track which is the current session, - * so that we can compare it to those GUI sessions to - * set the 'is_current_session' flag correctly. - * - * Now that you know the goals, these steps may make more sense: - * - * 1. create a ConsoleKitManager proxy - * 2. ask it for the current session - * 3. create a corresponding Session proxy - * 4. ask that Session proxy for its seat - * 5. create a corresponding Seat proxy - * 6. connect to that seat's session-added / session-removed signals - * 7. ask the seat for a list of its current sessions - * 8. create corresponding Session proxies - * 9. of them, look for the GUI sessions by checking their X11 properties - * 10. for each GUI session, get the corresponding uid - * 11. use the information to update our uid <--> GUI sessions tables - */ - -static void -track_session (IndicatorSessionUsersDbus * self, - const char * ssid, - guint uid) -{ - gpointer uid_key; - GHashTable * sessions; - - uid_key = GUINT_TO_POINTER (uid); - sessions = g_hash_table_lookup (self->priv->uid_to_sessions, uid_key); - if (sessions == NULL) - { - sessions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - g_hash_table_insert (self->priv->uid_to_sessions, uid_key, sessions); - } - - g_hash_table_add (sessions, g_strdup (ssid)); - g_hash_table_insert (self->priv->session_to_uid, g_strdup(ssid), uid_key); - - g_debug ("%s %s now tracking ssid:%s uid:%u. uid has %u tracked ssids.", - G_STRLOC, G_STRFUNC, ssid, uid, g_hash_table_size (sessions)); - - emit_user_changed_for_uid (self, uid); -} - -static void -untrack_session (IndicatorSessionUsersDbus * self, - const char * ssid) -{ - gpointer uidptr; - priv_t * p = self->priv; - - if (g_hash_table_lookup_extended (p->session_to_uid, ssid, NULL, &uidptr)) - { - const guint uid = GPOINTER_TO_UINT (uidptr); - GHashTable * sessions = g_hash_table_lookup (p->uid_to_sessions, uidptr); - - g_hash_table_remove (p->session_to_uid, ssid); - g_hash_table_remove (sessions, ssid); - g_debug ("%s %s not tracking ssid:%s uid:%u. uid has %u tracked ssids.", - G_STRLOC, G_STRFUNC, ssid, uid, - sessions ? g_hash_table_size (sessions) : 0); - - emit_user_changed_for_uid (self, uid); - } -} +/*** +**** +***/ +/* Based on the login1 manager's list of current sessions, + update our 'logins', 'is_live', and 'active_uid' fields */ static void -on_session_proxy_uid_ready (GObject * o, - GAsyncResult * res, - gpointer gself) +on_login1_manager_session_list_ready (GObject * o, + GAsyncResult * res, + gpointer gself) { - guint uid; + GVariant * sessions; GError * err; - ConsoleKitSession * session = CONSOLE_KIT_SESSION (o); - uid = 0; + sessions = NULL; err = NULL; - console_kit_session_call_get_unix_user_finish (session, &uid, res, &err); - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - - g_error_free (err); - } - else if (uid) - { - const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(session)); - track_session (gself, path, uid); - } + login1_manager_call_list_sessions_finish (LOGIN1_MANAGER(o), + &sessions, + res, + &err); - g_object_unref (o); -} - -static void -on_session_x11_display_ready (GObject * o, - GAsyncResult * res, - gpointer gself) -{ - priv_t * p; - GError * err; - gchar * gui; - ConsoleKitSession * session; - - p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; - - err = NULL; - gui = NULL; - session = CONSOLE_KIT_SESSION (o); - console_kit_session_call_get_x11_display_finish (session, &gui, res, &err); if (err != NULL) { if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_warning ("%s: %s", G_STRFUNC, err->message); g_error_free (err); } else { - gboolean is_gui_session; - - is_gui_session = gui && *gui; - - if (!is_gui_session) - g_clear_object (&session); - else - console_kit_session_call_get_unix_user (session, - p->cancellable, - on_session_proxy_uid_ready, - gself); + const gchar * const current_seat_id = g_getenv ("XDG_SEAT"); + const gchar * const current_session_id = g_getenv ("XDG_SESSION_ID"); + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (gself); + const gchar * session_id = NULL; + guint32 uid = 0; + const gchar * user_name = NULL; + const gchar * seat_id = NULL; + const gchar * path = NULL; + gboolean is_live_session = FALSE; + GHashTable * logins = g_hash_table_new (g_direct_hash, g_direct_equal); + GVariantIter iter; + + g_message ("%s %s %s", G_STRLOC, G_STRFUNC, g_variant_print (sessions, TRUE)); + + g_variant_iter_init (&iter, sessions); + while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, + &uid, + &user_name, + &seat_id, + &path)) + { + /* only track sessions on our seat */ + if (g_strcmp0 (seat_id, current_seat_id)) + continue; - g_free (gui); - } -} + if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) + is_live_session = TRUE; -static void -on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) -{ - GError * err; - ConsoleKitSession * session; + if (!g_strcmp0 (session_id, current_session_id)) + set_active_uid (self, uid); - err = NULL; - session = console_kit_session_proxy_new_finish (res, &err); - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + /* only count user accounts and the live session */ + if (uid >= 999) + g_hash_table_add (logins, GINT_TO_POINTER(uid)); + } - g_error_free (err); - } - else if (session != NULL) - { - priv_t * p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; + set_is_live_session_flag (self, is_live_session); + set_logins (self, logins); - console_kit_session_call_get_x11_display (session, - p->cancellable, - on_session_x11_display_ready, - gself); + g_variant_unref (sessions); } } static void -create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, - const char * ssid) -{ - const char * name = "org.freedesktop.ConsoleKit"; - GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - - console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, ssid, - self->priv->cancellable, - on_session_proxy_ready, self); -} - -static void -on_session_list_ready (GObject * o, GAsyncResult * res, gpointer gself) -{ - GError * err; - gchar ** sessions; - - err = NULL; - sessions = NULL; - console_kit_seat_call_get_sessions_finish (CONSOLE_KIT_SEAT(o), - &sessions, res, &err); - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - - g_error_free (err); - } - else - { - int i; - - for (i=0; sessions && sessions[i]; i++) - create_session_proxy_for_ssid (gself, sessions[i]); - - g_strfreev (sessions); - } -} - -static inline guint -get_uid_for_session (IndicatorSessionUsersDbus * self, const char * ssid) +update_session_list (IndicatorSessionUsersDbus * self) { - guint uid = 0; - gpointer value; - - if (ssid != NULL) - if ((value = g_hash_table_lookup (self->priv->session_to_uid, ssid))) - uid = GPOINTER_TO_UINT (value); - - return uid; -} - -/* it's a live session if username is 'ubuntu' and uid is 999 */ -static gboolean -is_live_ssid (IndicatorSessionUsersDbus * self, const char * ssid) -{ - priv_t * p; - guint uid; - - p = INDICATOR_SESSION_USERS_DBUS (self)->priv; - uid = get_uid_for_session (self, ssid); + priv_t * p = self->priv; - if (uid == 999) + if (p->login1_manager != NULL) { - const char * path; - AccountsUser * user = NULL; - - if ((path = g_hash_table_lookup (p->uid_to_user_path, GUINT_TO_POINTER (uid)))) - user = g_hash_table_lookup (p->path_to_user, path); - - return (user != NULL) && !g_strcmp0 (accounts_user_get_user_name(user), "ubuntu"); + login1_manager_call_list_sessions (p->login1_manager, + p->cancellable, + on_login1_manager_session_list_ready, + self); } - - return FALSE; } - static void -set_active_session (IndicatorSessionUsersDbus * self, const char * ssid) +set_login1_manager (IndicatorSessionUsersDbus * self, Login1Manager * login1_manager) { priv_t * p = self->priv; - const guint old_uid = get_uid_for_session (self, p->active_session_id); - const guint new_uid = get_uid_for_session (self, ssid); - const gboolean old_live = is_live_ssid (self, p->active_session_id); - const gboolean new_live = is_live_ssid (self, ssid); - - g_debug ("%s %s changing active_session_id from '%s' to '%s'", - G_STRLOC, G_STRFUNC, p->active_session_id, ssid); - g_free (p->active_session_id); - p->active_session_id = g_strdup (ssid); - if (old_uid != new_uid) + if (p->login1_manager != NULL) { - emit_user_changed_for_uid (self, old_uid); - emit_user_changed_for_uid (self, new_uid); - } + g_signal_handlers_disconnect_by_data (p->login1_manager, self); - if (old_live != new_live) - { - indicator_session_users_notify_is_live_session (INDICATOR_SESSION_USERS(self)); + g_clear_object (&p->login1_manager); } -} -static void -on_seat_active_session_ready (GObject * o, GAsyncResult * res, gpointer gself) -{ - GError * err; - gchar * ssid; - ConsoleKitSeat * seat; - - err = NULL; - ssid = NULL; - seat = CONSOLE_KIT_SEAT (o); - console_kit_seat_call_get_active_session_finish (seat, &ssid, res, &err); - if (err != NULL) + if (login1_manager != NULL) { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + p->login1_manager = g_object_ref (login1_manager); - g_error_free (err); - } - else if (ssid != NULL) - { - set_active_session (INDICATOR_SESSION_USERS_DBUS(gself), ssid); - g_free (ssid); + g_signal_connect_swapped (login1_manager, "session-new", + G_CALLBACK(update_session_list), self); + g_signal_connect_swapped (login1_manager, "session-removed", + G_CALLBACK(update_session_list), self); + update_session_list (self); } } static void -set_seat (IndicatorSessionUsersDbus * self, ConsoleKitSeat * seat) +set_login1_seat (IndicatorSessionUsersDbus * self, + Login1Seat * login1_seat) { priv_t * p = self->priv; - if (p->seat_proxy != NULL) + if (p->login1_seat != NULL) { - g_signal_handlers_disconnect_by_data (p->seat_proxy, self); - g_clear_object (&p->seat_proxy); + g_signal_handlers_disconnect_by_data (p->login1_seat, self); + + g_clear_object (&p->login1_seat); } - if (seat != NULL) + if (login1_seat != NULL) { - p->seat_proxy = g_object_ref (seat); - - /* ask the seat for a list of all the sessions */ - console_kit_seat_call_get_sessions (seat, - p->cancellable, - on_session_list_ready, - self); + p->login1_seat = g_object_ref (login1_seat); - /* ask the seat for the name of the active session */ - console_kit_seat_call_get_active_session (p->seat_proxy, - p->cancellable, - on_seat_active_session_ready, - self); - - /* listen for session changes in this seat */ - g_signal_connect_swapped (seat, "session-added", - G_CALLBACK(create_session_proxy_for_ssid),self); - g_signal_connect_swapped (seat, "session-removed", - G_CALLBACK(untrack_session), self); - g_signal_connect_swapped (seat, "active-session-changed", - G_CALLBACK(set_active_session), self); + g_signal_connect_swapped (login1_seat, "notify::active-session", + G_CALLBACK(update_session_list), self); + update_session_list (self); } } -/*** -**** -***/ - static void -set_dm_seat (IndicatorSessionUsersDbus * self, DisplayManagerSeat * dm_seat) +set_display_manager_seat (IndicatorSessionUsersDbus * self, + DisplayManagerSeat * dm_seat) { priv_t * p = self->priv; @@ -584,85 +513,49 @@ set_dm_seat (IndicatorSessionUsersDbus * self, DisplayManagerSeat * dm_seat) p->dm_seat = g_object_ref (dm_seat); } -static void -activate_username (IndicatorSessionUsersDbus * self, const char * username) -{ - priv_t * p = self->priv; - const char * session = ""; - - g_return_if_fail (p->dm_seat != NULL); - - display_manager_seat_call_switch_to_user (p->dm_seat, username, session, - p->cancellable, NULL, NULL); -} - /*** -**** +**** IndicatorSessionUsers virtual functions ***/ +/* switch to (or create) a session for the specified user */ static void -my_dispose (GObject * o) +my_activate_user (IndicatorSessionUsers * users, const char * public_key) { - IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); priv_t * p = self->priv; + AccountsUser * au; + const char * username; - if (p->cancellable) + au = get_user_for_public_key (self, public_key); + username = au ? accounts_user_get_user_name (au) : NULL; + + if (!username) { - g_cancellable_cancel (p->cancellable); - g_clear_object (&p->cancellable); + g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, public_key); } - - set_seat (self, NULL); - set_dm_seat (self, NULL); - set_account_manager (self, NULL); - - g_clear_pointer (&p->path_to_user, g_hash_table_destroy); - g_clear_pointer (&p->session_to_uid, g_hash_table_destroy); - g_clear_pointer (&p->uid_to_sessions, g_hash_table_destroy); - g_clear_pointer (&p->uid_to_user_path, g_hash_table_destroy); - - G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->dispose (o); -} - -static void -my_finalize (GObject * o) -{ - IndicatorSessionUsersDbus * u = INDICATOR_SESSION_USERS_DBUS (o); - - g_free (u->priv->active_session_id); - - G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->finalize (o); -} - -static void -my_activate_user (IndicatorSessionUsers * users, const char * key) -{ - priv_t * p; - const char * username = 0; - - p = INDICATOR_SESSION_USERS_DBUS (users)->priv; - if (p != 0) + else { - AccountsUser * au = g_hash_table_lookup (p->path_to_user, key); + g_return_if_fail (p->dm_seat != NULL); - if (au != NULL) - username = accounts_user_get_user_name (au); + display_manager_seat_call_switch_to_user (p->dm_seat, + username, + "", + p->cancellable, + NULL, + NULL); } - - if (username != 0) - activate_username (INDICATOR_SESSION_USERS_DBUS(users), username); - else - g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, key); } +/* returns true if this is a live session */ static gboolean my_is_live_session (IndicatorSessionUsers * users) { - IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), FALSE); - return is_live_ssid (self, self->priv->active_session_id); + return INDICATOR_SESSION_USERS_DBUS(users)->priv->is_live; } +/* get a list of public keys for the users that we know about */ static GStrv my_get_keys (IndicatorSessionUsers * users) { @@ -670,64 +563,93 @@ my_get_keys (IndicatorSessionUsers * users) priv_t * p; gchar ** keys; GHashTableIter iter; - gpointer path; + gpointer uid; gpointer user; + GHashTable * h; g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); p = INDICATOR_SESSION_USERS_DBUS (users)->priv; i = 0; - keys = g_new (gchar*, g_hash_table_size(p->path_to_user)+1); - g_hash_table_iter_init (&iter, p->path_to_user); - while (g_hash_table_iter_next (&iter, &path, &user)) + h = p->uid_to_account; + keys = g_new (gchar*, g_hash_table_size(h)+1); + g_hash_table_iter_init (&iter, h); + while (g_hash_table_iter_next (&iter, &uid, &user)) if (!accounts_user_get_system_account (user)) - keys[i++] = g_strdup (path); + keys[i++] = g_strdup (get_public_key_for_uid ((guint)uid)); keys[i] = NULL; return keys; } +/* build a new struct populated with info on the specified user */ static IndicatorSessionUser * -my_get_user (IndicatorSessionUsers * users, const gchar * key) +my_get_user (IndicatorSessionUsers * users, const gchar * public_key) { - priv_t * p; + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users); + priv_t * p = self->priv; + IndicatorSessionUser * ret; AccountsUser * au; - IndicatorSessionUser * ret = NULL; - p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + ret = NULL; + au = get_user_for_public_key (self, public_key); - au = g_hash_table_lookup (p->path_to_user, key); if (au && !accounts_user_get_system_account(au)) { - const guint uid = (guint) accounts_user_get_uid (au); - GHashTable * s; + const guint uid = accounts_user_get_uid (au); ret = g_new0 (IndicatorSessionUser, 1); - - s = g_hash_table_lookup (p->uid_to_sessions, GUINT_TO_POINTER(uid)); - if (s == NULL) - { - ret->is_logged_in = FALSE; - ret->is_current_user = FALSE; - } - else - { - ret->is_logged_in = g_hash_table_size (s) > 0; - ret->is_current_user = g_hash_table_contains (s, p->active_session_id); - } - ret->uid = uid; ret->user_name = g_strdup (accounts_user_get_user_name (au)); ret->real_name = g_strdup (accounts_user_get_real_name (au)); ret->icon_file = g_strdup (accounts_user_get_icon_file (au)); ret->login_frequency = accounts_user_get_login_frequency (au); + ret->is_logged_in = g_hash_table_contains (p->logins, GINT_TO_POINTER(uid)); + ret->is_current_user = uid == p->active_uid; } return ret; } +/*** +**** GObject virtual functions +***/ + +static void +my_dispose (GObject * o) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + priv_t * p = self->priv; + + if (p->cancellable) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + + set_account_manager (self, NULL); + set_display_manager_seat (self, NULL); + set_login1_seat (self, NULL); + set_login1_manager (self, NULL); + + g_hash_table_remove_all (p->uid_to_account); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + priv_t * p = self->priv; + + g_hash_table_destroy (p->logins); + g_hash_table_destroy (p->uid_to_account); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->finalize (o); +} + static void -/* cppcheck-suppress unusedFunction */ indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) { GObjectClass * object_class; @@ -747,7 +669,6 @@ indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) } static void -/* cppcheck-suppress unusedFunction */ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) { priv_t * p; @@ -758,18 +679,12 @@ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) self->priv = p; p->cancellable = g_cancellable_new (); - p->path_to_user = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_object_unref); - - p->uid_to_user_path = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, g_free); - - p->session_to_uid = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); + p->uid_to_account = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + object_unref_and_disconnect); - p->uid_to_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, - (GDestroyNotify)g_hash_table_destroy); + p->logins = g_hash_table_new (g_direct_hash, g_direct_equal); } /*** @@ -786,13 +701,15 @@ indicator_session_users_dbus_new (void) void indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus * self, - Accounts * accounts, + Login1Manager * login1_manager, + Login1Seat * login1_seat, DisplayManagerSeat * dm_seat, - ConsoleKitSeat * seat) + Accounts * accounts) { g_return_if_fail (INDICATOR_IS_SESSION_USERS_DBUS (self)); + set_login1_manager (self, login1_manager); + set_login1_seat (self, login1_seat); + set_display_manager_seat (self, dm_seat); set_account_manager (self, accounts); - set_seat (self, seat); - set_dm_seat (self, dm_seat); } diff --git a/src/backend-dbus/users.h b/src/backend-dbus/users.h index ff1e0ad..a9aaecf 100644 --- a/src/backend-dbus/users.h +++ b/src/backend-dbus/users.h @@ -25,7 +25,8 @@ #include "../users.h" /* parent class */ #include "dbus-accounts.h" -#include "dbus-consolekit-seat.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" #include "dbus-display-manager.h" G_BEGIN_DECLS @@ -60,9 +61,10 @@ GType indicator_session_users_dbus_get_type (void); IndicatorSessionUsers * indicator_session_users_dbus_new (void); void indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus *, - Accounts *, + Login1Manager *, + Login1Seat *, DisplayManagerSeat *, - ConsoleKitSeat *); + Accounts *); -- cgit v1.2.3 From eb6abe95552df3aa95f6a263cac3b79462c797ae Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:05:27 -0500 Subject: use login1's terminology 'power off', 'reboot' --- src/actions.c | 12 ++++++------ src/actions.h | 8 ++++---- src/service.c | 24 ++++++++++++------------ 3 files changed, 22 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/actions.c b/src/actions.c index 788f418..babc285 100644 --- a/src/actions.c +++ b/src/actions.c @@ -103,8 +103,8 @@ indicator_session_actions_class_init (IndicatorSessionActionsClass * klass) klass->logout = NULL; klass->suspend = NULL; klass->hibernate = NULL; - klass->restart = NULL; - klass->shutdown = NULL; + klass->reboot = NULL; + klass->power_off = NULL; klass->switch_to_screensaver = NULL; klass->switch_to_greeter = NULL; klass->switch_to_guest = NULL; @@ -246,11 +246,11 @@ indicator_session_actions_logout (IndicatorSessionActions * self) } void -indicator_session_actions_shutdown (IndicatorSessionActions * self) +indicator_session_actions_power_off (IndicatorSessionActions * self) { g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); - INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->shutdown (self); + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->power_off (self); } void @@ -270,11 +270,11 @@ indicator_session_actions_about (IndicatorSessionActions * self) } void -indicator_session_actions_restart (IndicatorSessionActions * self) +indicator_session_actions_reboot (IndicatorSessionActions * self) { g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); - INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->restart (self); + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->reboot (self); } void diff --git a/src/actions.h b/src/actions.h index e0d0ec5..bba6045 100644 --- a/src/actions.h +++ b/src/actions.h @@ -71,8 +71,8 @@ struct _IndicatorSessionActionsClass void (*suspend) (IndicatorSessionActions * self); void (*hibernate) (IndicatorSessionActions * self); void (*logout) (IndicatorSessionActions * self); - void (*restart) (IndicatorSessionActions * self); - void (*shutdown) (IndicatorSessionActions * self); + void (*reboot) (IndicatorSessionActions * self); + void (*power_off) (IndicatorSessionActions * self); void (*help) (IndicatorSessionActions * self); void (*about) (IndicatorSessionActions * self); void (*settings) (IndicatorSessionActions * self); @@ -111,8 +111,8 @@ void indicator_session_actions_lock (IndicatorSession void indicator_session_actions_suspend (IndicatorSessionActions * self); void indicator_session_actions_hibernate (IndicatorSessionActions * self); void indicator_session_actions_logout (IndicatorSessionActions * self); -void indicator_session_actions_restart (IndicatorSessionActions * self); -void indicator_session_actions_shutdown (IndicatorSessionActions * self); +void indicator_session_actions_reboot (IndicatorSessionActions * self); +void indicator_session_actions_power_off (IndicatorSessionActions * self); void indicator_session_actions_help (IndicatorSessionActions * self); void indicator_session_actions_about (IndicatorSessionActions * self); diff --git a/src/service.c b/src/service.c index ede3a9f..e41cca6 100644 --- a/src/service.c +++ b/src/service.c @@ -542,13 +542,13 @@ create_session_section (IndicatorSessionService * self) if (!g_settings_get_boolean (s, "suppress-restart-menuitem")) { const char * label = ellipsis ? _("Restart\342\200\246") : _("Restart"); - g_menu_append (menu, label, "indicator.restart"); + g_menu_append (menu, label, "indicator.reboot"); } if (!g_settings_get_boolean (s, "suppress-shutdown-menuitem")) { const char * label = ellipsis ? _("Shutdown\342\200\246") : _("Shutdown"); - g_menu_append (menu, label, "indicator.shutdown"); + g_menu_append (menu, label, "indicator.power-off"); } return G_MENU_MODEL (menu); @@ -661,19 +661,19 @@ on_hibernate_activated (GSimpleAction * a G_GNUC_UNUSED, } static void -on_restart_activated (GSimpleAction * action G_GNUC_UNUSED, - GVariant * param G_GNUC_UNUSED, - gpointer gself) +on_reboot_activated (GSimpleAction * action G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) { - indicator_session_actions_restart (get_backend_actions(gself)); + indicator_session_actions_reboot (get_backend_actions(gself)); } static void -on_shutdown_activated (GSimpleAction * a G_GNUC_UNUSED, - GVariant * param G_GNUC_UNUSED, - gpointer gself) +on_power_off_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) { - indicator_session_actions_shutdown (get_backend_actions(gself)); + indicator_session_actions_power_off (get_backend_actions(gself)); } static void @@ -724,8 +724,8 @@ init_gactions (IndicatorSessionService * self) { "logout", on_logout_activated }, { "suspend", on_suspend_activated }, { "hibernate", on_hibernate_activated }, - { "restart", on_restart_activated }, - { "shutdown", on_shutdown_activated }, + { "reboot", on_reboot_activated }, + { "power-off", on_power_off_activated }, { "switch-to-screensaver", on_screensaver_activated }, { "switch-to-greeter", on_greeter_activated } }; -- cgit v1.2.3 From 94f830aa6324ffa32913bfc8c8dd6c7bce07c9af Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:06:36 -0500 Subject: we don't need a login1 session proxy, so don't generate code for one. --- src/backend-dbus/CMakeLists.txt | 4 -- .../org.freedesktop.login1.Session.xml | 49 ---------------------- 2 files changed, 53 deletions(-) delete mode 100644 src/backend-dbus/org.freedesktop.login1.Session.xml (limited to 'src') diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index 58d7b6a..eb4d971 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -25,10 +25,6 @@ add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-seat org.freedesktop ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Seat.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-session - org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Session.xml) - add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-user org.freedesktop ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.User.xml) diff --git a/src/backend-dbus/org.freedesktop.login1.Session.xml b/src/backend-dbus/org.freedesktop.login1.Session.xml deleted file mode 100644 index 24a6fac..0000000 --- a/src/backend-dbus/org.freedesktop.login1.Session.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- 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 ++++++++++++++++++++++----------------------- src/backend-dbus/actions.h | 12 ++- 2 files changed, 91 insertions(+), 101 deletions(-) (limited to 'src') 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); } diff --git a/src/backend-dbus/actions.h b/src/backend-dbus/actions.h index 997dd73..0c8bed2 100644 --- a/src/backend-dbus/actions.h +++ b/src/backend-dbus/actions.h @@ -24,10 +24,8 @@ #include #include "../actions.h" /* parent class */ -#include "dbus-accounts.h" -#include "dbus-consolekit-manager.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" #include "dbus-display-manager.h" @@ -63,9 +61,9 @@ GType indicator_session_actions_dbus_get_type (void); IndicatorSessionActions * 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_END_DECLS -- cgit v1.2.3 From 9cfc9e9da79cabacf1f81e96511d10895992c47d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:13:07 -0500 Subject: get all the tests in test-actions passing again. --- src/backend-dbus/display-manager.xml | 30 ---------------------- .../org.freedesktop.DisplayManager.Seat | 30 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 30 deletions(-) delete mode 100644 src/backend-dbus/display-manager.xml create mode 100644 src/backend-dbus/org.freedesktop.DisplayManager.Seat (limited to 'src') diff --git a/src/backend-dbus/display-manager.xml b/src/backend-dbus/display-manager.xml deleted file mode 100644 index 07b5f29..0000000 --- a/src/backend-dbus/display-manager.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/backend-dbus/org.freedesktop.DisplayManager.Seat b/src/backend-dbus/org.freedesktop.DisplayManager.Seat new file mode 100644 index 0000000..07b5f29 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.DisplayManager.Seat @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 0ca4b9a4e6b552b9a59bade1d8d44cc950ded994 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 23:08:12 -0500 Subject: in backend-dbus/users.c, fix a user proxy leak --- src/backend-dbus/users.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 4466ede..c135610 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -172,6 +172,7 @@ object_unref_and_disconnect (gpointer instance) gulong * handler_id = l->data; g_signal_handler_disconnect (instance, *handler_id); g_free (handler_id); + g_object_unref (instance); } g_slist_free (ids); -- cgit v1.2.3 From b3938a1f14b687d62ad1d6e4e27bac47f58722de Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 11:16:34 -0500 Subject: in IndicatorSessionUsers, use the uid as the user's key. Users.ActivateUser is now green. --- src/backend-dbus/users.c | 73 +++++++++++++++++------------------------------- src/service.c | 40 +++++++++++++------------- src/users.c | 38 ++++++++++++------------- src/users.h | 30 ++++++++++---------- 4 files changed, 79 insertions(+), 102 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index c135610..48de06c 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -53,33 +53,22 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ -static const gchar * -get_public_key_for_uid (guint uid) -{ - static char buf[16]; - g_snprintf (buf, sizeof(buf), "%u", uid); - return buf; -} - static void emit_user_added (IndicatorSessionUsersDbus * self, guint uid) { - const gchar * const public_key = get_public_key_for_uid (uid); - indicator_session_users_added (INDICATOR_SESSION_USERS(self), public_key); + indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) { - const gchar * const public_key = get_public_key_for_uid (uid); - indicator_session_users_changed (INDICATOR_SESSION_USERS(self), public_key); + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) { - const gchar * const public_key = get_public_key_for_uid (uid); - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), public_key); + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); } /*** @@ -124,22 +113,22 @@ static void set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) { GHashTable * old_logins = self->priv->logins; - gpointer key; + gpointer uid; GHashTableIter iter; self->priv->logins = logins; /* fire 'user changed' event for users who logged out */ g_hash_table_iter_init (&iter, old_logins); - while ((g_hash_table_iter_next (&iter, &key, NULL))) - if (!g_hash_table_contains (logins, key)) - emit_user_changed (self, GPOINTER_TO_INT(key)); + while ((g_hash_table_iter_next (&iter, &uid, NULL))) + if (!g_hash_table_contains (logins, uid)) + emit_user_changed (self, GPOINTER_TO_UINT(uid)); /* fire 'user changed' event for users who logged in */ g_hash_table_iter_init (&iter, logins); - while ((g_hash_table_iter_next (&iter, &key, NULL))) - if (!g_hash_table_contains (old_logins, key)) - emit_user_changed (self, GPOINTER_TO_INT(key)); + while ((g_hash_table_iter_next (&iter, &uid, NULL))) + if (!g_hash_table_contains (old_logins, uid)) + emit_user_changed (self, GPOINTER_TO_UINT(uid)); g_hash_table_destroy (old_logins); } @@ -205,12 +194,6 @@ get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); } -static AccountsUser * -get_user_for_public_key (IndicatorSessionUsersDbus * self, const char * public_key) -{ - return get_user_for_uid (self, g_ascii_strtoull (public_key, NULL, 10)); -} - /*** **** User Account Tracking ***/ @@ -520,19 +503,19 @@ set_display_manager_seat (IndicatorSessionUsersDbus * self, /* switch to (or create) a session for the specified user */ static void -my_activate_user (IndicatorSessionUsers * users, const char * public_key) +my_activate_user (IndicatorSessionUsers * users, guint uid) { IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); priv_t * p = self->priv; AccountsUser * au; const char * username; - au = get_user_for_public_key (self, public_key); + au = get_user_for_uid (self, uid); username = au ? accounts_user_get_user_name (au) : NULL; if (!username) { - g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, public_key); + g_warning ("%s %s can't find user '%u'", G_STRLOC, G_STRFUNC, uid); } else { @@ -556,36 +539,31 @@ my_is_live_session (IndicatorSessionUsers * users) return INDICATOR_SESSION_USERS_DBUS(users)->priv->is_live; } -/* get a list of public keys for the users that we know about */ -static GStrv -my_get_keys (IndicatorSessionUsers * users) +/* get a list of our user ids */ +static GList * +my_get_uids (IndicatorSessionUsers * users) { - int i; priv_t * p; - gchar ** keys; + GList * uids; GHashTableIter iter; gpointer uid; gpointer user; - GHashTable * h; g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); p = INDICATOR_SESSION_USERS_DBUS (users)->priv; - i = 0; - h = p->uid_to_account; - keys = g_new (gchar*, g_hash_table_size(h)+1); - g_hash_table_iter_init (&iter, h); + uids = NULL; + g_hash_table_iter_init (&iter, p->uid_to_account); while (g_hash_table_iter_next (&iter, &uid, &user)) if (!accounts_user_get_system_account (user)) - keys[i++] = g_strdup (get_public_key_for_uid ((guint)uid)); - keys[i] = NULL; + uids = g_list_prepend (uids, uid); - return keys; + return uids; } /* build a new struct populated with info on the specified user */ static IndicatorSessionUser * -my_get_user (IndicatorSessionUsers * users, const gchar * public_key) +my_get_user (IndicatorSessionUsers * users, guint uid) { IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users); priv_t * p = self->priv; @@ -593,11 +571,10 @@ my_get_user (IndicatorSessionUsers * users, const gchar * public_key) AccountsUser * au; ret = NULL; - au = get_user_for_public_key (self, public_key); - + au = get_user_for_uid (self, uid); if (au && !accounts_user_get_system_account(au)) { - const guint uid = accounts_user_get_uid (au); + g_assert (uid == accounts_user_get_uid (au)); ret = g_new0 (IndicatorSessionUser, 1); ret->uid = uid; @@ -662,7 +639,7 @@ indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) users_class = INDICATOR_SESSION_USERS_CLASS (klass); users_class->is_live_session = my_is_live_session; - users_class->get_keys = my_get_keys; + users_class->get_uids = my_get_uids; users_class->get_user = my_get_user; users_class->activate_user = my_activate_user; diff --git a/src/service.c b/src/service.c index e41cca6..1fcbd07 100644 --- a/src/service.c +++ b/src/service.c @@ -206,13 +206,13 @@ update_header_action (IndicatorSessionService * self) static GMenuModel * create_switch_section (IndicatorSessionService * self); static void -add_user (IndicatorSessionService * self, const gchar * key) +add_user (IndicatorSessionService * self, guint uid) { IndicatorSessionUser * u; /* update our user table */ - u = indicator_session_users_get_user (self->priv->backend_users, key); - g_hash_table_insert (self->priv->users, g_strdup(key), u); + u = indicator_session_users_get_user (self->priv->backend_users, uid); + g_hash_table_insert (self->priv->users, GUINT_TO_POINTER(uid), u); /* enqueue rebuilds for the affected sections */ rebuild_switch_section_soon (self); @@ -222,30 +222,30 @@ add_user (IndicatorSessionService * self, const gchar * key) static void on_user_added (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, - const char * key, + guint uid, gpointer gself) { - add_user (INDICATOR_SESSION_SERVICE(gself), key); + add_user (INDICATOR_SESSION_SERVICE(gself), uid); } static void on_user_changed (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, - const char * key, + guint uid, gpointer gself) { - add_user (INDICATOR_SESSION_SERVICE(gself), key); + add_user (INDICATOR_SESSION_SERVICE(gself), uid); } static void on_user_removed (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, - const char * key, + guint uid, gpointer gself) { IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (gself); g_return_if_fail (self != NULL); /* update our user table */ - g_hash_table_remove (self->priv->users, key); + g_hash_table_remove (self->priv->users, GUINT_TO_POINTER(uid)); /* enqueue rebuilds for the affected sections */ rebuild_switch_section_soon (self); @@ -334,13 +334,13 @@ create_user_switcher_state (IndicatorSessionService * self) GVariantBuilder * b; GVariant * val; GHashTableIter ht_iter; - gpointer ht_key, ht_value; + gpointer ht_value; const char * current_user; current_user = ""; a = g_variant_builder_new (G_VARIANT_TYPE("as")); g_hash_table_iter_init (&ht_iter, self->priv->users); - while (g_hash_table_iter_next (&ht_iter, &ht_key, &ht_value)) + while (g_hash_table_iter_next (&ht_iter, NULL, &ht_value)) { const IndicatorSessionUser * u = ht_value; @@ -950,8 +950,8 @@ static void /* cppcheck-suppress unusedFunction */ indicator_session_service_init (IndicatorSessionService * self) { - int i; - GStrv keys; + GList * l; + GList * uids; priv_t * p; gpointer gp; @@ -970,14 +970,14 @@ indicator_session_service_init (IndicatorSessionService * self) &p->backend_guest); /* init our key-to-User table */ - p->users = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, + p->users = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, (GDestroyNotify)indicator_session_user_free); - keys = indicator_session_users_get_keys (p->backend_users); - for (i=0; keys && keys[i]; ++i) - add_user (self, keys[i]); - g_strfreev (keys); + uids = indicator_session_users_get_uids (p->backend_users); + for (l=uids; l!=NULL; l=l->next) + add_user (self, GPOINTER_TO_UINT(l->data)); + g_list_free (uids); init_gactions (self); diff --git a/src/users.c b/src/users.c index 4b9c0ad..5e4d910 100644 --- a/src/users.c +++ b/src/users.c @@ -75,24 +75,24 @@ indicator_session_users_class_init (IndicatorSessionUsersClass * klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_added), NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); signals[USER_REMOVED] = g_signal_new (INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED, G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_removed), NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); signals[USER_CHANGED] = g_signal_new (INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_changed), NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); properties[PROP_IS_LIVE_SESSION] = @@ -115,30 +115,30 @@ indicator_session_users_init (IndicatorSessionUsers * self G_GNUC_UNUSED) **** Virtual Functions ***/ -GStrv -indicator_session_users_get_keys (IndicatorSessionUsers * self) +GList * +indicator_session_users_get_uids (IndicatorSessionUsers * self) { g_return_val_if_fail (INDICATOR_IS_SESSION_USERS (self), NULL); - return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_keys (self); + return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_uids (self); } IndicatorSessionUser * indicator_session_users_get_user (IndicatorSessionUsers * self, - const char * key) + guint uid) { g_return_val_if_fail (INDICATOR_IS_SESSION_USERS (self), NULL); - return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_user (self, key); + return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_user (self, uid); } void indicator_session_users_activate_user (IndicatorSessionUsers * self, - const char * key) + guint uid) { g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); - INDICATOR_SESSION_USERS_GET_CLASS (self)->activate_user (self, key); + INDICATOR_SESSION_USERS_GET_CLASS (self)->activate_user (self, uid); } gboolean @@ -165,27 +165,27 @@ indicator_session_user_free (IndicatorSessionUser * user) ***/ void -indicator_session_users_added (IndicatorSessionUsers * self, const char * key) +indicator_session_users_added (IndicatorSessionUsers * self, guint uid) { g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); - g_signal_emit (self, signals[USER_ADDED], 0, key); + g_signal_emit (self, signals[USER_ADDED], 0, uid); } void -indicator_session_users_removed (IndicatorSessionUsers * self, const char * key) +indicator_session_users_removed (IndicatorSessionUsers * self, guint uid) { g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); - g_signal_emit (self, signals[USER_REMOVED], 0, key); + g_signal_emit (self, signals[USER_REMOVED], 0, uid); } void -indicator_session_users_changed (IndicatorSessionUsers * self, const char * key) +indicator_session_users_changed (IndicatorSessionUsers * self, guint uid) { g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); - g_signal_emit (self, signals[USER_CHANGED], 0, key); + g_signal_emit (self, signals[USER_CHANGED], 0, uid); } void diff --git a/src/users.h b/src/users.h index f2d7404..9871766 100644 --- a/src/users.h +++ b/src/users.h @@ -72,13 +72,13 @@ struct _IndicatorSessionUsersClass /* signals */ void (* user_added) (IndicatorSessionUsers * self, - const gchar * key); + guint uid); void (* user_removed) (IndicatorSessionUsers * self, - const gchar * key); + guint uid); void (* user_changed) (IndicatorSessionUsers * self, - const gchar * key); + guint uid); /* pure virtual functions */ @@ -86,13 +86,13 @@ struct _IndicatorSessionUsersClass gboolean (* is_live_session) (IndicatorSessionUsers * self); - GStrv (* get_keys) (IndicatorSessionUsers * self); + GList* (* get_uids) (IndicatorSessionUsers * self); IndicatorSessionUser * (* get_user) (IndicatorSessionUsers * self, - const gchar * key); + guint uid); void ( * activate_user) (IndicatorSessionUsers * self, - const gchar * key); + guint uid); }; /*** @@ -103,15 +103,15 @@ GType indicator_session_users_get_type (void); /* emits the "user-added" signal */ void indicator_session_users_added (IndicatorSessionUsers * self, - const gchar * key); + guint uid); /* emits the "user-removed" signal */ void indicator_session_users_removed (IndicatorSessionUsers * self, - const gchar * key); + guint uid); /* emits the "user-changed" signal */ void indicator_session_users_changed (IndicatorSessionUsers * self, - const gchar * key); + guint uid); /* notify listeners of a change to the 'is-live-session' property */ void indicator_session_users_notify_is_live_session (IndicatorSessionUsers * self); @@ -125,12 +125,12 @@ void indicator_session_users_notify_is_live_session (IndicatorSessionUsers * sel gboolean indicator_session_users_is_live_session (IndicatorSessionUsers * users); /** - * Get a list of user keys. + * Get a list of the users to show in the indicator * - * Return value: (transfer full): a NULL-terminated array of user keys. - * Free with g_strfreev() when done. + * Return value: (transfer container): a GList of guint user ids. + * Free with g_slist_free() when done. */ -GStrv indicator_session_users_get_keys (IndicatorSessionUsers * users); +GList * indicator_session_users_get_uids (IndicatorSessionUsers * users); /** * Get information about a particular user. @@ -141,14 +141,14 @@ GStrv indicator_session_users_get_keys (IndicatorSessionUsers * users); */ IndicatorSessionUser * indicator_session_users_get_user (IndicatorSessionUsers * users, - const gchar * key); + guint uid); /* frees a IndicatorSessionUser struct */ void indicator_session_user_free (IndicatorSessionUser * user); /* activate to a different session */ void indicator_session_users_activate_user (IndicatorSessionUsers * self, - const char * key); + guint uid); G_END_DECLS -- cgit v1.2.3 From d16aaaed46f3381ea7ac4cb4c2cb491d4c5d2e03 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 11:39:46 -0500 Subject: all the tests in test-users pass --- src/backend-dbus/users.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 48de06c..1ecadf3 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -93,8 +93,6 @@ set_active_uid (IndicatorSessionUsersDbus * self, guint uid) { priv_t * p = self->priv; - g_message ("%s %s setting active uid to %u", G_STRLOC, G_STRFUNC, uid); - if (p->active_uid != uid) { const guint old_uid = p->active_uid; @@ -393,8 +391,6 @@ on_login1_manager_session_list_ready (GObject * o, GHashTable * logins = g_hash_table_new (g_direct_hash, g_direct_equal); GVariantIter iter; - g_message ("%s %s %s", G_STRLOC, G_STRFUNC, g_variant_print (sessions, TRUE)); - g_variant_iter_init (&iter, sessions); while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, &uid, @@ -406,11 +402,13 @@ on_login1_manager_session_list_ready (GObject * o, if (g_strcmp0 (seat_id, current_seat_id)) continue; - if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) - is_live_session = TRUE; - if (!g_strcmp0 (session_id, current_session_id)) - set_active_uid (self, uid); + { + set_active_uid (self, uid); + + if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) + is_live_session = TRUE; + } /* only count user accounts and the live session */ if (uid >= 999) -- cgit v1.2.3 From 9ed837fbafae3021d597508ba9272a54d3623534 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 12:32:16 -0500 Subject: test-guest's HelloWorld and Allowed tests now pass --- src/backend-dbus/guest.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index fcb3604..08ac648 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -192,17 +192,6 @@ set_login1_manager (IndicatorSessionGuestDbus * self, } } -static void -update_guest_allowed (IndicatorSessionGuestDbus * self) -{ - priv_t * p = self->priv; - - gboolean allowed = p->login1_seat - && login1_seat_get_can_multi_session (p->login1_seat); - - set_guest_is_allowed_flag (self, allowed); -} - static void set_login1_seat (IndicatorSessionGuestDbus * self, Login1Seat * login1_seat) @@ -222,10 +211,6 @@ set_login1_seat (IndicatorSessionGuestDbus * self, g_signal_connect_swapped (login1_seat, "notify::active-session", G_CALLBACK(update_session_list), self); update_session_list (self); - - g_signal_connect_swapped (login1_seat, "notify::can-multi-session", - G_CALLBACK(update_guest_allowed), self); - update_guest_allowed (self); } } @@ -268,14 +253,37 @@ my_switch_to_guest (IndicatorSessionGuest * guest) self); } +static void +on_notify_has_guest_account (DisplayManagerSeat * dm_seat, + GParamSpec * pspec G_GNUC_UNUSED, + IndicatorSessionGuestDbus * self) +{ + gboolean guest_exists = display_manager_seat_get_has_guest_account (dm_seat); + set_guest_is_allowed_flag (self, guest_exists); +} + static void set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * dm_seat) { - g_clear_object (&self->priv->dm_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 (dm_seat != NULL) - self->priv->dm_seat = g_object_ref (dm_seat); + { + p->dm_seat = g_object_ref (dm_seat); + + g_signal_connect (dm_seat, "notify::has-guest-account", + G_CALLBACK(on_notify_has_guest_account), self); + on_notify_has_guest_account (dm_seat, NULL, self); + } + } /*** -- cgit v1.2.3 From 3cabab005963648247d8af74645c8e245efe13e8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 13:36:02 -0500 Subject: everything in test-guest now passes --- src/backend-dbus/guest.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 08ac648..963bdc8 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -283,7 +283,6 @@ set_display_manager_seat (IndicatorSessionGuestDbus * self, G_CALLBACK(on_notify_has_guest_account), self); on_notify_has_guest_account (dm_seat, NULL, self); } - } /*** -- cgit v1.2.3 From c23454157d46837d5cc6acd9cdd551c371819699 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 14:12:19 -0500 Subject: sync text with trunk: make the shutdown menuitem read 'Shut Down' instead of 'Shutdown' --- src/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 1fcbd07..7f90c9c 100644 --- a/src/service.c +++ b/src/service.c @@ -547,7 +547,7 @@ create_session_section (IndicatorSessionService * self) if (!g_settings_get_boolean (s, "suppress-shutdown-menuitem")) { - const char * label = ellipsis ? _("Shutdown\342\200\246") : _("Shutdown"); + const char * label = ellipsis ? _("Shut Down\342\200\246") : _("Shut Down"); g_menu_append (menu, label, "indicator.power-off"); } -- cgit v1.2.3 From 951592e1349e863b721ca32273577e6f1b517d13 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 26 Jun 2013 11:40:14 -0500 Subject: fix regression that displayed the 'restart' button even when prompting was enabled and the user was running Unity --- src/service.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 7f90c9c..d8fc961 100644 --- a/src/service.c +++ b/src/service.c @@ -539,7 +539,9 @@ create_session_section (IndicatorSessionService * self) if (indicator_session_actions_can_hibernate (p->backend_actions)) g_menu_append (menu, _("Hibernate"), "indicator.hibernate"); - if (!g_settings_get_boolean (s, "suppress-restart-menuitem")) + /* NB: check 'ellipsis' here to skip this item if prompting is enabled + because this shows the same prompt as 'Shut Down' in Unity */ + if (!ellipsis && !g_settings_get_boolean (s, "suppress-restart-menuitem")) { const char * label = ellipsis ? _("Restart\342\200\246") : _("Restart"); g_menu_append (menu, label, "indicator.reboot"); -- 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') 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 4c5a5e7146a878a17239e44ce2debffb5b525bf1 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 13:53:44 -0500 Subject: in users.c, fix bugs that leaked system accounts into the list of users to show in the indicator --- src/backend-dbus/users.c | 137 +++++++++++++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 1ecadf3..1db5ac1 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -53,22 +53,82 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ +/* returns true if the fields indicate this is the 'live cd' user */ +static gboolean +is_live_user (guint uid, const char * username) +{ + return uid==999 && !g_strcmp0 (username, "ubuntu"); +} + +/* returns true if this is a user who should be listed in the session indicator */ +static gboolean +is_public_user (IndicatorSessionUsersDbus * self G_GNUC_UNUSED, + AccountsUser * au) +{ + gboolean is_public; + + /* the 'live session' user is the only system account we'll show */ + if (is_live_user (accounts_user_get_uid(au), accounts_user_get_user_name(au))) + is_public = TRUE; + else + is_public = !accounts_user_get_system_account (au); + + return is_public; +} + +/* get our private org.freedesktop.Accounts.User proxy for the given uid */ +static AccountsUser * +get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + priv_t * p = self->priv; + + return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); +} + +/* returns true if this is a uid that should be listed in the session indicator */ +static gboolean +is_public_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + AccountsUser * au; + gboolean is_public; + + if ((au = get_user_for_uid (self, uid))) + { + is_public = is_public_user (self, au); + } + else + { + /* making a guess to serve until the user's proxy object is ready. + assuming that 999 is a 'live session' user, <999 is system account */ + is_public = uid >= 999; + } + + return is_public; +} + +/*** +**** +***/ + static void emit_user_added (IndicatorSessionUsersDbus * self, guint uid) { - indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); + if (is_public_uid (self, uid)) + indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) { - indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); + if (is_public_uid (self, uid)) + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) { - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); + if (is_public_uid (self, uid)) + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); } /*** @@ -99,11 +159,8 @@ set_active_uid (IndicatorSessionUsersDbus * self, guint uid) p->active_uid = uid; - if (old_uid) - emit_user_changed (self, old_uid); - - if (uid) - emit_user_changed (self, uid); + emit_user_changed (self, old_uid); + emit_user_changed (self, uid); } } @@ -180,18 +237,6 @@ object_add_connection (GObject * o, gulong connection_id) g_object_set_qdata (o, q, ids); } -/*** -**** -***/ - -static AccountsUser * -get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) -{ - priv_t * p = self->priv; - - return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); -} - /*** **** User Account Tracking ***/ @@ -213,25 +258,24 @@ static void track_user (IndicatorSessionUsersDbus * self, AccountsUser * user) { - priv_t * p = self->priv; const guint32 uid = accounts_user_get_uid (user); const gpointer uid_key = GUINT_TO_POINTER (uid); - gboolean already_had_user; + priv_t * p = self->priv; gulong id; + gboolean already_had_user; + + g_return_if_fail (is_public_user (self, user)); already_had_user = g_hash_table_contains (p->uid_to_account, uid_key); - id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); + id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); object_add_connection (G_OBJECT(user), id); g_hash_table_insert (p->uid_to_account, uid_key, user); - if (!accounts_user_get_system_account (user)) - { - if (already_had_user) - emit_user_changed (self, uid); - else - emit_user_added (self, uid); - } + if (already_had_user) + emit_user_changed (self, uid); + else + emit_user_added (self, uid); } static void @@ -258,6 +302,8 @@ untrack_user (IndicatorSessionUsersDbus * self, } } +/* We got a new org.freedesktop.Accounts.User proxy. + If it's one we want to remember, pass it to track_user() */ static void on_user_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, @@ -275,10 +321,14 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else + else if (is_public_user (self, user)) { track_user (self, user); } + else + { + g_object_unref (self); + } } static void @@ -293,7 +343,7 @@ create_user_proxy_for_path (IndicatorSessionUsersDbus * self, on_user_proxy_ready, self); } -/* create user proxies for everything in Account's user-list */ +/* create proxy objects for everything in Account's user-list */ static void on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) { @@ -406,12 +456,11 @@ on_login1_manager_session_list_ready (GObject * o, { set_active_uid (self, uid); - if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) + if (is_live_user (uid, user_name)) is_live_session = TRUE; } - /* only count user accounts and the live session */ - if (uid >= 999) + if (is_public_uid (self, uid)) g_hash_table_add (logins, GINT_TO_POINTER(uid)); } @@ -541,22 +590,8 @@ my_is_live_session (IndicatorSessionUsers * users) static GList * my_get_uids (IndicatorSessionUsers * users) { - priv_t * p; - GList * uids; - GHashTableIter iter; - gpointer uid; - gpointer user; - - g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); - p = INDICATOR_SESSION_USERS_DBUS (users)->priv; - - uids = NULL; - g_hash_table_iter_init (&iter, p->uid_to_account); - while (g_hash_table_iter_next (&iter, &uid, &user)) - if (!accounts_user_get_system_account (user)) - uids = g_list_prepend (uids, uid); - - return uids; + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users); + return g_hash_table_get_keys (self->priv->uid_to_account); } /* build a new struct populated with info on the specified user */ -- 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') 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 b6467f327dcfc2c4fb60b57f293747259d0b7228 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 21:44:03 -0500 Subject: in create_guest_switcher_state() and create_user_switcher_state(), don't leak GVariantBuilders --- src/service.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index d8fc961..931c626 100644 --- a/src/service.c +++ b/src/service.c @@ -311,15 +311,15 @@ static GVariant * create_guest_switcher_state (IndicatorSessionService * self) { GVariant * val; - GVariantBuilder * b; + GVariantBuilder b; IndicatorSessionGuest * const g = self->priv->backend_guest; - b = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_init (&b, G_VARIANT_TYPE ("a{sv}")); val = g_variant_new_boolean (indicator_session_guest_is_active (g)); - g_variant_builder_add (b, "{sv}", "is-active", val); + g_variant_builder_add (&b, "{sv}", "is-active", val); val = g_variant_new_boolean (indicator_session_guest_is_logged_in (g)); - g_variant_builder_add (b, "{sv}", "is-logged-in", val); - return g_variant_builder_end (b); + g_variant_builder_add (&b, "{sv}", "is-logged-in", val); + return g_variant_builder_end (&b); } /** @@ -330,15 +330,15 @@ create_guest_switcher_state (IndicatorSessionService * self) static GVariant * create_user_switcher_state (IndicatorSessionService * self) { - GVariantBuilder * a; - GVariantBuilder * b; + GVariantBuilder a; + GVariantBuilder b; GVariant * val; GHashTableIter ht_iter; gpointer ht_value; const char * current_user; current_user = ""; - a = g_variant_builder_new (G_VARIANT_TYPE("as")); + g_variant_builder_init (&a, G_VARIANT_TYPE("as")); g_hash_table_iter_init (&ht_iter, self->priv->users); while (g_hash_table_iter_next (&ht_iter, NULL, &ht_value)) { @@ -348,15 +348,15 @@ create_user_switcher_state (IndicatorSessionService * self) current_user = u->user_name; if (u->is_logged_in) - g_variant_builder_add (a, "s", u->user_name); + g_variant_builder_add (&a, "s", u->user_name); } - b = g_variant_builder_new (G_VARIANT_TYPE("a{sv}")); + g_variant_builder_init (&b, G_VARIANT_TYPE("a{sv}")); val = g_variant_new_string (current_user); - g_variant_builder_add (b, "{sv}", "active-user", val); - val = g_variant_builder_end (a); - g_variant_builder_add (b, "{sv}", "logged-in-users", val); - return g_variant_builder_end (b); + g_variant_builder_add (&b, "{sv}", "active-user", val); + val = g_variant_builder_end (&a); + g_variant_builder_add (&b, "{sv}", "logged-in-users", val); + return g_variant_builder_end (&b); } static void -- cgit v1.2.3 From 3bd279a7de3b32bc33ab2f80d4eae0ecfe83dd38 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 09:47:32 -0500 Subject: =?UTF-8?q?use=20the=20unicode=20'=E2=80=A6'=20directly=20intead?= =?UTF-8?q?=20of=20\342\200\246?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/service.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 931c626..a9f2f65 100644 --- a/src/service.c +++ b/src/service.c @@ -295,9 +295,9 @@ create_settings_section (IndicatorSessionService * self) priv_t * p = self->priv; menu = g_menu_new (); - g_menu_append (menu, _("System Settings\342\200\246"), "indicator.settings"); + g_menu_append (menu, _("System Settings…"), "indicator.settings"); if (indicator_session_actions_has_online_account_error (p->backend_actions)) - g_menu_append (menu, _("Online Accounts\342\200\246"), "indicator.online-accounts"); + g_menu_append (menu, _("Online Accounts…"), "indicator.online-accounts"); return G_MENU_MODEL (menu); } @@ -443,19 +443,19 @@ create_switch_section (IndicatorSessionService * self) else if (indicator_session_guest_is_active (p->backend_guest)) { const char * action = "indicator.switch-to-greeter"; - item = g_menu_item_new (ellipsis ? _("Switch Account\342\200\246") + item = g_menu_item_new (ellipsis ? _("Switch Account…") : _("Switch Account"), action); } else if (g_hash_table_size (p->users) == 1) { const char * action = "indicator.switch-to-greeter"; - item = g_menu_item_new (ellipsis ? _("Lock\342\200\246") + item = g_menu_item_new (ellipsis ? _("Lock…") : _("Lock"), action); } else { const char * action = "indicator.switch-to-greeter"; - item = g_menu_item_new (ellipsis ? _("Lock/Switch Account\342\200\246") + item = g_menu_item_new (ellipsis ? _("Lock/Switch Account…") : _("Lock/Switch Account"), action); } str = g_settings_get_string (p->keybinding_settings, "screensaver"); @@ -529,7 +529,7 @@ create_session_section (IndicatorSessionService * self) if (indicator_session_actions_can_logout (p->backend_actions) && !g_settings_get_boolean (s, "suppress-logout-menuitem")) { - const char * label = ellipsis ? _("Log Out\342\200\246") : _("Log Out"); + const char * label = ellipsis ? _("Log Out…") : _("Log Out"); g_menu_append (menu, label, "indicator.logout"); } @@ -543,13 +543,13 @@ create_session_section (IndicatorSessionService * self) because this shows the same prompt as 'Shut Down' in Unity */ if (!ellipsis && !g_settings_get_boolean (s, "suppress-restart-menuitem")) { - const char * label = ellipsis ? _("Restart\342\200\246") : _("Restart"); + const char * label = ellipsis ? _("Restart…") : _("Restart"); g_menu_append (menu, label, "indicator.reboot"); } if (!g_settings_get_boolean (s, "suppress-shutdown-menuitem")) { - const char * label = ellipsis ? _("Shut Down\342\200\246") : _("Shut Down"); + const char * label = ellipsis ? _("Shut Down…") : _("Shut Down"); g_menu_append (menu, label, "indicator.power-off"); } -- cgit v1.2.3 From 69bf3537b0fe5aa00d015c7339ce20e9c2b80d1f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 09:48:54 -0500 Subject: finish up backend-dbus/users.c: fix an unref bug when creating user proxies. fix an async race condition where we emitted change events for users before their proxy objects had finished being asynchronously constructed. --- src/backend-dbus/users.c | 118 ++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 1db5ac1..b5a6d32 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -41,6 +41,8 @@ struct _IndicatorSessionUsersDbusPriv gboolean is_live; GCancellable * cancellable; + + guint update_list_tag; }; typedef IndicatorSessionUsersDbusPriv priv_t; @@ -53,29 +55,6 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ -/* returns true if the fields indicate this is the 'live cd' user */ -static gboolean -is_live_user (guint uid, const char * username) -{ - return uid==999 && !g_strcmp0 (username, "ubuntu"); -} - -/* returns true if this is a user who should be listed in the session indicator */ -static gboolean -is_public_user (IndicatorSessionUsersDbus * self G_GNUC_UNUSED, - AccountsUser * au) -{ - gboolean is_public; - - /* the 'live session' user is the only system account we'll show */ - if (is_live_user (accounts_user_get_uid(au), accounts_user_get_user_name(au))) - is_public = TRUE; - else - is_public = !accounts_user_get_system_account (au); - - return is_public; -} - /* get our private org.freedesktop.Accounts.User proxy for the given uid */ static AccountsUser * get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) @@ -85,50 +64,30 @@ get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); } -/* returns true if this is a uid that should be listed in the session indicator */ static gboolean -is_public_uid (IndicatorSessionUsersDbus * self, guint uid) +is_tracked_uid (IndicatorSessionUsersDbus * self, guint uid) { - AccountsUser * au; - gboolean is_public; - - if ((au = get_user_for_uid (self, uid))) - { - is_public = is_public_user (self, au); - } - else - { - /* making a guess to serve until the user's proxy object is ready. - assuming that 999 is a 'live session' user, <999 is system account */ - is_public = uid >= 999; - } - - return is_public; + return get_user_for_uid (self, uid) != NULL; } -/*** -**** -***/ - static void -emit_user_added (IndicatorSessionUsersDbus * self, guint uid) +emit_user_added (IndicatorSessionUsersDbus * self, guint32 uid) { - if (is_public_uid (self, uid)) + if (is_tracked_uid (self, uid)) indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); } static void -emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) +emit_user_changed (IndicatorSessionUsersDbus * self, guint32 uid) { - if (is_public_uid (self, uid)) + if (is_tracked_uid (self, uid)) indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); } static void -emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) +emit_user_removed (IndicatorSessionUsersDbus * self, guint32 uid) { - if (is_public_uid (self, uid)) - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); } /*** @@ -259,18 +218,13 @@ track_user (IndicatorSessionUsersDbus * self, AccountsUser * user) { const guint32 uid = accounts_user_get_uid (user); - const gpointer uid_key = GUINT_TO_POINTER (uid); priv_t * p = self->priv; gulong id; - gboolean already_had_user; - - g_return_if_fail (is_public_user (self, user)); - - already_had_user = g_hash_table_contains (p->uid_to_account, uid_key); + const gboolean already_had_user = is_tracked_uid (self, uid); id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); object_add_connection (G_OBJECT(user), id); - g_hash_table_insert (p->uid_to_account, uid_key, user); + g_hash_table_insert (p->uid_to_account, GUINT_TO_POINTER (uid), user); if (already_had_user) emit_user_changed (self, uid); @@ -321,13 +275,13 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else if (is_public_user (self, user)) + else if (!accounts_user_get_system_account (user)) { track_user (self, user); } else { - g_object_unref (self); + g_object_unref (user); } } @@ -456,12 +410,11 @@ on_login1_manager_session_list_ready (GObject * o, { set_active_uid (self, uid); - if (is_live_user (uid, user_name)) + if ((uid==999) && !g_strcmp0 (user_name, "ubuntu")) is_live_session = TRUE; } - if (is_public_uid (self, uid)) - g_hash_table_add (logins, GINT_TO_POINTER(uid)); + g_hash_table_add (logins, GINT_TO_POINTER(uid)); } set_is_live_session_flag (self, is_live_session); @@ -485,8 +438,35 @@ update_session_list (IndicatorSessionUsersDbus * self) } } +static gboolean +on_update_session_list_timer (gpointer gself) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (gself); + + update_session_list (self); + + self->priv->update_list_tag = 0; + return G_SOURCE_REMOVE; +} + +/* A dead session can still show up in list-sessions for a few seconds. + So just to be safe, queue up a rebuild for a few seconds from now */ static void -set_login1_manager (IndicatorSessionUsersDbus * self, Login1Manager * login1_manager) +update_session_list_twice (IndicatorSessionUsersDbus * self) +{ + priv_t * p = self->priv; + + update_session_list (self); + + if (p->update_list_tag == 0) + p->update_list_tag = g_timeout_add_seconds (5, + on_update_session_list_timer, + self); +} + +static void +set_login1_manager (IndicatorSessionUsersDbus * self, + Login1Manager * login1_manager) { priv_t * p = self->priv; @@ -504,7 +484,11 @@ set_login1_manager (IndicatorSessionUsersDbus * self, Login1Manager * login1_man g_signal_connect_swapped (login1_manager, "session-new", G_CALLBACK(update_session_list), self); g_signal_connect_swapped (login1_manager, "session-removed", + G_CALLBACK(update_session_list_twice), self); + g_signal_connect_swapped (login1_manager, "user-new", G_CALLBACK(update_session_list), self); + g_signal_connect_swapped (login1_manager, "user-removed", + G_CALLBACK(update_session_list_twice), self); update_session_list (self); } } @@ -632,6 +616,12 @@ my_dispose (GObject * o) IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); priv_t * p = self->priv; + if (p->update_list_tag != 0) + { + g_source_remove (p->update_list_tag); + p->update_list_tag = 0; + } + if (p->cancellable) { g_cancellable_cancel (p->cancellable); -- cgit v1.2.3 From 4850b1b6ba8a1438d8c0903592108fcefc35235e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 10:31:51 -0500 Subject: update comments & documentation to reflect that we've replaced consolekit and login1 --- src/backend-dbus/actions.h | 2 +- src/backend-dbus/guest.h | 2 +- src/backend-dbus/users.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/actions.h b/src/backend-dbus/actions.h index 0c8bed2..d3d722d 100644 --- a/src/backend-dbus/actions.h +++ b/src/backend-dbus/actions.h @@ -42,7 +42,7 @@ typedef struct _IndicatorSessionActionsDbusClass IndicatorSessionActionsDbusCl /** * An implementation of IndicatorSessionActions that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * from org.freedesktop.login1 org.freedesktop.DisplayManager over DBus. */ struct _IndicatorSessionActionsDbus { diff --git a/src/backend-dbus/guest.h b/src/backend-dbus/guest.h index aca5588..73bb3ca 100644 --- a/src/backend-dbus/guest.h +++ b/src/backend-dbus/guest.h @@ -42,7 +42,7 @@ typedef struct _IndicatorSessionGuestDbusClass IndicatorSessionGuestDbusClass; /** * An implementation of IndicatorSessionGuest that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * from org.freedesktop.login1 and org.freedesktop.Accounts over DBus. */ struct _IndicatorSessionGuestDbus { diff --git a/src/backend-dbus/users.h b/src/backend-dbus/users.h index a9aaecf..d6c17df 100644 --- a/src/backend-dbus/users.h +++ b/src/backend-dbus/users.h @@ -42,7 +42,7 @@ typedef struct _IndicatorSessionUsersDbusClass IndicatorSessionUsersDbusClass; /** * An implementation of IndicatorSessionUsers that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * from org.freedesktop.login1 and org.freedesktop.Accounts over DBus. */ struct _IndicatorSessionUsersDbus { -- cgit v1.2.3 From d176666fbd302857b7af69774f516a53fbe086fa Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 14:58:11 -0500 Subject: cleanup: put an '.xml' file suffix at the end of the DisplayManager.Seat xml file --- src/backend-dbus/CMakeLists.txt | 2 +- .../org.freedesktop.DisplayManager.Seat | 30 ---------------------- .../org.freedesktop.DisplayManager.Seat.xml | 30 ++++++++++++++++++++++ 3 files changed, 31 insertions(+), 31 deletions(-) delete mode 100644 src/backend-dbus/org.freedesktop.DisplayManager.Seat create mode 100644 src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml (limited to 'src') diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index eb4d971..1c0df8e 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -3,7 +3,7 @@ set(BACKEND_GENERATED_SOURCES add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-display-manager org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.DisplayManager.Seat) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.DisplayManager.Seat.xml) add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-webcredentials com.canonical.indicators diff --git a/src/backend-dbus/org.freedesktop.DisplayManager.Seat b/src/backend-dbus/org.freedesktop.DisplayManager.Seat deleted file mode 100644 index 07b5f29..0000000 --- a/src/backend-dbus/org.freedesktop.DisplayManager.Seat +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml b/src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml new file mode 100644 index 0000000..07b5f29 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 9a3e46e73ee201771c8bc9ae9f95adecbb71fe69 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 18:38:51 -0500 Subject: in service.c's add_user(), test for NULL before adding the user struct to our collection --- src/service.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index a9f2f65..36ef282 100644 --- a/src/service.c +++ b/src/service.c @@ -210,14 +210,16 @@ add_user (IndicatorSessionService * self, guint uid) { IndicatorSessionUser * u; - /* update our user table */ - u = indicator_session_users_get_user (self->priv->backend_users, uid); - g_hash_table_insert (self->priv->users, GUINT_TO_POINTER(uid), u); + if ((u = indicator_session_users_get_user (self->priv->backend_users, uid))) + { + /* update our user table */ + g_hash_table_insert (self->priv->users, GUINT_TO_POINTER(uid), u); - /* enqueue rebuilds for the affected sections */ - rebuild_switch_section_soon (self); - if (u->is_current_user) - rebuild_header_soon (self); + /* queue rebuilds for the affected sections */ + rebuild_switch_section_soon (self); + if (u->is_current_user) + rebuild_header_soon (self); + } } static void -- cgit v1.2.3 From 39750137bbbbe1f3ba1aa7ae8dc5d39e0f354313 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 09:53:32 -0500 Subject: when user switching isn't available, don't ellipsize the 'Lock' menuitem --- src/service.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 36ef282..45bbdad 100644 --- a/src/service.c +++ b/src/service.c @@ -451,8 +451,7 @@ create_switch_section (IndicatorSessionService * self) else if (g_hash_table_size (p->users) == 1) { const char * action = "indicator.switch-to-greeter"; - item = g_menu_item_new (ellipsis ? _("Lock…") - : _("Lock"), action); + item = g_menu_item_new (_("Lock"), action); } else { -- 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') 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') 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') 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') 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 73a9ac42d15b01c6807eb5bdaee0c24431e7e539 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:54:52 -0500 Subject: in src/backend-dbus/guest.c's on_login1_manager_session_list_ready(), remove unused variable 'path' --- src/backend-dbus/guest.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 963bdc8..3269097 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -119,15 +119,14 @@ on_login1_manager_session_list_ready (GObject * o, guint32 uid = 0; const gchar * user_name = NULL; const gchar * seat_id = NULL; - const gchar * path = NULL; GVariantIter iter; g_variant_iter_init (&iter, sessions); - while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, + while (g_variant_iter_loop (&iter, "(&su&s&so)", &session_id, &uid, &user_name, &seat_id, - &path)) + NULL)) { gboolean is_current_session; gboolean is_guest; -- cgit v1.2.3 From 604640ebeca2fe1b2eb4aa475dbb4221dd8aeb72 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:06:17 -0500 Subject: in src/backend-dbus/users.c's set_logins(), fix ref/unref semantics of the hashtable argument --- src/backend-dbus/users.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index b5a6d32..caf6403 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -130,7 +130,7 @@ set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) gpointer uid; GHashTableIter iter; - self->priv->logins = logins; + self->priv->logins = g_hash_table_ref (logins); /* fire 'user changed' event for users who logged out */ g_hash_table_iter_init (&iter, old_logins); @@ -420,6 +420,7 @@ on_login1_manager_session_list_ready (GObject * o, set_is_live_session_flag (self, is_live_session); set_logins (self, logins); + g_hash_table_unref (logins); g_variant_unref (sessions); } } -- cgit v1.2.3 From d5421fec0a7e51ddb1979a97de271a3f1733321e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:07:33 -0500 Subject: in src/backend-dbus/users.c, use G_DEFINE_QUARK() instead of rolling our own quark func --- src/backend-dbus/users.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index caf6403..b9a79e5 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -151,23 +151,14 @@ set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) **** ***/ -static GQuark -get_connection_list_quark (void) -{ - static GQuark q = 0; - - if (G_UNLIKELY (q == 0)) - q = g_quark_from_static_string ("connection-ids"); - - return q; -} +G_DEFINE_QUARK (connection-ids, connection_list) static void object_unref_and_disconnect (gpointer instance) { - GSList * l; + const GQuark q = connection_list_quark (); GSList * ids; - const GQuark q = get_connection_list_quark (); + GSList * l; ids = g_object_steal_qdata (G_OBJECT(instance), q); for (l=ids; l!=NULL; l=l->next) @@ -184,7 +175,7 @@ object_unref_and_disconnect (gpointer instance) static void object_add_connection (GObject * o, gulong connection_id) { - const GQuark q = get_connection_list_quark (); + const GQuark q = connection_list_quark (); GSList * ids; gulong * ptr; -- cgit v1.2.3 From eb7e99b24b15a311f188754bf3d0d4f72551deab Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:12:08 -0500 Subject: in src/backend-dbus/users.c's track_user(), simplify the ref/unref semantics of the user argument --- src/backend-dbus/users.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index b9a79e5..738eda4 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -215,7 +215,9 @@ track_user (IndicatorSessionUsersDbus * self, id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); object_add_connection (G_OBJECT(user), id); - g_hash_table_insert (p->uid_to_account, GUINT_TO_POINTER (uid), user); + g_hash_table_insert (p->uid_to_account, + GUINT_TO_POINTER (uid), + g_object_ref (user)); if (already_had_user) emit_user_changed (self, uid); @@ -266,12 +268,11 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else if (!accounts_user_get_system_account (user)) - { - track_user (self, user); - } else { + if (!accounts_user_get_system_account (user)) + track_user (self, user); + g_object_unref (user); } } -- cgit v1.2.3 From bb2129f5fada412c88e5d3f739038d560a5444a9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:13:07 -0500 Subject: in src/backend-dbus/users.c's object_unref_and_disconnect(), fix an unbalanced ref/unref --- src/backend-dbus/users.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 738eda4..6f02a53 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -166,9 +166,10 @@ object_unref_and_disconnect (gpointer instance) gulong * handler_id = l->data; g_signal_handler_disconnect (instance, *handler_id); g_free (handler_id); - g_object_unref (instance); } + g_object_unref (instance); + g_slist_free (ids); } -- cgit v1.2.3 From c96e42d1d00d68b6c858d7d314c13b4d05ca0d8b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:28:05 -0500 Subject: in src/backend-dbus/users.c, use a helper struct for disconnecting the signals to the user proxies in our uid-to-user hashtable --- src/backend-dbus/users.c | 94 +++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 6f02a53..f770695 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -28,7 +28,7 @@ struct _IndicatorSessionUsersDbusPriv DisplayManagerSeat * dm_seat; Accounts * accounts; - /* hash table of int uids to AccountsUser* */ + /* hash table of int uids to UserRecord* */ GHashTable * uid_to_account; /* a hashset of int uids of users who are logged in */ @@ -55,13 +55,46 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ +struct UserRecord +{ + AccountsUser * user; + + gulong signal_id; +}; + +struct UserRecord * +user_record_new (AccountsUser * user, gulong signal_id) +{ + struct UserRecord * rec; + rec = g_new (struct UserRecord, 1); + rec->user = g_object_ref (user); + rec->signal_id = signal_id; + return rec; +} + +static void +user_record_free (struct UserRecord * rec) +{ + g_signal_handler_disconnect (rec->user, rec->signal_id); + g_object_unref (G_OBJECT (rec->user)); + g_free (rec); +} + +/*** +**** +***/ + /* get our private org.freedesktop.Accounts.User proxy for the given uid */ static AccountsUser * get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) { - priv_t * p = self->priv; + struct UserRecord * rec; + + if ((rec = g_hash_table_lookup (self->priv->uid_to_account, + GUINT_TO_POINTER(uid)))) + return rec->user; - return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); + return NULL; } static gboolean @@ -147,47 +180,6 @@ set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) g_hash_table_destroy (old_logins); } -/*** -**** -***/ - -G_DEFINE_QUARK (connection-ids, connection_list) - -static void -object_unref_and_disconnect (gpointer instance) -{ - const GQuark q = connection_list_quark (); - GSList * ids; - GSList * l; - - ids = g_object_steal_qdata (G_OBJECT(instance), q); - for (l=ids; l!=NULL; l=l->next) - { - gulong * handler_id = l->data; - g_signal_handler_disconnect (instance, *handler_id); - g_free (handler_id); - } - - g_object_unref (instance); - - g_slist_free (ids); -} - -static void -object_add_connection (GObject * o, gulong connection_id) -{ - const GQuark q = connection_list_quark (); - GSList * ids; - gulong * ptr; - - ptr = g_new (gulong, 1); - *ptr = connection_id; - - ids = g_object_steal_qdata (o, q); - ids = g_slist_prepend (ids, ptr); - g_object_set_qdata (o, q, ids); -} - /*** **** User Account Tracking ***/ @@ -215,10 +207,9 @@ track_user (IndicatorSessionUsersDbus * self, const gboolean already_had_user = is_tracked_uid (self, uid); id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); - object_add_connection (G_OBJECT(user), id); g_hash_table_insert (p->uid_to_account, GUINT_TO_POINTER (uid), - g_object_ref (user)); + user_record_new (user, id)); if (already_had_user) emit_user_changed (self, uid); @@ -236,11 +227,16 @@ untrack_user (IndicatorSessionUsersDbus * self, GHashTableIter iter; priv_t * p = self->priv; + /* find the uid matching this object path */ uid = 0; g_hash_table_iter_init (&iter, p->uid_to_account); while (!uid && g_hash_table_iter_next (&iter, &key, &val)) - if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (val))) - uid = GPOINTER_TO_UINT (key); + { + struct UserRecord * rec = val; + GDBusProxy * proxy = G_DBUS_PROXY (rec->user); + if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (proxy))) + uid = GPOINTER_TO_UINT (key); + } if (uid) { @@ -677,7 +673,7 @@ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) p->uid_to_account = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, - object_unref_and_disconnect); + (GDestroyNotify)user_record_free); p->logins = g_hash_table_new (g_direct_hash, g_direct_equal); } -- cgit v1.2.3 From 47bd4aebb17b165792c5883e73c99f57d601778b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 19:27:04 -0500 Subject: in our cmake files, rename PROJECT_LIBEXECDIR as CMAKE_INSTALL_LIBEXECDIR and CMAKE_INSTALL_FULL_LIBEXECDIR for consistency with the other GNUInstallDirs --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7b65629..b327820 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,4 +17,4 @@ link_directories(${SERVICE_LIBRARY_DIRS}) set (SERVICE_EXEC "indicator-session-service") add_executable (${SERVICE_EXEC} main.c) target_link_libraries (${SERVICE_EXEC} libindicatorsessionservice backenddbus ${SERVICE_LIBRARIES} ${GCOV_LIBS}) -install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${PROJECT_LIBEXECDIR}) +install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}) -- cgit v1.2.3 From cba24317a60a2670c0c917aaa637488b834da379 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 20:55:54 -0500 Subject: in main.c's on_name_lost(), silence minor 'unused parameter' compiler warning --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 8df5e60..45c5394 100644 --- a/src/main.c +++ b/src/main.c @@ -30,7 +30,7 @@ ***/ static void -on_name_lost (gpointer instance, gpointer loop) +on_name_lost (gpointer instance G_GNUC_UNUSED, gpointer loop) { g_warning ("exiting: service couldn't acquire, or lost ownership of, busname"); -- cgit v1.2.3 From e875abf22fc02939185b6aa881865cff58fc1543 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 21:00:17 -0500 Subject: in cmake files, limit scopes by moving single-target properties out of the global variables to single-target ones and moving single-use includes into the directories where they're used --- src/CMakeLists.txt | 11 +++++++++-- src/backend-dbus/CMakeLists.txt | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b327820..a00b6f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,12 +9,19 @@ add_library (libindicatorsessionservice STATIC service.h users.c users.h) -set_target_properties (libindicatorsessionservice PROPERTIES COMPILE_FLAGS " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") - include_directories(${SERVICE_INCLUDE_DIRS}) link_directories(${SERVICE_LIBRARY_DIRS}) set (SERVICE_EXEC "indicator-session-service") +set_property (SOURCE main.c + APPEND PROPERTY COMPILE_DEFINITIONS + GETTEXT_PACKAGE="${GETTEXT_PACKAGE}" + GNOMELOCALEDIR="@CMAKE_INSTALL_FULL_LOCALEDIR@") add_executable (${SERVICE_EXEC} main.c) target_link_libraries (${SERVICE_EXEC} libindicatorsessionservice backenddbus ${SERVICE_LIBRARIES} ${GCOV_LIBS}) install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}) + +# common properties +set_property (TARGET libindicatorsessionservice ${SERVICE_EXEC} + APPEND_STRING PROPERTY COMPILE_FLAGS + " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index 1c0df8e..fa41534 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -1,3 +1,5 @@ +include (GdbusCodegen) + set(BACKEND_GENERATED_SOURCES ) -- cgit v1.2.3 From d7248cf9ca466a9a3fbb9c722ad7029f9150fd0d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 5 Jul 2013 07:24:39 -0500 Subject: make the desktop greeter menu's name consistent across indicators: 'desktop_greeter' --- src/service.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/service.c b/src/service.c index 45bbdad..6cb9123 100644 --- a/src/service.c +++ b/src/service.c @@ -531,6 +531,7 @@ create_session_section (IndicatorSessionService * self) if (indicator_session_actions_can_logout (p->backend_actions) && !g_settings_get_boolean (s, "suppress-logout-menuitem")) { const char * label = ellipsis ? _("Log Out…") : _("Log Out"); + label = "Logggg outttt....."; g_menu_append (menu, label, "indicator.logout"); } -- cgit v1.2.3 From 6c4e44173ea46125697ed33e989f23db1f36b744 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 9 Jul 2013 23:25:12 -0500 Subject: in the desktop greeter, skip the logout menuitem --- src/service.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 6cb9123..166f729 100644 --- a/src/service.c +++ b/src/service.c @@ -519,7 +519,7 @@ create_switch_section (IndicatorSessionService * self) } static GMenuModel * -create_session_section (IndicatorSessionService * self) +create_session_section (IndicatorSessionService * self, int profile) { GMenu * menu; const priv_t * const p = self->priv; @@ -528,10 +528,11 @@ create_session_section (IndicatorSessionService * self) menu = g_menu_new (); - if (indicator_session_actions_can_logout (p->backend_actions) && !g_settings_get_boolean (s, "suppress-logout-menuitem")) + if ((profile == PROFILE_DESKTOP) && + (indicator_session_actions_can_logout (p->backend_actions)) && + (!g_settings_get_boolean (s, "suppress-logout-menuitem"))) { const char * label = ellipsis ? _("Log Out…") : _("Log Out"); - label = "Logggg outttt....."; g_menu_append (menu, label, "indicator.logout"); } @@ -576,11 +577,11 @@ create_menu (IndicatorSessionService * self, int profile) sections[n++] = create_admin_section (); sections[n++] = create_settings_section (self); sections[n++] = create_switch_section (self); - sections[n++] = create_session_section (self); + sections[n++] = create_session_section (self, profile); } else if (profile == PROFILE_GREETER) { - sections[n++] = create_session_section (self); + sections[n++] = create_session_section (self, profile); } /* add sections to the submenu */ @@ -811,8 +812,8 @@ rebuild_now (IndicatorSessionService * self, int sections) if (sections & SECTION_SESSION) { - rebuild_section (desktop->submenu, 3, create_session_section(self)); - rebuild_section (greeter->submenu, 0, create_session_section(self)); + rebuild_section (desktop->submenu, 3, create_session_section(self, PROFILE_DESKTOP)); + rebuild_section (greeter->submenu, 0, create_session_section(self, PROFILE_GREETER)); } } -- cgit v1.2.3 From 4168038976915aea6f73449f145d923cc63bd1be Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 10 Jul 2013 00:08:03 -0500 Subject: If g_getenv(XDG_SEAT_PATH) fails, don't try to get the DisplayManager seat. Fixes the greeter issue reported by seb128 --- src/backend-dbus/utils.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index 25ac7c3..d1511f4 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -126,13 +126,15 @@ indicator_session_util_get_session_proxies ( gpointer user_data) { struct session_proxy_data * data; - char * seat_path; + char * login1_seat_path; + const char * dm_seat_path; data = g_new0 (struct session_proxy_data, 1); data->callback = func; data->user_data = user_data; data->cancellable = g_object_ref (cancellable); + /* login1 */ data->pending++; login1_manager_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, @@ -141,15 +143,18 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_login1_manager_ready, data); - data->pending++; - seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); + /* login1 seat */ + login1_seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.login1", - seat_path, + login1_seat_path, data->cancellable, on_login1_seat_ready, data); + g_free (login1_seat_path); + + /* Accounts */ data->pending++; accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, @@ -158,14 +163,16 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_accounts_proxy_ready, data); - data->pending++; - display_manager_seat_proxy_new_for_bus ( + /* DisplayManager seat */ + if ((dm_seat_path = g_getenv ("XDG_SEAT_PATH"))) + { + data->pending++; + display_manager_seat_proxy_new_for_bus ( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.DisplayManager", - g_getenv ("XDG_SEAT_PATH"), + dm_seat_path, data->cancellable, on_display_manager_seat_proxy_ready, data); - - g_free (seat_path); + } } -- cgit v1.2.3 From f71bc96e3131f4241256a850ab8c0b556bdac4dd Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 10 Jul 2013 00:30:45 -0500 Subject: just to be safe, check to see that g_getenv('XDG_SEAT') passes too --- src/backend-dbus/utils.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index d1511f4..bc862e8 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -126,8 +126,7 @@ indicator_session_util_get_session_proxies ( gpointer user_data) { struct session_proxy_data * data; - char * login1_seat_path; - const char * dm_seat_path; + const char * str; data = g_new0 (struct session_proxy_data, 1); data->callback = func; @@ -144,15 +143,20 @@ indicator_session_util_get_session_proxies ( on_login1_manager_ready, data); /* login1 seat */ - login1_seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); - login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + if ((str = g_getenv ("XDG_SEAT"))) + { + char * path; + data->pending++; + path = g_strconcat ("/org/freedesktop/login1/seat/", str, NULL); + login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.login1", - login1_seat_path, + path, data->cancellable, on_login1_seat_ready, data); - g_free (login1_seat_path); + g_free (path); + } /* Accounts */ data->pending++; @@ -164,14 +168,14 @@ indicator_session_util_get_session_proxies ( on_accounts_proxy_ready, data); /* DisplayManager seat */ - if ((dm_seat_path = g_getenv ("XDG_SEAT_PATH"))) + if ((str = g_getenv ("XDG_SEAT_PATH"))) { data->pending++; display_manager_seat_proxy_new_for_bus ( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.DisplayManager", - dm_seat_path, + str, data->cancellable, on_display_manager_seat_proxy_ready, data); } -- cgit v1.2.3 From 98d1379784757b63e317bcd9ac7af69836e473d9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 12 Jul 2013 02:03:13 -0500 Subject: Add a 'can-reboot' property to the Actions class. This is used for handling a couple of pathological cases where features and states mix and match: 1. unity has the same dialog for 'reboot' and 'power off', so remove the duplicate menuitem, EXCEPT: 2. if the unity prompt isn't available (such as in the greeter), show both menuitems, OR 3. if the user has prompting disabled we need both, OR 4. if the user has the 'power off' button disabled, don't treat 'reboot' as redundant. --- src/actions.c | 26 ++++++++++++++++++++++++++ src/actions.h | 4 ++++ src/service.c | 11 ++--------- 3 files changed, 32 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/actions.c b/src/actions.c index babc285..ca086b7 100644 --- a/src/actions.c +++ b/src/actions.c @@ -34,6 +34,7 @@ enum PROP_CAN_SUSPEND, PROP_CAN_LOCK, PROP_CAN_LOGOUT, + PROP_CAN_REBOOT, PROP_CAN_PROMPT, PROP_HAS_ONLINE_ACCOUNT_ERROR, PROP_LAST @@ -71,6 +72,10 @@ my_get_property (GObject * o, g_value_set_boolean (value, indicator_session_actions_can_logout (self)); break; + case PROP_CAN_REBOOT: + g_value_set_boolean (value, indicator_session_actions_can_reboot (self)); + break; + case PROP_CAN_PROMPT: g_value_set_boolean (value, indicator_session_actions_can_prompt (self)); break; @@ -96,6 +101,7 @@ indicator_session_actions_class_init (IndicatorSessionActionsClass * klass) klass->can_lock = NULL; klass->can_logout = NULL; + klass->can_reboot = NULL; klass->can_switch = NULL; klass->can_suspend = NULL; klass->can_hibernate = NULL; @@ -144,6 +150,12 @@ indicator_session_actions_class_init (IndicatorSessionActionsClass * klass) "Whether or not the system services allow the user to logout", TRUE, flags); + properties[PROP_CAN_REBOOT] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_REBOOT, + "Can Reboot", + "Whether or not the system services allow the user to reboot", + TRUE, flags); + properties[PROP_CAN_PROMPT] = g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT, "Can Show End Session Dialog", @@ -185,6 +197,14 @@ indicator_session_actions_can_logout (IndicatorSessionActions * self) return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_logout (self); } +gboolean +indicator_session_actions_can_reboot (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_reboot (self); +} + gboolean indicator_session_actions_can_switch (IndicatorSessionActions * self) { @@ -352,6 +372,12 @@ indicator_session_actions_notify_can_logout (IndicatorSessionActions * self) notify_func (self, PROP_CAN_LOGOUT); } +void +indicator_session_actions_notify_can_reboot (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_REBOOT); +} + void indicator_session_actions_notify_can_switch (IndicatorSessionActions * self) { diff --git a/src/actions.h b/src/actions.h index bba6045..0f8aa1d 100644 --- a/src/actions.h +++ b/src/actions.h @@ -38,6 +38,7 @@ typedef struct _IndicatorSessionActionsClass IndicatorSessionActionsClass; /* property keys */ #define INDICATOR_SESSION_ACTIONS_PROP_CAN_LOCK "can-lock" #define INDICATOR_SESSION_ACTIONS_PROP_CAN_LOGOUT "can-logout" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_REBOOT "can-reboot" #define INDICATOR_SESSION_ACTIONS_PROP_CAN_SWITCH "can-switch" #define INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND "can-suspend" #define INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE "can-hibernate" @@ -62,6 +63,7 @@ struct _IndicatorSessionActionsClass gboolean (*can_lock) (IndicatorSessionActions * self); gboolean (*can_logout) (IndicatorSessionActions * self); + gboolean (*can_reboot) (IndicatorSessionActions * self); gboolean (*can_switch) (IndicatorSessionActions * self); gboolean (*can_suspend) (IndicatorSessionActions * self); gboolean (*can_hibernate) (IndicatorSessionActions * self); @@ -92,6 +94,7 @@ GType indicator_session_actions_get_type (void); gboolean indicator_session_actions_can_lock (IndicatorSessionActions * self); gboolean indicator_session_actions_can_logout (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_reboot (IndicatorSessionActions * self); gboolean indicator_session_actions_can_switch (IndicatorSessionActions * self); gboolean indicator_session_actions_can_suspend (IndicatorSessionActions * self); gboolean indicator_session_actions_can_hibernate (IndicatorSessionActions * self); @@ -101,6 +104,7 @@ gboolean indicator_session_actions_has_online_account_error (IndicatorSession void indicator_session_actions_notify_can_lock (IndicatorSessionActions * self); void indicator_session_actions_notify_can_logout (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_reboot (IndicatorSessionActions * self); void indicator_session_actions_notify_can_switch (IndicatorSessionActions * self); void indicator_session_actions_notify_can_suspend (IndicatorSessionActions * self); void indicator_session_actions_notify_can_hibernate (IndicatorSessionActions * self); diff --git a/src/service.c b/src/service.c index 166f729..3de37e3 100644 --- a/src/service.c +++ b/src/service.c @@ -529,8 +529,7 @@ create_session_section (IndicatorSessionService * self, int profile) menu = g_menu_new (); if ((profile == PROFILE_DESKTOP) && - (indicator_session_actions_can_logout (p->backend_actions)) && - (!g_settings_get_boolean (s, "suppress-logout-menuitem"))) + (indicator_session_actions_can_logout (p->backend_actions))) { const char * label = ellipsis ? _("Log Out…") : _("Log Out"); g_menu_append (menu, label, "indicator.logout"); @@ -542,9 +541,7 @@ create_session_section (IndicatorSessionService * self, int profile) if (indicator_session_actions_can_hibernate (p->backend_actions)) g_menu_append (menu, _("Hibernate"), "indicator.hibernate"); - /* NB: check 'ellipsis' here to skip this item if prompting is enabled - because this shows the same prompt as 'Shut Down' in Unity */ - if (!ellipsis && !g_settings_get_boolean (s, "suppress-restart-menuitem")) + if (indicator_session_actions_can_reboot (p->backend_actions)) { const char * label = ellipsis ? _("Restart…") : _("Restart"); g_menu_append (menu, label, "indicator.reboot"); @@ -1021,10 +1018,6 @@ indicator_session_service_init (IndicatorSessionService * self) G_CALLBACK(rebuild_switch_section_soon), self); g_signal_connect_swapped (gp, "changed::suppress-logout-restart-shutdown", G_CALLBACK(rebuild_session_section_soon), self); - g_signal_connect_swapped (gp, "changed::suppress-logout-menuitem", - G_CALLBACK(rebuild_session_section_soon), self); - g_signal_connect_swapped (gp, "changed::suppress-restart-menuitem", - G_CALLBACK(rebuild_session_section_soon), self); g_signal_connect_swapped (gp, "changed::suppress-shutdown-menuitem", G_CALLBACK(rebuild_session_section_soon), self); g_signal_connect_swapped (gp, "changed::show-real-name-on-panel", -- 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') 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/actions.c | 8 ++++++++ src/actions.h | 2 ++ src/backend-dbus/actions.c | 10 ++++++++++ src/service.c | 29 +++++++++++++++++++---------- 4 files changed, 39 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/actions.c b/src/actions.c index ca086b7..563f626 100644 --- a/src/actions.c +++ b/src/actions.c @@ -249,6 +249,14 @@ indicator_session_actions_has_online_account_error (IndicatorSessionActions * se **** ***/ +void +indicator_session_actions_online_accounts (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->online_accounts (self); +} + void indicator_session_actions_settings (IndicatorSessionActions * self) { diff --git a/src/actions.h b/src/actions.h index 0f8aa1d..e31685e 100644 --- a/src/actions.h +++ b/src/actions.h @@ -78,6 +78,7 @@ struct _IndicatorSessionActionsClass void (*help) (IndicatorSessionActions * self); void (*about) (IndicatorSessionActions * self); void (*settings) (IndicatorSessionActions * self); + void (*online_accounts) (IndicatorSessionActions * self); void (*switch_to_greeter) (IndicatorSessionActions * self); void (*switch_to_screensaver) (IndicatorSessionActions * self); @@ -121,6 +122,7 @@ void indicator_session_actions_power_off (IndicatorSession void indicator_session_actions_help (IndicatorSessionActions * self); void indicator_session_actions_about (IndicatorSessionActions * self); void indicator_session_actions_settings (IndicatorSessionActions * self); +void indicator_session_actions_online_accounts (IndicatorSessionActions * self); void indicator_session_actions_switch_to_screensaver (IndicatorSessionActions * self); void indicator_session_actions_switch_to_greeter (IndicatorSessionActions * self); 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; diff --git a/src/service.c b/src/service.c index 3de37e3..74acd89 100644 --- a/src/service.c +++ b/src/service.c @@ -622,6 +622,14 @@ on_about_activated (GSimpleAction * a G_GNUC_UNUSED, indicator_session_actions_about (get_backend_actions(gself)); } +static void +on_online_accounts_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_online_accounts (get_backend_actions(gself)); +} + static void on_help_activated (GSimpleAction * a G_GNUC_UNUSED, GVariant * param G_GNUC_UNUSED, @@ -720,16 +728,17 @@ init_gactions (IndicatorSessionService * self) priv_t * p = self->priv; GActionEntry entries[] = { - { "about", on_about_activated }, - { "help", on_help_activated }, - { "settings", on_settings_activated }, - { "logout", on_logout_activated }, - { "suspend", on_suspend_activated }, - { "hibernate", on_hibernate_activated }, - { "reboot", on_reboot_activated }, - { "power-off", on_power_off_activated }, - { "switch-to-screensaver", on_screensaver_activated }, - { "switch-to-greeter", on_greeter_activated } + { "about", on_about_activated }, + { "help", on_help_activated }, + { "hibernate", on_hibernate_activated }, + { "logout", on_logout_activated }, + { "online-accounts", on_online_accounts_activated }, + { "reboot", on_reboot_activated }, + { "settings", on_settings_activated }, + { "switch-to-screensaver", on_screensaver_activated }, + { "switch-to-greeter", on_greeter_activated }, + { "suspend", on_suspend_activated }, + { "power-off", on_power_off_activated } }; p->actions = g_simple_action_group_new (); -- cgit v1.2.3 From 843fa1f19c2d6c1072ab3479c0969eb0b6b73076 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 8 Aug 2013 16:00:42 -0500 Subject: as discussed with dednick and ted, have a header action state type of a{sv} rather than the obsoleted (sssb) --- src/service.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 74acd89..41dba10 100644 --- a/src/service.c +++ b/src/service.c @@ -143,29 +143,28 @@ rebuild_settings_section_soon (IndicatorSessionService * self) **** ***/ -static void -update_header_action (IndicatorSessionService * self) +static GVariant * +action_state_for_header (IndicatorSessionService * self) { - gchar * a11y; + const priv_t * const p = self->priv; gboolean need_attn; + GIcon * icon; gboolean show_name; - GVariant * variant; const gchar * real_name; const gchar * label; - const gchar * iconstr; - const priv_t * const p = self->priv; - - g_return_if_fail (p->header_action != NULL); + gchar * a11y; + GVariantBuilder b; + GVariant * state; if (indicator_session_actions_has_online_account_error (p->backend_actions)) { need_attn = TRUE; - iconstr = ICON_ALERT; + icon = g_themed_icon_new (ICON_ALERT); } else { need_attn = FALSE; - iconstr = ICON_DEFAULT; + icon = g_themed_icon_new (ICON_DEFAULT); } show_name = g_settings_get_boolean (p->indicator_settings, @@ -194,9 +193,27 @@ update_header_action (IndicatorSessionService * self) a11y = g_strdup (_("System")); } - variant = g_variant_new ("(sssb)", label, iconstr, a11y, TRUE); - g_simple_action_set_state (p->header_action, variant); + /* build the state */ + g_variant_builder_init (&b, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_string (a11y)); + g_variant_builder_add (&b, "{sv}", "icon", g_icon_serialize (icon)); + if (label && *label) + g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (label)); + g_variant_builder_add (&b, "{sv}", "visible", g_variant_new_boolean (TRUE)); + state = g_variant_builder_end (&b); +g_message ("---\n%s\n---\n", g_variant_print(state, TRUE)); + + /* cleanup */ g_free (a11y); + g_object_unref (G_OBJECT (icon)); + + return state; +} + +static void +update_header_action (IndicatorSessionService * self) +{ + g_simple_action_set_state (self->priv->header_action, action_state_for_header (self)); } /*** @@ -763,8 +780,7 @@ init_gactions (IndicatorSessionService * self) p->user_switcher_action = a; /* add the header action */ - v = g_variant_new ("(sssb)", "label", ICON_DEFAULT, "a11y", TRUE); - a = g_simple_action_new_stateful ("_header", NULL, v); + a = g_simple_action_new_stateful ("_header", NULL, action_state_for_header (self)); g_simple_action_group_insert (p->actions, G_ACTION(a)); p->header_action = a; -- cgit v1.2.3 From a699afab31403d69bbd6f20c45a6f601b1ea3dc5 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 8 Aug 2013 16:02:22 -0500 Subject: remove debugging stub --- src/service.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 41dba10..a097876 100644 --- a/src/service.c +++ b/src/service.c @@ -201,7 +201,6 @@ action_state_for_header (IndicatorSessionService * self) g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (label)); g_variant_builder_add (&b, "{sv}", "visible", g_variant_new_boolean (TRUE)); state = g_variant_builder_end (&b); -g_message ("---\n%s\n---\n", g_variant_print(state, TRUE)); /* cleanup */ g_free (a11y); -- 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') 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') 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') 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 From 3b35ef115b35d21b627f5802f364906243418247 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 22 Aug 2013 10:04:10 -0500 Subject: don't use deprecated API calls to GSimpleActionGroup --- src/service.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/service.c b/src/service.c index 74acd89..7303fcf 100644 --- a/src/service.c +++ b/src/service.c @@ -752,20 +752,20 @@ init_gactions (IndicatorSessionService * self) v = create_guest_switcher_state (self); a = g_simple_action_new_stateful ("switch-to-guest", NULL, v); g_signal_connect (a, "activate", G_CALLBACK(on_guest_activated), self); - g_simple_action_group_insert (p->actions, G_ACTION(a)); + g_action_map_add_action (G_ACTION_MAP (p->actions), G_ACTION(a)); p->guest_switcher_action = a; /* add switch-to-user action... parameter is the uesrname */ v = create_user_switcher_state (self); a = g_simple_action_new_stateful ("switch-to-user", G_VARIANT_TYPE_STRING, v); g_signal_connect (a, "activate", G_CALLBACK(on_user_activated), self); - g_simple_action_group_insert (p->actions, G_ACTION(a)); + g_action_map_add_action (G_ACTION_MAP (p->actions), G_ACTION(a)); p->user_switcher_action = a; /* add the header action */ v = g_variant_new ("(sssb)", "label", ICON_DEFAULT, "a11y", TRUE); a = g_simple_action_new_stateful ("_header", NULL, v); - g_simple_action_group_insert (p->actions, G_ACTION(a)); + g_action_map_add_action (G_ACTION_MAP (p->actions), G_ACTION(a)); p->header_action = a; rebuild_now (self, SECTION_HEADER); -- cgit v1.2.3