diff options
Diffstat (limited to 'gtk/gtkapplication-dbus.c')
-rw-r--r-- | gtk/gtkapplication-dbus.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/gtk/gtkapplication-dbus.c b/gtk/gtkapplication-dbus.c index d0110a73a9..3c241ca7b0 100644 --- a/gtk/gtkapplication-dbus.c +++ b/gtk/gtkapplication-dbus.c @@ -39,6 +39,9 @@ G_DEFINE_TYPE (GtkApplicationImplDBus, gtk_application_impl_dbus, GTK_TYPE_APPLI #define XFCE_DBUS_OBJECT_PATH "/org/xfce/SessionManager" #define XFCE_DBUS_INTERFACE "org.xfce.Session.Manager" #define XFCE_DBUS_CLIENT_INTERFACE "org.xfce.Session.Client" +#define GNOME_SCREENSAVER_DBUS_NAME "org.gnome.ScreenSaver" +#define GNOME_SCREENSAVER_DBUS_OBJECT_PATH "/org/gnome/ScreenSaver" +#define GNOME_SCREENSAVER_DBUS_INTERFACE "org.gnome.ScreenSaver" static void unregister_client (GtkApplicationImplDBus *dbus) @@ -176,6 +179,63 @@ stash_desktop_autostart_id (void) } static void +screensaver_signal_session (GDBusProxy *proxy, + const char *sender_name, + const char *signal_name, + GVariant *parameters, + GtkApplication *application) +{ + gboolean active; + + if (!g_str_equal (signal_name, "ActiveChanged")) + return; + + g_variant_get (parameters, "(b)", &active); + gtk_application_set_screensaver_active (application, active); +} + +static void +screensaver_signal_portal (GDBusConnection *connection, + const char *sender_name, + const char *object_path, + const char *interface_name, + const char *signal_name, + GVariant *parameters, + gpointer data) +{ + GtkApplication *application = data; + gboolean active; + GVariant *state; + + 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); +} + +static void +create_monitor_cb (GObject *source, + GAsyncResult *result, + gpointer data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (source); + GError *error = NULL; + GVariant *ret = NULL; + + ret = g_dbus_proxy_call_finish (proxy, result, &error); + if (ret == NULL) + { + g_warning ("Creating a portal monitor failed: %s", error->message); + g_error_free (error); + return; + } + + g_variant_unref (ret); +} + +static void gtk_application_impl_dbus_startup (GtkApplicationImpl *impl, gboolean register_session) { @@ -243,6 +303,27 @@ gtk_application_impl_dbus_startup (GtkApplicationImpl *impl, if (!register_session) goto out; + dbus->ss_proxy = gtk_application_get_proxy_if_service_present (dbus->session, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_NONE, + GNOME_SCREENSAVER_DBUS_NAME, + GNOME_SCREENSAVER_DBUS_OBJECT_PATH, + GNOME_SCREENSAVER_DBUS_INTERFACE, + &error); + if (error) + { + g_debug ("Failed to get the GNOME screensaver proxy: %s", error->message); + g_clear_error (&error); + g_clear_object (&dbus->ss_proxy); + } + + if (dbus->ss_proxy) + { + g_signal_connect (dbus->ss_proxy, "g-signal", + G_CALLBACK (screensaver_signal_session), impl->application); + } + g_debug ("Registering client '%s' '%s'", dbus->application_id, client_id); res = g_dbus_proxy_call_sync (dbus->sm_proxy, @@ -355,8 +436,43 @@ gtk_application_impl_dbus_startup (GtkApplicationImpl *impl, { g_debug ("Failed to get an inhibit portal proxy: %s", error->message); g_clear_error (&error); + goto end; + } + + if (register_session) + { + char *token; + GVariantBuilder opt_builder; + + /* Monitor screensaver state */ + + dbus->session_id = gtk_get_portal_session_path (dbus->session, &token); + dbus->state_changed_handler = + g_dbus_connection_signal_subscribe (dbus->session, + PORTAL_BUS_NAME, + PORTAL_INHIBIT_INTERFACE, + "StateChanged", + PORTAL_OBJECT_PATH, + NULL, + G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, + screensaver_signal_portal, + impl->application, + NULL); + g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&opt_builder, "{sv}", + "session_handle_token", g_variant_new_string (token)); + g_dbus_proxy_call (dbus->inhibit_proxy, + "CreateMonitor", + g_variant_new ("(sa{sv})", "", &opt_builder), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + NULL, + create_monitor_cb, dbus); + g_free (token); } } + +end:; } static void @@ -674,11 +790,21 @@ gtk_application_impl_dbus_finalize (GObject *object) { GtkApplicationImplDBus *dbus = (GtkApplicationImplDBus *) object; + g_dbus_connection_call (dbus->session, + PORTAL_BUS_NAME, + dbus->session_id, + PORTAL_SESSION_INTERFACE, + "Close", + NULL, NULL, 0, -1, NULL, NULL, NULL); + + g_free (dbus->session_id); + g_dbus_connection_signal_unsubscribe (dbus->session, dbus->state_changed_handler); g_clear_object (&dbus->inhibit_proxy); g_slist_free_full (dbus->inhibit_handles, inhibit_handle_free); g_free (dbus->app_menu_path); g_free (dbus->menubar_path); g_clear_object (&dbus->sm_proxy); + g_clear_object (&dbus->ss_proxy); G_OBJECT_CLASS (gtk_application_impl_dbus_parent_class)->finalize (object); } |