499787d
commit 7b3be6884096a2d21af3c6c26090641c16988b15
499787d
Merge: f0a0955 4c20614
499787d
Author: Ray Strode <rstrode@redhat.com>
499787d
Date:   Tue Oct 20 17:56:09 2009 -0400
499787d
499787d
    Move Shutdown functions to panel instead of login window
499787d
    
499787d
    Robert Ancell gives a good rationale for the move:
499787d
    "In GDM 2.28/master on startup the user is presented with a window
499787d
    containing:
499787d
    - A list of users to log in as with the first user selected
499787d
    - Two buttons, restart and shutdown, below the user list
499787d
    
499787d
    Since the first user is selected, users who are unfamiliar/not paying
499787d
    close attention sometimes click on the shutdown button as this is placed
499787d
    where the default action (in this case login) is conventionally placed
499787d
    (the lower right hand corner of the window).  The penalty of making this
499787d
    mistake is for the computer to shut down immediately with no chance of
499787d
    aborting this mistake.
499787d
    
499787d
    An additional mistake users can make is to miss clicking on their user
499787d
    and then click on the shutdown button (as this button is replaced with
499787d
    the login button after selecting a user).
499787d
    
499787d
    Recommended behaviour:
499787d
    
499787d
    Move the shutdown actions (shutdown, sleep, hibernate, restart) to a
499787d
    menu on the GDM panel.
499787d
    
499787d
    The shutdown buttons do not need to be prominently located as:
499787d
    - They are used less frequently than the login buttons (normal operation
499787d
      is to shutdown from within your session).
499787d
    - Most hardware has a dedicated power button that performs the same
499787d
      action
499787d
    - It is better to have them in a location where they are less likely to
499787d
      be accidentally activated"
499787d
    
499787d
    (see https://bugs.gnome.org/596151)
499787d
499787d
From e53b45310bc0b83ab14fdfde1cac6e6ea22d82b7 Mon Sep 17 00:00:00 2001
499787d
From: Robert Ancell <robert.ancell@canonical.com>
499787d
Date: Thu, 24 Sep 2009 15:51:10 +1000
499787d
Subject: [PATCH 1/3] Move shutdown buttons to menu in panel (Bug #596151)
499787d
499787d
---
499787d
 gui/simple-greeter/Makefile.am                    |    2 +-
499787d
 gui/simple-greeter/gdm-greeter-login-window.c     |  294 ---------------------
499787d
 gui/simple-greeter/gdm-greeter-login-window.glade |  194 --------------
499787d
 gui/simple-greeter/gdm-greeter-panel.c            |  263 ++++++++++++++++++-
499787d
 gui/simple-greeter/gdm-greeter-panel.h            |    3 +-
499787d
 gui/simple-greeter/gdm-greeter-session.c          |    4 +-
499787d
 gui/simple-greeter/test-greeter-panel.c           |    2 +-
499787d
 7 files changed, 267 insertions(+), 495 deletions(-)
499787d
499787d
diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
499787d
index 4c06bc3..519e652 100644
499787d
--- a/gui/simple-greeter/Makefile.am
499787d
+++ b/gui/simple-greeter/Makefile.am
499787d
@@ -92,7 +92,6 @@ test_greeter_login_window_LDADD =	\
499787d
 	libgdmuser.la			\
499787d
 	$(COMMON_LIBS)			\
499787d
 	$(SIMPLE_GREETER_LIBS)		\
499787d
-	$(DEVKIT_POWER_LIBS)		\
499787d
 	$(RBAC_LIBS)			\
499787d
 	$(NULL)
499787d
 
499787d
@@ -144,6 +143,7 @@ test_greeter_panel_LDADD =	\
499787d
 	$(GTK_LIBS)			\
499787d
 	$(GCONF_LIBS)			\
499787d
 	$(LIBXKLAVIER_LIBS)		\
499787d
+	$(DEVKIT_POWER_LIBS)		\
499787d
 	$(NULL)
499787d
 
499787d
 test_remote_login_window_SOURCES = 	\
499787d
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
499787d
index 10a5132..9a29a2e 100644
499787d
--- a/gui/simple-greeter/gdm-greeter-login-window.c
499787d
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
499787d
@@ -34,11 +34,6 @@
499787d
 #include <errno.h>
499787d
 #include <pwd.h>
499787d
 
499787d
-#ifdef ENABLE_RBAC_SHUTDOWN
499787d
-#include <auth_attr.h>
499787d
-#include <secdb.h>
499787d
-#endif
499787d
-
499787d
 #include <glib.h>
499787d
 #include <glib/gi18n.h>
499787d
 #include <glib/gstdio.h>
499787d
@@ -56,10 +51,6 @@
499787d
 #include <dbus/dbus-glib.h>
499787d
 #include <dbus/dbus-glib-lowlevel.h>
499787d
 
499787d
-#ifdef HAVE_DEVICEKIT_POWER
499787d
-#include <devkit-power-gobject/devicekit-power.h>
499787d
-#endif
499787d
-
499787d
 #include "gdm-settings-client.h"
499787d
 #include "gdm-settings-keys.h"
499787d
 #include "gdm-profile.h"
499787d
@@ -90,7 +81,6 @@
499787d
 #define KEY_BANNER_MESSAGE_TEXT     KEY_GREETER_DIR "/banner_message_text"
499787d
 #define KEY_BANNER_MESSAGE_TEXT_NOCHOOSER     KEY_GREETER_DIR "/banner_message_text_nochooser"
499787d
 #define KEY_LOGO                    KEY_GREETER_DIR "/logo_icon_name"
499787d
-#define KEY_DISABLE_RESTART_BUTTONS KEY_GREETER_DIR "/disable_restart_buttons"
499787d
 #define GDM_GREETER_LOGIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_LOGIN_WINDOW, GdmGreeterLoginWindowPrivate))
499787d
 
499787d
 enum {
499787d
@@ -125,8 +115,6 @@ struct GdmGreeterLoginWindowPrivate
499787d
         char            *timed_login_username;
499787d
         guint            timed_login_timeout_id;
499787d
 
499787d
-        guint            sensitize_power_buttons_timeout_id;
499787d
-
499787d
         guint            login_button_handler_id;
499787d
         guint            start_session_handler_id;
499787d
 };
499787d
@@ -353,37 +341,6 @@ sensitize_widget (GdmGreeterLoginWindow *login_window,
499787d
         }
499787d
 }
499787d
 
499787d
-static gboolean
499787d
-get_show_restart_buttons (GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        gboolean     show;
499787d
-        GError      *error;
499787d
-
499787d
-        error = NULL;
499787d
-        show = ! gconf_client_get_bool (login_window->priv->client, KEY_DISABLE_RESTART_BUTTONS, &error);
499787d
-        if (error != NULL) {
499787d
-                g_debug ("GdmGreeterLoginWindow: unable to get disable-restart-buttons configuration: %s", error->message);
499787d
-                g_error_free (error);
499787d
-        }
499787d
-
499787d
-#ifdef ENABLE_RBAC_SHUTDOWN
499787d
-        {
499787d
-                char *username;
499787d
-
499787d
-                username = g_get_user_name ();
499787d
-                if (username == NULL || !chkauthattr (RBAC_SHUTDOWN_KEY, username)) {
499787d
-                        show = FALSE;
499787d
-                        g_debug ("GdmGreeterLoginWindow: Not showing stop/restart buttons for user %s due to RBAC key %s",
499787d
-                                 username, RBAC_SHUTDOWN_KEY);
499787d
-                } else {
499787d
-                        g_debug ("GdmGreeterLoginWindow: Showing stop/restart buttons for user %s due to RBAC key %s",
499787d
-                                 username, RBAC_SHUTDOWN_KEY);
499787d
-                }
499787d
-        }
499787d
-#endif
499787d
-        return show;
499787d
-}
499787d
-
499787d
 static void
499787d
 on_login_button_clicked_answer_query (GtkButton             *button,
499787d
                                       GdmGreeterLoginWindow *login_window)
499787d
@@ -477,61 +434,6 @@ adjust_other_login_visibility(GdmGreeterLoginWindow *login_window)
499787d
         }
