diff options
author | Daiki Ueno <ueno@gnu.org> | 2014-03-11 17:31:45 +0900 |
---|---|---|
committer | Daiki Ueno <ueno@unixuser.org> | 2014-03-11 18:00:31 +0900 |
commit | 99d67447737be2d0b08fefc4d9fba588621fe8fb (patch) | |
tree | 2f1c3d5e841c6efa207852a574666b0406fdc025 | |
parent | ef46df52104e1c2c09f4de504f5bc890ba6a877d (diff) | |
download | ibus-hangul-99d67447737be2d0b08fefc4d9fba588621fe8fb.tar.gz |
Allow hangul mode to be toggled
Since 1.5 of IBus, IME's enable/disable feature has gone, and one can
no longer quickly turn on/off IME status by keyboard (although he can
switch between an XKB layout and the Hangul IME with Super-Space, it
is known to be too slow/inconvenient). So, some IMEs have already
started providing enable/disable feature by themselves. See:
https://fedorahosted.org/i18n/ticket/26
This patch makes hangul_mode (currently not in use) to be switchable.
This is implemented in a similar manner as hanja_mode, except that I
renamed HanjaKeyList into more generic HotkeyList.
-rw-r--r-- | src/engine.c | 122 |
1 files changed, 94 insertions, 28 deletions
diff --git a/src/engine.c b/src/engine.c index 602f073..4cb792f 100644 --- a/src/engine.c +++ b/src/engine.c @@ -35,7 +35,7 @@ typedef struct _IBusHangulEngine IBusHangulEngine; typedef struct _IBusHangulEngineClass IBusHangulEngineClass; -typedef struct _HanjaKeyList HanjaKeyList; +typedef struct _HotkeyList HotkeyList; struct _IBusHangulEngine { IBusEngine parent; @@ -50,6 +50,7 @@ struct _IBusHangulEngine { IBusLookupTable *table; + IBusProperty *prop_hangul_mode; IBusProperty *prop_hanja_mode; IBusPropList *prop_list; }; @@ -63,7 +64,7 @@ struct KeyEvent { guint modifiers; }; -struct _HanjaKeyList { +struct _HotkeyList { guint all_modifiers; GArray *keys; }; @@ -159,17 +160,17 @@ static gboolean key_event_list_match (GArray *list, guint keyval, guint modifiers); -static void hanja_key_list_init (HanjaKeyList *list); -static void hanja_key_list_fini (HanjaKeyList *list); -static void hanja_key_list_set_from_string(HanjaKeyList *list, +static void hotkey_list_init (HotkeyList *list); +static void hotkey_list_fini (HotkeyList *list); +static void hotkey_list_set_from_string (HotkeyList *list, const char *str); -static void hanja_key_list_append (HanjaKeyList *list, +static void hotkey_list_append (HotkeyList *list, guint keyval, guint modifiers); -static gboolean hanja_key_list_match (HanjaKeyList *list, +static gboolean hotkey_list_match (HotkeyList *list, guint keyval, guint modifiers); -static gboolean hanja_key_list_has_modifier (HanjaKeyList *list, +static gboolean hotkey_list_has_modifier (HotkeyList *list, guint keyval); static glong ucschar_strlen (const ucschar* str); @@ -179,7 +180,8 @@ static HanjaTable *hanja_table = NULL; static HanjaTable *symbol_table = NULL; static IBusConfig *config = NULL; static GString *hangul_keyboard = NULL; -static HanjaKeyList hanja_keys; +static HotkeyList hangul_keys; +static HotkeyList hanja_keys; static int lookup_table_orientation = 0; static IBusKeymap *keymap = NULL; static gboolean word_commit = FALSE; @@ -243,17 +245,29 @@ ibus_hangul_init (IBusBus *bus) g_variant_unref(value); } - hanja_key_list_init(&hanja_keys); + hotkey_list_init(&hangul_keys); + + value = ibus_config_get_value (config, "engine/Hangul", + "HangulKeys"); + if (value != NULL) { + const gchar* str = g_variant_get_string (value, NULL); + hotkey_list_set_from_string(&hangul_keys, str); + g_variant_unref(value); + } else { + hotkey_list_append(&hangul_keys, IBUS_Hangul, 0); + } + + hotkey_list_init(&hanja_keys); value = ibus_config_get_value (config, "engine/Hangul", "HanjaKeys"); if (value != NULL) { const gchar* str = g_variant_get_string (value, NULL); - hanja_key_list_set_from_string(&hanja_keys, str); + hotkey_list_set_from_string(&hanja_keys, str); g_variant_unref(value); } else { - hanja_key_list_append(&hanja_keys, IBUS_Hangul_Hanja, 0); - hanja_key_list_append(&hanja_keys, IBUS_F9, 0); + hotkey_list_append(&hanja_keys, IBUS_Hangul_Hanja, 0); + hotkey_list_append(&hanja_keys, IBUS_F9, 0); } value = ibus_config_get_value (config, "engine/Hangul", @@ -280,7 +294,8 @@ ibus_hangul_exit (void) keymap = NULL; } - hanja_key_list_fini(&hanja_keys); + hotkey_list_fini(&hangul_keys); + hotkey_list_fini(&hanja_keys); hanja_table_delete (hanja_table); hanja_table = NULL; @@ -347,6 +362,18 @@ ibus_hangul_engine_init (IBusHangulEngine *hangul) hangul->prop_list = ibus_prop_list_new (); g_object_ref_sink (hangul->prop_list); + label = ibus_text_new_from_string (_("Hangul lock")); + tooltip = ibus_text_new_from_string (_("Enable/Disable Hangul mode")); + prop = ibus_property_new ("hangul_mode", + PROP_TYPE_TOGGLE, + label, + NULL, + tooltip, + TRUE, TRUE, PROP_STATE_UNCHECKED, NULL); + g_object_ref_sink (prop); + ibus_prop_list_append (hangul->prop_list, prop); + hangul->prop_hangul_mode = prop; + label = ibus_text_new_from_string (_("Hanja lock")); tooltip = ibus_text_new_from_string (_("Enable/Disable Hanja mode")); prop = ibus_property_new ("hanja_mode", @@ -394,6 +421,11 @@ ibus_hangul_engine_constructor (GType type, static void ibus_hangul_engine_destroy (IBusHangulEngine *hangul) { + if (hangul->prop_hangul_mode) { + g_object_unref (hangul->prop_hangul_mode); + hangul->prop_hangul_mode = NULL; + } + if (hangul->prop_hanja_mode) { g_object_unref (hangul->prop_hanja_mode); hangul->prop_hanja_mode = NULL; @@ -929,17 +961,31 @@ ibus_hangul_engine_process_key_event (IBusEngine *engine, if (keyval == IBUS_Shift_L || keyval == IBUS_Shift_R) return FALSE; - // If hanja key has any modifiers, we ignore that modifier keyval, - // or we cannot make the hanja key work. + // If a hotkey has any modifiers, we ignore that modifier + // keyval, or we cannot make the hanja key work. // Because when we get the modifier key alone, we commit the // current preedit string. So after that, even if we get the // right hanja key event, we don't have preedit string to be changed // to hanja word. // See this bug: http://code.google.com/p/ibus/issues/detail?id=1036 - if (hanja_key_list_has_modifier(&hanja_keys, keyval)) + if (hotkey_list_has_modifier(&hangul_keys, keyval)) + return FALSE; + + if (hotkey_list_match(&hangul_keys, keyval, modifiers)) { + if (hangul->hangul_mode) + ibus_hangul_engine_flush (hangul); + + hangul->hangul_mode = !hangul->hangul_mode; + return TRUE; + } + + if (!hangul->hangul_mode) + return FALSE; + + if (hotkey_list_has_modifier(&hanja_keys, keyval)) return FALSE; - if (hanja_key_list_match(&hanja_keys, keyval, modifiers)) { + if (hotkey_list_match(&hanja_keys, keyval, modifiers)) { if (hangul->hanja_list == NULL) { ibus_hangul_engine_update_lookup_table (hangul); } else { @@ -1095,6 +1141,12 @@ ibus_hangul_engine_focus_in (IBusEngine *engine) { IBusHangulEngine *hangul = (IBusHangulEngine *) engine; + if (hangul->hangul_mode) { + ibus_property_set_state (hangul->prop_hangul_mode, PROP_STATE_CHECKED); + } else { + ibus_property_set_state (hangul->prop_hangul_mode, PROP_STATE_UNCHECKED); + } + if (hangul->hanja_mode) { ibus_property_set_state (hangul->prop_hanja_mode, PROP_STATE_CHECKED); } else { @@ -1205,6 +1257,20 @@ ibus_hangul_engine_property_activate (IBusEngine *engine, argv[0] = "ibus-setup-hangul"; argv[1] = NULL; g_spawn_async (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error); + } else if (strcmp(prop_name, "hangul_mode") == 0) { + IBusHangulEngine *hangul = (IBusHangulEngine *) engine; + + hangul->hangul_mode = !hangul->hangul_mode; + if (hangul->hangul_mode) { + ibus_property_set_state (hangul->prop_hangul_mode, + PROP_STATE_CHECKED); + } else { + ibus_property_set_state (hangul->prop_hangul_mode, + PROP_STATE_UNCHECKED); + } + + ibus_engine_update_property (engine, hangul->prop_hangul_mode); + ibus_hangul_engine_flush (hangul); } else if (strcmp(prop_name, "hanja_mode") == 0) { IBusHangulEngine *hangul = (IBusHangulEngine *) engine; @@ -1276,7 +1342,7 @@ ibus_config_value_changed (IBusConfig *config, hangul_ic_select_keyboard (hangul->context, hangul_keyboard->str); } else if (strcmp(name, "HanjaKeys") == 0) { const gchar* str = g_variant_get_string(value, NULL); - hanja_key_list_set_from_string(&hanja_keys, str); + hotkey_list_set_from_string(&hanja_keys, str); } else if (strcmp(name, "WordCommit") == 0) { word_commit = g_variant_get_boolean (value); } else if (strcmp (name, "AutoReorder") == 0) { @@ -1358,20 +1424,20 @@ ibus_hangul_engine_candidate_clicked (IBusEngine *engine, } static void -hanja_key_list_init(HanjaKeyList* list) +hotkey_list_init(HotkeyList* list) { list->all_modifiers = 0; list->keys = g_array_sized_new(FALSE, TRUE, sizeof(struct KeyEvent), 4); } static void -hanja_key_list_fini(HanjaKeyList* list) +hotkey_list_fini(HotkeyList* list) { g_array_free(list->keys, TRUE); } static void -hanja_key_list_append_from_string(HanjaKeyList *list, const char* str) +hotkey_list_append_from_string(HotkeyList *list, const char* str) { guint keyval = 0; guint modifiers = 0; @@ -1379,19 +1445,19 @@ hanja_key_list_append_from_string(HanjaKeyList *list, const char* str) res = ibus_key_event_from_string(str, &keyval, &modifiers); if (res) { - hanja_key_list_append(list, keyval, modifiers); + hotkey_list_append(list, keyval, modifiers); } } static void -hanja_key_list_append(HanjaKeyList *list, guint keyval, guint modifiers) +hotkey_list_append(HotkeyList *list, guint keyval, guint modifiers) { list->all_modifiers |= modifiers; key_event_list_append(list->keys, keyval, modifiers); } static void -hanja_key_list_set_from_string(HanjaKeyList *list, const char* str) +hotkey_list_set_from_string(HotkeyList *list, const char* str) { gchar** items = g_strsplit(str, ",", 0); @@ -1401,20 +1467,20 @@ hanja_key_list_set_from_string(HanjaKeyList *list, const char* str) if (items != NULL) { int i; for (i = 0; items[i] != NULL; ++i) { - hanja_key_list_append_from_string(list, items[i]); + hotkey_list_append_from_string(list, items[i]); } g_strfreev(items); } } static gboolean -hanja_key_list_match(HanjaKeyList* list, guint keyval, guint modifiers) +hotkey_list_match(HotkeyList* list, guint keyval, guint modifiers) { return key_event_list_match(list->keys, keyval, modifiers); } static gboolean -hanja_key_list_has_modifier(HanjaKeyList* list, guint keyval) +hotkey_list_has_modifier(HotkeyList* list, guint keyval) { if (list->all_modifiers & IBUS_CONTROL_MASK) { if (keyval == IBUS_Control_L || keyval == IBUS_Control_R) |