summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeng Huang <shawn.p.huang@gmail.com>2009-03-29 13:44:25 +0800
committerPeng Huang <shawn.p.huang@gmail.com>2009-03-29 13:44:25 +0800
commit7600d42c7cb5ccd91f1da694e8196fc8f57cba7d (patch)
tree0b29abcb6236bcb3076d9d58a9b496c258d6834e
parenta3b47259c4bf15d5e0afb759acb2a68ebb7724b4 (diff)
downloadibus-7600d42c7cb5ccd91f1da694e8196fc8f57cba7d.tar.gz
ibus-7600d42c7cb5ccd91f1da694e8196fc8f57cba7d.tar.xz
ibus-7600d42c7cb5ccd91f1da694e8196fc8f57cba7d.zip
Use gtk key snooper to get the key events.
-rw-r--r--client/gtk2/ibusimcontext.c89
1 files changed, 77 insertions, 12 deletions
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
index b542bd3..f99e60a 100644
--- a/client/gtk2/ibusimcontext.c
+++ b/client/gtk2/ibusimcontext.c
@@ -32,6 +32,7 @@ struct _IBusIMContext {
/* instance members */
GtkIMContext *slave;
GdkWindow *client_window;
+ GdkWindow *event_window;
/* enabled */
gboolean enable;
@@ -62,6 +63,7 @@ static guint _signal_preedit_end_id = 0;
static guint _signal_delete_surrounding_id = 0;
static guint _signal_retrieve_surrounding_id = 0;
static GQuark _q_ibus_im_context = 0;
+static gboolean _use_key_snooper = TRUE;
/* functions prototype */
static void ibus_im_context_class_init (IBusIMContextClass *klass);
@@ -81,6 +83,10 @@ static void ibus_im_context_get_preedit_string
static void ibus_im_context_set_client_window
(GtkIMContext *context,
GdkWindow *client);
+
+static void ibus_im_context_set_event_window
+ (IBusIMContext *ibusimcontext,
+ GdkWindow *client);
static void ibus_im_context_set_cursor_location
(GtkIMContext *context,
GdkRectangle *area);
@@ -175,6 +181,30 @@ ibus_im_context_new (void)
return obj;
}
+static gint
+_key_snooper_cb (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ GdkWindow *gdkwindow;
+ GtkIMContext *imcontext;
+
+ if (!_use_key_snooper)
+ return 0;
+
+ gdkwindow = gtk_widget_get_window (widget);
+
+ if (gdkwindow == NULL)
+ return 0;
+
+ imcontext = (GtkIMContext *) g_object_get_qdata ((GObject *) gdkwindow, _q_ibus_im_context);
+
+ if (imcontext == NULL)
+ return 0;
+
+ return gtk_im_context_filter_keypress (imcontext, event);
+}
+
static void
ibus_im_context_class_init (IBusIMContextClass *klass)
{
@@ -218,6 +248,10 @@ ibus_im_context_class_init (IBusIMContextClass *klass)
g_assert (_signal_retrieve_surrounding_id != 0);
_q_ibus_im_context = g_quark_from_static_string ("IBusIMContext");
+
+ if (_use_key_snooper) {
+ gtk_key_snooper_install (_key_snooper_cb, NULL);
+ }
}
static void
@@ -227,6 +261,7 @@ ibus_im_context_init (GObject *obj)
IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (obj);
ibusimcontext->client_window = NULL;
+ ibusimcontext->event_window = NULL;
// Init ibus status
ibusimcontext->enable = FALSE;
@@ -300,13 +335,12 @@ ibus_im_context_finalize (GObject *obj)
ibus_object_destroy ((IBusObject *)ibusimcontext->ibuscontext);
}
- g_object_unref (ibusimcontext->slave);
+ ibus_im_context_set_client_window ((GtkIMContext *)ibusimcontext, NULL);
+ ibus_im_context_set_event_window (ibusimcontext, NULL);
- if (ibusimcontext->client_window) {
- if (g_object_steal_qdata ((GObject *) ibusimcontext->client_window, _q_ibus_im_context) == ibusimcontext) {
- g_object_unref (ibusimcontext);
- }
- g_object_unref (ibusimcontext->client_window);
+ if (ibusimcontext->slave) {
+ g_object_unref (ibusimcontext->slave);
+ ibusimcontext->slave = NULL;
}
// release preedit
@@ -322,13 +356,17 @@ ibus_im_context_finalize (GObject *obj)
static gboolean
ibus_im_context_filter_keypress (GtkIMContext *context,
- GdkEventKey *event)
+ GdkEventKey *event)
{
g_return_val_if_fail (context != NULL, FALSE);
g_return_val_if_fail (IBUS_IS_IM_CONTEXT (context), FALSE);
IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context);
+ if (event->window != ibusimcontext->client_window && event->window != ibusimcontext->event_window) {
+ ibus_im_context_set_event_window (ibusimcontext, event->window);
+ }
+
if (ibusimcontext->ibuscontext && ibusimcontext->has_focus) {
/* If context does not have focus, ibus will process key event in sync mode.
* It is a workaround for increase search in treeview.
@@ -454,7 +492,7 @@ ibus_im_context_get_preedit_string (GtkIMContext *context,
static void
-ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client)
+ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client)
{
g_return_if_fail (context != NULL);
g_return_if_fail (IBUS_IS_IM_CONTEXT (context));
@@ -462,20 +500,47 @@ ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client)
IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context);
if (ibusimcontext->client_window) {
- if (g_object_steal_qdata ((GObject *) ibusimcontext->client_window, _q_ibus_im_context) == ibusimcontext) {
- g_object_unref (ibusimcontext);
+ if (g_object_get_qdata ((GObject *) ibusimcontext->client_window, _q_ibus_im_context) == ibusimcontext) {
+ g_object_set_qdata ((GObject *) ibusimcontext->client_window, _q_ibus_im_context, NULL);
}
g_object_unref (ibusimcontext->client_window);
}
+ ibus_im_context_set_event_window (ibusimcontext, NULL);
+
if (client) {
g_object_ref (client);
- g_object_ref (context);
+ g_object_ref (ibusimcontext);
g_object_set_qdata_full ((GObject *) client, _q_ibus_im_context, context, g_object_unref);
}
ibusimcontext->client_window = client;
- gtk_im_context_set_client_window (ibusimcontext->slave, client);
+
+ if (ibusimcontext->slave)
+ gtk_im_context_set_client_window (ibusimcontext->slave, client);
+}
+
+static void
+ibus_im_context_set_event_window (IBusIMContext *ibusimcontext, GdkWindow *window)
+{
+ if (ibusimcontext->event_window) {
+ if (g_object_get_qdata ((GObject *) ibusimcontext->event_window, _q_ibus_im_context) == ibusimcontext) {
+ g_object_set_qdata ((GObject *) ibusimcontext->event_window, _q_ibus_im_context, NULL);
+ }
+ g_object_unref (ibusimcontext->event_window);
+ ibusimcontext->event_window = NULL;
+ }
+
+ if (window == ibusimcontext->client_window)
+ window = NULL;
+
+ if (window != NULL) {
+ g_object_ref (window);
+ g_object_ref (ibusimcontext);
+ g_object_set_qdata_full ((GObject *) window, _q_ibus_im_context, ibusimcontext, g_object_unref);
+ }
+
+ ibusimcontext->event_window = window;
}
static void