499787d
 }
499787d
 
499787d
-#ifdef HAVE_DEVICEKIT_POWER
499787d
-static gboolean
499787d
-can_suspend (GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        gboolean ret;
499787d
-        DkpClient *dkp_client;
499787d
-
499787d
-        /* use DeviceKit-power to get data */
499787d
-        dkp_client = dkp_client_new ();
499787d
-        g_object_get (dkp_client,
499787d
-                      "can-suspend", &ret,
499787d
-                      NULL);
499787d
-        g_object_unref (dkp_client);
499787d
-        return ret;
499787d
-}
499787d
-#endif
499787d
-
499787d
-static void
499787d
-remove_sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        if (login_window->priv->sensitize_power_buttons_timeout_id > 0) {
499787d
-                g_source_remove (login_window->priv->sensitize_power_buttons_timeout_id);
499787d
-                login_window->priv->sensitize_power_buttons_timeout_id = 0;
499787d
-        }
499787d
-}
499787d
-
499787d
-static gboolean
499787d
-sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        switch (login_window->priv->dialog_mode) {
499787d
-        case MODE_SELECTION:
499787d
-                sensitize_widget (login_window, "shutdown-button", TRUE);
499787d
-                sensitize_widget (login_window, "restart-button", TRUE);
499787d
-                sensitize_widget (login_window, "suspend-button", TRUE);
499787d
-                sensitize_widget (login_window, "disconnect-button", TRUE);
499787d
-                break;
499787d
-        case MODE_AUTHENTICATION:
499787d
-                break;
499787d
-        default:
499787d
-                g_assert_not_reached ();
499787d
-        }
499787d
-
499787d
-        login_window->priv->sensitize_power_buttons_timeout_id = 0;
499787d
-        return FALSE;
499787d
-}
499787d
-
499787d
-static void
499787d
-add_sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        remove_sensitize_power_buttons_timeout (login_window);
499787d
-        login_window->priv->sensitize_power_buttons_timeout_id = g_timeout_add_seconds (1,
499787d
-                                                                                   (GSourceFunc)sensitize_power_buttons_timeout,
499787d
-                                                                                   login_window);
499787d
-}
499787d
-
499787d
 static void
499787d
 switch_mode (GdmGreeterLoginWindow *login_window,
499787d
              int                    number)
499787d
@@ -539,16 +441,6 @@ switch_mode (GdmGreeterLoginWindow *login_window,
499787d
         const char *default_name;
499787d
         GtkWidget  *user_chooser;
499787d
         GtkWidget  *box;
499787d
-        gboolean    show_restart_buttons;
499787d
-        gboolean    show_suspend_button;
499787d
-
499787d
-        show_restart_buttons = get_show_restart_buttons (login_window);
499787d
-
499787d
-#ifdef HAVE_DEVICEKIT_POWER
499787d
-        show_suspend_button = can_suspend (login_window);
499787d
-#else
499787d
-        show_suspend_button = FALSE;
499787d
-#endif
499787d
 
499787d
         /* we want to run this even if we're supposed to
499787d
            be in the mode already so that we reset everything
499787d
@@ -557,38 +449,20 @@ switch_mode (GdmGreeterLoginWindow *login_window,
499787d
 
499787d
         default_name = NULL;
499787d
 
499787d
-        remove_sensitize_power_buttons_timeout (login_window);
499787d
-
499787d
         switch (number) {
499787d
         case MODE_SELECTION:
499787d
                 set_log_in_button_mode (login_window, LOGIN_BUTTON_HIDDEN);
499787d
 
499787d
                 show_widget (login_window, "cancel-button", FALSE);
499787d
 
499787d
-                show_widget (login_window, "shutdown-button",
499787d
-                             login_window->priv->display_is_local && show_restart_buttons);
499787d
-                show_widget (login_window, "restart-button",
499787d
-                             login_window->priv->display_is_local && show_restart_buttons);
499787d
-                show_widget (login_window, "suspend-button",
499787d
-                             login_window->priv->display_is_local && show_restart_buttons && show_suspend_button);
499787d
-                show_widget (login_window, "disconnect-button",
499787d
-                             ! login_window->priv->display_is_local);
499787d
-
499787d
                 show_widget (login_window, "auth-input-box", FALSE);
499787d
 
499787d
-                add_sensitize_power_buttons_timeout (login_window);
499787d
-                sensitize_widget (login_window, "shutdown-button", FALSE);
499787d
-                sensitize_widget (login_window, "restart-button", FALSE);
499787d
-                sensitize_widget (login_window, "suspend-button", FALSE);
499787d
                 sensitize_widget (login_window, "disconnect-button", FALSE);
499787d
 
499787d
                 default_name = NULL;
499787d
                 break;
499787d
         case MODE_AUTHENTICATION:
499787d
                 show_widget (login_window, "cancel-button", TRUE);
499787d
-                show_widget (login_window, "shutdown-button", FALSE);
499787d
-                show_widget (login_window, "restart-button", FALSE);
499787d
-                show_widget (login_window, "suspend-button", FALSE);
499787d
                 show_widget (login_window, "disconnect-button", FALSE);
499787d
                 default_name = "log-in-button";
499787d
                 break;
499787d
@@ -629,32 +503,6 @@ switch_mode (GdmGreeterLoginWindow *login_window,
499787d
 }
499787d
 
499787d
 static void
499787d
-do_disconnect (GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        gtk_main_quit ();
499787d
-}
499787d
-
499787d
-#ifdef HAVE_DEVICEKIT_POWER
499787d
-static void
499787d
-do_suspend (GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        gboolean ret;
499787d
-        DkpClient *dkp_client;
499787d
-        GError *error = NULL;
499787d
-
499787d
-        /* use DeviceKit-power to get data */
499787d
-        dkp_client = dkp_client_new ();
499787d
-        ret = dkp_client_suspend (dkp_client, &error);
499787d
-        if (!ret) {
499787d
-                g_warning ("Couldn't suspend: %s", error->message);
499787d
-                g_error_free (error);
499787d
-                return;
499787d
-        }
499787d
-        g_object_unref (dkp_client);
499787d
-}
499787d
-#endif
499787d
-
499787d
-static void
499787d
 delete_entry_text (GtkWidget *entry)
