Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3024)

Unified Diff: bus/ibusimpl.c

Issue 1702015: Support engine specific hotkey. (Closed) Base URL: ssh://git@chromiumos-git/ibus.git
Patch Set: Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « bus/ibusimpl.h ('k') | ibus/component.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: bus/ibusimpl.c
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
index ee5f9993206151781769da446ee1c64aa3daaf3d..01ec61c6fd88eb3ec535c85272a848a1b8a624f2 100644
--- a/bus/ibusimpl.c
+++ b/bus/ibusimpl.c
@@ -88,6 +88,10 @@ static void bus_ibus_impl_global_engine_changed
static void _factory_destroy_cb (BusFactoryProxy *factory,
BusIBusImpl *ibus);
+static void bus_ibus_impl_set_context_engine_from_desc
+ (BusIBusImpl *ibus,
+ BusInputContext *context,
+ IBusEngineDesc *engine_desc);
static void bus_ibus_impl_set_context_engine(BusIBusImpl *ibus,
BusInputContext *context,
BusEngineProxy *engine);
@@ -101,6 +105,8 @@ static gchar *bus_ibus_impl_load_global_previous_engine_name_from_config
(BusIBusImpl *ibus);
static void bus_ibus_impl_save_global_previous_engine_name_to_config
(BusIBusImpl *ibus);
+static void bus_ibus_impl_update_engines_hotkey_profile
+ (BusIBusImpl *ibus);
G_DEFINE_TYPE(BusIBusImpl, bus_ibus_impl, IBUS_TYPE_SERVICE)
@@ -248,6 +254,8 @@ bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus,
ibus_component_start (component, g_verbose);
}
}
+
+ bus_ibus_impl_update_engines_hotkey_profile (ibus);
}
static void
@@ -606,6 +614,9 @@ bus_ibus_impl_init (BusIBusImpl *ibus)
ibus->global_engine = NULL;
ibus->global_previous_engine_name = NULL;
+ ibus->engines_hotkey_profile = NULL;
+ ibus->hotkey_to_engines_map = NULL;
+
bus_ibus_impl_reload_config (ibus);
g_signal_connect (BUS_DEFAULT_DBUS,
@@ -682,6 +693,16 @@ bus_ibus_impl_destroy (BusIBusImpl *ibus)
g_free (ibus->global_previous_engine_name);
+ if (ibus->engines_hotkey_profile != NULL) {
+ g_object_unref (ibus->engines_hotkey_profile);
+ ibus->engines_hotkey_profile = NULL;
+ }
+
+ if (ibus->hotkey_to_engines_map) {
+ g_hash_table_unref (ibus->hotkey_to_engines_map);
+ ibus->hotkey_to_engines_map = NULL;
+ }
+
bus_server_quit (BUS_DEFAULT_SERVER);
ibus_object_destroy ((IBusObject *) BUS_DEFAULT_SERVER);
IBUS_OBJECT_CLASS(bus_ibus_impl_parent_class)->destroy (IBUS_OBJECT (ibus));
@@ -891,12 +912,7 @@ _context_request_engine_cb (BusInputContext *context,
engine_desc = _find_engine_desc_by_name (ibus, engine_name);
}
- if (engine_desc != NULL) {
- engine = bus_ibus_impl_create_engine (engine_desc);
- if (engine != NULL) {
- bus_ibus_impl_set_context_engine (ibus, context, engine);
- }
- }
+ bus_ibus_impl_set_context_engine_from_desc (ibus, context, engine_desc);
}
static void
@@ -939,12 +955,7 @@ bus_ibus_impl_context_request_next_engine_in_menu (BusIBusImpl *ibus,
}
}
- if (next_desc != NULL) {
- engine = bus_ibus_impl_create_engine (next_desc);
- if (engine != NULL) {
- bus_ibus_impl_set_context_engine (ibus, context, engine);
- }
- }
+ bus_ibus_impl_set_context_engine_from_desc (ibus, context, next_desc);
}
static void
@@ -1013,6 +1024,19 @@ bus_ibus_impl_set_global_engine (BusIBusImpl *ibus,
}
static void
+bus_ibus_impl_set_context_engine_from_desc (BusIBusImpl *ibus,
+ BusInputContext *context,
+ IBusEngineDesc *engine_desc)
+{
+ if (engine_desc != NULL) {
+ BusEngineProxy *engine = bus_ibus_impl_create_engine (engine_desc);
+ if (engine != NULL) {
+ bus_ibus_impl_set_context_engine (ibus, context, engine);
+ }
+ }
+}
+
+static void
bus_ibus_impl_set_context_engine (BusIBusImpl *ibus,
BusInputContext *context,
BusEngineProxy *engine) {
@@ -1285,6 +1309,8 @@ _factory_destroy_cb (BusFactoryProxy *factory,
}
g_object_unref (factory);
+
+ bus_ibus_impl_update_engines_hotkey_profile (ibus);
}
static void
@@ -1344,6 +1370,8 @@ _ibus_register_component (BusIBusImpl *ibus,
ibus->register_engine_list = g_list_concat (ibus->register_engine_list, engines);
g_object_unref (component);
+ bus_ibus_impl_update_engines_hotkey_profile (ibus);
+
reply = ibus_message_new_method_return (message);
return reply;
}
@@ -1781,18 +1809,22 @@ bus_ibus_impl_filter_keyboard_shortcuts (BusIBusImpl *ibus,
static GQuark next = 0;
static GQuark previous = 0;
+ GQuark event;
+ GList *engine_list;
+
if (trigger == 0) {
trigger = g_quark_from_static_string ("trigger");
next = g_quark_from_static_string ("next-engine-in-menu");
previous = g_quark_from_static_string ("previous-engine");
}
- GQuark event = ibus_hotkey_profile_filter_key_event (ibus->hotkey_profile,
- keyval,
- modifiers,
- prev_keyval,
- prev_modifiers,
- 0);
+ /* Try global hotkeys first. */
+ event = ibus_hotkey_profile_filter_key_event (ibus->hotkey_profile,
+ keyval,
+ modifiers,
+ prev_keyval,
+ prev_modifiers,
+ 0);
if (event == trigger) {
gboolean enabled = bus_input_context_is_enabled (context);
@@ -1822,6 +1854,50 @@ bus_ibus_impl_filter_keyboard_shortcuts (BusIBusImpl *ibus,
}
return TRUE;
}
+
+ if (!ibus->engines_hotkey_profile || !ibus->hotkey_to_engines_map) {
+ return FALSE;
+ }
+
+ /* Then try engines hotkeys. */
+ event = ibus_hotkey_profile_filter_key_event (ibus->engines_hotkey_profile,
+ keyval,
+ modifiers,
+ prev_keyval,
+ prev_modifiers,
+ 0);
+ if (event == 0) {
+ return FALSE;
+ }
+
+ engine_list = g_hash_table_lookup (ibus->hotkey_to_engines_map,
+ GUINT_TO_POINTER (event));
+ if (engine_list) {
+ BusEngineProxy *current_engine = bus_input_context_get_engine (context);
+ IBusEngineDesc *current_engine_desc =
+ (current_engine ? bus_engine_proxy_get_desc (current_engine) : NULL);
+ IBusEngineDesc *new_engine_desc = (IBusEngineDesc *) engine_list->data;
+
+ g_assert (new_engine_desc);
+
+ /* Find out what engine we should switch to. If the current engine has
+ * the same hotkey, then we should switch to the next engine with the
+ * same hotkey in the list. Otherwise, we just switch to the first
+ * engine in the list. */
+ GList *p = engine_list;
+ for (; p->next != NULL; p = p->next) {
+ if (current_engine_desc == (IBusEngineDesc *) p->data) {
+ new_engine_desc = (IBusEngineDesc *) p->next->data;
+ break;
+ }
+ }
+
+ if (current_engine_desc != new_engine_desc) {
+ bus_ibus_impl_set_context_engine_from_desc (ibus, context, new_engine_desc);
+ return TRUE;
+ }
+ }
+
return FALSE;
}
@@ -1888,3 +1964,74 @@ bus_ibus_impl_save_global_previous_engine_name_to_config (BusIBusImpl *ibus)
g_value_unset (&value);
}
}
+
+static void
+_add_engine_hotkey (IBusEngineDesc *engine, BusIBusImpl *ibus)
+{
+ gchar **hotkey_list;
+ gchar **p;
+ gchar *hotkey;
+ GList *engine_list;
+
+ GQuark event;
+ guint keyval;
+ guint modifiers;
+
+ if (!engine || !engine->hotkeys || !*engine->hotkeys) {
+ return;
+ }
+
+ hotkey_list = g_strsplit_set (engine->hotkeys, ";,", 0);
+
+ for (p = hotkey_list; p && *p; ++p) {
+ hotkey = g_strstrip (*p);
+ if (!*hotkey || !ibus_key_event_from_string (hotkey, &keyval, &modifiers)) {
+ continue;
+ }
+
+ /* If the hotkey already exists, we won't need to add it again. */
+ event = ibus_hotkey_profile_lookup_hotkey (ibus->engines_hotkey_profile,
+ keyval, modifiers);
+ if (event == 0) {
+ event = g_quark_from_string (hotkey);
+ ibus_hotkey_profile_add_hotkey (ibus->engines_hotkey_profile,
+ keyval, modifiers, event);
+ }
+
+ engine_list = g_hash_table_lookup (ibus->hotkey_to_engines_map,
+ GUINT_TO_POINTER (event));
+
+ /* As we will rebuild the engines hotkey map whenever an engine was
+ * added or removed, we don't need to hold a reference of the engine
+ * here. */
+ engine_list = g_list_append (engine_list, engine);
+
+ /* We need to steal the value before adding it back, otherwise it will
+ * be destroyed. */
+ g_hash_table_steal (ibus->hotkey_to_engines_map, GUINT_TO_POINTER (event));
+
+ g_hash_table_insert (ibus->hotkey_to_engines_map,
+ GUINT_TO_POINTER (event), engine_list);
+ }
+
+ g_strfreev (hotkey_list);
+}
+
+static void
+bus_ibus_impl_update_engines_hotkey_profile (BusIBusImpl *ibus)
+{
+ if (ibus->engines_hotkey_profile) {
+ g_object_unref (ibus->engines_hotkey_profile);
+ }
+
+ if (ibus->hotkey_to_engines_map) {
+ g_hash_table_unref (ibus->hotkey_to_engines_map);
+ }
+
+ ibus->engines_hotkey_profile = ibus_hotkey_profile_new();
+ ibus->hotkey_to_engines_map =
+ g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_list_free);
+
+ g_list_foreach (ibus->register_engine_list, (GFunc) _add_engine_hotkey, ibus);
+ g_list_foreach (ibus->engine_list, (GFunc) _add_engine_hotkey, ibus);
+}
« no previous file with comments | « bus/ibusimpl.h ('k') | ibus/component.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698