From a3e070f59ce8a692c6e53e8e7104f6cac8bd4170 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 20 Jan 2019 11:29:04 -0500 Subject: [PATCH] Application: Support sandboxed session state changes React to the session-state in StateChanged signals from the inhibit portal and call QueryEndResponse as appropriate. --- gtk/gtkapplication-dbus.c | 39 ++++++++++++++++++++++++++++++++++--- gtk/gtkapplicationprivate.h | 1 + 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/gtk/gtkapplication-dbus.c b/gtk/gtkapplication-dbus.c index 82b1e23d66..3bd8eb80cb 100644 --- a/gtk/gtkapplication-dbus.c +++ b/gtk/gtkapplication-dbus.c @@ -193,6 +193,13 @@ screensaver_signal_session (GDBusProxy *proxy, gtk_application_set_screensaver_active (application, active); } +enum { + UNKNOWN = 0, + RUNNING = 1, + QUERY_END = 2, + ENDING = 3 +}; + static void screensaver_signal_portal (GDBusConnection *connection, const char *sender_name, @@ -202,16 +209,42 @@ screensaver_signal_portal (GDBusConnection *connection, GVariant *parameters, gpointer data) { - GtkApplication *application = data; + GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *)data; + GtkApplication *application = data; gboolean active; GVariant *state; + guint32 session_state = UNKNOWN; if (!g_str_equal (signal_name, "StateChanged")) return; g_variant_get (parameters, "(o@a{sv})", NULL, &state); g_variant_lookup (state, "screensaver-active", "b", &active); - gtk_application_set_screensaver_active (application, active); + gtk_application_set_screensaver_active (dbus->impl.application, active); + + g_variant_lookup (state, "session-state", "u", &session_state); + if (session_state != dbus->session_state) + { + dbus->session_state = session_state; + + /* Note that we'll only ever get here if we get a session-state, + * in which case, the interface is new enough to have QueryEndResponse. + */ + if (session_state == ENDING) + { + g_application_quit (G_APPLICATION (application)); + } + else if (session_state == QUERY_END) + { + g_dbus_proxy_call (dbus->inhibit_proxy, + "QueryEndResponse", + g_variant_new ("(o)", dbus->session_id), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + NULL, + NULL, NULL); + } + } } static void @@ -455,7 +488,7 @@ gtk_application_impl_dbus_startup (GtkApplicationImpl *impl, NULL, G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, screensaver_signal_portal, - impl->application, + dbus, NULL); g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&opt_builder, "{sv}", diff --git a/gtk/gtkapplicationprivate.h b/gtk/gtkapplicationprivate.h index cbea1973c6..01b674a709 100644 --- a/gtk/gtkapplicationprivate.h +++ b/gtk/gtkapplicationprivate.h @@ -139,6 +139,7 @@ typedef struct GSList *inhibit_handles; guint state_changed_handler; char * session_id; + guint session_state; } GtkApplicationImplDBus; typedef struct