499787d
 {
499787d
         const char *typed_text;
499787d
@@ -968,16 +816,6 @@ gdm_greeter_login_window_get_property (GObject    *object,
499787d
 }
499787d
 
499787d
 static void
499787d
-suspend_button_clicked (GtkButton             *button,
499787d
-                        GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-#ifdef HAVE_DEVICEKIT_POWER
499787d
-        do_suspend (login_window);
499787d
-#endif
499787d
-}
499787d
-
499787d
-
499787d
-static void
499787d
 cancel_button_clicked (GtkButton             *button,
499787d
                        GdmGreeterLoginWindow *login_window)
499787d
 {
499787d
@@ -985,125 +823,6 @@ cancel_button_clicked (GtkButton             *button,
499787d
 }
499787d
 
499787d
 static void
499787d
-disconnect_button_clicked (GtkButton             *button,
499787d
-                           GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        do_disconnect (login_window);
499787d
-}
499787d
-
499787d
-static gboolean
499787d
-try_system_stop (DBusGConnection *connection,
499787d
-                 GError         **error)
499787d
-{
499787d
-        DBusGProxy      *proxy;
499787d
-        gboolean         res;
499787d
-
499787d
-        g_debug ("GdmGreeterLoginWindow: trying to stop system");
499787d
-
499787d
-        proxy = dbus_g_proxy_new_for_name (connection,
499787d
-                                           CK_NAME,
499787d
-                                           CK_MANAGER_PATH,
499787d
-                                           CK_MANAGER_INTERFACE);
499787d
-        res = dbus_g_proxy_call_with_timeout (proxy,
499787d
-                                              "Stop",
499787d
-                                              INT_MAX,
499787d
-                                              error,
499787d
-                                              /* parameters: */
499787d
-                                              G_TYPE_INVALID,
499787d
-                                              /* return values: */
499787d
-                                              G_TYPE_INVALID);
499787d
-        return res;
499787d
-}
499787d
-
499787d
-static gboolean
499787d
-try_system_restart (DBusGConnection *connection,
499787d
-                    GError         **error)
499787d
-{
499787d
-        DBusGProxy      *proxy;
499787d
-        gboolean         res;
499787d
-
499787d
-        g_debug ("GdmGreeterLoginWindow: trying to restart system");
499787d
-
499787d
-        proxy = dbus_g_proxy_new_for_name (connection,
499787d
-                                           CK_NAME,
499787d
-                                           CK_MANAGER_PATH,
499787d
-                                           CK_MANAGER_INTERFACE);
499787d
-        res = dbus_g_proxy_call_with_timeout (proxy,
499787d
-                                              "Restart",
499787d
-                                              INT_MAX,
499787d
-                                              error,
499787d
-                                              /* parameters: */
499787d
-                                              G_TYPE_INVALID,
499787d
-                                              /* return values: */
499787d
-                                              G_TYPE_INVALID);
499787d
-        return res;
499787d
-}
499787d
-
499787d
-static void
499787d
-do_system_restart (GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        gboolean         res;
499787d
-        GError          *error;
499787d
-        DBusGConnection *connection;
499787d
-
499787d
-        error = NULL;
499787d
-        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
499787d
-        if (connection == NULL) {
499787d
-                g_warning ("Unable to get system bus connection: %s", error->message);
499787d
-                g_error_free (error);
499787d
-                return;
499787d
-        }
499787d
-
499787d
-        res = try_system_restart (connection, &error);
499787d
-        if (!res) {
499787d
-                g_debug ("GdmGreeterLoginWindow: unable to restart system: %s: %s",
499787d
-                         dbus_g_error_get_name (error),
499787d
-                         error->message);
499787d
-		g_error_free (error);
499787d
-        }
499787d
-}
499787d
-
499787d
-static void
499787d
-do_system_stop (GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        gboolean         res;
499787d
-        GError          *error;
499787d
-        DBusGConnection *connection;
499787d
-
499787d
-        error = NULL;
499787d
-        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
499787d
-        if (connection == NULL) {
499787d
-                g_warning ("Unable to get system bus connection: %s", error->message);
499787d
-                g_error_free (error);
499787d
-                return;
499787d
-        }
499787d
-
499787d
-        res = try_system_stop (connection, &error);
499787d
-        if (!res) {
499787d
-                g_debug ("GdmGreeterLoginWindow: unable to stop system: %s: %s",
499787d
-                         dbus_g_error_get_name (error),
499787d
-                         error->message);
499787d
-                g_error_free (error);
499787d
-        }
499787d
-}
499787d
-
499787d
-static void
499787d
-restart_button_clicked (GtkButton             *button,
499787d
-                        GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        g_debug ("GdmGreeterLoginWindow: restart button clicked");
499787d
-        do_system_restart (login_window);
499787d
-}
499787d
-
499787d
-static void
499787d
-shutdown_button_clicked (GtkButton             *button,
499787d
-                         GdmGreeterLoginWindow *login_window)
499787d
-{
499787d
-        g_debug ("GdmGreeterLoginWindow: stop button clicked");
499787d
-        do_system_stop (login_window);
499787d
-}
499787d
-
499787d
-static void
499787d
 on_user_chooser_visibility_changed (GdmGreeterLoginWindow *login_window)
499787d
 {
499787d
         update_banner_message (login_window);
499787d
@@ -1400,20 +1119,9 @@ load_theme (GdmGreeterLoginWindow *login_window)
499787d
         login_window->priv->auth_banner_label = glade_xml_get_widget (login_window->priv->xml, "auth-banner-label");
499787d
         /*make_label_small_italic (login_window->priv->auth_banner_label);*/
499787d
 
499787d
-        button = glade_xml_get_widget (login_window->priv->xml, "suspend-button");
499787d
-        g_signal_connect (button, "clicked", G_CALLBACK (suspend_button_clicked), login_window);
499787d
-
499787d
         button = glade_xml_get_widget (login_window->priv->xml, "cancel-button");
499787d
         g_signal_connect (button, "clicked", G_CALLBACK (cancel_button_clicked), login_window);
499787d
 
499787d
-        button = glade_xml_get_widget (login_window->priv->xml, "disconnect-button");
499787d
-        g_signal_connect (button, "clicked", G_CALLBACK (disconnect_button_clicked), login_window);
499787d
-
499787d
-        button = glade_xml_get_widget (login_window->priv->xml, "restart-button");
499787d
-        g_signal_connect (button, "clicked", G_CALLBACK (restart_button_clicked), login_window);
499787d
-        button = glade_xml_get_widget (login_window->priv->xml, "shutdown-button");
499787d
-        g_signal_connect (button, "clicked", G_CALLBACK (shutdown_button_clicked), login_window);
499787d
-
499787d
         entry = glade_xml_get_widget (login_window->priv->xml, "auth-prompt-entry");
499787d
         /* Only change the invisible character if it '*' otherwise assume it is OK */
499787d
         if ('*' == gtk_entry_get_invisible_char (GTK_ENTRY (entry))) {
499787d
@@ -1780,8 +1488,6 @@ gdm_greeter_login_window_finalize (GObject *object)
499787d
                 g_object_unref (login_window->priv->client);
499787d
         }
499787d
 
499787d
-        remove_sensitize_power_buttons_timeout (login_window);
499787d
-
499787d
         G_OBJECT_CLASS (gdm_greeter_login_window_parent_class)->finalize (object);
499787d
 }
499787d
 
499787d
diff --git a/gui/simple-greeter/gdm-greeter-login-window.glade b/gui/simple-greeter/gdm-greeter-login-window.glade
499787d
index d972c82..7c6e94b 100644
499787d
--- a/gui/simple-greeter/gdm-greeter-login-window.glade
499787d
+++ b/gui/simple-greeter/gdm-greeter-login-window.glade
499787d
@@ -337,200 +337,6 @@
499787d
 		  <property name="spacing">6</property>
499787d
 
499787d
 		  <child>
499787d
-		    <widget class="GtkButton" id="disconnect-button">
499787d
-		      <property name="visible">True</property>
499787d
-		      <property name="can_focus">True</property>
499787d
-		      <property name="label">gtk-disconnect</property>
499787d
-		      <property name="use_stock">True</property>
499787d
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
499787d
-		      <property name="focus_on_click">True</property>
499787d
-		    </widget>
499787d
-		  </child>
499787d
-
499787d
-		  <child>
499787d
-		    <widget class="GtkButton" id="suspend-button">
499787d
-		      <property name="visible">True</property>
499787d
-		      <property name="can_default">True</property>
499787d
-		      <property name="has_default">True</property>
499787d
-		      <property name="can_focus">True</property>
499787d
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
499787d
-		      <property name="focus_on_click">True</property>
499787d
-
499787d
-		      <child>
499787d
-			<widget class="GtkHBox" id="hbox3">
499787d
-			  <property name="visible">True</property>
499787d
-			  <property name="homogeneous">False</property>
499787d
-			  <property name="spacing">0</property>
499787d
-
499787d
-			  <child>
499787d
-			    <widget class="GtkImage" id="image9">
499787d
-			      <property name="visible">True</property>
499787d
-			      <property name="icon_name">media-playback-pause</property>
499787d
-			      <property name="pixel_size">16</property>
499787d
-			      <property name="xalign">0.5</property>
499787d
-			      <property name="yalign">0.5</property>
499787d
-			      <property name="xpad">0</property>
499787d
-			      <property name="ypad">0</property>
499787d
-			    </widget>
499787d
-			    <packing>
499787d
-			      <property name="padding">0</property>
499787d
-			      <property name="expand">True</property>
499787d
-			      <property name="fill">True</property>
499787d
-			    </packing>
499787d
-			  </child>
499787d
-
499787d
-			  <child>
499787d
-			    <widget class="GtkLabel" id="label4">
499787d
-			      <property name="visible">True</property>
499787d
-			      <property name="label" translatable="yes">Suspend</property>
499787d
-			      <property name="use_underline">False</property>
499787d
-			      <property name="use_markup">False</property>
499787d
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
499787d
-			      <property name="wrap">False</property>
499787d
-			      <property name="selectable">False</property>
499787d
-			      <property name="xalign">0</property>
499787d
-			      <property name="yalign">0.5</property>
499787d
-			      <property name="xpad">0</property>
499787d
-			      <property name="ypad">0</property>
499787d
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
499787d
-			      <property name="width_chars">-1</property>
499787d
-			      <property name="single_line_mode">False</property>
499787d
-			      <property name="angle">0</property>
499787d
-			    </widget>
499787d
-			    <packing>
499787d
-			      <property name="padding">0</property>
499787d
-			      <property name="expand">True</property>
499787d
-			      <property name="fill">True</property>
499787d
-			    </packing>
499787d
-			  </child>
499787d
-			</widget>
499787d
-		      </child>
499787d
-		    </widget>
499787d
-		  </child>
499787d
-
499787d
-		  <child>
499787d
-		    <widget class="GtkButton" id="restart-button">
499787d
-		      <property name="visible">True</property>
499787d
-		      <property name="can_default">True</property>
499787d
-		      <property name="has_default">True</property>
499787d
-		      <property name="can_focus">True</property>
499787d
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
499787d
-		      <property name="focus_on_click">True</property>
499787d
-
499787d
-		      <child>
499787d
-			<widget class="GtkHBox" id="hbox1">
499787d
-			  <property name="visible">True</property>
499787d
-			  <property name="homogeneous">False</property>
499787d
-			  <property name="spacing">0</property>
499787d
-
499787d
-			  <child>
499787d
-			    <widget class="GtkImage" id="image7">
499787d
-			      <property name="visible">True</property>
499787d
-			      <property name="icon_name">view-refresh</property>
499787d
-			      <property name="pixel_size">16</property>
499787d
-			      <property name="xalign">0.5</property>
499787d
-			      <property name="yalign">0.5</property>
499787d
-			      <property name="xpad">0</property>
499787d
-			      <property name="ypad">0</property>
499787d
-			    </widget>
499787d
-			    <packing>
499787d
-			      <property name="padding">0</property>
499787d
-			      <property name="expand">True</property>
499787d
-			      <property name="fill">True</property>
499787d
-			    </packing>
499787d
-			  </child>
499787d
-
499787d
-			  <child>
499787d
-			    <widget class="GtkLabel" id="label2">
499787d
-			      <property name="visible">True</property>
499787d
-			      <property name="label" translatable="yes">Restart</property>
499787d
-			      <property name="use_underline">False</property>
499787d
-			      <property name="use_markup">False</property>
499787d
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
499787d
-			      <property name="wrap">False</property>
499787d
-			      <property name="selectable">False</property>
499787d
-			      <property name="xalign">0</property>
499787d
-			      <property name="yalign">0.5</property>
499787d
-			      <property name="xpad">0</property>
499787d
-			      <property name="ypad">0</property>
499787d
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
499787d
-			      <property name="width_chars">-1</property>
499787d
-			      <property name="single_line_mode">False</property>
499787d
-			      <property name="angle">0</property>
499787d
-			    </widget>
499787d
-			    <packing>
499787d
-			      <property name="padding">0</property>
499787d
-			      <property name="expand">True</property>
499787d
-			      <property name="fill">True</property>
499787d
-			    </packing>
499787d
-			  </child>
499787d
-			</widget>
499787d
-		      </child>
499787d
-		    </widget>
499787d
-		  </child>
499787d
-
499787d
-		  <child>
499787d
-		    <widget class="GtkButton" id="shutdown-button">
499787d
-		      <property name="visible">True</property>
499787d
-		      <property name="can_default">True</property>
499787d
-		      <property name="has_default">True</property>
499787d
-		      <property name="can_focus">True</property>
499787d
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
499787d
-		      <property name="focus_on_click">True</property>
499787d
-
499787d
-		      <child>
499787d
-			<widget class="GtkHBox" id="hbox4">
499787d
-			  <property name="visible">True</property>
499787d
-			  <property name="homogeneous">False</property>
499787d
-			  <property name="spacing">0</property>
499787d
-
499787d
-			  <child>
499787d
-			    <widget class="GtkImage" id="image5">
499787d
-			      <property name="visible">True</property>
499787d
-			      <property name="icon_name">system-shutdown</property>
499787d
-			      <property name="pixel_size">16</property>
499787d
-			      <property name="xalign">0.5</property>
499787d
-			      <property name="yalign">0.5</property>
499787d
-			      <property name="xpad">0</property>
499787d
-			      <property name="ypad">0</property>
499787d
-			    </widget>
499787d
-			    <packing>
499787d
-			      <property name="padding">0</property>
499787d
-			      <property name="expand">True</property>
499787d
-			      <property name="fill">True</property>
499787d
-			    </packing>
499787d
-			  </child>
499787d
-
499787d
-			  <child>
499787d
-			    <widget class="GtkLabel" id="label10">
499787d
-			      <property name="visible">True</property>
499787d
-			      <property name="label" translatable="yes">Shut Down</property>
499787d
-			      <property name="use_underline">False</property>
499787d
-			      <property name="use_markup">False</property>
499787d
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
499787d
-			      <property name="wrap">False</property>
499787d
-			      <property name="selectable">False</property>
499787d
-			      <property name="xalign">0.5</property>
499787d
-			      <property name="yalign">0.5</property>
499787d
-			      <property name="xpad">0</property>
499787d
-			      <property name="ypad">0</property>
499787d
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
499787d
-			      <property name="width_chars">-1</property>
499787d
-			      <property name="single_line_mode">False</property>
499787d
-			      <property name="angle">0</property>
499787d
-			    </widget>
499787d
-			    <packing>
499787d
-			      <property name="padding">0</property>
499787d
-			      <property name="expand">True</property>
499787d
-			      <property name="fill">True</property>
499787d
-			    </packing>
499787d
-			  </child>
499787d
-			</widget>
499787d
-		      </child>
499787d
-		    </widget>
499787d
-		  </child>
499787d
-
499787d
-		  <child>
499787d
 		    <widget class="GtkButton" id="cancel-button">
499787d
 		      <property name="visible">True</property>
499787d
 		      <property name="can_focus">True</property>
499787d
diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
499787d
index dbdef29..dd0cb32 100644
499787d
--- a/gui/simple-greeter/gdm-greeter-panel.c
499787d
+++ b/gui/simple-greeter/gdm-greeter-panel.c
499787d
@@ -27,12 +27,22 @@
499787d
 #include <unistd.h>
499787d
 #include <string.h>
499787d
 
499787d
+#ifdef ENABLE_RBAC_SHUTDOWN
499787d
+#include <auth_attr.h>
499787d
+#include <secdb.h>
499787d
+#endif
499787d
+
499787d
 #include <glib.h>
499787d
 #include <glib/gi18n.h>
499787d
 #include <glib-object.h>
499787d
 #include <gtk/gtk.h>
499787d
 
499787d
 #include <gconf/gconf-client.h>
499787d
+#include <dbus/dbus-glib.h>
499787d
+
499787d
+#ifdef HAVE_DEVICEKIT_POWER
499787d
+#include <devkit-power-gobject/devicekit-power.h>
499787d
+#endif
499787d
 
499787d
 #include "gdm-languages.h"
499787d
 #include "gdm-layouts.h"
499787d
@@ -46,6 +56,16 @@
499787d
 
499787d
 #include "na-tray.h"
499787d
 
499787d
+#define CK_NAME              "org.freedesktop.ConsoleKit"
499787d
+#define CK_MANAGER_PATH      "/org/freedesktop/ConsoleKit/Manager"
499787d
+#define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager"
499787d
+
499787d
+#define GPM_DBUS_NAME      "org.freedesktop.PowerManagement"
499787d
+#define GPM_DBUS_PATH      "/org/freedesktop/PowerManagement"
499787d
+#define GPM_DBUS_INTERFACE "org.freedesktop.PowerManagement"
499787d
+
499787d
+#define KEY_DISABLE_RESTART_BUTTONS "/apps/gdm/simple-greeter/disable_restart_buttons"
499787d
+
499787d
 #define GDM_GREETER_PANEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_PANEL, GdmGreeterPanelPrivate))
499787d
 
499787d
 struct GdmGreeterPanelPrivate
499787d
@@ -66,11 +86,15 @@ struct GdmGreeterPanelPrivate
499787d
 
499787d
         char                   *default_session_name;
499787d
         char                   *default_language_name;
499787d
+
499787d
+        GConfClient            *client;
499787d
+        guint                   display_is_local : 1;
499787d
 };
499787d
 
499787d
 enum {
499787d
         PROP_0,
499787d
-        PROP_MONITOR
499787d
+        PROP_MONITOR,
499787d
+        PROP_DISPLAY_IS_LOCAL
499787d
 };
499787d
 
499787d
 enum {
499787d
@@ -107,6 +131,13 @@ gdm_greeter_panel_set_monitor (GdmGreeterPanel *panel,
499787d
 }
499787d
 
499787d
 static void
499787d
+_gdm_greeter_panel_set_display_is_local (GdmGreeterPanel       *panel,
499787d
+                                         gboolean               is)
499787d
+{
499787d
+        panel->priv->display_is_local = is;
499787d
+}
499787d
+
499787d
+static void
499787d
 gdm_greeter_panel_set_property (GObject        *object,
499787d
                                 guint           prop_id,
499787d
                                 const GValue   *value,
499787d
@@ -120,6 +151,9 @@ gdm_greeter_panel_set_property (GObject        *object,
499787d
         case PROP_MONITOR:
499787d
                 gdm_greeter_panel_set_monitor (self, g_value_get_int (value));
499787d
                 break;
499787d
+        case PROP_DISPLAY_IS_LOCAL:
499787d
+                _gdm_greeter_panel_set_display_is_local (self, g_value_get_boolean (value));
499787d
+                break;
499787d
         default:
499787d
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
499787d
                 break;
499787d
@@ -140,6 +174,9 @@ gdm_greeter_panel_get_property (GObject        *object,
499787d
         case PROP_MONITOR:
499787d
                 g_value_set_int (value, self->priv->monitor);
499787d
                 break;
499787d
+        case PROP_DISPLAY_IS_LOCAL:
499787d
+                g_value_set_boolean (value, self->priv->display_is_local);
499787d
+                break;
499787d
         default:
499787d
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
499787d
                 break;
499787d
@@ -477,6 +514,13 @@ gdm_greeter_panel_class_init (GdmGreeterPanelClass *klass)
499787d
                                                            G_MAXINT,
499787d
                                                            0,
499787d
                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
499787d
+        g_object_class_install_property (object_class,
499787d
+                                         PROP_DISPLAY_IS_LOCAL,
499787d
+                                         g_param_spec_boolean ("display-is-local",
499787d
+                                                               "display is local",
499787d
+                                                               "display is local",
499787d
+                                                               FALSE,
499787d
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
499787d
 
499787d
         g_type_class_add_private (klass, sizeof (GdmGreeterPanelPrivate));
499787d
 }
499787d
@@ -563,11 +607,185 @@ on_animation_tick (GdmGreeterPanel *panel,
499787d
         gtk_widget_queue_resize (GTK_WIDGET (panel));
499787d
 }
499787d
 
499787d
+static gboolean
499787d
+try_system_stop (DBusGConnection *connection,
499787d
+                 GError         **error)
499787d
+{
499787d
+        DBusGProxy      *proxy;
499787d
+        gboolean         res;
499787d
+
499787d
+        g_debug ("GdmGreeterPanel: trying to stop system");
499787d
+
499787d
+        proxy = dbus_g_proxy_new_for_name (connection,
499787d
+                                           CK_NAME,
499787d
+                                           CK_MANAGER_PATH,
499787d
+                                           CK_MANAGER_INTERFACE);
499787d
+        res = dbus_g_proxy_call_with_timeout (proxy,
499787d
+                                              "Stop",
499787d
+                                              INT_MAX,
499787d
+                                              error,
499787d
+                                              /* parameters: */
499787d
+                                              G_TYPE_INVALID,
499787d
+                                              /* return values: */
499787d
+                                              G_TYPE_INVALID);
499787d
+        return res;
499787d
+}
499787d
+
499787d
+static gboolean
499787d
+try_system_restart (DBusGConnection *connection,
499787d
+                    GError         **error)
499787d
+{
499787d
+        DBusGProxy      *proxy;
499787d
+        gboolean         res;
499787d
+
499787d
+        g_debug ("GdmGreeterPanel: trying to restart system");
499787d
+
499787d
+        proxy = dbus_g_proxy_new_for_name (connection,
499787d
+                                           CK_NAME,
499787d
+                                           CK_MANAGER_PATH,
499787d
+                                           CK_MANAGER_INTERFACE);
499787d
+        res = dbus_g_proxy_call_with_timeout (proxy,
499787d
+                                              "Restart",
499787d
+                                              INT_MAX,
499787d
+                                              error,
499787d
+                                              /* parameters: */
499787d
+                                              G_TYPE_INVALID,
499787d
+                                              /* return values: */
499787d
+                                              G_TYPE_INVALID);
499787d
+        return res;
499787d
+}
499787d
+
499787d
+static gboolean
499787d
+can_suspend (void)
499787d
+{
499787d
+        gboolean ret = FALSE;
499787d
+
499787d
+#ifdef HAVE_DEVICEKIT_POWER
499787d
+        DkpClient *dkp_client;
499787d
+
499787d
+        /* use DeviceKit-power to get data */
499787d
+        dkp_client = dkp_client_new ();
499787d
+        g_object_get (dkp_client,
499787d
+                      "can-suspend", &ret,
499787d
+                      NULL);
499787d
+        g_object_unref (dkp_client);
499787d
+#endif
499787d
+
499787d
+        return ret;
499787d
+}
499787d
+
499787d
+static void
499787d
+do_system_suspend (void)
499787d
+{
499787d
+#ifdef HAVE_DEVICEKIT_POWER
499787d
+        gboolean ret;
499787d
+        DkpClient *dkp_client;
499787d
+        GError *error = NULL;
499787d
+
499787d
+        /* use DeviceKit-power to get data */
499787d
+        dkp_client = dkp_client_new ();
499787d
+        ret = dkp_client_suspend (dkp_client, &error);
499787d
+        if (!ret) {
499787d
+                g_warning ("Couldn't suspend: %s", error->message);
499787d
+                g_error_free (error);
499787d
+                return;
499787d
+        }
499787d
+        g_object_unref (dkp_client);
499787d
+#endif
499787d
+}
499787d
+
499787d
+static void
499787d
+do_system_restart (void)
499787d
+{
499787d
+        gboolean         res;
499787d
+        GError          *error;
499787d
+        DBusGConnection *connection;
499787d
+
499787d
+        error = NULL;
499787d
+        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
499787d
+        if (connection == NULL) {
499787d
+                g_warning ("Unable to get system bus connection: %s", error->message);
499787d
+                g_error_free (error);
499787d
+                return;
499787d
+        }
499787d
+
499787d
+        res = try_system_restart (connection, &error);
499787d
+        if (!res) {
499787d
+                g_debug ("GdmGreeterPanel: unable to restart system: %s: %s",
499787d
+                         dbus_g_error_get_name (error),
499787d
+                         error->message);
499787d
+                g_error_free (error);
499787d
+        }
499787d
+}
499787d
+
499787d
+static void
499787d
+do_system_stop (void)
499787d
+{
499787d
+        gboolean         res;
499787d
+        GError          *error;
499787d
+        DBusGConnection *connection;
499787d
+
499787d
+        error = NULL;
499787d
+        connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
499787d
+        if (connection == NULL) {
499787d
+                g_warning ("Unable to get system bus connection: %s", error->message);
499787d
+                g_error_free (error);
499787d
+                return;
499787d
+        }
499787d
+
499787d
+        res = try_system_stop (connection, &error);
499787d
+        if (!res) {
499787d
+                g_debug ("GdmGreeterPanel: unable to stop system: %s: %s",
499787d
+                         dbus_g_error_get_name (error),
499787d
+                         error->message);
499787d
+                g_error_free (error);
499787d
+        }
499787d
+}
499787d
+
499787d
+static void
499787d
+do_disconnect (void)
499787d
+{
499787d
+        gtk_main_quit ();
499787d
+}
499787d
+
499787d
+static gboolean
499787d
+get_show_restart_buttons (GdmGreeterPanel *panel)
499787d
+{
499787d
+        gboolean     show;
499787d
+        GError      *error;
499787d
+
499787d
+        error = NULL;
499787d
+        show = ! gconf_client_get_bool (panel->priv->client, KEY_DISABLE_RESTART_BUTTONS, &error);
499787d
+        if (error != NULL) {
499787d
+                g_debug ("GdmGreeterPanel: unable to get disable-restart-buttons configuration: %s", error->message);
499787d
+                g_error_free (error);
499787d
+        }
499787d
+
499787d
+#ifdef ENABLE_RBAC_SHUTDOWN
499787d
+        {
499787d
+                char *username;
499787d
+
499787d
+                username = g_get_user_name ();
499787d
+                if (username == NULL || !chkauthattr (RBAC_SHUTDOWN_KEY, username)) {
499787d
+                        show = FALSE;
499787d
+                        g_debug ("GdmGreeterPanel: Not showing stop/restart buttons for user %s due to RBAC key %s",
499787d
+                                 username, RBAC_SHUTDOWN_KEY);
499787d
+                } else {
499787d
+                        g_debug ("GdmGreeterPanel: Showing stop/restart buttons for user %s due to RBAC key %s",
499787d
+                                 username, RBAC_SHUTDOWN_KEY);
499787d
+                }
499787d
+        }
499787d
+#endif
499787d
+        return show;
499787d
+}
499787d
+
499787d
 static void
499787d
 gdm_greeter_panel_init (GdmGreeterPanel *panel)
499787d
 {
499787d
         NaTray    *tray;
499787d
         GtkWidget *spacer;
499787d
+        GtkWidget *shutdown_menu;
499787d
+        GtkWidget *menu, *menu_item;
499787d
 
499787d
         gdm_profile_start (NULL);
499787d
 
499787d
@@ -603,6 +821,8 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
499787d
         spacer = gtk_label_new ("");
499787d
         gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), spacer, TRUE, TRUE, 6);
499787d
         gtk_widget_show (spacer);
499787d
+    
499787d
+        panel->priv->client = gconf_client_get_default ();
499787d
 
499787d
         gdm_profile_start ("creating option widget");
499787d
         panel->priv->language_option_widget = gdm_language_option_widget_new ();
499787d
@@ -642,6 +862,42 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
499787d
                 gtk_widget_show (panel->priv->hostname_label);
499787d
         }
499787d
 
499787d
+        if (panel->priv->display_is_local || get_show_restart_buttons (panel)) {
499787d
+                shutdown_menu = gtk_menu_bar_new ();
499787d
+
499787d
+                menu_item = gtk_image_menu_item_new ();
499787d
+                menu = gtk_menu_new ();
499787d
+                gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
499787d
+                gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menu_item), TRUE);
499787d
+                gtk_menu_item_set_label (GTK_MENU_ITEM (menu_item), "");
499787d
+                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
499787d
+                                               gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_BUTTON));
499787d
+                gtk_menu_shell_append (GTK_MENU_SHELL (shutdown_menu), menu_item);
499787d
+
499787d
+                if (panel->priv->display_is_local) {
499787d
+                        menu_item = gtk_menu_item_new_with_label ("Disconnect");
499787d
+                        g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_disconnect), NULL);
499787d
+                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
499787d
+                } else {
499787d
+                        if (can_suspend ()) {
499787d
+                                menu_item = gtk_menu_item_new_with_label ("Suspend");
499787d
+                                g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_suspend), NULL);
499787d
+                                gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
499787d
+                        }
499787d
+
499787d
+                        menu_item = gtk_menu_item_new_with_label ("Restart");
499787d
+                        g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_restart), NULL);
499787d
+                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
499787d
+
499787d
+                        menu_item = gtk_menu_item_new_with_label ("Shut Down");
499787d
+                        g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_stop), NULL);
499787d
+                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
499787d
+                }
499787d
+
499787d
+                gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (shutdown_menu), FALSE, FALSE, 0);
499787d
+                gtk_widget_show_all (GTK_WIDGET (shutdown_menu));
499787d
+        }
499787d
+
499787d
         panel->priv->clock = gdm_clock_widget_new ();
