[gnome-session/wip/cleanups: 8/15] Make the fallback end session dialog a separate program
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-session/wip/cleanups: 8/15] Make the fallback end session dialog a separate program
- Date: Mon, 12 Nov 2012 13:37:19 +0000 (UTC)
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]