[gnome-session/wip/cleanups: 8/15] Make the fallback end session dialog a separate program



commit 940cbe6c9acba5df3d2724b24d3fb0e3732fa133
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Nov 11 18:07:29 2012 -0500

    Make the fallback end session dialog a separate program
    
    Turn GsmInhibitDialog into a standalone program that provides
    the same EndSessionDialog D-Bus interface as gnome-shell. This
    also combines the roles of the inhibit and logout dialogs, so
    there is no separate fallback logout dialog anymore.

 gnome-session/Makefile.am                          |   38 ++-
 gnome-session/gsm-end-session-dialog.c             |  168 +++++++
 gnome-session/gsm-inhibit-dialog.c                 |  476 ++++++++++++--------
 gnome-session/gsm-inhibit-dialog.h                 |    7 +-
 .../org.gnome.SessionManager.EndSessionDialog.xml  |   53 +++
 5 files changed, 556 insertions(+), 186 deletions(-)
---
diff --git a/gnome-session/Makefile.am b/gnome-session/Makefile.am
index beaf51a..0067c75 100644
--- a/gnome-session/Makefile.am
+++ b/gnome-session/Makefile.am
@@ -1,5 +1,5 @@
 bin_PROGRAMS = gnome-session
-libexec_PROGRAMS = gnome-session-failed
+libexec_PROGRAMS = gnome-session-failed gnome-session-end-dialog
 noinst_LTLIBRARIES = libgsmutil.la
 noinst_PROGRAMS = 		\
 	test-client-dbus	\
@@ -69,8 +69,8 @@ gnome_session_CPPFLAGS =			\
 	$(SYSTEMD_CFLAGS)			\
 	-I$(top_srcdir)/egg			\
 	-DLOCALE_DIR=\""$(datadir)/locale"\"	\
+	-DLIBEXECDIR=\"$(libexecdir)\"		\
 	-DDATA_DIR=\""$(datadir)/gnome-session"\" \
-	-DGTKBUILDER_DIR=\""$(pkgdatadir)"\"	\
 	-DGCONF_SANITY_CHECK=\""$(GCONF_SANITY_CHECK)"\" \
 	-DGCONFTOOL_CMD=\"$(GCONFTOOL)\"
 
@@ -88,8 +88,7 @@ gnome_session_LDADD =				\
 	$(EXECINFO_LIBS)
 
 libgsmutil_la_CPPFLAGS =			\
-	$(AM_CPPFLAGS)				\
-	-DLIBEXECDIR=\"$(libexecdir)\"
+	$(AM_CPPFLAGS)
 
 libgsmutil_la_SOURCES =				\
 	gsm-util.c				\
@@ -110,6 +109,25 @@ gnome_session_failed_CPPFLAGS = \
 gnome_session_failed_LDADD = 	\
 	$(GTK3_LIBS)
 
+gnome_session_end_dialog_SOURCES = \
+	gsm-inhibit-dialog.c \
+	gsm-inhibit-dialog.h \
+	gsm-end-session-dialog-generated.c \
+	gsm-end-session-dialog-generated.h \
+	gsm-end-session-dialog.c
+
+gnome_session_end_dialog_CPPFLAGS = \
+	-I$(top_srcdir)/egg			\
+	-DGTKBUILDER_DIR=\""$(pkgdatadir)"\"	\
+	$(XRENDER_CFLAGS)			\
+	$(GTK3_CFLAGS)
+
+gnome_session_end_dialog_LDADD = \
+	libgsmutil.la 				\
+	$(top_builddir)/egg/libeggdesktopfile.la \
+	$(XRENDER_LIBS)				 \
+	$(GTK3_LIBS)
+
 test_inhibit_SOURCES = test-inhibit.c
 test_inhibit_LDADD = $(GNOME_SESSION_LIBS)
 
@@ -134,12 +152,22 @@ gsm-inhibitor-glue.h: org.gnome.SessionManager.Inhibitor.xml Makefile.am
 gsm-presence-glue.h: org.gnome.SessionManager.Presence.xml Makefile.am
 	$(AM_V_GEN)dbus-binding-tool --prefix=gsm_presence --mode=glib-server --output=gsm-presence-glue.h $(srcdir)/org.gnome.SessionManager.Presence.xml
 
+gsm-end-session-dialog-generated.h:
+gsm-end-session-dialog-generated.c: org.gnome.SessionManager.EndSessionDialog.xml Makefile.am
+	$(AM_V_GEN) gdbus-codegen \
+		--interface-prefix=org.gnome.SessionManager \
+		--generate-c-code gsm-end-session-dialog-generated \
+		--c-namespace Gsm \
+		org.gnome.SessionManager.EndSessionDialog.xml
+
 BUILT_SOURCES =			\
 	gsm-manager-glue.h	\
 	gsm-presence-glue.h	\
 	gsm-inhibitor-glue.h	\
 	gsm-client-glue.h	\
-	gsm-app-glue.h
+	gsm-app-glue.h		\
+	gsm-end-session-dialog-generated.h \
+	gsm-end-session-dialog-generated.c
 
 EXTRA_DIST =						\
 	README						\
