Make sure to disconnect signal handlers on dispose.

This commit is contained in:
Daiki Ueno
2011-02-01 12:13:26 +09:00
parent 30d88ceb78
commit aed12cd831
6 changed files with 94 additions and 34 deletions

1
README
View File

@ -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:

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);
}