499787d
         gtk_box_pack_end (GTK_BOX (panel->priv->hbox),
499787d
                             GTK_WIDGET (panel->priv->clock), FALSE, FALSE, 6);
499787d
@@ -651,7 +907,6 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
499787d
                                        GTK_ORIENTATION_HORIZONTAL);
499787d
         gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (tray), FALSE, FALSE, 6);
499787d
         gtk_widget_show (GTK_WIDGET (tray));
499787d
-
499787d
         gdm_greeter_panel_hide_user_options (panel);
499787d
 
499787d
         panel->priv->progress = 0.0;
499787d
@@ -684,13 +939,15 @@ gdm_greeter_panel_finalize (GObject *object)
499787d
 
499787d
 GtkWidget *
499787d
 gdm_greeter_panel_new (GdkScreen *screen,
499787d
-                       int        monitor)
499787d
+                       int        monitor,
499787d
+                       gboolean   is_local)
499787d
 {
499787d
         GObject *object;
499787d
 
499787d
         object = g_object_new (GDM_TYPE_GREETER_PANEL,
499787d
                                "screen", screen,
499787d
                                "monitor", monitor,
499787d
+                               "display-is-local", is_local,                               
499787d
                                NULL);
499787d
 
499787d
         return GTK_WIDGET (object);
499787d
diff --git a/gui/simple-greeter/gdm-greeter-panel.h b/gui/simple-greeter/gdm-greeter-panel.h
499787d
index 1e637f5..625c80d 100644
499787d
--- a/gui/simple-greeter/gdm-greeter-panel.h
499787d
+++ b/gui/simple-greeter/gdm-greeter-panel.h
499787d
@@ -60,7 +60,8 @@ typedef struct
499787d
 GType                  gdm_greeter_panel_get_type                       (void);
499787d
 
499787d
 GtkWidget            * gdm_greeter_panel_new                            (GdkScreen *screen,
499787d
-                                                                         int        monitor);
499787d
+                                                                         int        monitor,
499787d
+                                                                         gboolean   is_local);
499787d
 