diff --git a/gnome-session/gsm-end-session-dialog.c b/gnome-session/gsm-end-session-dialog.c
new file mode 100644
index 0000000..a09cebf
--- /dev/null
+++ b/gnome-session/gsm-end-session-dialog.c
@@ -0,0 +1,168 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ *      Matthias Clasen
+ */
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+
+#include "gsm-inhibit-dialog.h"
+#include "gsm-end-session-dialog-generated.h"
+
+static GtkWidget *
+gsm_end_session_dialog_new (guint               action,
+                            guint               seconds,
+                            const gchar *const *inhibitor_paths)
+{
+        GtkWidget *dialog;
+
+        dialog = gsm_inhibit_dialog_new (action, seconds, inhibitor_paths);
+
+        return dialog;
+}
+
+static void
+inhibit_dialog_response (GsmInhibitDialog    *dialog,
+                         guint                response_id,
+                         GsmEndSessionDialog *object)
+{
+        int action;
+
+        g_object_get (dialog, "action", &action, NULL);
+        gtk_widget_destroy (GTK_WIDGET (dialog));
+
+        switch (response_id) {
+        case GTK_RESPONSE_CANCEL:
+        case GTK_RESPONSE_NONE:
+        case GTK_RESPONSE_DELETE_EVENT:
+                if (action == GSM_LOGOUT_ACTION_LOGOUT
+                    || action == GSM_LOGOUT_ACTION_SHUTDOWN
+                    || action == GSM_LOGOUT_ACTION_REBOOT) {
+                        g_print ("cancel action %d\n", action);
+                        gsm_end_session_dialog_emit_canceled (object);
+                        gsm_end_session_dialog_emit_closed (object);
+                }
+                break;
+        case GTK_RESPONSE_ACCEPT:
+                g_print ("confirm action %d\n", action);
+                if (action == GSM_LOGOUT_ACTION_LOGOUT) {
+                        gsm_end_session_dialog_emit_confirmed_logout (object);
+                } else if (action == GSM_LOGOUT_ACTION_SHUTDOWN) {
+                        gsm_end_session_dialog_emit_confirmed_shutdown (object);
+                } else if (action == GSM_LOGOUT_ACTION_REBOOT) {
+                        gsm_end_session_dialog_emit_confirmed_reboot (object);
+                }
+                break;
+        default:
+                g_assert_not_reached ();
+                break;
+        }
+}
+
+static gboolean
+handle_open (GsmEndSessionDialog   *object,
+             GDBusMethodInvocation *invocation,
+             guint                  arg_type,
+             guint                  arg_timestamp,
+             guint                  arg_seconds_to_stay_open,
+             const gchar *const    *arg_inhibitor_object_paths,
+             gpointer               user_data)
+{
+        GtkWidget *dialog;
+
+        g_print ("handle open\n");
+
+        dialog = gsm_end_session_dialog_new (arg_type, arg_seconds_to_stay_open, arg_inhibitor_object_paths);
+
+        g_signal_connect (dialog, "response",
+                          G_CALLBACK (inhibit_dialog_response), object);
+
+        gtk_window_present_with_time (GTK_WINDOW (dialog), arg_timestamp);
+
+        gsm_end_session_dialog_complete_open (object, invocation);
+
+        return TRUE;
+}
+
+static void
+on_bus_acquired (GDBusConnection *connection,
+                 const gchar     *name,
+                 gpointer         user_data)
+{
+        GDBusInterfaceSkeleton *iface;
+        GError *error = NULL;
+
+        g_print ("Acquired a message bus connection\n");
+
+        iface = G_DBUS_INTERFACE_SKELETON (gsm_end_session_dialog_skeleton_new ());
+        g_signal_connect (iface, "handle-open",
+                          G_CALLBACK (handle_open), NULL);
+
+        if (!g_dbus_interface_skeleton_export (iface,
+                                               connection,
+                                               "/org/gnome/SessionManager/EndSessionDialog",
+                                               &error)) {
+                g_warning ("Failed to export interface: %s", error->message);
+                g_error_free (error);
+                return;
+        }
+}
+
+static void
+on_name_acquired (GDBusConnection *connection,
+                  const gchar     *name,
+                  gpointer         user_data)
+{
+        g_print ("Acquired the name %s\n", name);
+}
+
+static void
+on_name_lost (GDBusConnection *connection,
+              const gchar     *name,
+              gpointer         user_data)
+{
+        g_print ("Lost the name %s\n", name);
+}
+
+gint
+main (gint argc, gchar *argv[])
+{
+        guint id;
+
+        gtk_init (&argc, &argv);
+
+        id = g_bus_own_name (G_BUS_TYPE_SESSION,
+                             "org.gnome.SessionManager.EndSessionDialog",
+                             G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+                             G_BUS_NAME_OWNER_FLAGS_REPLACE,
+                             on_bus_acquired,
+                             on_name_acquired,
+                             on_name_lost,
+                             NULL,
+                             NULL);
+
+        gtk_main ();
+
+        g_bus_unown_name (id);
+
+        return 0;
+}
diff --git a/gnome-session/gsm-inhibit-dialog.c b/gnome-session/gsm-inhibit-dialog.c
index e2c39de..71d49a6 100644
--- a/gnome-session/gsm-inhibit-dialog.c
+++ b/gnome-session/gsm-inhibit-dialog.c
@@ -36,7 +36,6 @@
 #include "gsm-store.h"
 #include "gsm-client.h"
 #include "gsm-icon-names.h"
