diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-01-20 11:29:04 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-02-19 00:56:31 -0500 |
commit | 65e9d71da56de9802d04bd94cf6e52b764bdf91b (patch) | |
tree | c0bdbaec8e633e1c250e9ebc6076175afff93147 /gtk | |
parent | 9174616a17aa60792089d5af38263c3a732a424d (diff) | |
download | gtk+-65e9d71da56de9802d04bd94cf6e52b764bdf91b.tar.gz |
Application: Support sandboxed session state changes
React to the session-state in StateChanged signals from
the inhibit portal and call QueryEndResponse as appropriate.
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtkapplication-dbus.c | 39 | ||||
-rw-r--r-- | gtk/gtkapplicationprivate.h | 1 |
2 files changed, 37 insertions, 3 deletions
diff --git a/gtk/gtkapplication-dbus.c b/gtk/gtkapplication-dbus.c index 25766aaae2..05a35cc945 100644 --- a/gtk/gtkapplication-dbus.c +++ b/gtk/gtkapplication-dbus.c @@ -194,6 +194,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, @@ -203,16 +210,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 @@ -456,7 +489,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 8f6cdb001d..24ef7c4a40 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 |