499787d
 void                   gdm_greeter_panel_show_user_options              (GdmGreeterPanel *panel);
499787d
 void                   gdm_greeter_panel_hide_user_options              (GdmGreeterPanel *panel);
499787d
diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
499787d
index 167b693..e7d206a 100644
499787d
--- a/gui/simple-greeter/gdm-greeter-session.c
499787d
+++ b/gui/simple-greeter/gdm-greeter-session.c
499787d
@@ -332,13 +332,15 @@ toggle_panel (GdmGreeterSession *session,
499787d
                 GdkScreen  *screen;
499787d
                 int         monitor;
499787d
                 int         x, y;
499787d
+                gboolean    is_local;
499787d
 
499787d
                 display = gdk_display_get_default ();
499787d
                 gdk_display_get_pointer (display, &screen, &x, &y, NULL);
499787d
 
499787d
                 monitor = get_tallest_monitor_at_point (screen, x, y);
499787d
 
499787d
-                session->priv->panel = gdm_greeter_panel_new (screen, monitor);
499787d
+                is_local = gdm_greeter_client_get_display_is_local (session->priv->client);
499787d
+                session->priv->panel = gdm_greeter_panel_new (screen, monitor, is_local);
499787d
 
499787d
                 g_signal_connect_swapped (session->priv->panel,
499787d
                                           "language-selected",
499787d
diff --git a/gui/simple-greeter/test-greeter-panel.c b/gui/simple-greeter/test-greeter-panel.c
499787d
index 80ef0a9..86adae3 100644
499787d
--- a/gui/simple-greeter/test-greeter-panel.c
499787d
+++ b/gui/simple-greeter/test-greeter-panel.c
499787d
@@ -53,7 +53,7 @@ main (int argc, char *argv[])
499787d
         gdk_display_get_pointer (display, &screen, &x, &y, NULL);
499787d
         monitor = gdk_screen_get_monitor_at_point (screen, x, y);
499787d
 
499787d
-        panel = gdm_greeter_panel_new (screen, monitor);
499787d
+        panel = gdm_greeter_panel_new (screen, monitor, TRUE);
499787d
         gdm_greeter_panel_show_user_options (GDM_GREETER_PANEL (panel));
499787d
 
499787d
         gtk_widget_show (panel);
499787d
-- 
499787d
1.6.5.rc2
499787d
499787d
499787d
From 4ee17e4732cbdc4c91e93da732de6849c4f95a86 Mon Sep 17 00:00:00 2001
499787d
From: Ray Strode <rstrode@redhat.com>
499787d
Date: Tue, 20 Oct 2009 17:06:58 -0400
499787d
Subject: [PATCH 2/3] Use button instead of menu bar
499787d
499787d
The menu bar isn't a great fit for the panel
499787d
---
499787d
 gui/simple-greeter/gdm-greeter-panel.c |   81 +++++++++++++++++++++++++-------
499787d
 1 files changed, 64 insertions(+), 17 deletions(-)
499787d
499787d
diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
499787d
index dd0cb32..d5dd820 100644
499787d
--- a/gui/simple-greeter/gdm-greeter-panel.c
499787d
+++ b/gui/simple-greeter/gdm-greeter-panel.c
499787d
@@ -77,6 +77,8 @@ struct GdmGreeterPanelPrivate
499787d
         GtkWidget              *option_hbox;
499787d
         GtkWidget              *hostname_label;
499787d
         GtkWidget              *clock;
499787d
+        GtkWidget              *shutdown_button;
499787d
+        GtkWidget              *shutdown_menu;
499787d
         GtkWidget              *language_option_widget;
499787d
         GtkWidget              *layout_option_widget;
499787d
         GtkWidget              *session_option_widget;
499787d
@@ -780,12 +782,48 @@ get_show_restart_buttons (GdmGreeterPanel *panel)
499787d
 }
499787d
 
499787d
 static void
499787d
+position_shutdown_menu (GtkMenu         *menu,
499787d
+                        int             *x,
499787d
+                        int             *y,
499787d
+                        gboolean        *push_in,
499787d
+                        GdmGreeterPanel *panel)
499787d
+{
499787d
+        GtkRequisition menu_requisition;
499787d
+
499787d
+        *push_in = TRUE;
499787d
+
499787d
+        *x = panel->priv->shutdown_button->allocation.x;
499787d
+        gtk_window_get_position (GTK_WINDOW (panel), NULL, y);
499787d
+
499787d
+        gtk_widget_size_request (GTK_WIDGET (menu), &menu_requisition);
499787d
+
499787d
+        *y -= menu_requisition.height;
499787d
+}
499787d
+
499787d
+static void
499787d
+on_shutdown_button_toggled (GdmGreeterPanel *panel)
499787d
+{
499787d
+        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (panel->priv->shutdown_button))) {
499787d
+                gtk_menu_popup (GTK_MENU (panel->priv->shutdown_menu), NULL, NULL,
499787d
+                                (GtkMenuPositionFunc) position_shutdown_menu,
499787d
+                                panel, 0, 0);
499787d
+        } else {
499787d
+                gtk_menu_popdown (GTK_MENU (panel->priv->shutdown_menu));
499787d
+        }
499787d
+}
499787d
+
499787d
+static void
499787d
+on_shutdown_menu_deactivate (GdmGreeterPanel *panel)
499787d
+{
499787d
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->priv->shutdown_button),
499787d
+                                      FALSE);
499787d
+}
499787d
+
499787d
+static void
499787d
 gdm_greeter_panel_init (GdmGreeterPanel *panel)