-#include "gsm-inhibitor.h"
 #include "eggdesktopfile.h"
 #include "gsm-util.h"
 
@@ -62,9 +61,10 @@ struct GsmInhibitDialogPrivate
 {
         GtkBuilder        *xml;
         int                action;
+        int                timeout;
+        guint              timeout_id;
         gboolean           is_done;
-        GsmStore          *inhibitors;
-        GsmStore          *clients;
+        const char *const *inhibitor_paths;
         GtkListStore      *list_store;
         gboolean           have_xrender;
         int                xrender_event_base;
@@ -74,8 +74,8 @@ struct GsmInhibitDialogPrivate
 enum {
         PROP_0,
         PROP_ACTION,
-        PROP_INHIBITOR_STORE,
-        PROP_CLIENT_STORE
+        PROP_TIMEOUT,
+        PROP_INHIBITOR_PATHS
 };
 
 enum {
@@ -83,6 +83,7 @@ enum {
         INHIBIT_NAME_COLUMN,
         INHIBIT_REASON_COLUMN,
         INHIBIT_ID_COLUMN,
+        INHIBIT_PROXY_COLUMN,
         NUMBER_OF_COLUMNS
 };
 
@@ -132,6 +133,21 @@ gsm_inhibit_dialog_set_action (GsmInhibitDialog *dialog,
         dialog->priv->action = action;
 }
 
+static void
+gsm_inhibit_dialog_set_timeout (GsmInhibitDialog *dialog,
+                                int               timeout)
+{
+        dialog->priv->timeout = timeout;
+}
+
+static void
+gsm_inhibit_dialog_set_inhibitor_paths (GsmInhibitDialog  *dialog,
+                                        const char *const *paths)
+{
+        dialog->priv->inhibitor_paths = (const char *const*)g_strdupv ((gchar **)paths);
+}
+
+#if 0
 static gboolean
 find_inhibitor (GsmInhibitDialog *dialog,
                 const char       *id,
@@ -166,6 +182,7 @@ find_inhibitor (GsmInhibitDialog *dialog,
 
         return found_item;
 }
+#endif
 
 /* copied from gnome-panel panel-util.c */
 static char *
@@ -448,14 +465,70 @@ get_pixbuf_for_window (GdkDisplay *gdkdisplay,
         return pixbuf;
 }
 
+static gchar *
+inhibitor_get_app_id (GDBusProxy *proxy)
+{
+        GError *error = NULL;
+        GVariant *res;
+        gchar *app_id;
+
+        res = g_dbus_proxy_call_sync (proxy, "GetAppId", NULL, 0, G_MAXINT, NULL, &error);
+        if (res == NULL) {
+                g_warning ("Failed to get Inhibitor app id: %s", error->message);
+                g_error_free (error);
+                return NULL;
+        }
+        g_variant_get (res, "(s)", &app_id);
+        g_variant_unref (res);
+
+        return app_id;
+}
+
+static gchar *
+inhibitor_get_reason (GDBusProxy *proxy)
+{
+        GError *error = NULL;
+        GVariant *res;
+        gchar *reason;
+
+        res = g_dbus_proxy_call_sync (proxy, "GetReason", NULL, 0, G_MAXINT, NULL, &error);
+        if (res == NULL) {
+                g_warning ("Failed to get Inhibitor reason: %s", error->message);
+                g_error_free (error);
+                return NULL;
+        }
+        g_variant_get (res, "(s)", &reason);
+        g_variant_unref (res);
+
+        return reason;
+}
+
+static guint
+inhibitor_get_xid (GDBusProxy *proxy)
+{
+        GError *error = NULL;
+        GVariant *res;
+        guint xid;
+
+        res = g_dbus_proxy_call_sync (proxy, "GetToplevelXid", NULL, 0, G_MAXINT, NULL, &error);
+        if (res == NULL) {
+                g_warning ("Failed to get Inhibitor xid: %s", error->message);
+                g_error_free (error);
+                return 0;
+        }
+        g_variant_get (res, "(u)", &xid);
+        g_variant_unref (res);
+
+        return xid;
+}
 static void
 add_inhibitor (GsmInhibitDialog *dialog,
-               GsmInhibitor     *inhibitor)
+               GDBusProxy       *inhibitor)
 {
         GdkDisplay     *gdkdisplay;
         const char     *name;
         const char     *icon_name;
-        const char     *app_id;
+        char           *app_id;
         char           *desktop_filename;
         GdkPixbuf      *pixbuf;
         EggDesktopFile *desktop_file;
@@ -463,6 +536,7 @@ add_inhibitor (GsmInhibitDialog *dialog,
         char          **search_dirs;
         guint           xid;
         char           *freeme;
+        gchar          *reason;
 
         gdkdisplay = gtk_widget_get_display (GTK_WIDGET (dialog));
 
@@ -473,7 +547,9 @@ add_inhibitor (GsmInhibitDialog *dialog,
         pixbuf = NULL;
         freeme = NULL;
 
-        app_id = gsm_inhibitor_peek_app_id (inhibitor);
+        app_id = inhibitor_get_app_id (inhibitor);
+        reason = inhibitor_get_reason (inhibitor);
+        xid = inhibitor_get_xid (inhibitor);
 
         if (IS_STRING_EMPTY (app_id)) {
                 desktop_filename = NULL;
@@ -483,7 +559,6 @@ add_inhibitor (GsmInhibitDialog *dialog,
                 desktop_filename = g_strdup (app_id);
         }
 
-        xid = gsm_inhibitor_peek_toplevel_xid (inhibitor);
         g_debug ("GsmInhibitDialog: inhibitor has XID %u", xid);
         if (xid > 0 && dialog->priv->have_xrender) {
                 pixbuf = get_pixbuf_for_window (gdkdisplay, xid, DEFAULT_SNAPSHOT_SIZE, DEFAULT_SNAPSHOT_SIZE);
@@ -567,20 +642,6 @@ add_inhibitor (GsmInhibitDialog *dialog,
                 }
         }
 
-        /* try client info */
-        if (name == NULL) {
-                const char *client_id;
-                client_id = gsm_inhibitor_peek_client_id (inhibitor);
-                if (! IS_STRING_EMPTY (client_id)) {
-                        GsmClient *client;
-                        client = GSM_CLIENT (gsm_store_lookup (dialog->priv->clients, client_id));
-                        if (client != NULL) {
-                                freeme = gsm_client_get_app_name (client);
-                                name = freeme;
-                        }
-                }
-        }
-
         if (name == NULL) {
                 if (! IS_STRING_EMPTY (app_id)) {
                         name = app_id;
@@ -602,66 +663,142 @@ add_inhibitor (GsmInhibitDialog *dialog,
                                            NULL, 0,
                                            INHIBIT_IMAGE_COLUMN, pixbuf,
                                            INHIBIT_NAME_COLUMN, name,
-                                           INHIBIT_REASON_COLUMN, gsm_inhibitor_peek_reason (inhibitor),
-                                           INHIBIT_ID_COLUMN, gsm_inhibitor_peek_id (inhibitor),
+                                           INHIBIT_REASON_COLUMN, reason,
+                                           INHIBIT_ID_COLUMN, g_dbus_proxy_get_object_path (inhibitor),
+                                           INHIBIT_PROXY_COLUMN, inhibitor,
                                            -1);
 
         g_free (desktop_filename);
         g_free (freeme);
         g_clear_object (&pixbuf);
         g_clear_pointer (&desktop_file, egg_desktop_file_free);
+
+        g_free (app_id);
+        g_free (reason);
 }
 
 static gboolean
-model_has_one_entry (GtkTreeModel *model)
+model_is_empty (GtkTreeModel *model)
 {
-        guint n_rows;
+        gint n;
 
-        n_rows = gtk_tree_model_iter_n_children (model, NULL);
-        g_debug ("Model has %d rows", n_rows);
-
-        return (n_rows > 0 && n_rows < 2);
+        n = gtk_tree_model_iter_n_children (model, NULL);
+        g_print ("model rows: %d\n", n);
+        return n == 0;
 }
 
+static void gsm_inhibit_dialog_start_timer (GsmInhibitDialog *dialog);
+static void gsm_inhibit_dialog_stop_timer (GsmInhibitDialog *dialog);
+
 static void
 update_dialog_text (GsmInhibitDialog *dialog)
 {
-        const char *description_text;
         const char *header_text;
+        gchar *description_text;
         GtkWidget  *widget;
+        gchar *title;
+        const gchar *user;
+        gchar *markup;
+        gboolean inhibited;
+        gint seconds;
+
+        user = g_get_real_name ();
+        inhibited = !model_is_empty (GTK_TREE_MODEL (dialog->priv->list_store));
+
+        g_print ("update dialog text: inhibited %d\n", inhibited);
+
+        if (inhibited) {
+                gsm_inhibit_dialog_stop_timer (dialog);
+        }
+        else {
+                gsm_inhibit_dialog_start_timer (dialog);
+        }
 
-        if (model_has_one_entry (GTK_TREE_MODEL (dialog->priv->list_store))) {
-                g_debug ("Found one entry in model");
-                header_text = _("A program is still running:");
-                description_text = _("Waiting for the program to finish.  Interrupting the program may cause you to lose work.");
+        if (dialog->priv->timeout <= 30) {
+                seconds = dialog->priv->timeout;
         } else {
-                g_debug ("Found multiple entries (or none) in model");
-                header_text = _("Some programs are still running:");
-                description_text = _("Waiting for programs to finish.  Interrupting these programs may cause you to lose work.");
+                seconds = (dialog->priv->timeout / 10) * 10;
+                if (dialog->priv->timeout % 10) {
+                        seconds += 10;
+                }
         }
 
-        widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
-                                                     "header-label"));
-        if (widget != NULL) {
-                char *markup;
+        if (dialog->priv->action == GSM_LOGOUT_ACTION_LOGOUT) {
+                title = g_strdup_printf (_("Log Out %s"), user);
+                if (inhibited) {
+                        header_text = _("Some applications are still running:");
+                        description_text = g_strdup (_("Click Log Out to quit these applications and log out of the system."));
+                } else {
+                        header_text = NULL;
+                        description_text = g_strdup_printf (ngettext ("%s will be logged out automatically in %d second.",
+                                                                      "%s will be logged out automatically in %d seconds.", seconds), user, seconds);
+                }
+        } else if (dialog->priv->action == GSM_LOGOUT_ACTION_SHUTDOWN) {
+                title = g_strdup_printf (_("Power Off"));
+                if (inhibited) {
+                        header_text = _("Some applications are still running:");
+                        description_text = g_strdup (_("Click Power Off to quit these applications and power off the system."));
+                } else {
+                        header_text = NULL;
+                        description_text = g_strdup_printf (ngettext ("The system will power off automatically in %d second.",
+                                                                      "The system will power off automatically in %d seconds.", seconds), seconds);
+                }
+        } else if (dialog->priv->action == GSM_LOGOUT_ACTION_REBOOT) {
+                title = g_strdup_printf (_("Restart"));
+                if (inhibited) {
+                        header_text = _("Some applications are still running:");
+                        description_text = g_strdup (_("Click Restart to quit these applications and restart the system."));
+                } else {
+                        header_text = NULL;
+                        description_text = g_strdup_printf (ngettext ("The system will restart automatically in %d second.",
+                                                                      "The system will restart automatically in %d seconds.", seconds), seconds);
+                }
+        }
+        else {
+                title = g_strdup ("");
+                if (inhibited) {
+                        header_text = _("Some applications are still running:");
+                        description_text = g_strdup (_("Waiting for these application to finish.  Interrupting them can lead to loss of data."));
+
+                } else {
+                        header_text = NULL;
+                        description_text = g_strdup_printf (ngettext ("The action will proceed automatically in %d second.",
+                                                                      "The action will proceed automatically in %d seconds.", seconds), seconds);
+                }
+        }
+
+        gtk_window_set_title (GTK_WINDOW (dialog), title);
+
+        widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml, "header-label"));
+        if (header_text) {
                 markup = g_strdup_printf ("<b>%s</b>", header_text);
                 gtk_label_set_markup (GTK_LABEL (widget), markup);
                 g_free (markup);
+                gtk_widget_show (widget);
+        } else {
+                gtk_widget_hide (widget);
         }
 
-        widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
-                                                     "description-label"));
-        if (widget != NULL) {
-                gtk_label_set_text (GTK_LABEL (widget), description_text);
+        widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml, "scrolledwindow1"));
+        if (inhibited) {
+                gtk_widget_show (widget);
+        } else {
+                gtk_widget_hide (widget);
         }
+
+        widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml, "description-label"));
+        gtk_label_set_text (GTK_LABEL (widget), description_text);
+
+        g_free (description_text);
+        g_free (title);
 }
 
