Back to index

indicator-session  12.10.0
Classes | Defines | Enumerations | Functions
session-menu-mgr.c File Reference
#include "config.h"
#include <sys/types.h>
#include <pwd.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <libdbusmenu-glib/client.h>
#include <libdbusmenu-gtk/menuitem.h>
#include "dbus-upower.h"
#include "session-menu-mgr.h"
#include "shared-names.h"
#include "users-service-dbus.h"

Go to the source code of this file.

Classes

struct  _SessionMenuMgr
 Creates and manages the menumodel and associated actions for the session menu described at https://wiki.ubuntu.com/SystemMenu. More...
struct  SignalHandlerData

Defines

#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"
#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"

Enumerations

enum  SwitcherMode { SWITCHER_MODE_SCREENSAVER, SWITCHER_MODE_LOCK, SWITCHER_MODE_SWITCH, SWITCHER_MODE_SWITCH_OR_LOCK }
 Which switch menuitem to show -- based on lockdown settings, greeter mode, number of users in the system, and so on. More...

Functions

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 *)
 G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT)
 GObject init / dispose.
static void session_menu_mgr_init (SessionMenuMgr *mgr)
static void session_menu_mgr_dispose (GObject *object)
static void session_menu_mgr_class_init (SessionMenuMgrClass *klass)
static void on_upower_properties_changed (SessionMenuMgr *mgr)
static void mi_set_label (DbusmenuMenuitem *mi, const char *str)
static void mi_set_type (DbusmenuMenuitem *mi, const char *str)
static void mi_set_visible (DbusmenuMenuitem *mi, gboolean b)
static void mi_set_logged_in (DbusmenuMenuitem *mi, gboolean b)
static DbusmenuMenuitem * mi_new_separator (void)
static DbusmenuMenuitem * mi_new (const char *label)
static void build_admin_menuitems (SessionMenuMgr *mgr)
static void build_session_menuitems (SessionMenuMgr *mgr)
static GQuark get_menuitem_quark (void)
static DbusmenuMenuitem * user_get_menuitem (AccountsUser *user)
static void user_clear_menuitem (AccountsUser *user)
static void user_set_menuitem (AccountsUser *user, DbusmenuMenuitem *mi)
static GQuark get_mgr_quark (void)
static SessionMenuMgr * user_get_mgr (AccountsUser *user)
static void user_set_mgr (AccountsUser *user, SessionMenuMgr *mgr)
static GQuark get_collision_quark (void)
static gboolean user_has_name_collision (AccountsUser *u)
static void user_set_name_collision (AccountsUser *u, gboolean b)
static void update_user_menuitem_icon (DbusmenuMenuitem *mi, AccountsUser *user)
static void update_user_menuitem_name (DbusmenuMenuitem *mi, AccountsUser *user)
static void on_user_property_changed (AccountsUser *user, GParamSpec *pspec, DbusmenuMenuitem *mi)
static void on_user_menuitem_destroyed (SignalHandlerData *data)
static DbusmenuMenuitem * user_menuitem_new (AccountsUser *user, SessionMenuMgr *mgr)
static gint compare_users_by_login_frequency (gconstpointer a, gconstpointer b)
static gint compare_users_by_username (gconstpointer ga, gconstpointer gb)
static gboolean is_user_switching_allowed (SessionMenuMgr *mgr)
static void build_user_menuitems (SessionMenuMgr *mgr)
static void lock_helper (SessionMenuMgr *mgr, gboolean show_lock_screen)
SessionMenuMgr * session_menu_mgr_new (SessionDbus *session_dbus, gboolean greeter_mode)
DbusmenuMenuitem * session_menu_mgr_get_menu (SessionMenuMgr *mgr)
 session_menu_mgr_get_menu:

Class Documentation

struct _SessionMenuMgr

Creates and manages the menumodel and associated actions for the session menu described at https://wiki.ubuntu.com/SystemMenu.

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.

Definition at line 82 of file session-menu-mgr.c.