499787d
 {
499787d
         NaTray    *tray;
499787d
         GtkWidget *spacer;
499787d
-        GtkWidget *shutdown_menu;
499787d
-        GtkWidget *menu, *menu_item;
499787d
 
499787d
         gdm_profile_start (NULL);
499787d
 
499787d
@@ -863,39 +901,48 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
499787d
         }
499787d
 
499787d
         if (panel->priv->display_is_local || get_show_restart_buttons (panel)) {
499787d
-                shutdown_menu = gtk_menu_bar_new ();
499787d
+                GtkWidget *menu_item;
499787d
+                GtkWidget *image;
499787d
+
499787d
+                panel->priv->shutdown_button = gtk_toggle_button_new ();
499787d
+                gtk_button_set_relief (GTK_BUTTON (panel->priv->shutdown_button),
499787d
+                                       GTK_RELIEF_NONE);
499787d
+
499787d
+                panel->priv->shutdown_menu = gtk_menu_new ();
499787d
+                gtk_menu_attach_to_widget (GTK_MENU (panel->priv->shutdown_menu),
499787d
+                                           panel->priv->shutdown_button, NULL);
499787d
+                g_signal_connect_swapped (panel->priv->shutdown_button, "toggled",
499787d
+                                          G_CALLBACK (on_shutdown_button_toggled), panel);
499787d
+                g_signal_connect_swapped (panel->priv->shutdown_menu, "deactivate",
499787d
+                                          G_CALLBACK (on_shutdown_menu_deactivate), panel);
499787d
 
499787d
-                menu_item = gtk_image_menu_item_new ();
499787d
-                menu = gtk_menu_new ();
499787d
-                gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
499787d
-                gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menu_item), TRUE);
499787d
-                gtk_menu_item_set_label (GTK_MENU_ITEM (menu_item), "");
499787d
-                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
499787d
-                                               gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_BUTTON));
499787d
-                gtk_menu_shell_append (GTK_MENU_SHELL (shutdown_menu), menu_item);
499787d
+                image = gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_BUTTON);
499787d
+                gtk_widget_show (image);
499787d
+                gtk_container_add (GTK_CONTAINER (panel->priv->shutdown_button), image);
499787d
 