+#if 0
 static void
 on_store_inhibitor_added (GsmStore          *store,
                           const char        *id,
                           GsmInhibitDialog  *dialog)
 {
-        GsmInhibitor *inhibitor;
         GtkTreeIter   iter;
 
         g_debug ("GsmInhibitDialog: inhibitor added: %s", id);
@@ -704,61 +841,7 @@ on_store_inhibitor_removed (GsmStore          *store,
                 gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
         }
 }
-
-static void
-gsm_inhibit_dialog_set_inhibitor_store (GsmInhibitDialog *dialog,
-                                        GsmStore         *store)
-{
-        g_return_if_fail (GSM_IS_INHIBIT_DIALOG (dialog));
-
-        if (store != NULL) {
-                g_object_ref (store);
-        }
-
-        if (dialog->priv->inhibitors != NULL) {
-                g_signal_handlers_disconnect_by_func (dialog->priv->inhibitors,
-                                                      on_store_inhibitor_added,
-                                                      dialog);
-                g_signal_handlers_disconnect_by_func (dialog->priv->inhibitors,
-                                                      on_store_inhibitor_removed,
-                                                      dialog);
-
-                g_object_unref (dialog->priv->inhibitors);
-        }
-
-
-        g_debug ("GsmInhibitDialog: setting store %p", store);
-
-        dialog->priv->inhibitors = store;
-
-        if (dialog->priv->inhibitors != NULL) {
-                g_signal_connect (dialog->priv->inhibitors,
-                                  "added",
-                                  G_CALLBACK (on_store_inhibitor_added),
-                                  dialog);
-                g_signal_connect (dialog->priv->inhibitors,
-                                  "removed",
-                                  G_CALLBACK (on_store_inhibitor_removed),
-                                  dialog);
-        }
-}
-
-static void
-gsm_inhibit_dialog_set_client_store (GsmInhibitDialog *dialog,
-                                     GsmStore         *store)
-{
-        g_return_if_fail (GSM_IS_INHIBIT_DIALOG (dialog));
-
-        if (store != NULL) {
-                g_object_ref (store);
-        }
-
-        if (dialog->priv->clients != NULL) {
-                g_object_unref (dialog->priv->clients);
-        }
-
-        dialog->priv->clients = store;
-}
+#endif
 
 static void
 gsm_inhibit_dialog_set_property (GObject        *object,
@@ -772,11 +855,11 @@ gsm_inhibit_dialog_set_property (GObject        *object,
         case PROP_ACTION:
                 gsm_inhibit_dialog_set_action (dialog, g_value_get_int (value));
                 break;
-        case PROP_INHIBITOR_STORE:
-                gsm_inhibit_dialog_set_inhibitor_store (dialog, g_value_get_object (value));
+        case PROP_TIMEOUT:
+                gsm_inhibit_dialog_set_timeout (dialog, g_value_get_int (value));
                 break;
-        case PROP_CLIENT_STORE:
-                gsm_inhibit_dialog_set_client_store (dialog, g_value_get_object (value));
+        case PROP_INHIBITOR_PATHS:
+                gsm_inhibit_dialog_set_inhibitor_paths (dialog, g_value_get_boxed (value));
                 break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -796,11 +879,11 @@ gsm_inhibit_dialog_get_property (GObject        *object,
         case PROP_ACTION:
                 g_value_set_int (value, dialog->priv->action);
                 break;
-        case PROP_INHIBITOR_STORE:
-                g_value_set_object (value, dialog->priv->inhibitors);
+        case PROP_TIMEOUT:
+                g_value_set_int (value, dialog->priv->action);
                 break;
-        case PROP_CLIENT_STORE:
-                g_value_set_object (value, dialog->priv->clients);
+        case PROP_INHIBITOR_PATHS:
+                g_value_set_boxed (value, dialog->priv->inhibitor_paths);
                 break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -839,21 +922,40 @@ name_cell_data_func (GtkTreeViewColumn *tree_column,
         g_free (markup);
 }
 
-static gboolean
-add_to_model (const char       *id,
-              GsmInhibitor     *inhibitor,
-              GsmInhibitDialog *dialog)
+static void
+on_inhibitor_created (GObject *source, GAsyncResult *res, gpointer user_data)
 {
-        add_inhibitor (dialog, inhibitor);
-        return FALSE;
+        GsmInhibitDialog *dialog = user_data;
+        GError *error = NULL;
+        GDBusProxy *proxy;
+
+        proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
+        if (proxy == NULL) {
+                g_warning ("Failed to create Inhibitor proxy: %s", error->message);
+                g_error_free (error);
+                return;
+        }
+
+        add_inhibitor (dialog, proxy);
+
+        g_object_unref (proxy);
 }
 
 static void
 populate_model (GsmInhibitDialog *dialog)
 {
-        gsm_store_foreach_remove (dialog->priv->inhibitors,
-                                  (GsmStoreFunc)add_to_model,
-                                  dialog);
+        gint i;
+        for (i = 0; dialog->priv->inhibitor_paths && dialog->priv->inhibitor_paths[i]; i++) {
+                g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+                                          0,
+                                          NULL,
+                                          "org.gnome.SessionManager",
+                                          dialog->priv->inhibitor_paths[i],
+                                          "org.gnome.SessionManager.Inhibitor",
+                                          NULL,
+                                          on_inhibitor_created,
+                                          dialog);
+        }
         update_dialog_text (dialog);
 }
 
@@ -865,24 +967,25 @@ setup_dialog (GsmInhibitDialog *dialog)
         GtkTreeViewColumn *column;
         GtkCellRenderer   *renderer;
 
+        g_print ("setting up dialog\n");
         switch (dialog->priv->action) {
         case GSM_LOGOUT_ACTION_SWITCH_USER:
-                button_text = _("Switch User Anyway");
+                button_text = _("Switch User");
                 break;
         case GSM_LOGOUT_ACTION_LOGOUT:
-                button_text = _("Log Out Anyway");
+                button_text = _("Log Out");
                 break;
         case GSM_LOGOUT_ACTION_SLEEP:
-                button_text = _("Suspend Anyway");
+                button_text = _("Suspend");
                 break;
         case GSM_LOGOUT_ACTION_HIBERNATE:
-                button_text = _("Hibernate Anyway");
+                button_text = _("Hibernate");
                 break;
         case GSM_LOGOUT_ACTION_SHUTDOWN:
-                button_text = _("Shut Down Anyway");
+                button_text = _("Power Off");
                 break;
         case GSM_LOGOUT_ACTION_REBOOT:
-                button_text = _("Restart Anyway");
+                button_text = _("Restart");
                 break;
         default:
                 g_assert_not_reached ();
@@ -907,7 +1010,9 @@ setup_dialog (GsmInhibitDialog *dialog)
                                                        GDK_TYPE_PIXBUF,
                                                        G_TYPE_STRING,
                                                        G_TYPE_STRING,
-                                                       G_TYPE_STRING);
+                                                       G_TYPE_STRING,
+                                                       G_TYPE_OBJECT);
+        g_print ("empty model: %d\n", gtk_tree_model_iter_n_children (GTK_TREE_MODEL (dialog->priv->list_store), NULL));
 
         treeview = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
                                                        "inhibitors-treeview"));
