875 lines
30 KiB
Diff
875 lines
30 KiB
Diff
|
From a3a7b364410511b3a17f2b1566ba4c4c4f0de2cf Mon Sep 17 00:00:00 2001
|
||
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
||
|
Date: Tue, 21 Jun 2011 17:00:54 +0900
|
||
|
Subject: [PATCH] Add a bridge hotkey which use prev-next engines instead
|
||
|
of on-off.
|
||
|
|
||
|
---
|
||
|
bus/Makefile.am | 20 ++--
|
||
|
bus/ibusimpl.c | 244 ++++++++++++++++++++++++++++----------
|
||
|
bus/registry.c | 35 ++++++
|
||
|
configure.ac | 31 +++++
|
||
|
data/Makefile.am | 6 +-
|
||
|
data/ibus.schemas.in | 286 --------------------------------------------
|
||
|
data/ibus.schemas.in.in | 286 ++++++++++++++++++++++++++++++++++++++++++++
|
||
|
ibus/_config.py.in | 6 +
|
||
|
ibus/inputcontext.py | 4 +
|
||
|
src/Makefile.am | 1 +
|
||
|
src/ibusbus.c | 6 +
|
||
|
src/ibusbus.h | 9 ++
|
||
|
src/ibusenginedesc.c | 4 +
|
||
|
src/ibushotkey.c | 11 ++
|
||
|
src/ibushotkey.h | 11 ++
|
||
|
ui/gtk/panel.py | 60 +++++++++-
|
||
|
xkb/Makefile.am | 2 +
|
||
|
xkb/ibus-engine-xkb-main.c | 8 ++
|
||
|
xkb/xkbxml.c | 8 +-
|
||
|
19 files changed, 677 insertions(+), 361 deletions(-)
|
||
|
delete mode 100644 data/ibus.schemas.in
|
||
|
create mode 100644 data/ibus.schemas.in.in
|
||
|
|
||
|
diff --git a/bus/Makefile.am b/bus/Makefile.am
|
||
|
index 074b456..0efaa1b 100644
|
||
|
--- a/bus/Makefile.am
|
||
|
+++ b/bus/Makefile.am
|
||
|
@@ -29,15 +29,17 @@ INCLUDES = \
|
||
|
-I$(top_builddir)/src \
|
||
|
$(NULL)
|
||
|
|
||
|
-AM_CFLAGS = \
|
||
|
- @GLIB2_CFLAGS@ \
|
||
|
- @GIO2_CFLAGS@ \
|
||
|
- @GTHREAD2_CFLAGS@ \
|
||
|
- -DG_LOG_DOMAIN=\"IBUS\" \
|
||
|
- -DPKGDATADIR=\"$(pkgdatadir)\" \
|
||
|
- -DLIBEXECDIR=\"$(libexecdir)\" \
|
||
|
- -DBINDIR=\"@bindir@\" \
|
||
|
- $(INCLUDES) \
|
||
|
+AM_CFLAGS = \
|
||
|
+ @GLIB2_CFLAGS@ \
|
||
|
+ @GIO2_CFLAGS@ \
|
||
|
+ @GTHREAD2_CFLAGS@ \
|
||
|
+ -DG_LOG_DOMAIN=\"IBUS\" \
|
||
|
+ -DPKGDATADIR=\"$(pkgdatadir)\" \
|
||
|
+ -DLIBEXECDIR=\"$(libexecdir)\" \
|
||
|
+ -DBINDIR=\"@bindir@\" \
|
||
|
+ -DUSE_BRIDGE_HOTKEY=$(USE_BRIDGE_HOTKEY) \
|
||
|
+ -DDEFAULT_BRIDGE_ENGINE_NAME=\"$(DEFAULT_BRIDGE_ENGINE_NAME)\" \
|
||
|
+ $(INCLUDES) \
|
||
|
$(NULL)
|
||
|
AM_LDADD = \
|
||
|
@GOBJECT2_LIBS@ \
|
||
|
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
|
||
|
index 38d6d11..3b2d539 100644
|
||
|
--- a/bus/ibusimpl.c
|
||
|
+++ b/bus/ibusimpl.c
|
||
|
@@ -20,6 +20,10 @@
|
||
|
* Boston, MA 02111-1307, USA.
|
||
|
*/
|
||
|
|
||
|
+#ifdef HAVE_CONFIG_H
|
||
|
+#include <config.h>
|
||
|
+#endif
|
||
|
+
|
||
|
#include <unistd.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/wait.h>
|
||
|
@@ -79,6 +83,8 @@ struct _BusIBusImpl {
|
||
|
/* engine-specific hotkeys */
|
||
|
IBusHotkeyProfile *engines_hotkey_profile;
|
||
|
GHashTable *hotkey_to_engines_map;
|
||
|
+
|
||
|
+ IBusEngineDesc *prev_hotkey_engine;
|
||
|
};
|
||
|
|
||
|
struct _BusIBusImplClass {
|
||
|
@@ -285,6 +291,30 @@ _panel_destroy_cb (BusPanelProxy *panel,
|
||
|
g_object_unref (panel);
|
||
|
}
|
||
|
|
||
|
+static IBusEngineDesc *
|
||
|
+_find_engine_desc_by_name (BusIBusImpl *ibus,
|
||
|
+ const gchar *engine_name)
|
||
|
+{
|
||
|
+ IBusEngineDesc *desc = NULL;
|
||
|
+ GList *p;
|
||
|
+
|
||
|
+ /* find engine in registered engine list */
|
||
|
+ for (p = ibus->register_engine_list; p != NULL; p = p->next) {
|
||
|
+ desc = (IBusEngineDesc *) p->data;
|
||
|
+ if (g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name) == 0)
|
||
|
+ return desc;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* find engine in preload engine list */
|
||
|
+ for (p = ibus->engine_list; p != NULL; p = p->next) {
|
||
|
+ desc = (IBusEngineDesc *) p->data;
|
||
|
+ if (g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name) == 0)
|
||
|
+ return desc;
|
||
|
+ }
|
||
|
+
|
||
|
+ return NULL;
|
||
|
+}
|
||
|
+
|
||
|
static void
|
||
|
_config_set_value_done (GObject *object,
|
||
|
GAsyncResult *res,
|
||
|
@@ -475,8 +505,17 @@ _set_preload_engines (BusIBusImpl *ibus,
|
||
|
g_variant_unref (value);
|
||
|
}
|
||
|
|
||
|
- g_list_foreach (engine_list, (GFunc) g_object_ref, NULL);
|
||
|
ibus->engine_list = engine_list;
|
||
|
+#if USE_BRIDGE_HOTKEY
|
||
|
+ if (_find_engine_desc_by_name (ibus, DEFAULT_BRIDGE_ENGINE_NAME) == NULL) {
|
||
|
+ IBusEngineDesc *engine = bus_registry_find_engine_by_name (ibus->registry,
|
||
|
+ DEFAULT_BRIDGE_ENGINE_NAME);
|
||
|
+ g_assert (engine != NULL);
|
||
|
+ engine_list = g_list_append (engine_list, engine);
|
||
|
+ ibus->engine_list = engine_list;
|
||
|
+ }
|
||
|
+#endif
|
||
|
+ g_list_foreach (engine_list, (GFunc) g_object_ref, NULL);
|
||
|
|
||
|
if (ibus->engine_list) {
|
||
|
BusComponent *component = bus_component_from_engine_desc ((IBusEngineDesc *) ibus->engine_list->data);
|
||
|
@@ -1182,28 +1221,110 @@ _ibus_get_address (BusIBusImpl
|
||
|
g_variant_new ("(s)", bus_server_get_address ()));
|
||
|
}
|
||
|
|
||
|
-static IBusEngineDesc *
|
||
|
-_find_engine_desc_by_name (BusIBusImpl *ibus,
|
||
|
- const gchar *engine_name)
|
||
|
-{
|
||
|
- IBusEngineDesc *desc = NULL;
|
||
|
- GList *p;
|
||
|
+/**
|
||
|
+ * _foreach_remove_engine_hotkey:
|
||
|
+ *
|
||
|
+ * Remove the engine-specific hot key of the engine, and update ibus->engines_hotkey_profile.
|
||
|
+ */
|
||
|
+gboolean
|
||
|
+_foreach_remove_engine_hotkey (gpointer key,
|
||
|
+ gpointer value,
|
||
|
+ gpointer data)
|
||
|
+{
|
||
|
+ GQuark event = GPOINTER_TO_UINT (value);
|
||
|
+ struct _impl_and_desc {
|
||
|
+ BusIBusImpl *ibus;
|
||
|
+ IBusEngineDesc *desc;
|
||
|
+ } *id = (struct _impl_and_desc *) data;
|
||
|
+ BusIBusImpl *ibus = id->ibus;
|
||
|
+ IBusEngineDesc *desc = id->desc;
|
||
|
+ GList *engine_list;
|
||
|
|
||
|
- /* find engine in registered engine list */
|
||
|
- for (p = ibus->register_engine_list; p != NULL; p = p->next) {
|
||
|
- desc = (IBusEngineDesc *) p->data;
|
||
|
- if (g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name) == 0)
|
||
|
- return desc;
|
||
|
+ g_assert (ibus != NULL);
|
||
|
+ g_assert (desc != NULL);
|
||
|
+
|
||
|
+ if (event == 0) {
|
||
|
+ return FALSE;
|
||
|
}
|
||
|
|
||
|
- /* find engine in preload engine list */
|
||
|
- for (p = ibus->engine_list; p != NULL; p = p->next) {
|
||
|
- desc = (IBusEngineDesc *) p->data;
|
||
|
- if (g_strcmp0 (ibus_engine_desc_get_name (desc), engine_name) == 0)
|
||
|
- return desc;
|
||
|
+ 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. */
|
||
|
+ if (engine_list && g_list_find (engine_list, desc) != NULL) {
|
||
|
+ engine_list = g_list_remove (engine_list, desc);
|
||
|
}
|
||
|
|
||
|
- return NULL;
|
||
|
+ /* 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));
|
||
|
+
|
||
|
+ if (engine_list != NULL) {
|
||
|
+ g_hash_table_insert (ibus->hotkey_to_engines_map,
|
||
|
+ GUINT_TO_POINTER (event), engine_list);
|
||
|
+ }
|
||
|
+
|
||
|
+ return FALSE;
|
||
|
+}
|
||
|
+
|
||
|
+/**
|
||
|
+ * _add_engine_hotkey_with_hotkeys:
|
||
|
+ *
|
||
|
+ * Check the engine-specific hot key of the engine, and update ibus->engines_hotkey_profile.
|
||
|
+ */
|
||
|
+static void
|
||
|
+_add_engine_hotkey_with_hotkeys (IBusEngineDesc *engine,
|
||
|
+ BusIBusImpl *ibus,
|
||
|
+ const gchar *hotkeys)
|
||
|
+{
|
||
|
+ gchar **hotkey_list;
|
||
|
+ gchar **p;
|
||
|
+ gchar *hotkey;
|
||
|
+ GList *engine_list;
|
||
|
+
|
||
|
+ GQuark event;
|
||
|
+ guint keyval;
|
||
|
+ guint modifiers;
|
||
|
+
|
||
|
+ g_assert (engine != NULL);
|
||
|
+ g_assert (hotkeys && *hotkeys);
|
||
|
+
|
||
|
+ hotkey_list = g_strsplit_set (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);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
@@ -1216,7 +1337,39 @@ _context_request_engine_cb (BusInputCont
|
||
|
const gchar *engine_name,
|
||
|
BusIBusImpl *ibus)
|
||
|
{
|
||
|
- return bus_ibus_impl_get_engine_desc (ibus, engine_name);
|
||
|
+ IBusEngineDesc *desc = bus_ibus_impl_get_engine_desc (ibus, engine_name);
|
||
|
+ struct _impl_and_desc {
|
||
|
+ BusIBusImpl *ibus;
|
||
|
+ IBusEngineDesc *desc;
|
||
|
+ } id = {ibus, desc};
|
||
|
+
|
||
|
+#if USE_BRIDGE_HOTKEY
|
||
|
+ IBusEngineDesc *current_desc = NULL;
|
||
|
+ if (context) {
|
||
|
+ BusEngineProxy *engine = bus_input_context_get_engine (context);
|
||
|
+ if (engine != NULL) {
|
||
|
+ current_desc = bus_engine_proxy_get_desc (engine);
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if (current_desc) {
|
||
|
+ ibus->prev_hotkey_engine = current_desc;
|
||
|
+ }
|
||
|
+ if (current_desc != NULL && desc != NULL &&
|
||
|
+ g_strcmp0 (ibus_engine_desc_get_name (current_desc),
|
||
|
+ ibus_engine_desc_get_name (desc)) != 0 &&
|
||
|
+ g_strcmp0 (ibus_engine_desc_get_name (desc),
|
||
|
+ DEFAULT_BRIDGE_ENGINE_NAME) == 0) {
|
||
|
+ const gchar *hotkeys = ibus_engine_desc_get_hotkeys (current_desc);
|
||
|
+ if (!hotkeys || !*hotkeys) {
|
||
|
+ hotkeys = "Control+space";
|
||
|
+ }
|
||
|
+ ibus_hotkey_profile_foreach_hotkey (ibus->engines_hotkey_profile,
|
||
|
+ _foreach_remove_engine_hotkey,
|
||
|
+ &id);
|
||
|
+ _add_engine_hotkey_with_hotkeys (desc, ibus, hotkeys);
|
||
|
+ }
|
||
|
+#endif
|
||
|
+ return desc;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
@@ -2357,6 +2510,11 @@ bus_ibus_impl_filter_keyboard_shortcuts
|
||
|
* 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. */
|
||
|
+#if USE_BRIDGE_HOTKEY
|
||
|
+ if (ibus->prev_hotkey_engine) {
|
||
|
+ new_engine_desc = ibus->prev_hotkey_engine;
|
||
|
+ }
|
||
|
+#else
|
||
|
GList *p = engine_list;
|
||
|
for (; p->next != NULL; p = p->next) {
|
||
|
if (current_engine_desc == (IBusEngineDesc *) p->data) {
|
||
|
@@ -2364,9 +2522,14 @@ bus_ibus_impl_filter_keyboard_shortcuts
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
+#endif
|
||
|
|
||
|
if (current_engine_desc != new_engine_desc) {
|
||
|
+ ibus->prev_hotkey_engine = current_engine_desc;
|
||
|
bus_ibus_impl_set_context_engine_from_desc (ibus, context, new_engine_desc);
|
||
|
+ } else {
|
||
|
+ g_warning ("The engine %s is registered twice in hotkeys",
|
||
|
+ ibus_engine_desc_get_name (current_engine_desc));
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
@@ -2470,14 +2633,6 @@ static void
|
||
|
_add_engine_hotkey (IBusEngineDesc *engine, BusIBusImpl *ibus)
|
||
|
{
|
||
|
const gchar *hotkeys;
|
||
|
- gchar **hotkey_list;
|
||
|
- gchar **p;
|
||
|
- gchar *hotkey;
|
||
|
- GList *engine_list;
|
||
|
-
|
||
|
- GQuark event;
|
||
|
- guint keyval;
|
||
|
- guint modifiers;
|
||
|
|
||
|
if (!engine) {
|
||
|
return;
|
||
|
@@ -2489,40 +2644,7 @@ _add_engine_hotkey (IBusEngineDesc *engi
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- hotkey_list = g_strsplit_set (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);
|
||
|
+ _add_engine_hotkey_with_hotkeys (engine, ibus, hotkeys);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
diff --git a/bus/registry.c b/bus/registry.c
|
||
|
index bc6680d..f47f727 100644
|
||
|
--- a/bus/registry.c
|
||
|
+++ b/bus/registry.c
|
||
|
@@ -19,6 +19,11 @@
|
||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||
|
* Boston, MA 02111-1307, USA.
|
||
|
*/
|
||
|
+
|
||
|
+#ifdef HAVE_CONFIG_H
|
||
|
+#include <config.h>
|
||
|
+#endif
|
||
|
+
|
||
|
#include "registry.h"
|
||
|
#include <glib/gstdio.h>
|
||
|
#include <gio/gio.h>
|
||
|
@@ -101,6 +106,9 @@ bus_registry_init (BusRegistry *registry)
|
||
|
registry->observed_paths = NULL;
|
||
|
registry->components = NULL;
|
||
|
registry->engine_table = g_hash_table_new (g_str_hash, g_str_equal);
|
||
|
+#if USE_BRIDGE_HOTKEY
|
||
|
+ gboolean has_default_engine = FALSE;
|
||
|
+#endif
|
||
|
|
||
|
#ifdef G_THREADS_ENABLED
|
||
|
/* If glib supports thread, we'll create a thread to monitor changes in IME
|
||
|
@@ -145,12 +153,39 @@ bus_registry_init (BusRegistry *registry)
|
||
|
GList *p1;
|
||
|
for (p1 = engines; p1 != NULL; p1 = p1->next) {
|
||
|
IBusEngineDesc *desc = (IBusEngineDesc *) p1->data;
|
||
|
+#if USE_BRIDGE_HOTKEY
|
||
|
+ if (g_strcmp0 (ibus_engine_desc_get_name (desc),
|
||
|
+ DEFAULT_BRIDGE_ENGINE_NAME) == 0) {
|
||
|
+ has_default_engine = TRUE;
|
||
|
+ }
|
||
|
+#endif
|
||
|
g_hash_table_insert (registry->engine_table,
|
||
|
(gpointer) ibus_engine_desc_get_name (desc),
|
||
|
desc);
|
||
|
}
|
||
|
g_list_free (engines);
|
||
|
}
|
||
|
+
|
||
|
+#if USE_BRIDGE_HOTKEY
|
||
|
+ if (has_default_engine == FALSE) {
|
||
|
+ bus_registry_remove_all (registry);
|
||
|
+ bus_registry_load (registry);
|
||
|
+ bus_registry_save_cache (registry);
|
||
|
+
|
||
|
+ for (p = registry->components; p != NULL; p = p->next) {
|
||
|
+ BusComponent *comp = (BusComponent *) p->data;
|
||
|
+ GList *engines = bus_component_get_engines (comp);
|
||
|
+ GList *p1;
|
||
|
+ for (p1 = engines; p1 != NULL; p1 = p1->next) {
|
||
|
+ IBusEngineDesc *desc = (IBusEngineDesc *) p1->data;
|
||
|
+ g_hash_table_insert (registry->engine_table,
|
||
|
+ (gpointer) ibus_engine_desc_get_name (desc),
|
||
|
+ desc);
|
||
|
+ }
|
||
|
+ g_list_free (engines);
|
||
|
+ }
|
||
|
+ }
|
||
|
+#endif
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
diff --git a/configure.ac b/configure.ac
|
||
|
index 85e5e30..a6974d4 100644
|
||
|
--- a/configure.ac
|
||
|
+++ b/configure.ac
|
||
|
@@ -438,6 +438,34 @@ else
|
||
|
enable_surrounding_text="no (disabled, use --enable-surrounding-text to enable)"
|
||
|
fi
|
||
|
|
||
|
+# option for bridge hotkey
|
||
|
+AC_ARG_ENABLE(bridge-hotkey,
|
||
|
+ AS_HELP_STRING([--enable-bridge-hotkey],
|
||
|
+ [Enable bridge hotkey instead of ON/OFF hotkey]),
|
||
|
+ [enable_bridge_hotkey=$enableval],
|
||
|
+ [enable_bridge_hotkey=no]
|
||
|
+)
|
||
|
+
|
||
|
+if test x"$enable_bridge_hotkey" = x"yes"; then
|
||
|
+ USE_BRIDGE_HOTKEY=1
|
||
|
+ TRIGGER_HOTKEYS=""
|
||
|
+else
|
||
|
+ USE_BRIDGE_HOTKEY=0
|
||
|
+ TRIGGER_HOTKEYS="Control+space,Zenkaku_Hankaku,Alt+Kanji,Alt+grave,Hangul,Alt+Release+Alt_R"
|
||
|
+ enable_bridge_hotkey="no (disabled, use --enable-bridge-hotkey to enable)"
|
||
|
+fi
|
||
|
+AC_SUBST(USE_BRIDGE_HOTKEY)
|
||
|
+AC_SUBST(TRIGGER_HOTKEYS)
|
||
|
+
|
||
|
+# define default bridge engine name
|
||
|
+AC_ARG_WITH(bridge-engine,
|
||
|
+ AS_HELP_STRING([--with-bridge-engine[=bridge_engine_name]],
|
||
|
+ [Set bridge engine name in IM bridge hotkey. (default: xkb:layout:default)]),
|
||
|
+ [DEFAULT_BRIDGE_ENGINE_NAME=$with_bridge_engine],
|
||
|
+ [DEFAULT_BRIDGE_ENGINE_NAME="xkb:layout:default"]
|
||
|
+)
|
||
|
+AC_SUBST(DEFAULT_BRIDGE_ENGINE_NAME)
|
||
|
+
|
||
|
# check iso-codes
|
||
|
PKG_CHECK_MODULES(ISOCODES, [
|
||
|
iso-codes
|
||
|
@@ -464,6 +492,7 @@ bus/Makefile
|
||
|
util/Makefile
|
||
|
util/IMdkit/Makefile
|
||
|
data/Makefile
|
||
|
+data/ibus.schemas.in
|
||
|
data/icons/Makefile
|
||
|
data/keymaps/Makefile
|
||
|
docs/Makefile
|
||
|
@@ -512,5 +541,7 @@ Build options:
|
||
|
No snooper regexes "$NO_SNOOPER_APPS"
|
||
|
Panel icon "$IBUS_ICON_KEYBOARD"
|
||
|
Enable surrounding-text $enable_surrounding_text
|
||
|
+ Enable bridge hotkey $enable_bridge_hotkey
|
||
|
+ Default bridge engine $DEFAULT_BRIDGE_ENGINE_NAME
|
||
|
])
|
||
|
|
||
|
diff --git a/data/Makefile.am b/data/Makefile.am
|
||
|
index ba9f4bb..a909e5b 100644
|
||
|
--- a/data/Makefile.am
|
||
|
+++ b/data/Makefile.am
|
||
|
@@ -26,7 +26,8 @@ SUBDIRS = \
|
||
|
$(NULL)
|
||
|
|
||
|
schemasdir = $(GCONF_SCHEMA_FILE_DIR)
|
||
|
-schemas_in_files = ibus.schemas.in
|
||
|
+schemas_in_in_files = ibus.schemas.in.in
|
||
|
+schemas_in_files = $(schemas_in_in_files:.schemas.in.in=.schemas.in)
|
||
|
schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
|
||
|
@INTLTOOL_SCHEMAS_RULE@
|
||
|
|
||
|
@@ -41,11 +42,12 @@ if GCONF_SCHEMAS_INSTALL
|
||
|
endif
|
||
|
|
||
|
EXTRA_DIST = \
|
||
|
- $(schemas_in_files) \
|
||
|
+ $(schemas_in_in_files) \
|
||
|
$(NULL)
|
||
|
|
||
|
DISTCLEANFILES = \
|
||
|
$(schemas_DATA) \
|
||
|
+ $(schemas_in_files) \
|
||
|
$(NULL)
|
||
|
|
||
|
-include $(top_srcdir)/git.mk
|
||
|
diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in.in
|
||
|
index 7ca4899..42d9297
|
||
|
--- a/data/ibus.schemas.in
|
||
|
+++ b/data/ibus.schemas.in.in
|
||
|
@@ -31,7 +31,7 @@
|
||
|
<owner>ibus</owner>
|
||
|
<type>list</type>
|
||
|
<list_type>string</list_type>
|
||
|
- <default>[Control+space,Zenkaku_Hankaku,Alt+Kanji,Alt+grave,Hangul,Alt+Release+Alt_R]</default>
|
||
|
+ <default>[@TRIGGER_HOTKEYS@]</default>
|
||
|
<locale name="C">
|
||
|
<short>Trigger shortcut keys</short>
|
||
|
<long>The shortcut keys for turning input method on or off</long>
|
||
|
diff --git a/ibus/_config.py.in b/ibus/_config.py.in
|
||
|
index a830136..4c3c980 100644
|
||
|
--- a/ibus/_config.py.in
|
||
|
+++ b/ibus/_config.py.in
|
||
|
@@ -25,6 +25,8 @@ __all__ = (
|
||
|
"get_copyright",
|
||
|
"get_license",
|
||
|
"get_ICON_KEYBOARD",
|
||
|
+ "use_bridge_hotkey",
|
||
|
+ "DEFAULT_BRIDGE_ENGINE_NAME",
|
||
|
"ISOCODES_PREFIX",
|
||
|
"_"
|
||
|
)
|
||
|
@@ -51,4 +53,8 @@ def get_ICON_KEYBOARD():
|
||
|
icon = 'ibus-keyboard'
|
||
|
return icon
|
||
|
|
||
|
+def use_bridge_hotkey():
|
||
|
+ return True if @USE_BRIDGE_HOTKEY@ == 1 else False
|
||
|
+
|
||
|
+DEFAULT_BRIDGE_ENGINE_NAME='@DEFAULT_BRIDGE_ENGINE_NAME@'
|
||
|
ISOCODES_PREFIX='@ISOCODES_PREFIX@'
|
||
|
diff --git a/ibus/inputcontext.py b/ibus/inputcontext.py
|
||
|
index ceeb56d..2694fa3 100644
|
||
|
--- a/ibus/inputcontext.py
|
||
|
+++ b/ibus/inputcontext.py
|
||
|
@@ -28,6 +28,7 @@ import sys
|
||
|
import gobject
|
||
|
import dbus
|
||
|
import dbus.lowlevel
|
||
|
+import _config
|
||
|
import object
|
||
|
import common
|
||
|
import serializable
|
||
|
@@ -282,6 +283,9 @@ class InputContext(object.Object):
|
||
|
def set_engine(self, engine):
|
||
|
return self.__context.SetEngine(engine.name)
|
||
|
|
||
|
+ def set_bridge_engine(self):
|
||
|
+ return self.__context.SetEngine(_config.DEFAULT_BRIDGE_ENGINE_NAME)
|
||
|
+
|
||
|
def introspect(self):
|
||
|
return self.__context.Introspect()
|
||
|
|
||
|
diff --git a/src/Makefile.am b/src/Makefile.am
|
||
|
index 6454522..443b0db 100644
|
||
|
--- a/src/Makefile.am
|
||
|
+++ b/src/Makefile.am
|
||
|
@@ -46,6 +46,7 @@ AM_CPPFLAGS = \
|
||
|
-DIBUS_DATA_DIR=\"$(pkgdatadir)\" \
|
||
|
-DIBUS_COMPILATION \
|
||
|
-DISOCODES_PREFIX=\"$(ISOCODES_PREFIX)\" \
|
||
|
+ -DUSE_BRIDGE_HOTKEY=$(USE_BRIDGE_HOTKEY) \
|
||
|
$(NULL)
|
||
|
|
||
|
# ibus library
|
||
|
diff --git a/src/ibusbus.c b/src/ibusbus.c
|
||
|
index 39ad784..5a8f9a9 100644
|
||
|
--- a/src/ibusbus.c
|
||
|
+++ b/src/ibusbus.c
|
||
|
@@ -1902,3 +1902,9 @@ ibus_bus_call_async (IBusBus *bus,
|
||
|
(GAsyncReadyCallback) ibus_bus_call_async_done,
|
||
|
simple);
|
||
|
}
|
||
|
+
|
||
|
+gboolean
|
||
|
+ibus_bus_use_bridge_hotkey (IBusBus *bus)
|
||
|
+{
|
||
|
+ return (USE_BRIDGE_HOTKEY == 1) ? TRUE : FALSE;
|
||
|
+}
|
||
|
diff --git a/src/ibusbus.h b/src/ibusbus.h
|
||
|
index 77d3916..4bdf760 100644
|
||
|
--- a/src/ibusbus.h
|
||
|
+++ b/src/ibusbus.h
|
||
|
@@ -971,5 +971,14 @@ void ibus_bus_set_watch_ibus_signal
|
||
|
*/
|
||
|
IBusConfig *ibus_bus_get_config (IBusBus *bus);
|
||
|
|
||
|
+/**
|
||
|
+ * ibus_bus_use_bridge_hotkey:
|
||
|
+ * @bus: An #IBusBus.
|
||
|
+ * @returns: %TRUE if @bus use bridge hotkey, %FALSE otherwise.
|
||
|
+ *
|
||
|
+ * Return %TRUE if @bus use bridge hotkey.
|
||
|
+ */
|
||
|
+gboolean ibus_bus_use_bridge_hotkey (IBusBus *bus);
|
||
|
+
|
||
|
G_END_DECLS
|
||
|
#endif
|
||
|
diff --git a/src/ibusenginedesc.c b/src/ibusenginedesc.c
|
||
|
index d3800e1..a9e68be 100644
|
||
|
--- a/src/ibusenginedesc.c
|
||
|
+++ b/src/ibusenginedesc.c
|
||
|
@@ -233,7 +233,11 @@ ibus_engine_desc_class_init (IBusEngineDescClass *class)
|
||
|
g_param_spec_string ("hotkeys",
|
||
|
"description hotkeys",
|
||
|
"The hotkeys of engine description",
|
||
|
+#if USE_BRIDGE_HOTKEY
|
||
|
+ "Control+space",
|
||
|
+#else
|
||
|
"",
|
||
|
+#endif
|
||
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||
|
|
||
|
/**
|
||
|
diff --git a/src/ibushotkey.c b/src/ibushotkey.c
|
||
|
index 32f8338..bef7dfc 100644
|
||
|
--- a/src/ibushotkey.c
|
||
|
+++ b/src/ibushotkey.c
|
||
|
@@ -562,3 +562,14 @@ ibus_hotkey_profile_lookup_hotkey (IBusHotkeyProfile *profile,
|
||
|
|
||
|
return (GQuark) GPOINTER_TO_UINT (g_tree_lookup (priv->hotkeys, &hotkey));
|
||
|
}
|
||
|
+
|
||
|
+void
|
||
|
+ibus_hotkey_profile_foreach_hotkey (IBusHotkeyProfile *profile,
|
||
|
+ GTraverseFunc func,
|
||
|
+ gpointer user_data)
|
||
|
+{
|
||
|
+ IBusHotkeyProfilePrivate *priv;
|
||
|
+ priv = IBUS_HOTKEY_PROFILE_GET_PRIVATE (profile);
|
||
|
+
|
||
|
+ g_tree_foreach (priv->hotkeys, func, user_data);
|
||
|
+}
|
||
|
diff --git a/src/ibushotkey.h b/src/ibushotkey.h
|
||
|
index 9a341f6..92ec6af 100644
|
||
|
--- a/src/ibushotkey.h
|
||
|
+++ b/src/ibushotkey.h
|
||
|
@@ -179,5 +179,16 @@ GQuark ibus_hotkey_profile_lookup_hotkey
|
||
|
guint keyval,
|
||
|
guint modifiers);
|
||
|
|
||
|
+/**
|
||
|
+ * ibus_hotkey_profile_foreach_hotkey:
|
||
|
+ * @profile: An IBusHotkeyProfile.
|
||
|
+ * @func: (scope call): A GTraverseFunc for g_tree_traverse.
|
||
|
+ * @user_data: A gpointer for g_tree_traverse.
|
||
|
+ */
|
||
|
+void ibus_hotkey_profile_foreach_hotkey
|
||
|
+ (IBusHotkeyProfile *profile,
|
||
|
+ GTraverseFunc func,
|
||
|
+ gpointer user_data);
|
||
|
+
|
||
|
G_END_DECLS
|
||
|
#endif
|
||
|
diff --git a/ui/gtk/panel.py b/ui/gtk/panel.py
|
||
|
index de64920..7f2edcd 100644
|
||
|
--- a/ui/gtk/panel.py
|
||
|
+++ b/ui/gtk/panel.py
|
||
|
@@ -133,6 +133,11 @@ class Panel(ibus.PanelBase):
|
||
|
# self.__bus.request_name(ibus.panel.IBUS_SERVICE_PANEL, 0)
|
||
|
|
||
|
# init xkb
|
||
|
+ self.__default_layout = 'default'
|
||
|
+ self.__default_model = 'default'
|
||
|
+ self.__default_option = 'default'
|
||
|
+ self.__disabled_engine = None
|
||
|
+
|
||
|
self.__xkblayout = ibus.XKBLayout(self.__config)
|
||
|
use_xkb = self.__config.get_value("general", "use_system_keyboard_layout", False)
|
||
|
if not use_xkb:
|
||
|
@@ -142,11 +147,18 @@ class Panel(ibus.PanelBase):
|
||
|
value = 'default'
|
||
|
if value != 'default':
|
||
|
self.__xkblayout.set_default_layout(value)
|
||
|
+ if value.find('(') >= 0:
|
||
|
+ self.__default_layout = value.split('(')[0]
|
||
|
+ self.__default_model = value.split('(')[1].split(')')[0]
|
||
|
+ else:
|
||
|
+ self.__default_layout = value
|
||
|
+ self.__default_model = None
|
||
|
value = str(self.__config.get_value("general", "system_keyboard_option", ''))
|
||
|
if value == '':
|
||
|
value = 'default'
|
||
|
if value != 'default':
|
||
|
self.__xkblayout.set_default_option(value)
|
||
|
+ self.__default_option = value
|
||
|
|
||
|
def set_cursor_location(self, x, y, w, h):
|
||
|
self.__candidate_panel.set_cursor_location(x, y, w, h)
|
||
|
@@ -233,6 +245,41 @@ class Panel(ibus.PanelBase):
|
||
|
def __set_im_name(self, name):
|
||
|
self.__language_bar.set_im_name(name)
|
||
|
|
||
|
+ def __set_default_layout_engine(self):
|
||
|
+ default_layout = self.__default_layout
|
||
|
+ default_model = self.__default_model
|
||
|
+ if default_layout == 'default':
|
||
|
+ default_layout = self.__xkblayout.get_default_layout()[0]
|
||
|
+ default_model = None
|
||
|
+ if default_model == 'default':
|
||
|
+ default_model = self.__xkblayout.get_default_layout()[1]
|
||
|
+ layouts = default_layout.split(',')
|
||
|
+ group = self.__xkblayout.get_group()
|
||
|
+ layout = layouts[group]
|
||
|
+ model = None
|
||
|
+ if default_model != None and default_model != '':
|
||
|
+ models = default_model.split(',')
|
||
|
+ if group < models.length:
|
||
|
+ model = models[group]
|
||
|
+ registry = ibus.XKBConfigRegistry()
|
||
|
+ langs = registry.get_layout_lang()[layout]
|
||
|
+ lang = 'en'
|
||
|
+ im_icon = layout[:2]
|
||
|
+ if langs != None:
|
||
|
+ im_icon = langs[0][:2]
|
||
|
+ lang = str(langs[0])
|
||
|
+ if self.__disabled_engine == None:
|
||
|
+ self.__disabled_engine = registry.engine_desc_new(lang,
|
||
|
+ self.__default_layout,
|
||
|
+ 'Default Layout',
|
||
|
+ default_model,
|
||
|
+ None)
|
||
|
+ if self.__focus_ic != None:
|
||
|
+ prev_engine = self.__focus_ic.get_engine()
|
||
|
+ if prev_engine == None or \
|
||
|
+ prev_engine.name != self.__disabled_engine.name:
|
||
|
+ self.__focus_ic.set_bridge_engine()
|
||
|
+
|
||
|
def focus_in(self, ic):
|
||
|
self.reset()
|
||
|
self.__focus_ic = ibus.InputContext(self.__bus, ic)
|
||
|
@@ -240,6 +287,9 @@ class Panel(ibus.PanelBase):
|
||
|
self.__language_bar.set_enabled(enabled)
|
||
|
|
||
|
if not enabled:
|
||
|
+ if ibus.use_bridge_hotkey():
|
||
|
+ self.__set_default_layout_engine()
|
||
|
+
|
||
|
self.__set_im_icon(ICON_KEYBOARD)
|
||
|
self.__set_im_name(None)
|
||
|
if self.__bus.get_use_sys_layout():
|
||
|
@@ -453,7 +503,12 @@ class Panel(ibus.PanelBase):
|
||
|
size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)
|
||
|
menu = gtk.Menu()
|
||
|
for i, engine in enumerate(engines):
|
||
|
- lang = ibus.get_language_name(engine.language)
|
||
|
+ language = engine.language
|
||
|
+ if ibus.use_bridge_hotkey() and \
|
||
|
+ engine.name == ibus.DEFAULT_BRIDGE_ENGINE_NAME and \
|
||
|
+ self.__disabled_engine != None:
|
||
|
+ language = self.__disabled_engine.language
|
||
|
+ lang = ibus.get_language_name(language)
|
||
|
item = gtk.ImageMenuItem("%s - %s" % (lang, engine.longname))
|
||
|
if current_engine and current_engine.name == engine.name:
|
||
|
for widget in item.get_children():
|
||
|
@@ -471,7 +526,8 @@ class Panel(ibus.PanelBase):
|
||
|
item.connect("activate", self.__im_menu_item_activate_cb, None)
|
||
|
if self.__focus_ic == None or not self.__focus_ic.is_enabled():
|
||
|
item.set_sensitive(False)
|
||
|
- menu.add(item)
|
||
|
+ if not ibus.use_bridge_hotkey():
|
||
|
+ menu.add(item)
|
||
|
|
||
|
menu.show_all()
|
||
|
menu.set_take_focus(False)
|
||
|
diff --git a/xkb/Makefile.am b/xkb/Makefile.am
|
||
|
index ad9cdd9..c4d5afb 100644
|
||
|
--- a/xkb/Makefile.am
|
||
|
+++ b/xkb/Makefile.am
|
||
|
@@ -28,6 +28,8 @@ INCLUDES = \
|
||
|
-I$(top_srcdir)/src \
|
||
|
-DIBUS_LOCALEDIR=\"$(datadir)/locale\" \
|
||
|
-DLIBEXECDIR=\""$(libexecdir)"\" \
|
||
|
+ -DUSE_BRIDGE_HOTKEY=$(USE_BRIDGE_HOTKEY) \
|
||
|
+ -DDEFAULT_BRIDGE_ENGINE_NAME=\"$(DEFAULT_BRIDGE_ENGINE_NAME)\" \
|
||
|
$(NULL)
|
||
|
|
||
|
noinst_PROGRAMS = $(TESTS)
|
||
|
diff --git a/xkb/ibus-engine-xkb-main.c b/xkb/ibus-engine-xkb-main.c
|
||
|
index 5d748cc..a80f349 100644
|
||
|
--- a/xkb/ibus-engine-xkb-main.c
|
||
|
+++ b/xkb/ibus-engine-xkb-main.c
|
||
|
@@ -288,6 +288,14 @@ print_component ()
|
||
|
layout_desc = (GHashTable *) ibus_xkb_config_registry_get_layout_desc (config_registry);
|
||
|
variant_desc = (GHashTable *) ibus_xkb_config_registry_get_variant_desc (config_registry);
|
||
|
component = ibus_xkb_component_new ();
|
||
|
+#if USE_BRIDGE_HOTKEY
|
||
|
+ engine = ibus_xkb_engine_desc_new ("en",
|
||
|
+ "default",
|
||
|
+ "Default Layout",
|
||
|
+ NULL,
|
||
|
+ NULL);
|
||
|
+ ibus_component_add_engine (component, engine);
|
||
|
+#endif
|
||
|
for (keys = g_hash_table_get_keys (layout_list); keys; keys = keys->next) {
|
||
|
if (keys->data == NULL) {
|
||
|
continue;
|
||
|
diff --git a/xkb/xkbxml.c b/xkb/xkbxml.c
|
||
|
index 2ce7bcf..de6648f 100644
|
||
|
--- a/xkb/xkbxml.c
|
||
|
+++ b/xkb/xkbxml.c
|
||
|
@@ -273,6 +273,7 @@ ibus_xkb_engine_desc_new (const gchar *lang,
|
||
|
gchar *longname = NULL;
|
||
|
gchar *desc = NULL;
|
||
|
gchar *engine_layout = NULL;
|
||
|
+ const gchar *icon = "ibus-engine";
|
||
|
|
||
|
g_return_val_if_fail (lang != NULL && layout != NULL, NULL);
|
||
|
|
||
|
@@ -294,6 +295,11 @@ ibus_xkb_engine_desc_new (const gchar *lang,
|
||
|
desc = g_strdup_printf ("XKB %s keyboard layout", layout);
|
||
|
engine_layout = g_strdup (layout);
|
||
|
}
|
||
|
+#if USE_BRIDGE_HOTKEY
|
||
|
+ if (g_strcmp0 (name, DEFAULT_BRIDGE_ENGINE_NAME) == 0) {
|
||
|
+ icon = "input-keyboard-symbolic";
|
||
|
+ }
|
||
|
+#endif
|
||
|
|
||
|
engine = ibus_engine_desc_new (name,
|
||
|
longname,
|
||
|
@@ -301,7 +307,7 @@ ibus_xkb_engine_desc_new (const gchar *lang,
|
||
|
lang,
|
||
|
"LGPL2.1",
|
||
|
"Takao Fujiwara <takao.fujiwara1@gmail.com>",
|
||
|
- "ibus-engine",
|
||
|
+ icon,
|
||
|
engine_layout);
|
||
|
|
||
|
g_free (name);
|
||
|
--
|
||
|
1.7.4.4
|
||
|
|