summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-01-20 11:29:04 -0500
committerMatthias Clasen <mclasen@redhat.com>2019-02-19 00:56:31 -0500
commit65e9d71da56de9802d04bd94cf6e52b764bdf91b (patch)
treec0bdbaec8e633e1c250e9ebc6076175afff93147 /gtk
parent9174616a17aa60792089d5af38263c3a732a424d (diff)
downloadgtk+-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.c39
-rw-r--r--gtk/gtkapplicationprivate.h1
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