Make sure to disconnect signal handlers on dispose.
This commit is contained in:
1
README
1
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:
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
35
src/server.c
35
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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user