[gtk+/portal: 13/17] Support the Inhibit portal
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/portal: 13/17] Support the Inhibit portal
- Date: Wed, 6 Jul 2016 03:08:00 +0000 (UTC)
commit 89439232add5aaa7390402240d08bcab67c5d5ea
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Jul 1 21:19:12 2016 -0400
Support the Inhibit portal
xdg-desktop-portal now has a portal for inhibiting session status
changes. We don't need to use it if we can talk to the session
manager, but if can't, try org.freedesktop.portal.Inhibit.
gtk/gtkapplication-dbus.c | 177 ++++++++++++++++++++++++++++++++++---------
gtk/gtkapplicationprivate.h | 4 +
2 files changed, 144 insertions(+), 37 deletions(-)
---
diff --git a/gtk/gtkapplication-dbus.c b/gtk/gtkapplication-dbus.c
index 128c000..844dd03 100644
--- a/gtk/gtkapplication-dbus.c
+++ b/gtk/gtkapplication-dbus.c
@@ -190,7 +190,6 @@ gtk_application_impl_dbus_startup (GtkApplicationImpl *impl,
g_warning ("Failed to get the GNOME session proxy: %s", error->message);
g_clear_error (&error);
g_clear_object (&dbus->sm_proxy);
- goto out;
}
if (!dbus->sm_proxy)
@@ -228,7 +227,7 @@ gtk_application_impl_dbus_startup (GtkApplicationImpl *impl,
if (error)
{
g_warning ("Failed to register client: %s", error->message);
- g_error_free (error);
+ g_clear_error (&error);
g_clear_object (&dbus->sm_proxy);
goto out;
}
@@ -238,7 +237,6 @@ gtk_application_impl_dbus_startup (GtkApplicationImpl *impl,
g_debug ("Registered client at '%s'", dbus->client_path);
- /* Try the GNOME client interface */
if (g_str_equal (g_dbus_proxy_get_name (dbus->sm_proxy), GNOME_DBUS_NAME))
{
bus_name = GNOME_DBUS_NAME;
@@ -259,8 +257,11 @@ gtk_application_impl_dbus_startup (GtkApplicationImpl *impl,
&error);
if (error)
{
- g_warning ("Failed to connect to the GNOME client proxy: %s", error->message);
+ g_warning ("Failed to get client proxy: %s", error->message);
g_clear_error (&error);
+ g_clear_object (&dbus->client_proxy);
+ g_free (dbus->client_path);
+ dbus->client_path = NULL;
goto out;
}
@@ -313,6 +314,23 @@ gtk_application_impl_dbus_startup (GtkApplicationImpl *impl,
"gtk-shell-shows-app-menu", FALSE,
"gtk-shell-shows-menubar", FALSE,
NULL);
+
+ if (dbus->sm_proxy == NULL)
+ {
+ dbus->inhibit_proxy = g_dbus_proxy_new_sync (dbus->session,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.freedesktop.portal.Desktop",
+ "/org/freedesktop/portal/desktop",
+ "org.freedesktop.portal.Inhibit",
+ NULL,
+ &error);
+ if (error)
+ {
+ g_warning ("Failed to get an inhibit portal proxy: %s", error->message);
+ g_clear_error (&error);
+ }
+ }
}
static void
@@ -438,6 +456,22 @@ gtk_application_impl_dbus_get_window_system_id (GtkApplicationImplDBus *dbus,
return GTK_APPLICATION_IMPL_DBUS_GET_CLASS (dbus)->get_window_system_id (dbus, window);
}
+static int next_cookie;
+
+typedef struct {
+ char *handle;
+ int cookie;
+} InhibitHandle;
+
+static void
+inhibit_handle_free (gpointer data)
+{
+ InhibitHandle *handle = data;
+
+ g_free (handle->handle);
+ g_free (handle);
+}
+
static guint
gtk_application_impl_dbus_inhibit (GtkApplicationImpl *impl,
GtkWindow *window,
@@ -450,37 +484,80 @@ gtk_application_impl_dbus_inhibit (GtkApplicationImpl *impl,
guint cookie;
static gboolean warned = FALSE;
- if (dbus->sm_proxy == NULL)
- return 0;
-
- res = g_dbus_proxy_call_sync (dbus->sm_proxy,
- "Inhibit",
- g_variant_new ("(s@usu)",
- dbus->application_id,
- window ? gtk_application_impl_dbus_get_window_system_id
(dbus, window) : g_variant_new_uint32 (0),
- reason,
- flags),
- G_DBUS_CALL_FLAGS_NONE,
- G_MAXINT,
- NULL,
- &error);
-
- if (error)
+ if (dbus->sm_proxy)
{
- if (!warned)
+ res = g_dbus_proxy_call_sync (dbus->sm_proxy,
+ "Inhibit",
+ g_variant_new ("(s@usu)",
+ dbus->application_id,
+ window ? gtk_application_impl_dbus_get_window_system_id
(dbus, window) : g_variant_new_uint32 (0),
+ reason,
+ flags),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ &error);
+
+ if (res)
{
- g_warning ("Calling Inhibit failed: %s", error->message);
- warned = TRUE;
+ g_variant_get (res, "(u)", &cookie);
+ g_variant_unref (res);
+ return cookie;
+ }
+
+ if (error)
+ {
+ if (!warned)
+ {
+ g_warning ("Calling org.gnome.SessionManager.Inhibit failed: %s", error->message);
+ warned = TRUE;
+ }
+ g_clear_error (&error);
}
- g_error_free (error);
- return 0;
}
+ else if (dbus->inhibit_proxy)
+ {
+ GVariantBuilder options;
+
+ g_variant_builder_init (&options, G_VARIANT_TYPE_VARDICT);
+ g_variant_builder_add (&options, "{sv}", "reason", g_variant_new_string (reason));
+ res = g_dbus_proxy_call_sync (dbus->inhibit_proxy,
+ "Inhibit",
+ g_variant_new ("(su@a{sv})",
+ "", /* window */
+ flags,
+ g_variant_builder_end (&options)),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL,
+ &error);
+ if (res)
+ {
+ InhibitHandle *handle;
- g_variant_get (res, "(u)", &cookie);
- g_variant_unref (res);
+ handle = g_new (InhibitHandle, 1);
+ handle->cookie = ++next_cookie;
- return cookie;
+ g_variant_get (res, "(o)", &handle->handle);
+ g_variant_unref (res);
+
+ dbus->inhibit_handles = g_slist_prepend (dbus->inhibit_handles, handle);
+
+ return handle->cookie;
+ }
+
+ if (error)
+ {
+ if (!warned)
+ {
+ g_warning ("Calling org.freedesktop.portal.Inhibit.Inhibit failed: %s", error->message);
+ warned = TRUE;
+ }
+ g_clear_error (&error);
+ }
+ }
+ return 0;
}
static void
@@ -489,16 +566,40 @@ gtk_application_impl_dbus_uninhibit (GtkApplicationImpl *impl,
{
GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) impl;
- /* Application could only obtain a cookie through a session
- * manager proxy, so it's valid to assert its presence here. */
- g_return_if_fail (dbus->sm_proxy != NULL);
+ if (dbus->sm_proxy)
+ {
+ g_dbus_proxy_call (dbus->sm_proxy,
+ "Uninhibit",
+ g_variant_new ("(u)", cookie),
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL, NULL, NULL);
+ }
+ else if (dbus->inhibit_proxy)
+ {
+ GSList *l;
- g_dbus_proxy_call (dbus->sm_proxy,
- "Uninhibit",
- g_variant_new ("(u)", cookie),
- G_DBUS_CALL_FLAGS_NONE,
- G_MAXINT,
- NULL, NULL, NULL);
+ for (l = dbus->inhibit_handles; l; l = l->next)
+ {
+ InhibitHandle *handle = l->data;
+ if (handle->cookie == cookie)
+ {
+ g_dbus_connection_call (dbus->session,
+ "org.freedesktop.portal.Desktop",
+ handle->handle,
+ "org.freedesktop.portal.Request",
+ "Close",
+ g_variant_new ("()"),
+ G_VARIANT_TYPE_UNIT,
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT,
+ NULL, NULL, NULL);
+ dbus->inhibit_handles = g_slist_remove (dbus->inhibit_handles, handle);
+ inhibit_handle_free (handle);
+ break;
+ }
+ }
+ }
}
static gboolean
@@ -580,6 +681,8 @@ gtk_application_impl_dbus_finalize (GObject *object)
{
GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) object;
+ g_object_unref (dbus->inhibit_proxy);
+ g_slist_free_full (dbus->inhibit_handles, inhibit_handle_free);
g_free (dbus->app_menu_path);
g_free (dbus->menubar_path);
diff --git a/gtk/gtkapplicationprivate.h b/gtk/gtkapplicationprivate.h
index f359d20..59eff02 100644
--- a/gtk/gtkapplicationprivate.h
+++ b/gtk/gtkapplicationprivate.h
@@ -129,6 +129,10 @@ typedef struct
GDBusProxy *sm_proxy;
GDBusProxy *client_proxy;
gchar *client_path;
+
+ /* Portal support */
+ GDBusProxy *inhibit_proxy;
+ GSList *inhibit_handles;
} GtkApplicationImplDBus;
typedef struct
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]