Index: client-common/scim-bridge-client.c =================================================================== RCS file: /cvsroot/scim/scim-bridge/client-common/scim-bridge-client.c,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- client-common/scim-bridge-client.c 24 Sep 2006 10:06:37 -0000 1.26 +++ client-common/scim-bridge-client.c 28 Sep 2006 16:23:58 -0000 1.27 @@ -1421,19 +1421,7 @@ } } - while (pending_response.status == RESPONSE_PENDING) { - if (scim_bridge_client_read_and_dispatch ()) { - scim_bridge_perrorln ("An IOException at scim_bridge_client_reset_imcontext ()"); - pending_response.header = NULL; - pending_response.status = RESPONSE_DONE; - - return RETVAL_FAILED; - } - } - scim_bridge_pdebugln (6, "reseted: id = %d", id); - pending_response.header = NULL; - pending_response.status = RESPONSE_DONE; return RETVAL_SUCCEEDED; } Index: client-gtk/scim-bridge-client-imcontext-gtk.c =================================================================== RCS file: /cvsroot/scim/scim-bridge/client-gtk/scim-bridge-client-imcontext-gtk.c,v retrieving revision 1.56 retrieving revision 1.59 diff -u -r1.56 -r1.59 --- client-gtk/scim-bridge-client-imcontext-gtk.c 24 Sep 2006 10:06:37 -0000 1.56 +++ client-gtk/scim-bridge-client-imcontext-gtk.c 28 Sep 2006 16:23:58 -0000 1.59 @@ -65,6 +65,7 @@ int window_y; }; + /* Private variables */ static GdkColor preedit_normal_background; static GdkColor preedit_normal_foreground; @@ -75,9 +76,10 @@ static GObjectClass *root_klass = NULL; static ScimBridgeClientIMContext *focused_imcontext = NULL; +static GtkWidget *focused_widget = NULL; static GtkIMContext *fallback_imcontext = NULL; -static gulong fallback_commit_handler; +static gulong fallback_commit_handler; static guint key_snooper_id = 0; static boolean key_snooper_used = FALSE; @@ -112,8 +114,10 @@ { scim_bridge_pdebugln (5, "filter_key_event ()"); - if (focused_imcontext != imcontext) scim_bridge_client_imcontext_focus_in (GTK_IM_CONTEXT (imcontext)); - + GtkWidget *widget = gtk_get_event_widget ((GdkEvent*) event); + if (focused_imcontext != imcontext || (focused_widget != NULL && focused_widget != widget)) scim_bridge_client_imcontext_focus_in (GTK_IM_CONTEXT (imcontext)); + focused_widget = widget; + if (scim_bridge_client_is_messenger_opened ()) { ScimBridgeKeyEvent *bridge_key_event = scim_bridge_alloc_key_event (); scim_bridge_key_event_gdk_to_bridge (bridge_key_event, imcontext->client_window, event); @@ -165,7 +169,7 @@ { scim_bridge_pdebugln (7, "key_snooper ()"); - if (scim_bridge_client_is_messenger_opened () && focused_imcontext != NULL) { + if (!event->send_event && scim_bridge_client_is_messenger_opened () && focused_imcontext != NULL) { if (focused_imcontext->client_window != NULL) { int new_window_x; int new_window_y; @@ -381,10 +385,23 @@ void scim_bridge_client_imcontext_forward_key_event (ScimBridgeClientIMContext *imcontext, const ScimBridgeKeyEvent *key_event) -{ +{ GdkEventKey gdk_event; scim_bridge_key_event_bridge_to_gdk (&gdk_event, imcontext->client_window, key_event); - gdk_event_put ((GdkEvent*) &gdk_event); + gdk_event.send_event = TRUE; + if (imcontext == focused_imcontext && focused_widget != NULL) { + const char *signal_name = NULL; + if (scim_bridge_key_event_is_pressed (key_event)) { + signal_name = "key-press-event"; + } else { + signal_name = "key-release-event"; + } + + gboolean consumed; + g_signal_emit_by_name (focused_widget, signal_name, &gdk_event, &consumed); + } else { + gdk_event_put ((GdkEvent*) &gdk_event); + } } @@ -559,8 +576,8 @@ scim_bridge_pdebugln (8, "scim_bridge_client_imcontext_filter_key_event ()"); ScimBridgeClientIMContext *imcontext = SCIM_BRIDGE_CLIENT_IMCONTEXT (context); - - if (scim_bridge_client_is_messenger_opened () && imcontext != NULL && !key_snooper_used) { + + if (!event->send_event && scim_bridge_client_is_messenger_opened () && imcontext != NULL && !key_snooper_used) { if (imcontext->client_window != NULL) { int new_window_x; @@ -725,9 +742,8 @@ scim_bridge_pdebugln (8, "scim_bridge_client_imcontext_focus_in ()"); ScimBridgeClientIMContext *imcontext = SCIM_BRIDGE_CLIENT_IMCONTEXT (context); - + if (focused_imcontext != NULL) scim_bridge_client_imcontext_focus_out (GTK_IM_CONTEXT (focused_imcontext)); - focused_imcontext = imcontext; if (!scim_bridge_client_is_messenger_opened () && scim_bridge_client_is_reconnection_enabled ()) { @@ -752,6 +768,7 @@ scim_bridge_pdebugln (8, "scim_bridge_client_imcontext_focus_out ()"); ScimBridgeClientIMContext *imcontext = SCIM_BRIDGE_CLIENT_IMCONTEXT (context); + focused_widget = NULL; focused_imcontext = imcontext; if (imcontext->preedit_shown) { Index: client-gtk/scim-bridge-client-key-event-utility-gtk.c =================================================================== RCS file: /cvsroot/scim/scim-bridge/client-gtk/scim-bridge-client-key-event-utility-gtk.c,v retrieving revision 1.6 retrieving revision 1.8 diff -u -r1.6 -r1.8 --- client-gtk/scim-bridge-client-key-event-utility-gtk.c 24 Sep 2006 10:06:37 -0000 1.6 +++ client-gtk/scim-bridge-client-key-event-utility-gtk.c 27 Sep 2006 15:13:28 -0000 1.8 @@ -25,6 +25,8 @@ #include "scim-bridge-client-key-event-utility-gtk.h" #include "scim-bridge-key-event.h" + +/* Helper Functions */ static GdkKeymap *get_gdk_keymap (GdkWindow *window) { #if GDK_MULTIHEAD_SAFE @@ -35,6 +37,7 @@ } +/* Implementations */ void scim_bridge_key_event_bridge_to_gdk (GdkEventKey *gdk_key_event, GdkWindow *client_window, const ScimBridgeKeyEvent *key_event) { gdk_key_event->state = 0; @@ -56,7 +59,6 @@ struct timeval current_time; gettimeofday (¤t_time, NULL); - gdk_key_event->send_event = TRUE; gdk_key_event->time = current_time.tv_sec * 1000 + current_time.tv_usec / 1000; gdk_key_event->keyval = scim_bridge_key_event_get_code (key_event); gdk_key_event->length = 0; Index: client-qt/scim-bridge-client-imcontext-qt.cpp =================================================================== RCS file: /cvsroot/scim/scim-bridge/client-qt/scim-bridge-client-imcontext-qt.cpp,v retrieving revision 1.6 retrieving revision 1.9 diff -u -r1.6 -r1.9 --- client-qt/scim-bridge-client-imcontext-qt.cpp 24 Sep 2006 10:06:37 -0000 1.6 +++ client-qt/scim-bridge-client-imcontext-qt.cpp 28 Sep 2006 16:23:58 -0000 1.9 @@ -31,6 +31,8 @@ static ScimBridgeClientIMContextImpl *focused_imcontext = NULL; +static QKeyEvent *forwarded_key_event = NULL; + /* Class Definition */ class ScimBridgeClientIMContextImpl: public _ScimBridgeClientIMContext @@ -193,11 +195,14 @@ scim_bridge_pdebugln (5, "ScimBridgeClientIMContextImpl::filterEvent ()"); if (event->type() != QEvent::KeyPress && event->type() != QEvent::KeyRelease) return false; + + const QKeyEvent *key_event = static_cast<const QKeyEvent*> (event); + if (key_event == forwarded_key_event) return false; if (focused_imcontext != this) focus_in (); if (scim_bridge_client_is_messenger_opened ()) { - ScimBridgeKeyEvent *bridge_key_event = scim_bridge_key_event_qt_to_bridge ((const QKeyEvent*) event); + ScimBridgeKeyEvent *bridge_key_event = scim_bridge_key_event_qt_to_bridge (key_event); boolean consumed = FALSE; const retval_t retval_error = scim_bridge_client_handle_key_event (this, bridge_key_event, &consumed); @@ -211,7 +216,7 @@ } } - return FALSE; + return false; } @@ -322,8 +327,10 @@ QWidget *focused_widget = qApp->focusWidget (); if (focused_widget != NULL) { - QKeyEvent *qt_key_event = scim_bridge_key_event_bridge_to_qt (key_event); - QApplication::sendEvent (focused_widget, qt_key_event); + forwarded_key_event = scim_bridge_key_event_bridge_to_qt (key_event); + QApplication::sendEvent (focused_widget, forwarded_key_event); + delete forwarded_key_event; + forwarded_key_event = NULL; } }