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
|
$ ./src/eekboard-client --listen # press some keys on the keyboard
|
||||||
KeyPressed XXXXX
|
KeyPressed XXXXX
|
||||||
KeyReleased XXXXX
|
KeyReleased XXXXX
|
||||||
|
$ ./src/eekboard-client --set-group 1
|
||||||
|
|
||||||
Listen and follow the system events:
|
Listen and follow the system events:
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,9 @@ struct _EekGtkKeyboardPrivate
|
|||||||
EekRenderer *renderer;
|
EekRenderer *renderer;
|
||||||
EekKeyboard *keyboard;
|
EekKeyboard *keyboard;
|
||||||
EekKey *dragged_key;
|
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);
|
static EekColor * color_from_gdk_color (GdkColor *gdk_color);
|
||||||
@ -206,10 +209,13 @@ eek_gtk_keyboard_set_keyboard (EekGtkKeyboard *self,
|
|||||||
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
EekGtkKeyboardPrivate *priv = EEK_GTK_KEYBOARD_GET_PRIVATE(self);
|
||||||
priv->keyboard = g_object_ref (keyboard);
|
priv->keyboard = g_object_ref (keyboard);
|
||||||
|
|
||||||
|
priv->key_pressed_handler =
|
||||||
g_signal_connect (priv->keyboard, "key-pressed",
|
g_signal_connect (priv->keyboard, "key-pressed",
|
||||||
G_CALLBACK(on_key_pressed), self);
|
G_CALLBACK(on_key_pressed), self);
|
||||||
|
priv->key_released_handler =
|
||||||
g_signal_connect (priv->keyboard, "key-released",
|
g_signal_connect (priv->keyboard, "key-released",
|
||||||
G_CALLBACK(on_key_released), self);
|
G_CALLBACK(on_key_released), self);
|
||||||
|
priv->symbol_index_changed_handler =
|
||||||
g_signal_connect (priv->keyboard, "symbol-index-changed",
|
g_signal_connect (priv->keyboard, "symbol-index-changed",
|
||||||
G_CALLBACK(on_symbol_index_changed), self);
|
G_CALLBACK(on_symbol_index_changed), self);
|
||||||
}
|
}
|
||||||
@ -246,6 +252,19 @@ eek_gtk_keyboard_dispose (GObject *object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (priv->keyboard) {
|
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);
|
g_object_unref (priv->keyboard);
|
||||||
priv->keyboard = NULL;
|
priv->keyboard = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,6 +53,7 @@ struct _EekRendererPrivate
|
|||||||
PangoFontDescription *font;
|
PangoFontDescription *font;
|
||||||
GHashTable *outline_surface_cache;
|
GHashTable *outline_surface_cache;
|
||||||
cairo_surface_t *keyboard_surface;
|
cairo_surface_t *keyboard_surface;
|
||||||
|
gulong symbol_index_changed_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@ -536,6 +537,7 @@ eek_renderer_set_property (GObject *object,
|
|||||||
priv->keyboard = g_value_get_object (value);
|
priv->keyboard = g_value_get_object (value);
|
||||||
g_object_ref (priv->keyboard);
|
g_object_ref (priv->keyboard);
|
||||||
|
|
||||||
|
priv->symbol_index_changed_handler =
|
||||||
g_signal_connect (priv->keyboard, "symbol-index-changed",
|
g_signal_connect (priv->keyboard, "symbol-index-changed",
|
||||||
G_CALLBACK(on_symbol_index_changed),
|
G_CALLBACK(on_symbol_index_changed),
|
||||||
object);
|
object);
|
||||||
@ -553,6 +555,10 @@ eek_renderer_dispose (GObject *object)
|
|||||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
|
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
|
||||||
|
|
||||||
if (priv->keyboard) {
|
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);
|
g_object_unref (priv->keyboard);
|
||||||
priv->keyboard = NULL;
|
priv->keyboard = NULL;
|
||||||
}
|
}
|
||||||
@ -571,7 +577,6 @@ static void
|
|||||||
eek_renderer_finalize (GObject *object)
|
eek_renderer_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
|
EekRendererPrivate *priv = EEK_RENDERER_GET_PRIVATE(object);
|
||||||
|
|
||||||
g_hash_table_destroy (priv->outline_surface_cache);
|
g_hash_table_destroy (priv->outline_surface_cache);
|
||||||
G_OBJECT_CLASS (eek_renderer_parent_class)->finalize (object);
|
G_OBJECT_CLASS (eek_renderer_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -638,6 +643,7 @@ eek_renderer_init (EekRenderer *self)
|
|||||||
NULL,
|
NULL,
|
||||||
free_surface);
|
free_surface);
|
||||||
priv->keyboard_surface = NULL;
|
priv->keyboard_surface = NULL;
|
||||||
|
priv->symbol_index_changed_handler = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
|
|
||||||
static gchar *opt_set_keyboard = NULL;
|
static gchar *opt_set_keyboard = NULL;
|
||||||
|
static gint opt_set_group = -1;
|
||||||
static gboolean opt_show = FALSE;
|
static gboolean opt_show = FALSE;
|
||||||
static gboolean opt_hide = FALSE;
|
static gboolean opt_hide = FALSE;
|
||||||
static gboolean opt_listen = FALSE;
|
static gboolean opt_listen = FALSE;
|
||||||
@ -29,6 +30,8 @@ static gboolean opt_listen = FALSE;
|
|||||||
static const GOptionEntry options[] = {
|
static const GOptionEntry options[] = {
|
||||||
{"set-keyboard", '\0', 0, G_OPTION_ARG_STRING, &opt_set_keyboard,
|
{"set-keyboard", '\0', 0, G_OPTION_ARG_STRING, &opt_set_keyboard,
|
||||||
"Set keyboard from an XML file"},
|
"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", '\0', 0, G_OPTION_ARG_NONE, &opt_show,
|
||||||
"Show keyboard"},
|
"Show keyboard"},
|
||||||
{"hide", '\0', 0, G_OPTION_ARG_NONE, &opt_hide,
|
{"hide", '\0', 0, G_OPTION_ARG_NONE, &opt_hide,
|
||||||
@ -112,6 +115,10 @@ main (int argc, char **argv)
|
|||||||
g_object_unref (keyboard);
|
g_object_unref (keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt_set_group >= 0) {
|
||||||
|
eekboard_proxy_set_group (proxy, opt_set_group);
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_show) {
|
if (opt_show) {
|
||||||
eekboard_proxy_show (proxy);
|
eekboard_proxy_show (proxy);
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/server.c
31
src/server.c
@ -100,6 +100,16 @@ on_allocation_changed (ClutterActor *stage,
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
static void
|
||||||
update_widget (EekboardServer *server)
|
update_widget (EekboardServer *server)
|
||||||
{
|
{
|
||||||
@ -141,6 +151,8 @@ update_widget (EekboardServer *server)
|
|||||||
gtk_widget_set_size_request (server->widget, bounds.width, bounds.height);
|
gtk_widget_set_size_request (server->widget, bounds.width, bounds.height);
|
||||||
|
|
||||||
server->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
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_container_add (GTK_CONTAINER(server->window), server->widget);
|
||||||
|
|
||||||
gtk_widget_set_can_focus (server->window, FALSE);
|
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_keyboard_set_modifier_behavior (server->keyboard,
|
||||||
EEK_MODIFIER_BEHAVIOR_LATCH);
|
EEK_MODIFIER_BEHAVIOR_LATCH);
|
||||||
|
|
||||||
|
if (server->window) {
|
||||||
|
gboolean was_visible = gtk_widget_get_visible (server->window);
|
||||||
update_widget (server);
|
update_widget (server);
|
||||||
|
if (was_visible)
|
||||||
|
gtk_widget_show_all (server->window);
|
||||||
|
}
|
||||||
|
|
||||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -326,6 +344,14 @@ handle_method_call (GDBusConnection *connection,
|
|||||||
|
|
||||||
g_variant_get (parameters, "(i)", &group);
|
g_variant_get (parameters, "(i)", &group);
|
||||||
eek_keyboard_set_group (server->keyboard, 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);
|
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -339,11 +365,12 @@ handle_method_call (GDBusConnection *connection,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server->window)
|
if (!server->window)
|
||||||
|
update_widget (server);
|
||||||
|
g_assert (server->window);
|
||||||
gtk_widget_show_all (server->window);
|
gtk_widget_show_all (server->window);
|
||||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_strcmp0 (method_name, "Hide") == 0) {
|
if (g_strcmp0 (method_name, "Hide") == 0) {
|
||||||
|
|||||||
@ -51,11 +51,11 @@ struct _EekboardSystemClient {
|
|||||||
XklConfigRegistry *xkl_config_registry;
|
XklConfigRegistry *xkl_config_registry;
|
||||||
FakeKey *fakekey;
|
FakeKey *fakekey;
|
||||||
|
|
||||||
gulong xkl_config_changed_handler_id;
|
gulong xkl_config_changed_handler;
|
||||||
gulong xkl_state_changed_handler_id;
|
gulong xkl_state_changed_handler;
|
||||||
|
|
||||||
gulong key_pressed_handler_id;
|
gulong key_pressed_handler;
|
||||||
gulong key_released_handler_id;
|
gulong key_released_handler;
|
||||||
|
|
||||||
AccessibleEventListener *focus_listener;
|
AccessibleEventListener *focus_listener;
|
||||||
AccessibleEventListener *keystroke_listener;
|
AccessibleEventListener *keystroke_listener;
|
||||||
@ -167,10 +167,10 @@ eekboard_system_client_init (EekboardSystemClient *client)
|
|||||||
client->keystroke_listener = NULL;
|
client->keystroke_listener = NULL;
|
||||||
client->proxy = NULL;
|
client->proxy = NULL;
|
||||||
client->fakekey = NULL;
|
client->fakekey = NULL;
|
||||||
client->key_pressed_handler_id = 0;
|
client->key_pressed_handler = 0;
|
||||||
client->key_released_handler_id = 0;
|
client->key_released_handler = 0;
|
||||||
client->xkl_config_changed_handler_id = 0;
|
client->xkl_config_changed_handler = 0;
|
||||||
client->xkl_state_changed_handler_id = 0;
|
client->xkl_state_changed_handler = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -189,10 +189,10 @@ eekboard_system_client_enable_xkl (EekboardSystemClient *client)
|
|||||||
xkl_config_registry_load (client->xkl_config_registry, FALSE);
|
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_signal_connect (client->xkl_engine, "X-config-changed",
|
||||||
G_CALLBACK(on_xkl_config_changed), client);
|
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_signal_connect (client->xkl_engine, "X-state-changed",
|
||||||
G_CALLBACK(on_xkl_state_changed), client);
|
G_CALLBACK(on_xkl_state_changed), client);
|
||||||
|
|
||||||
@ -216,13 +216,13 @@ eekboard_system_client_disable_xkl (EekboardSystemClient *client)
|
|||||||
if (client->xkl_engine)
|
if (client->xkl_engine)
|
||||||
xkl_engine_stop_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE);
|
xkl_engine_stop_listen (client->xkl_engine, XKLL_TRACK_KEYBOARD_STATE);
|
||||||
if (g_signal_handler_is_connected (client->xkl_engine,
|
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,
|
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,
|
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,
|
g_signal_handler_disconnect (client->xkl_engine,
|
||||||
client->xkl_state_changed_handler_id);
|
client->xkl_state_changed_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
@ -450,10 +450,10 @@ eekboard_system_client_enable_fakekey (EekboardSystemClient *client)
|
|||||||
}
|
}
|
||||||
g_assert (client->fakekey);
|
g_assert (client->fakekey);
|
||||||
|
|
||||||
client->key_pressed_handler_id =
|
client->key_pressed_handler =
|
||||||
g_signal_connect (client->proxy, "key-pressed",
|
g_signal_connect (client->proxy, "key-pressed",
|
||||||
G_CALLBACK(on_key_pressed), client);
|
G_CALLBACK(on_key_pressed), client);
|
||||||
client->key_released_handler_id =
|
client->key_released_handler =
|
||||||
g_signal_connect (client->proxy, "key-pressed",
|
g_signal_connect (client->proxy, "key-pressed",
|
||||||
G_CALLBACK(on_key_released), client);
|
G_CALLBACK(on_key_released), client);
|
||||||
|
|
||||||
@ -467,11 +467,11 @@ eekboard_system_client_disable_fakekey (EekboardSystemClient *client)
|
|||||||
fakekey_release (client->fakekey);
|
fakekey_release (client->fakekey);
|
||||||
|
|
||||||
if (g_signal_handler_is_connected (client->proxy,
|
if (g_signal_handler_is_connected (client->proxy,
|
||||||
client->key_pressed_handler_id))
|
client->key_pressed_handler))
|
||||||
g_signal_handler_disconnect (client->proxy,
|
g_signal_handler_disconnect (client->proxy,
|
||||||
client->key_pressed_handler_id);
|
client->key_pressed_handler);
|
||||||
if (g_signal_handler_is_connected (client->proxy,
|
if (g_signal_handler_is_connected (client->proxy,
|
||||||
client->key_released_handler_id))
|
client->key_released_handler))
|
||||||
g_signal_handler_disconnect (client->proxy,
|
g_signal_handler_disconnect (client->proxy,
|
||||||
client->key_released_handler_id);
|
client->key_released_handler);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user