From bdd7e15c849cd641000e0efddaeacfe420b1b3e4 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 3 Jan 2012 15:02:49 -0500 Subject: GtkApplication: Add an inhibit api This lets applications block logout and similar actions ahead of time. Currently only implemented for D-Bus, but Windows has very similar API since Vista. --- gtk/gtk.symbols | 3 ++ gtk/gtkapplication.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++ gtk/gtkapplication.h | 17 +++++++++ 3 files changed, 117 insertions(+) diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index ece3c31559..06ebd7b1d9 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -223,12 +223,15 @@ gtk_application_get_app_menu gtk_application_get_menubar gtk_application_get_type gtk_application_get_windows +gtk_application_inhibit +gtk_application_is_inhibited gtk_application_new gtk_application_quit_response gtk_application_remove_accelerator gtk_application_remove_window gtk_application_set_app_menu gtk_application_set_menubar +gtk_application_uninhibit gtk_application_window_get_show_menubar gtk_application_window_get_type gtk_application_window_new diff --git a/gtk/gtkapplication.c b/gtk/gtkapplication.c index 7f3f252148..7ee766f641 100644 --- a/gtk/gtkapplication.c +++ b/gtk/gtkapplication.c @@ -1073,6 +1073,7 @@ gtk_application_startup_session_dbus (GtkApplication *app) g_variant_unref (res); g_debug ("Registered client at '%s'", app->priv->client_path); + app->priv->client_proxy = g_dbus_proxy_new_sync (app->priv->session_bus, 0, NULL, "org.gnome.SessionManager", @@ -1112,4 +1113,100 @@ gtk_application_quit_response (GtkApplication *application, NULL, NULL, NULL); } +guint +gtk_application_inhibit (GtkApplication *application, + GtkWindow *window, + GtkApplicationInhibitFlags flags, + const gchar *reason) +{ + GVariant *res; + GError *error = NULL; + guint cookie; + guint xid; + + g_return_val_if_fail (GTK_IS_APPLICATION (application), 0); + g_return_val_if_fail (!g_application_get_is_remote (G_APPLICATION (application)), 0); + g_return_val_if_fail (application->priv->sm_proxy != NULL, 0); + + g_debug ("Calling Inhibit\n"); + + if (window != NULL) + xid = GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (window))); + else + xid = 0; + + res = g_dbus_proxy_call_sync (application->priv->sm_proxy, + "Inhibit", + g_variant_new ("(susu)", + application->priv->app_id, + xid, + reason, + flags), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + NULL, + &error); + if (error) + { + g_warning ("Calling Inhibit failed: %s\n", error->message); + g_error_free (error); + return 0; + } + + g_variant_get (res, "(u)", &cookie); + g_variant_unref (res); + + return cookie; +} + +void +gtk_application_uninhibit (GtkApplication *application, + guint cookie) +{ + g_return_if_fail (GTK_IS_APPLICATION (application)); + g_return_if_fail (!g_application_get_is_remote (G_APPLICATION (application))); + g_return_if_fail (application->priv->sm_proxy != NULL); + + g_dbus_proxy_call (application->priv->sm_proxy, + "Uninhibit", + g_variant_new ("(u)", cookie), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + NULL, NULL, NULL); +} + +gboolean +gtk_application_is_inhibited (GtkApplication *application, + GtkApplicationInhibitFlags flags) +{ + GVariant *res; + GError *error = NULL; + gboolean inhibited; + + g_return_val_if_fail (GTK_IS_APPLICATION (application), FALSE); + g_return_val_if_fail (!g_application_get_is_remote (G_APPLICATION (application)), FALSE); + g_return_val_if_fail (application->priv->sm_proxy != NULL, FALSE); + + g_debug ("Calling IsInhibited\n"); + + res = g_dbus_proxy_call_sync (application->priv->sm_proxy, + "IsInhibited", + g_variant_new ("(u)", flags), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + NULL, + &error); + if (error) + { + g_warning ("Calling IsInhibited failed: %s\n", error->message); + g_error_free (error); + return FALSE; + } + + g_variant_get (res, "(b)", &inhibited); + g_variant_unref (res); + + return inhibited; +} + #endif diff --git a/gtk/gtkapplication.h b/gtk/gtkapplication.h index aeb4688cbe..298e50d27f 100644 --- a/gtk/gtkapplication.h +++ b/gtk/gtkapplication.h @@ -99,6 +99,23 @@ void gtk_application_quit_response (GtkApplication *application gboolean will_quit, const gchar *reason); +typedef enum +{ + GTK_APPLICATION_INHIBIT_LOGOUT = (1 << 0), + GTK_APPLICATION_INHIBIT_SWITCH = (1 << 1), + GTK_APPLICATION_INHIBIT_SUSPEND = (1 << 2), + GTK_APPLICATION_INHIBIT_IDLE = (1 << 3) +} GtkApplicationInhibitFlags; + +guint gtk_application_inhibit (GtkApplication *application, + GtkWindow *window, + GtkApplicationInhibitFlags flags, + const gchar *reason); +void gtk_application_uninhibit (GtkApplication *application, + guint cookie); +gboolean gtk_application_is_inhibited (GtkApplication *application, + GtkApplicationInhibitFlags flags); + G_END_DECLS #endif /* __GTK_APPLICATION_H__ */ -- cgit v1.2.1