499787d
                 if (panel->priv->display_is_local) {
499787d
                         menu_item = gtk_menu_item_new_with_label ("Disconnect");
499787d
                         g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_disconnect), NULL);
499787d
-                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
499787d
+                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
499787d
                 } else {
499787d
                         if (can_suspend ()) {
499787d
                                 menu_item = gtk_menu_item_new_with_label ("Suspend");
499787d
                                 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_suspend), NULL);
499787d
-                                gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
499787d
+                                gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
499787d
                         }
499787d
 
499787d
                         menu_item = gtk_menu_item_new_with_label ("Restart");
499787d
                         g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_restart), NULL);
499787d
-                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
499787d
+                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
499787d
 
499787d
                         menu_item = gtk_menu_item_new_with_label ("Shut Down");
499787d
                         g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_stop), NULL);
499787d
-                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
499787d
+                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
499787d
                 }
499787d
 
499787d
-                gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (shutdown_menu), FALSE, FALSE, 0);
499787d
-                gtk_widget_show_all (GTK_WIDGET (shutdown_menu));
499787d
+                gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (panel->priv->shutdown_button), FALSE, FALSE, 0);
499787d
+                gtk_widget_show_all (panel->priv->shutdown_menu);
499787d
+                gtk_widget_show_all (GTK_WIDGET (panel->priv->shutdown_button));
499787d
         }
