From e800a88893722c1fb29400b0750f6dc1ab10d451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Thu, 25 Mar 2021 16:03:57 +0100 Subject: [PATCH 1/2] server-main: Add quit() This allows to exit the mainloop e.g. when signalled from gnome-session or by a signal. --- src/server-main.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/server-main.c b/src/server-main.c index d199acab..dd8f3563 100644 --- a/src/server-main.c +++ b/src/server-main.c @@ -50,9 +50,16 @@ struct squeekboard { }; +GMainLoop *loop; static gboolean opt_system = FALSE; static gchar *opt_address = NULL; +static void +quit (void) +{ + g_main_loop_quit (loop); +} + // D-Bus static void @@ -307,8 +314,7 @@ main (int argc, char **argv) session_register(); - GMainLoop *loop = g_main_loop_new (NULL, FALSE); - + loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); if (connection) { From 40bf3ca5deab948dee443f330d81ab6c64814243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Thu, 25 Mar 2021 16:04:46 +0100 Subject: [PATCH 2/2] server-main: Properly register to gnome-session So far squeeboard only did half of the registration failing to respond to the signals sent by the session. This causes problems e.g. when exiting the session since the it thinks the client hangs or is busy. Closes: #274 --- src/server-main.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/src/server-main.c b/src/server-main.c index dd8f3563..1dafbac1 100644 --- a/src/server-main.c +++ b/src/server-main.c @@ -138,6 +138,67 @@ static const struct wl_registry_listener registry_listener = { #define SESSION_NAME "sm.puri.OSK0" GDBusProxy *_proxy = NULL; +GDBusProxy *_client_proxy = NULL; +gchar *_client_path = NULL; + + +static void +send_quit_response (GDBusProxy *proxy) +{ + g_debug ("Calling EndSessionResponse"); + g_dbus_proxy_call (proxy, "EndSessionResponse", + g_variant_new ("(bs)", TRUE, ""), G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, NULL, NULL, NULL); +} + +static void +unregister_client (void) +{ + g_autoptr (GError) error = NULL; + + g_return_if_fail (G_IS_DBUS_PROXY (_proxy)); + g_return_if_fail (_client_path != NULL); + + g_debug ("Unregistering client"); + + g_dbus_proxy_call_sync (_proxy, + "UnregisterClient", + g_variant_new ("(o)", _client_path), + G_DBUS_CALL_FLAGS_NONE, + G_MAXINT, + NULL, + &error); + + if (error) { + g_warning ("Failed to unregister client: %s", error->message); + } + + g_clear_object (&_client_proxy); + g_clear_pointer (&_client_path, g_free); +} + +static void client_proxy_signal (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + if (g_str_equal (signal_name, "QueryEndSession")) { + g_debug ("Received QueryEndSession"); + send_quit_response (proxy); + } else if (g_str_equal (signal_name, "CancelEndSession")) { + g_debug ("Received CancelEndSession"); + } else if (g_str_equal (signal_name, "EndSession")) { + g_debug ("Received EndSession"); + send_quit_response (proxy); + unregister_client (); + quit (); + } else if (g_str_equal (signal_name, "Stop")) { + g_debug ("Received Stop"); + unregister_client (); + quit (); + } +} static void session_register(void) { @@ -158,7 +219,8 @@ session_register(void) { return; } - g_dbus_proxy_call_sync(_proxy, "RegisterClient", + g_autoptr (GVariant) res = NULL; + res = g_dbus_proxy_call_sync(_proxy, "RegisterClient", g_variant_new("(ss)", SESSION_NAME, autostart_id), G_DBUS_CALL_FLAGS_NONE, 1000, NULL, &error); if (error) { @@ -167,6 +229,22 @@ session_register(void) { g_clear_error(&error); return; } + + g_variant_get (res, "(o)", &_client_path); + g_debug ("Registered client at '%s'", _client_path); + + _client_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + 0, NULL, "org.gnome.SessionManager", _client_path, + "org.gnome.SessionManager.ClientPrivate", NULL, &error); + if (error) { + g_warning ("Failed to get client proxy: %s", error->message); + g_clear_error (&error); + g_free (_client_path); + _client_path = NULL; + return; + } + + g_signal_connect (_client_proxy, "g-signal", G_CALLBACK (client_proxy_signal), NULL); } int