From 39fa54405614335fccfad5dfcf5b420ab3cf3c06 Mon Sep 17 00:00:00 2001 From: Jihoon Kim Date: Wed, 18 Jan 2012 04:38:04 +0000 Subject: [PATCH] From: Jihoon Kim Long time ago, in http://www.mail-archive.com/enlightenment-devel@lists.sourceforge.net/msg32795.html mail thread and IRC, I talked with about problem of asynchronous event API such as ecore_imf_context_commit_event_add, ecore_imf_context_preedit_changed_event_add, so on. In short, The problem is that key event and text_set APIs are processed immediately, but commit event and preedit changed event is processed asynchronously because those APIs add each event to ecore event queue. To fix these problems, I've decided to create synchronous event APIs such as ecore_imf_context_event_callback_add, del and call. For considering compatibility, sync and async event callback functions are used in xim and scim immodule. SVN revision: 67290 --- src/bin/e_entry.c | 100 +++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 58 deletions(-) diff --git a/src/bin/e_entry.c b/src/bin/e_entry.c index 4c1860c98..0eea437a7 100644 --- a/src/bin/e_entry.c +++ b/src/bin/e_entry.c @@ -16,9 +16,6 @@ struct _E_Entry_Smart_Data #ifdef HAVE_ECORE_IMF Ecore_IMF_Context *imf_context; #endif - Ecore_Event_Handler *imf_ee_commit_handler; - Ecore_Event_Handler *imf_ee_preedit_changed_handler; - Ecore_Event_Handler *imf_ee_delete_handler; int enabled; int focused; @@ -63,9 +60,9 @@ static void _e_entry_imf_cursor_info_set(Evas_Object *object); static void _e_entry_imf_context_reset(Evas_Object *object); #ifdef HAVE_ECORE_IMF static Eina_Bool _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos); -static Eina_Bool _e_entry_cb_imf_event_commit(void *data, int type, void *event); -static Eina_Bool _e_entry_cb_imf_event_preedit_changed(void *data, int type __UNUSED__, void *event); -static Eina_Bool _e_entry_cb_imf_event_delete_surrounding(void *data, int type, void *event); +static void _e_entry_cb_imf_event_commit(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info); +static void _e_entry_cb_imf_event_preedit_changed(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info); +static void _e_entry_cb_imf_event_delete_surrounding(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info); #endif /* local subsystem globals */ @@ -252,9 +249,8 @@ e_entry_focus(Evas_Object *entry) edje_object_signal_emit(sd->entry_object, "e,state,focused", "e"); if (!sd->selection_dragging) { - e_editable_cursor_move_to_end(sd->editable_object); - _e_entry_imf_context_reset(entry); + e_editable_cursor_move_to_end(sd->editable_object); _e_entry_imf_cursor_info_set(entry); e_editable_selection_move_to_end(sd->editable_object); @@ -264,10 +260,7 @@ e_entry_focus(Evas_Object *entry) e_editable_selection_show(sd->editable_object); #ifdef HAVE_ECORE_IMF if (sd->imf_context) - { - ecore_imf_context_reset(sd->imf_context); - ecore_imf_context_focus_in(sd->imf_context); - } + ecore_imf_context_focus_in(sd->imf_context); #endif sd->focused = 1; } @@ -431,6 +424,8 @@ _e_entry_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *o } #endif + _e_entry_imf_context_reset(obj); + evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL); pos = e_editable_pos_get_from_coords(sd->editable_object, event->canvas.x - ox, @@ -549,7 +544,6 @@ _e_entry_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *o E_MENU_POP_DIRECTION_DOWN, event->timestamp); } - _e_entry_imf_context_reset(obj); _e_entry_imf_cursor_info_set(obj); } @@ -615,9 +609,8 @@ _e_entry_mouse_move_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *o pos = e_editable_pos_get_from_coords(sd->editable_object, event->cur.canvas.x - ox, event->cur.canvas.y - oy); - e_editable_cursor_pos_set(sd->editable_object, pos); - _e_entry_imf_context_reset(obj); + e_editable_cursor_pos_set(sd->editable_object, pos); _e_entry_imf_cursor_info_set(obj); } } @@ -727,6 +720,10 @@ _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event) start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos; end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos; selecting = (start_pos != end_pos); + + if ((!strcmp(event->key, "Escape")) || + (!strcmp(event->key, "Return")) || (!strcmp(event->key, "KP_Enter"))) + _e_entry_imf_context_reset(entry); /* Move the cursor/selection to the left */ if (strcmp(event->key, "Left") == 0) @@ -850,7 +847,6 @@ _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event) changed |= e_editable_insert(editable, start_pos, event->string); } - _e_entry_imf_context_reset(entry); _e_entry_imf_cursor_info_set(entry); if (changed) @@ -884,7 +880,11 @@ _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event) start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos; end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos; selecting = (start_pos != end_pos); - + + if ((!strcmp(event->key, "Escape")) || + (!strcmp(event->key, "Return")) || (!strcmp(event->key, "KP_Enter"))) + _e_entry_imf_context_reset(entry); + /* Move the cursor/selection to the left */ if ((strcmp(event->key, "Left") == 0) || ((evas_key_modifier_is_set(event->modifiers, "Control")) && @@ -997,7 +997,6 @@ _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event) (event->string[0] >= 0x20 && event->string[0] != 0x7f))) changed = e_editable_insert(editable, cursor_pos, event->string); - _e_entry_imf_context_reset(entry); _e_entry_imf_cursor_info_set(entry); if (changed) @@ -1056,15 +1055,9 @@ _e_entry_smart_add(Evas_Object *object) ecore_imf_context_retrieve_surrounding_callback_set(sd->imf_context, _e_entry_cb_imf_retrieve_surrounding, sd); - sd->imf_ee_commit_handler = - ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, - _e_entry_cb_imf_event_commit, object); - sd->imf_ee_preedit_changed_handler = - ecore_event_handler_add(ECORE_IMF_EVENT_PREEDIT_CHANGED, - _e_entry_cb_imf_event_preedit_changed, object); - sd->imf_ee_delete_handler = - ecore_event_handler_add(ECORE_IMF_EVENT_DELETE_SURROUNDING, - _e_entry_cb_imf_event_delete_surrounding, sd); + ecore_imf_context_event_callback_add(sd->imf_context, ECORE_IMF_CALLBACK_COMMIT, _e_entry_cb_imf_event_commit, object); + ecore_imf_context_event_callback_add(sd->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _e_entry_cb_imf_event_preedit_changed, object); + ecore_imf_context_event_callback_add(sd->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _e_entry_cb_imf_event_delete_surrounding, sd); } #endif @@ -1116,12 +1109,10 @@ _e_entry_smart_del(Evas_Object *object) #ifdef HAVE_ECORE_IMF if (sd->imf_context) { - if (sd->imf_ee_commit_handler) - ecore_event_handler_del(sd->imf_ee_commit_handler); - if (sd->imf_ee_preedit_changed_handler) - ecore_event_handler_del(sd->imf_ee_preedit_changed_handler); - if (sd->imf_ee_delete_handler) - ecore_event_handler_del(sd->imf_ee_delete_handler); + ecore_imf_context_event_callback_del(sd->imf_context, ECORE_IMF_CALLBACK_COMMIT, _e_entry_cb_imf_event_commit); + ecore_imf_context_event_callback_del(sd->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _e_entry_cb_imf_event_preedit_changed); + ecore_imf_context_event_callback_del(sd->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _e_entry_cb_imf_event_delete_surrounding); + ecore_imf_context_del(sd->imf_context); } #endif @@ -1413,23 +1404,23 @@ _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx __UNUSED return EINA_TRUE; } -static Eina_Bool -_e_entry_cb_imf_event_commit(void *data, int type __UNUSED__, void *event) +static void +_e_entry_cb_imf_event_commit(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info) { Evas_Object *entry; E_Entry_Smart_Data *sd; - Ecore_IMF_Event_Commit *ev = event; Evas_Object *editable; + char *commit_str = event_info; int cursor_pos, selection_pos; int start_pos, end_pos; int selecting; int changed = 0; if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry)))) - return ECORE_CALLBACK_PASS_ON; + return; - if ((!sd->imf_context) || (sd->imf_context != ev->ctx)) - return ECORE_CALLBACK_PASS_ON; + if (!sd->imf_context) + return; editable = sd->editable_object; cursor_pos = e_editable_cursor_pos_get(editable); @@ -1450,22 +1441,19 @@ _e_entry_cb_imf_event_commit(void *data, int type __UNUSED__, void *event) start_pos = sd->preedit_start_pos; } - changed |= e_editable_insert(editable, start_pos, ev->str); + changed |= e_editable_insert(editable, start_pos, commit_str); _e_entry_imf_cursor_info_set(entry); if (changed) evas_object_smart_callback_call(entry, "changed", NULL); - - return ECORE_CALLBACK_DONE; } -static Eina_Bool -_e_entry_cb_imf_event_preedit_changed(void *data, int type __UNUSED__, void *event) +static void +_e_entry_cb_imf_event_preedit_changed(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info) { Evas_Object *entry; E_Entry_Smart_Data *sd; - Ecore_IMF_Event_Preedit_Changed *ev = event; Evas_Object *editable; int cursor_pos, selection_pos; char *preedit_string = NULL; @@ -1474,14 +1462,14 @@ _e_entry_cb_imf_event_preedit_changed(void *data, int type __UNUSED__, void *eve int changed = 0; if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry)))) - return ECORE_CALLBACK_PASS_ON; + return; - if ((!sd->imf_context) || (sd->imf_context != ev->ctx)) - return ECORE_CALLBACK_PASS_ON; + if (!sd->imf_context) + return; /* Get the preedit string from IMF */ ecore_imf_context_preedit_string_get(sd->imf_context, &preedit_string, &cursor_pos); - if (!preedit_string) return ECORE_CALLBACK_PASS_ON; + if (!preedit_string) return; editable = sd->editable_object; cursor_pos = e_editable_cursor_pos_get(editable); @@ -1519,29 +1507,25 @@ _e_entry_cb_imf_event_preedit_changed(void *data, int type __UNUSED__, void *eve evas_object_smart_callback_call(entry, "preedit,changed", NULL); free(preedit_string); - - return ECORE_CALLBACK_DONE; } -static Eina_Bool -_e_entry_cb_imf_event_delete_surrounding(void *data, int type __UNUSED__, void *event) +static void +_e_entry_cb_imf_event_delete_surrounding(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info) { E_Entry_Smart_Data *sd; - Ecore_IMF_Event_Delete_Surrounding *ev = event; + Ecore_IMF_Event_Delete_Surrounding *ev = event_info; Evas_Object *editable; int cursor_pos; sd = data; - if (sd->imf_context != ev->ctx) - return ECORE_CALLBACK_PASS_ON; + if ((!sd) || (!sd->imf_context)) + return; editable = sd->editable_object; cursor_pos = e_editable_cursor_pos_get(editable); e_editable_delete(editable, cursor_pos + ev->offset, cursor_pos + ev->offset + ev->n_chars); - - return ECORE_CALLBACK_DONE; } #endif