@@ -979,7 +1084,7 @@ gsm_inhibit_dialog_constructor (GType                  type,
 
         setup_dialog (dialog);
 
-        gtk_widget_show_all (GTK_WIDGET (dialog));
+        gtk_widget_show (GTK_WIDGET (dialog));
 
         return G_OBJECT (dialog);
 }
@@ -987,37 +1092,63 @@ gsm_inhibit_dialog_constructor (GType                  type,
 static void
 gsm_inhibit_dialog_dispose (GObject *object)
 {
-        GsmInhibitDialog *dialog;
+        GsmInhibitDialog *dialog = GSM_INHIBIT_DIALOG (object);
 
-        g_return_if_fail (object != NULL);
-        g_return_if_fail (GSM_IS_INHIBIT_DIALOG (object));
+        gsm_inhibit_dialog_stop_timer (dialog);
 
-        dialog = GSM_INHIBIT_DIALOG (object);
+        g_clear_object (&dialog->priv->list_store);
+        g_clear_object (&dialog->priv->xml);
 
-        g_debug ("GsmInhibitDialog: dispose called");
+        G_OBJECT_CLASS (gsm_inhibit_dialog_parent_class)->dispose (object);
+}
 
-        g_clear_object (&dialog->priv->list_store);
+static gboolean
+gsm_inhibit_dialog_timeout (GsmInhibitDialog *dialog)
+{
+        if (dialog->priv->timeout == 0) {
+                gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+                return G_SOURCE_REMOVE;
+        }
 
-        if (dialog->priv->inhibitors != NULL) {
-                g_signal_handlers_disconnect_by_func (dialog->priv->inhibitors,
-                                                      on_store_inhibitor_added,
-                                                      dialog);
-                g_signal_handlers_disconnect_by_func (dialog->priv->inhibitors,
-                                                      on_store_inhibitor_removed,
-                                                      dialog);
+        update_dialog_text (dialog);
 
-                g_clear_object (&dialog->priv->inhibitors);
+        dialog->priv->timeout--;
+
+        return G_SOURCE_CONTINUE;
+}
+
+static void
+gsm_inhibit_dialog_start_timer (GsmInhibitDialog *dialog)
+{
+        if (dialog->priv->timeout_id == 0) {
+                dialog->priv->timeout_id = g_timeout_add (1000, (GSourceFunc)gsm_inhibit_dialog_timeout, dialog);
         }
+}
 
-        g_clear_object (&dialog->priv->xml);
+static void
+gsm_inhibit_dialog_stop_timer (GsmInhibitDialog *dialog)
+{
+        if (dialog->priv->timeout_id != 0) {
+                g_source_remove (dialog->priv->timeout_id);
+                dialog->priv->timeout_id = 0;
+        }
+}
 
-        G_OBJECT_CLASS (gsm_inhibit_dialog_parent_class)->dispose (object);
+static void
+gsm_inhibit_dialog_show (GtkWidget *widget)
+{
+        GsmInhibitDialog *dialog = GSM_INHIBIT_DIALOG (widget);
+
+        GTK_WIDGET_CLASS (gsm_inhibit_dialog_parent_class)->show (widget);
+
+        update_dialog_text (dialog);
 }
 
 static void
 gsm_inhibit_dialog_class_init (GsmInhibitDialogClass *klass)
 {
         GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
         object_class->get_property = gsm_inhibit_dialog_get_property;
         object_class->set_property = gsm_inhibit_dialog_set_property;
@@ -1025,6 +1156,8 @@ gsm_inhibit_dialog_class_init (GsmInhibitDialogClass *klass)
         object_class->dispose = gsm_inhibit_dialog_dispose;
         object_class->finalize = gsm_inhibit_dialog_finalize;
 
+        widget_class->show = gsm_inhibit_dialog_show;
+
         g_object_class_install_property (object_class,
                                          PROP_ACTION,
                                          g_param_spec_int ("action",
@@ -1035,19 +1168,21 @@ gsm_inhibit_dialog_class_init (GsmInhibitDialogClass *klass)
                                                            -1,
                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
         g_object_class_install_property (object_class,
-                                         PROP_INHIBITOR_STORE,
-                                         g_param_spec_object ("inhibitor-store",
-                                                              NULL,
-                                                              NULL,
-                                                              GSM_TYPE_STORE,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+                                         PROP_TIMEOUT,
+                                         g_param_spec_int ("timeout",
+                                                           "timeout",
+                                                           "timeout",
+                                                           -1,
+                                                           G_MAXINT,
+                                                           -1,
+                                                           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
         g_object_class_install_property (object_class,
-                                         PROP_CLIENT_STORE,
-                                         g_param_spec_object ("client-store",
-                                                              NULL,
-                                                              NULL,
-                                                              GSM_TYPE_STORE,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+                                         PROP_INHIBITOR_PATHS,
+                                         g_param_spec_boxed ("inhibitor-paths",
+                                                             "inhibitor-paths",
+                                                             "inhibitor-paths",
+                                                             G_TYPE_STRV,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
         g_type_class_add_private (klass, sizeof (GsmInhibitDialogPrivate));
 }
@@ -1078,46 +1213,33 @@ gsm_inhibit_dialog_init (GsmInhibitDialog *dialog)
         }
 
         content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
-        widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml,
-                                                     "main-box"));
+        widget = GTK_WIDGET (gtk_builder_get_object (dialog->priv->xml, "main-box"));
         gtk_container_add (GTK_CONTAINER (content_area), widget);
 
         gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
         gtk_window_set_icon_name (GTK_WINDOW (dialog), GSM_ICON_LOGOUT);
         gtk_window_set_title (GTK_WINDOW (dialog), "");
-        g_object_set (dialog,
-                      "resizable", FALSE,
-                      NULL);
+        g_object_set (dialog, "resizable", FALSE, NULL);
+
 }
 
 static void
 gsm_inhibit_dialog_finalize (GObject *object)
 {
-        GsmInhibitDialog *dialog;
-
-        g_return_if_fail (object != NULL);
-        g_return_if_fail (GSM_IS_INHIBIT_DIALOG (object));
-
-        dialog = GSM_INHIBIT_DIALOG (object);
-
-        g_return_if_fail (dialog->priv != NULL);
-
-        g_debug ("GsmInhibitDialog: finalizing");
-
         G_OBJECT_CLASS (gsm_inhibit_dialog_parent_class)->finalize (object);
 }
 
 GtkWidget *
-gsm_inhibit_dialog_new (GsmStore *inhibitors,
-                        GsmStore *clients,
-                        int       action)
+gsm_inhibit_dialog_new (int action,
+                        int seconds,
+                        const char *const *inhibitor_paths)
 {
         GObject *object;
 
         object = g_object_new (GSM_TYPE_INHIBIT_DIALOG,
                                "action", action,
-                               "inhibitor-store", inhibitors,
-                               "client-store", clients,
+                               "timeout", seconds,
+                               "inhibitor-paths", inhibitor_paths,
                                NULL);
 
         return GTK_WIDGET (object);
diff --git a/gnome-session/gsm-inhibit-dialog.h b/gnome-session/gsm-inhibit-dialog.h
index f4d31a5..1c99f09 100644
--- a/gnome-session/gsm-inhibit-dialog.h
+++ b/gnome-session/gsm-inhibit-dialog.h
@@ -60,10 +60,9 @@ typedef struct
 
 GType                  gsm_inhibit_dialog_get_type           (void);
 
-GtkWidget            * gsm_inhibit_dialog_new                (GsmStore         *inhibitors,
-                                                              GsmStore         *clients,
-                                                              int               action);
-GtkTreeModel         * gsm_inhibit_dialog_get_model          (GsmInhibitDialog *dialog);
+GtkWidget            * gsm_inhibit_dialog_new                (int action,
+                                                              int seconds,
+                                                              const char *const *inhibitor_paths);
 
 G_END_DECLS
 
diff --git a/gnome-session/org.gnome.SessionManager.EndSessionDialog.xml b/gnome-session/org.gnome.SessionManager.EndSessionDialog.xml
new file mode 100644
index 0000000..5392de0
--- /dev/null
+++ b/gnome-session/org.gnome.SessionManager.EndSessionDialog.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+<node xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd";>
+  <interface name="org.gnome.SessionManager.EndSessionDialog">
+    <method name="Open">
+      <arg type="u" name="type" direction="in">
+        <doc:doc>
+          <doc:summary>
+            The type of dialog to show.
+            0 for logout, 1 for shutdown, 2 for restart.
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="u" name="timestamp" direction="in">
+        <doc:doc>
+          <doc:summary>
+            Timestamp of the user-initiated event which triggered
+            the call, or 0 if the call was not triggered by an event.
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="u" name="seconds_to_stay_open" direction="in">
+        <doc:doc>
+          <doc:summary>
+            The number of seconds which the dialog should stay open
+            before automatic action is taken.
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <arg type="ao" name="inhibitor_object_paths" direction="in">
+        <doc:doc>
+          <doc:summary>
+            The object paths of all inhibitors that are registered
+            for the action.
+          </doc:summary>
+        </doc:doc>
+      </arg>
+      <doc:doc>
+        <doc:summary>
+          This function opens a dialog which asks the user for confirmation
+          of a logout, poweroff or reboot action. The dialog has a timeout
+          after which the action is automatically taken, and it should show
+          the inhibitors to the user.
+        </doc:summary>
+      </doc:doc>
+    </method>
+    <signal name="ConfirmedLogout" />
+    <signal name="ConfirmedReboot" />
+    <signal name="ConfirmedShutdown" />
+    <signal name="Canceled" />
+    <signal name="Closed" />
+  </interface>
+</node>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]