499787d
 
499787d
         panel->priv->clock = gdm_clock_widget_new ();
499787d
-- 
499787d
1.6.5.rc2
499787d
499787d
499787d
From 4c206142ddb22315d9beb42eae9d868f449bdf11 Mon Sep 17 00:00:00 2001
499787d
From: Ray Strode <rstrode@redhat.com>
499787d
Date: Tue, 20 Oct 2009 17:23:15 -0400
499787d
Subject: [PATCH 3/3] Mark Shutdown, Restart, and Suspend for translation
499787d
499787d
---
499787d
 gui/simple-greeter/gdm-greeter-panel.c |    6 +++---
499787d
 1 files changed, 3 insertions(+), 3 deletions(-)
499787d
499787d
diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
499787d
index d5dd820..016f636 100644
499787d
--- a/gui/simple-greeter/gdm-greeter-panel.c
499787d
+++ b/gui/simple-greeter/gdm-greeter-panel.c
499787d
@@ -926,16 +926,16 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
499787d
                         gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
499787d
                 } else {
499787d
                         if (can_suspend ()) {
499787d
-                                menu_item = gtk_menu_item_new_with_label ("Suspend");
499787d
+                                menu_item = gtk_menu_item_new_with_label (_("Suspend"));
499787d
                                 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_suspend), NULL);
499787d
                                 gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
499787d
                         }
499787d
 
499787d
-                        menu_item = gtk_menu_item_new_with_label ("Restart");
499787d
+                        menu_item = gtk_menu_item_new_with_label (_("Restart"));
499787d
                         g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_restart), NULL);
499787d
                         gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
499787d
 
499787d
-                        menu_item = gtk_menu_item_new_with_label ("Shut Down");
499787d
+                        menu_item = gtk_menu_item_new_with_label (_("Shut Down"));
499787d
                         g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_stop), NULL);
499787d
                         gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
499787d
                 }
499787d
-- 
499787d
1.6.5.rc2
499787d
499787d
From 7fbb5c0dec8aa42b1d8985c6f62be02c035175da Mon Sep 17 00:00:00 2001
499787d
From: Ray Strode <rstrode@redhat.com>
499787d
Date: Mon, 26 Oct 2009 15:00:43 -0400
499787d
Subject: [PATCH] Position shutdown menu better in multi-monitor displays
499787d
499787d
---
499787d
 gui/simple-greeter/gdm-greeter-panel.c |   13 ++++++++++++-
499787d
 1 files changed, 12 insertions(+), 1 deletions(-)
499787d
499787d
diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
499787d
index 43b91d5..caade7a 100644
499787d
--- a/gui/simple-greeter/gdm-greeter-panel.c
499787d
+++ b/gui/simple-greeter/gdm-greeter-panel.c
499787d
@@ -790,10 +790,21 @@ position_shutdown_menu (GtkMenu         *menu,
499787d
                         GdmGreeterPanel *panel)
499787d
 {
499787d
         GtkRequisition menu_requisition;
499787d
+        GdkScreen *screen;
499787d
+        int monitor;
499787d
 
499787d
         *push_in = TRUE;
499787d
 
499787d
-        *x = panel->priv->shutdown_button->allocation.x;
499787d
+        screen = gtk_widget_get_screen (GTK_WIDGET (panel));
499787d
+        monitor = gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (panel)->window);
499787d
+        gtk_menu_set_monitor (menu, monitor);
499787d
+
499787d
+        gtk_widget_translate_coordinates (GTK_WIDGET (panel->priv->shutdown_button),
499787d
+                                          GTK_WIDGET (panel),
499787d
+                                          panel->priv->shutdown_button->allocation.x,
499787d
+                                          panel->priv->shutdown_button->allocation.y,
499787d
+                                          x, y);
499787d
+
499787d
         gtk_window_get_position (GTK_WINDOW (panel), NULL, y);
499787d
 
499787d
         gtk_widget_size_request (GTK_WIDGET (menu), &menu_requisition);
499787d
-- 
499787d
1.6.5.1
499787d