Class Members
gboolean allow_hibernate
gboolean allow_suspend
gboolean can_hibernate
gboolean can_suspend
GCancellable * cancellable
gboolean greeter_mode
DbusmenuMenuitem * guest_mi
DbusmenuMenuitem * hibernate_mi
GSettings * indicator_settings
GSettings * keybinding_settings
DbusmenuMenuitem * lock_mi
DbusmenuMenuitem * lock_switch_mi
GSettings * lockdown_settings
DbusmenuMenuitem * logout_mi
GObject parent_instance
DbusmenuMenuitem * restart_mi
DbusmenuMenuitem * screensaver_mi
SessionDbus * session_dbus
DbusmenuMenuitem * shutdown_mi
DbusmenuMenuitem * suspend_mi
DbusmenuMenuitem * top_mi
DBusUPower * upower_proxy
gint user_menuitem_index
GSList * user_menuitems
UsersServiceDbus * users_dbus_facade
struct SignalHandlerData

Definition at line 701 of file session-menu-mgr.c.

Class Members
gulong handler_id
gpointer instance

Define Documentation

#define CMD_HELP   "yelp"

Definition at line 42 of file session-menu-mgr.c.

#define CMD_INFO   "gnome-control-center info"

Definition at line 43 of file session-menu-mgr.c.

#define CMD_LOGOUT   "gnome-session-quit --logout"

Definition at line 53 of file session-menu-mgr.c.

#define CMD_RESTART   ""

Definition at line 52 of file session-menu-mgr.c.

#define CMD_SHUTDOWN   "gnome-session-quit --power-off"

Definition at line 54 of file session-menu-mgr.c.

#define CMD_SYSTEM_SETTINGS   "gnome-control-center"

Definition at line 44 of file session-menu-mgr.c.

#define DEBUG_SHOW_ALL   FALSE

Definition at line 37 of file session-menu-mgr.c.

#define HAVE_RESTART_CMD   FALSE /* hmm, no gnome-session-quit --restart? */

Definition at line 51 of file session-menu-mgr.c.

#define UPOWER_ADDRESS   "org.freedesktop.UPower"

Definition at line 39 of file session-menu-mgr.c.

#define UPOWER_PATH   "/org/freedesktop/UPower"

Definition at line 40 of file session-menu-mgr.c.


Enumeration Type Documentation

Which switch menuitem to show -- based on lockdown settings, greeter mode, number of users in the system, and so on.

See get_switcher_mode()

Enumerator:
SWITCHER_MODE_SCREENSAVER 
SWITCHER_MODE_LOCK 
SWITCHER_MODE_SWITCH 
SWITCHER_MODE_SWITCH_OR_LOCK 

Definition at line 62 of file session-menu-mgr.c.


Function Documentation

static void action_func_hibernate ( SessionMenuMgr *  mgr) [static]

Definition at line 1067 of file session-menu-mgr.c.

{
  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);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void action_func_lock ( SessionMenuMgr *  mgr) [static]

Definition at line 1016 of file session-menu-mgr.c.

{
  lock_helper (mgr, FALSE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void action_func_spawn_async ( const char *  cmd) [static]

Definition at line 959 of file session-menu-mgr.c.

{
  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);
    }
}

Here is the caller graph for this function:

static void action_func_suspend ( SessionMenuMgr *  mgr) [static]

Definition at line 1051 of file session-menu-mgr.c.

{
  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);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void action_func_switch_to_greeter ( SessionMenuMgr *  mgr) [static]

Definition at line 1028 of file session-menu-mgr.c.

