From aed12cd831b9bb46a9cc620cafd4a0da8cb38100 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Tue, 1 Feb 2011 12:13:26 +0900 Subject: [PATCH] Make sure to disconnect signal handlers on dispose. --- README | 1 + eek/eek-gtk-keyboard.c | 31 +++++++++++++++++++++++++------ eek/eek-renderer.c | 14 ++++++++++---- src/client-main.c | 7 +++++++ src/server.c | 35 +++++++++++++++++++++++++++++++---- src/system-client.c | 40 ++++++++++++++++++++-------------------- 6 files changed, 94 insertions(+), 34 deletions(-) diff --git a/README b/README index 3eb40eed..cb67e326 100644 --- a/README +++ b/README @@ -41,6 +41,7 @@ Access to the D-Bus server: $ ./src/eekboard-client --listen # press some keys on the keyboard KeyPressed XXXXX KeyReleased XXXXX + $ ./src/eekboard-client --set-group 1 Listen and follow the system events: diff --git a/eek/eek-gtk-keyboard.c b/eek/eek-gtk-keyboard.c index a79883ef..ab8c81f9 100644 --- a/eek/eek-gtk-keyboard.c +++ b/eek/eek-gtk-keyboard.c @@ -57,6 +57,9 @@ struct _EekGtkKeyboardPrivate EekRenderer *renderer; EekKeyboard *keyboard; EekKey *dragged_key; + gulong key_pressed_handler; + gulong key_released_handler; + gulong symbol_index_changed_handler; }; static EekColor * color_from_gdk_color (GdkColor *gdk_color); @@ -206,12 +209,15 @@ eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self, EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self); priv->keyboard = g_object_ref (keyboard); - g_signal_connect (priv->keyboard, "key-pressed", - G_CALLBACK(on_key_pressed), self); - g_signal_connect (priv->keyboard, "key-released", - G_CALLBACK(on_key_released), self); - g_signal_connect (priv->keyboard, "symbol-index-changed", - G_CALLBACK(on_symbol_index_changed), self); + priv->key_pressed_handler = + g_signal_connect (priv->keyboard, "key-pressed", + G_CALLBACK(on_key_pressed), self); + priv->key_released_handler = + g_signal_connect (priv->keyboard, "key-released", + G_CALLBACK(on_key_released), self); + priv->symbol_index_changed_handler = + g_signal_connect (priv->keyboard, "symbol-index-changed", + G_CALLBACK(on_symbol_index_changed), self); } static void @@ -246,6 +252,19 @@ eek_gtk_keyboard_dispose (GObject *object) } if (priv->keyboard) { + if (g_signal_handler_is_connected (priv->keyboard, + priv->key_pressed_handler)) + g_signal_handler_disconnect (priv->keyboard, + priv->key_pressed_handler); + if (g_signal_handler_is_connected (priv->keyboard, + priv->key_released_handler)) + g_signal_handler_disconnect (priv->keyboard, + priv->key_released_handler); + if (g_signal_handler_is_connected (priv->keyboard, + priv->symbol_index_changed_handler)) + g_signal_handler_disconnect (priv->keyboard, + priv->symbol_index_changed_handler); + g_object_unref (priv->keyboard); priv->keyboard = NULL; } diff --git a/eek/eek-renderer.c b/eek/eek-renderer.c index a6e21bea..cfab8a39 100644 --- a/eek/eek-renderer.c +++ b/eek/eek-renderer.c @@ -53,6 +53,7 @@ struct _EekRendererPrivate PangoFontDescription *font; GHashTable *outline_surface_cache; cairo_surface_t *keyboard_surface; + gulong symbol_index_changed_handler; }; struct { @@ -536,9 +537,10 @@ eek_renderer_set_property (GObject *object, priv->keyboard = g_value_get_object (value); g_object_ref (priv->keyboard); - g_signal_connect (priv->keyboard, "symbol-index-changed", - G_CALLBACK(on_symbol_index_changed), - object); + priv->symbol_index_changed_handler = + g_signal_connect (priv->keyboard, "symbol-index-changed", + G_CALLBACK(on_symbol_index_changed), + object); break; case PROP_PCONTEXT: priv->pcontext = g_value_get_object (value); @@ -553,6 +555,10 @@ eek_renderer_dispose (GObject *object) EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object); if (priv->keyboard) { + if (g_signal_handler_is_connected (priv->keyboard, + priv->symbol_index_changed_handler)) + g_signal_handler_disconnect (priv->keyboard, + priv->symbol_index_changed_handler); g_object_unref (priv->keyboard); priv->keyboard = NULL; } @@ -571,7 +577,6 @@ static void eek_renderer_finalize (GObject *object) { EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object); - g_hash_table_destroy (priv->outline_surface_cache); G_OBJECT_CLASS (eek_renderer_parent_class)->finalize (object); } @@ -638,6 +643,7 @@ eek_renderer_init (EekRenderer *self) NULL, free_surface); priv->keyboard_surface = NULL; + priv->symbol_index_changed_handler = 0; } static void diff --git a/src/client-main.c b/src/client-main.c index 606d8a33..34114586 100644 --- a/src/client-main.c +++ b/src/client-main.c @@ -22,6 +22,7 @@ #include "proxy.h" static gchar *opt_set_keyboard = NULL; +static gint opt_set_group = -1; static gboolean opt_show = FALSE; static gboolean opt_hide = FALSE; static gboolean opt_listen = FALSE; @@ -29,6 +30,8 @@ static gboolean opt_listen = FALSE; static const GOptionEntry options[] = { {"set-keyboard", '\0', 0, G_OPTION_ARG_STRING, &opt_set_keyboard, "Set keyboard from an XML file"}, + {"set-group", '\0', 0, G_OPTION_ARG_INT, &opt_set_group, + "Set group of the keyboard"}, {"show", '\0', 0, G_OPTION_ARG_NONE, &opt_show, "Show keyboard"}, {"hide", '\0', 0, G_OPTION_ARG_NONE, &opt_hide, @@ -112,6 +115,10 @@ main (int argc, char **argv) g_object_unref (keyboard); } + if (opt_set_group >= 0) { + eekboard_proxy_set_group (proxy, opt_set_group); + } + if (opt_show) { eekboard_proxy_show (proxy); } diff --git a/src/server.c b/src/server.c index a724525d..c2fc0332 100644 --- a/src/server.c +++ b/src/server.c @@ -100,6 +100,16 @@ on_allocation_changed (ClutterActor *stage, } #endif +static void +on_destroy (GtkWidget *widget, gpointer user_data) +{ + EekboardServer *server = user_data; + + g_assert (widget == server->window); + server->window = NULL; + server->widget = NULL; +} + static void update_widget (EekboardServer *server) { @@ -141,6 +151,8 @@ update_widget (EekboardServer *server) gtk_widget_set_size_request (server->widget, bounds.width, bounds.height); server->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + g_signal_connect (server->window, "destroy", + G_CALLBACK(on_destroy), server); gtk_container_add (GTK_CONTAINER(server->window), server->widget); gtk_widget_set_can_focus (server->window, FALSE); @@ -308,7 +320,13 @@ handle_method_call (GDBusConnection *connection, eek_keyboard_set_modifier_behavior (server->keyboard, EEK_MODIFIER_BEHAVIOR_LATCH); - update_widget (server); + if (server->window) { + gboolean was_visible = gtk_widget_get_visible (server->window); + update_widget (server); + if (was_visible) + gtk_widget_show_all (server->window); + } + g_dbus_method_invocation_return_value (invocation, NULL); return; } @@ -326,6 +344,14 @@ handle_method_call (GDBusConnection *connection, g_variant_get (parameters, "(i)", &group); eek_keyboard_set_group (server->keyboard, group); + + if (server->window) { + gboolean was_visible = gtk_widget_get_visible (server->window); + update_widget (server); + if (was_visible) + gtk_widget_show_all (server->window); + } + g_dbus_method_invocation_return_value (invocation, NULL); return; } @@ -339,11 +365,12 @@ handle_method_call (GDBusConnection *connection, return; } - if (server->window) - gtk_widget_show_all (server->window); + if (!server->window) + update_widget (server); + g_assert (server->window); + gtk_widget_show_all (server->window); g_dbus_method_invocation_return_value (invocation, NULL); return; - } if (g_strcmp0 (method_name, "Hide") == 0) { diff --git a/src/system-client.c b/src/system-client.c index 5629cdb4..38d4833b 100644 --- a/src/system-client.c +++ b/src/system-client.c @@ -51,11 +51,11 @@ struct _EekboardSystemClient { XklConfigRegistry *xkl_config_registry; FakeKey *fakekey; - gulong xkl_config_changed_handler_id; - gulong xkl_state_changed_handler_id; + gulong xkl_config_changed_handler; + gulong xkl_state_changed_handler; - gulong key_pressed_handler_id; - gulong key_released_handler_id; + gulong key_pressed_handler; + gulong key_released_handler; AccessibleEventListener *focus_listener; AccessibleEventListener *keystroke_listener; @@ -167,10 +167,10 @@ eekboard_system_client_init (EekboardSystemClient *client) client->keystroke_listener = NULL; client->proxy = NULL; client->fakekey = NULL; - client->key_pressed_handler_id = 0; - client->key_released_handler_id = 0; - client->xkl_config_changed_handler_id = 0; - client->xkl_state_changed_handler_id = 0; + client->key_pressed_handler = 0; + client->key_released_handler = 0; + client->xkl_config_changed_handler = 0; + client->xkl_state_changed_handler = 0; } gboolean @@ -189,10 +189,10 @@ eekboard_system_client_enable_xkl (EekboardSystemClient *client) xkl_config_registry_load (client->xkl_config_registry, FALSE); } - client->xkl_config_changed_handler_id = + client->xkl_config_changed_handler = g_signal_connect (client->xkl_engine, "X-config-changed", G_CALLBACK(on_xkl_config_changed), client); - client->xkl_state_changed_handler_id = + client->xkl_state_changed_handler = g_signal_connect (client->xkl_engine, "X-state-changed", G_CALLBACK(on_xkl_state_changed), client); @@ -216,13 +216,13 @@ eekboard_system_client_disable_xkl (EekboardSystemClient *client) if (client->xkl_engine) xkl_engine_stop_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE); if (g_signal_handler_is_connected (client->xkl_engine, - client->xkl_config_changed_handler_id)) + client->xkl_config_changed_handler)) g_signal_handler_disconnect (client->xkl_engine, - client->xkl_config_changed_handler_id); + client->xkl_config_changed_handler); if (g_signal_handler_is_connected (client->xkl_engine, - client->xkl_state_changed_handler_id)) + client->xkl_state_changed_handler)) g_signal_handler_disconnect (client->xkl_engine, - client->xkl_state_changed_handler_id); + client->xkl_state_changed_handler); } gboolean @@ -450,10 +450,10 @@ eekboard_system_client_enable_fakekey (EekboardSystemClient *client) } g_assert (client->fakekey); - client->key_pressed_handler_id = + client->key_pressed_handler = g_signal_connect (client->proxy, "key-pressed", G_CALLBACK(on_key_pressed), client); - client->key_released_handler_id = + client->key_released_handler = g_signal_connect (client->proxy, "key-pressed", G_CALLBACK(on_key_released), client); @@ -467,11 +467,11 @@ eekboard_system_client_disable_fakekey (EekboardSystemClient *client) fakekey_release (client->fakekey); if (g_signal_handler_is_connected (client->proxy, - client->key_pressed_handler_id)) + client->key_pressed_handler)) g_signal_handler_disconnect (client->proxy, - client->key_pressed_handler_id); + client->key_pressed_handler); if (g_signal_handler_is_connected (client->proxy, - client->key_released_handler_id)) + client->key_released_handler)) g_signal_handler_disconnect (client->proxy, - client->key_released_handler_id); + client->key_released_handler); }