{
  action_func_lock (mgr);
  users_service_dbus_show_greeter (mgr->users_dbus_facade);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void action_func_switch_to_guest ( SessionMenuMgr *  mgr) [static]

Definition at line 1044 of file session-menu-mgr.c.

{
  action_func_lock (mgr);
  users_service_dbus_activate_guest_session (mgr->users_dbus_facade);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void action_func_switch_to_lockscreen ( SessionMenuMgr *  mgr) [static]

Definition at line 1022 of file session-menu-mgr.c.

{
  lock_helper (mgr, TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void action_func_switch_to_user ( AccountsUser *  user) [static]

Definition at line 1035 of file session-menu-mgr.c.

{
  SessionMenuMgr * mgr = user_get_mgr (user);
  g_return_if_fail (mgr != NULL);
  action_func_lock (mgr);
  users_service_dbus_activate_user_session (mgr->users_dbus_facade, user);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void build_admin_menuitems ( SessionMenuMgr *  mgr) [static]

Definition at line 371 of file session-menu-mgr.c.

{
  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 = mi_new_separator ();
    dbusmenu_menuitem_child_append (mgr->top_mi, mi);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void build_session_menuitems ( SessionMenuMgr *  mgr) [static]

Definition at line 462 of file session-menu-mgr.c.

{
  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 = dbusmenu_menuitem_new ();
  mi_set_type (mi, RESTART_ITEM_TYPE);
  dbusmenu_menuitem_property_set (mi, RESTART_ITEM_LABEL, _("Restart\342\200\246"));
  dbusmenu_menuitem_child_append (mgr->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 (_("Switch Off\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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void build_user_menuitems ( SessionMenuMgr *  mgr) [static]

Start Screen Saver Switch Account... Lock Lock / Switch Account...

Definition at line 803 of file session-menu-mgr.c.

{
  g_return_if_fail (!mgr->greeter_mode);

  DbusmenuMenuitem * mi;
  GSList * items = NULL;
  gint pos = mgr->user_menuitem_index;
  const char * current_real_name = NULL;

  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; i<MAX_USERS && u!=NULL; u=u->next, 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 */
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gint compare_users_by_login_frequency ( gconstpointer  a,
gconstpointer  b 
) [static]

Definition at line 756 of file session-menu-mgr.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gint compare_users_by_username ( gconstpointer  ga,
gconstpointer  gb 
) [static]

Definition at line 767 of file session-menu-mgr.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

G_DEFINE_TYPE ( SessionMenuMgr  ,
session_menu_mgr  ,
G_TYPE_OBJECT   
)

GObject init / dispose.

static GQuark get_collision_quark ( void  ) [static]

Definition at line 567 of file session-menu-mgr.c.

{
  static GQuark q = 0;

  if (G_UNLIKELY(!q))
    {
      q = g_quark_from_static_string ("name-collision");
    }

  return q;
}

Here is the caller graph for this function:

static GQuark get_menuitem_quark ( void  ) [static]

Definition at line 505 of file session-menu-mgr.c.

{
  static GQuark q = 0;

  if (G_UNLIKELY(!q))
    {
      q = g_quark_from_static_string ("menuitem");
    }

  return q;
}

Here is the caller graph for this function:

static GQuark get_mgr_quark ( void  ) [static]

Definition at line 540 of file session-menu-mgr.c.

{
  static GQuark q = 0;

  if (G_UNLIKELY(!q))
    {
      q = g_quark_from_static_string ("session-menu-mgr");
    }

  return q;
}

Here is the caller graph for this function:

static SwitcherMode get_switcher_mode ( SessionMenuMgr *  mgr) [static]

Definition at line 1102 of file session-menu-mgr.c.

{
  SwitcherMode mode;

  const gboolean can_lock = !g_settings_get_boolean (mgr->lockdown_settings,
                                                     "disable-lock-screen");
  const gboolean can_switch = is_user_switching_allowed (mgr);

  if (!can_lock && !can_switch) /* hmm, quite an extreme lockdown */
    {
      mode = SWITCHER_MODE_SCREENSAVER;
    }
  else if (is_this_live_session()) /* live sessions can't lock or switch */
    {
      mode = SWITCHER_MODE_SCREENSAVER;
    }
  else if (!can_switch) /* switching's locked down */
    {
      mode = SWITCHER_MODE_LOCK;
    }
  else if (is_this_guest_session ()) /* guest sessions can't lock */
    {
      mode = SWITCHER_MODE_SWITCH;
    }
  else /* 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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init_upower_proxy ( SessionMenuMgr *  mgr) [static]

Definition at line 269 of file session-menu-mgr.c.

{
  /* 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);
        }

      on_upower_properties_changed (mgr);
      g_signal_connect_swapped (mgr->upower_proxy, "changed",
                                G_CALLBACK(on_upower_properties_changed), mgr);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean is_this_guest_session ( void  ) [static]

Definition at line 1087 of file session-menu-mgr.c.

{
  /* FIXME: this test has been here awhile and seems to work,
     but seems brittle to me */
  return geteuid() < 500;
}

Here is the caller graph for this function:

static gboolean is_this_live_session ( void  ) [static]

Definition at line 1095 of file session-menu-mgr.c.

{
  const struct passwd * const pw = getpwuid (geteuid());
  return (pw->pw_uid==999) && !g_strcmp0("ubuntu",pw->pw_name);
}

Here is the caller graph for this function:

static gboolean is_user_switching_allowed ( SessionMenuMgr *  mgr) [static]

Definition at line 785 of file session-menu-mgr.c.

{
  /* 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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void lock_helper ( SessionMenuMgr *  mgr,
gboolean  show_lock_screen 
) [static]

Definition at line 976 of file session-menu-mgr.c.

{
  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);
    }
}

Here is the caller graph for this function:

static DbusmenuMenuitem* mi_new ( const char *  label) [static]

Definition at line 358 of file session-menu-mgr.c.

{
  DbusmenuMenuitem * mi = dbusmenu_menuitem_new ();
  mi_set_label (mi, label);
  return mi;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static DbusmenuMenuitem* mi_new_separator ( void  ) [static]

Definition at line 350 of file session-menu-mgr.c.

{
  DbusmenuMenuitem * mi = dbusmenu_menuitem_new ();
  mi_set_type (mi, DBUSMENU_CLIENT_TYPES_SEPARATOR);
  return mi;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void mi_set_label ( DbusmenuMenuitem *  mi,
const char *  str 
) [inline, static]

Definition at line 325 of file session-menu-mgr.c.

{
  dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, str);
}

Here is the caller graph for this function:

static void mi_set_logged_in ( DbusmenuMenuitem *  mi,
gboolean  b 
) [inline, static]

Definition at line 344 of file session-menu-mgr.c.

{
  dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b);
}

Here is the caller graph for this function:

static void mi_set_type ( DbusmenuMenuitem *  mi,
const char *  str 
) [inline, static]

Definition at line 331 of file session-menu-mgr.c.

{
  dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, str);
}

Here is the caller graph for this function:

static void mi_set_visible ( DbusmenuMenuitem *  mi,
gboolean  b 
) [inline, static]

Definition at line 337 of file session-menu-mgr.c.

{
  dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE,
                                       b || DEBUG_SHOW_ALL);
}

Here is the caller graph for this function:

static void on_guest_logged_in_changed ( UsersServiceDbus *  usd,
SessionMenuMgr *  mgr 
) [static]

Definition at line 596 of file session-menu-mgr.c.

{
  if (mgr->guest_mi != NULL)
    {
      mi_set_logged_in (mgr->guest_mi,
                        users_service_dbus_is_guest_logged_in (usd));
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void on_upower_properties_changed ( SessionMenuMgr *  mgr) [static]

Definition at line 241 of file session-menu-mgr.c.

{
  gboolean b;
  gboolean need_refresh = FALSE;

  /* 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);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void on_user_logged_in_changed ( UsersServiceDbus *  usd,
AccountsUser *  user,
SessionMenuMgr *  mgr 
) [static]

Definition at line 609 of file session-menu-mgr.c.

{
  DbusmenuMenuitem * mi = user_get_menuitem (user);

  if (mi != NULL)
    {
      mi_set_logged_in (mi, users_service_dbus_is_user_logged_in (usd, user));
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void on_user_menuitem_destroyed ( SignalHandlerData data) [static]

Definition at line 711 of file session-menu-mgr.c.

{
  g_signal_handler_disconnect (data->instance, data->handler_id);
  g_free (data);
}

Here is the caller graph for this function:

static void on_user_property_changed ( AccountsUser *  user,
GParamSpec *  pspec,
DbusmenuMenuitem *  mi 
) [static]

Definition at line 673 of file session-menu-mgr.c.

{
  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));
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void session_menu_mgr_class_init ( SessionMenuMgrClass *  klass) [static]

Definition at line 223 of file session-menu-mgr.c.

{
  GObjectClass* object_class = G_OBJECT_CLASS (klass);
  object_class->dispose = session_menu_mgr_dispose;
}

Here is the call graph for this function:

static void session_menu_mgr_dispose ( GObject *  object) [static]

Definition at line 198 of file session-menu-mgr.c.

{
  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_slist_free (mgr->user_menuitems);
  mgr->user_menuitems = NULL;

  G_OBJECT_CLASS (session_menu_mgr_parent_class)->dispose (object);
}

Here is the caller graph for this function:

DbusmenuMenuitem* session_menu_mgr_get_menu ( SessionMenuMgr *  mgr)

session_menu_mgr_get_menu:

Returns: (transfer none): the manager's menu.

Definition at line 1167 of file session-menu-mgr.c.

{
  g_return_val_if_fail (IS_SESSION_MENU_MGR(mgr), NULL);

  return mgr->top_mi;
}

Here is the caller graph for this function:

static void session_menu_mgr_init ( SessionMenuMgr *  mgr) [static]

Definition at line 153 of file session-menu-mgr.c.

{
  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);
}

Here is the call graph for this function:

SessionMenuMgr* session_menu_mgr_new ( SessionDbus *  session_dbus,
gboolean  greeter_mode 
)

Definition at line 1147 of file session-menu-mgr.c.

{
  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);
  return mgr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void update_confirmation_labels ( SessionMenuMgr *  mgr) [static]

Definition at line 444 of file session-menu-mgr.c.

{
  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 ? _("Switch Off\342\200\246")
                                                 : _("Switch Off"));

  dbusmenu_menuitem_property_set (mgr->restart_mi, RESTART_ITEM_LABEL,
                                  confirm_needed ? _("Restart\342\200\246")
                                                 : _("Restart"));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void update_screensaver_shortcut ( SessionMenuMgr *  mgr) [static]

Definition at line 622 of file session-menu-mgr.c.

{
  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);
}

Here is the caller graph for this function:

static void update_session_menuitems ( SessionMenuMgr *  mgr) [static]

Definition at line 410 of file session-menu-mgr.c.

{
  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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void update_user_menuitem_icon ( DbusmenuMenuitem *  mi,
AccountsUser *  user 
) [static]

Definition at line 646 of file session-menu-mgr.c.

{
  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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void update_user_menuitem_name ( DbusmenuMenuitem *  mi,
AccountsUser *  user 
) [static]

Definition at line 659 of file session-menu-mgr.c.

{
  GString * gstr = g_string_new (accounts_user_get_real_name (user));

  if (user_has_name_collision (user))
    {
      g_string_append_printf (gstr, " (%s)", accounts_user_get_user_name(user));
    }

  dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, gstr->str);
  g_string_free (gstr, TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void update_user_menuitems ( SessionMenuMgr *  mgr) [static]

Definition at line 936 of file session-menu-mgr.c.

{
  /* 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);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void user_clear_menuitem ( AccountsUser *  user) [static]

Definition at line 524 of file session-menu-mgr.c.

{
  g_object_steal_qdata (G_OBJECT(user), get_menuitem_quark());
}

Here is the call graph for this function:

Here is the caller graph for this function:

static DbusmenuMenuitem* user_get_menuitem ( AccountsUser *  user) [static]

Definition at line 518 of file session-menu-mgr.c.

{
  return g_object_get_qdata (G_OBJECT(user), get_menuitem_quark());
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SessionMenuMgr* user_get_mgr ( AccountsUser *  user) [static]

Definition at line 553 of file session-menu-mgr.c.

{
  return g_object_get_qdata (G_OBJECT(user), get_mgr_quark());
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean user_has_name_collision ( AccountsUser *  u) [static]

Definition at line 580 of file session-menu-mgr.c.

{
  return g_object_get_qdata (G_OBJECT(u), get_collision_quark()) != NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static DbusmenuMenuitem* user_menuitem_new ( AccountsUser *  user,
SessionMenuMgr *  mgr 
) [static]

Definition at line 718 of file session-menu-mgr.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void user_set_menuitem ( AccountsUser *  user,
DbusmenuMenuitem *  mi 
) [static]

Definition at line 530 of file session-menu-mgr.c.

{
  g_object_set_qdata (G_OBJECT(user), get_menuitem_quark(), mi);

  g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)user_clear_menuitem, user);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void user_set_mgr ( AccountsUser *  user,
SessionMenuMgr *  mgr 
) [static]

Definition at line 559 of file session-menu-mgr.c.

{
  g_object_set_qdata (G_OBJECT(user), get_mgr_quark(), mgr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void user_set_name_collision ( AccountsUser *  u,
gboolean  b 
) [static]

Definition at line 586 of file session-menu-mgr.c.

{
  g_object_set_qdata (G_OBJECT(u), get_collision_quark(), GINT_TO_POINTER(b));
}

Here is the call graph for this function:

Here is the caller graph for this function: