summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Peng <shawn.p.huang@gmail.com>2009-02-24 08:13:18 +0800
committerHuang Peng <shawn.p.huang@gmail.com>2009-02-24 08:14:19 +0800
commit9265deb7c084c5e37b8402de8d38c0e7b0671e2b (patch)
tree2e045a74e3e185fcc00d18a277b80a9435c48fe8
parentcc16419cf27d12f2be12774d71399fd82cf497e3 (diff)
downloadibus-9265deb7c084c5e37b8402de8d38c0e7b0671e2b.tar.gz
ibus-9265deb7c084c5e37b8402de8d38c0e7b0671e2b.tar.xz
ibus-9265deb7c084c5e37b8402de8d38c0e7b0671e2b.zip
implement next_engine & prev_engine hotkeys.
-rw-r--r--bus/ibusimpl.c178
-rw-r--r--bus/inputcontext.c41
-rw-r--r--bus/inputcontext.h5
3 files changed, 172 insertions, 52 deletions
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
index 053080f..c52907e 100644
--- a/bus/ibusimpl.c
+++ b/bus/ibusimpl.c
@@ -130,22 +130,18 @@ _panel_destroy_cb (BusPanelProxy *panel,
}
static void
-bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
- GValue *value)
+bus_ibus_impl_set_hotkey (BusIBusImpl *ibus,
+ GQuark hotkey,
+ GValue *value)
{
g_assert (BUS_IS_IBUS_IMPL (ibus));
GValueArray *array;
gint i;
- ibus_hotkey_profile_remove_hotkey_by_event (ibus->hotkey_profile,
- g_quark_from_static_string ("trigger"));
+ ibus_hotkey_profile_remove_hotkey_by_event (ibus->hotkey_profile, hotkey);
if (value == NULL) {
- ibus_hotkey_profile_add_hotkey (ibus->hotkey_profile,
- IBUS_space,
- IBUS_CONTROL_MASK,
- g_quark_from_static_string ("trigger"));
return;
}
@@ -160,8 +156,39 @@ bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
ibus_hotkey_profile_add_hotkey_from_string (ibus->hotkey_profile,
g_value_get_string (str),
- g_quark_from_static_string ("trigger"));
+ hotkey);
}
+
+}
+
+static void
+bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
+ GValue *value)
+{
+ GQuark hotkey = g_quark_from_static_string ("trigger");
+ bus_ibus_impl_set_hotkey (ibus, hotkey, value);
+ if (value == NULL) {
+ ibus_hotkey_profile_add_hotkey (ibus->hotkey_profile,
+ IBUS_space,
+ IBUS_CONTROL_MASK,
+ hotkey);
+ }
+}
+
+static void
+bus_ibus_impl_set_next_engine (BusIBusImpl *ibus,
+ GValue *value)
+{
+ GQuark hotkey = g_quark_from_static_string ("next-engine");
+ bus_ibus_impl_set_hotkey (ibus, hotkey, value);
+}
+
+static void
+bus_ibus_impl_set_prev_engine (BusIBusImpl *ibus,
+ GValue *value)
+{
+ GQuark hotkey = g_quark_from_static_string ("prev-engine");
+ bus_ibus_impl_set_hotkey (ibus, hotkey, value);
}
static void
@@ -214,6 +241,8 @@ bus_ibus_impl_reload_config (BusIBusImpl *ibus)
void ( *func) (BusIBusImpl *, GValue *);
} entries [] = {
{ "general/hotkey", "trigger", bus_ibus_impl_set_trigger },
+ { "general/hotkey", "next_engine", bus_ibus_impl_set_next_engine },
+ { "general/hotkey", "prev_engine", bus_ibus_impl_set_prev_engine },
{ "general", "preload_engines", bus_ibus_impl_set_preload_engines },
{ NULL, NULL, NULL },
};
@@ -253,8 +282,10 @@ _config_value_changed_cb (IBusConfig *config,
gchar *key;
void ( *func) (BusIBusImpl *, GValue *);
} entries [] = {
- { "general/hotkey", "trigger", bus_ibus_impl_set_trigger },
- { "general", "preload_engines", bus_ibus_impl_set_preload_engines },
+ { "general/hotkey", "trigger", bus_ibus_impl_set_trigger },
+ { "general/hotkey", "next_engine", bus_ibus_impl_set_next_engine },
+ { "general/hotkey", "prev_engine", bus_ibus_impl_set_prev_engine },
+ { "general", "preload_engines", bus_ibus_impl_set_preload_engines },
{ NULL, NULL, NULL },
};
@@ -504,14 +535,58 @@ _ibus_get_address (BusIBusImpl *ibus,
return reply;
}
+static BusEngineProxy *
+bus_ibus_impl_create_engine (IBusEngineDesc *engine_desc)
+{
+ IBusComponent *comp;
+ BusFactoryProxy *factory;
+ BusEngineProxy *engine;
+
+ factory = bus_factory_proxy_get_from_engine (engine_desc);
+
+ if (factory == NULL) {
+ /* try to execute the engine */
+ comp = ibus_component_get_from_engine (engine_desc);
+ g_assert (comp);
+
+ if (!ibus_component_is_running (comp)) {
+ ibus_component_start (comp);
+
+ gint time = 0;
+ while (time < G_USEC_PER_SEC * 3) {
+ if (g_main_context_pending (NULL)) {
+ g_main_context_iteration (NULL, FALSE);
+ }
+ else {
+ g_usleep (50 * 1000);
+ time += 50 * 1000;
+ }
+ factory = bus_factory_proxy_get_from_engine (engine_desc);
+ if (factory != NULL) {
+ break;
+ }
+ }
+ }
+ factory = bus_factory_proxy_get_from_engine (engine_desc);
+ }
+
+ if (factory == NULL) {
+ return NULL;
+ }
+
+ g_object_ref (factory);
+ engine = bus_factory_proxy_create_engine (factory, engine_desc);
+ g_object_unref (factory);
+
+ return engine;
+}
+
static void
_context_request_engine_cb (BusInputContext *context,
gchar *engine_name,
BusIBusImpl *ibus)
{
IBusEngineDesc *engine_desc = NULL;
- IBusComponent *comp;
- BusFactoryProxy *factory;
BusEngineProxy *engine;
if (engine_name == NULL || engine_name[0] == '\0') {
@@ -553,44 +628,15 @@ _context_request_engine_cb (BusInputContext *context,
}
}
- if (engine_desc == NULL)
+ if (engine_desc == NULL) {
return;
-
- factory = bus_factory_proxy_get_from_engine (engine_desc);
-
- if (factory == NULL) {
- /* try to execute the engine */
- comp = ibus_component_get_from_engine (engine_desc);
- g_assert (comp);
-
- if (!ibus_component_is_running (comp)) {
- ibus_component_start (comp);
-
- gint time = 0;
- while (time < G_USEC_PER_SEC * 3) {
- if (g_main_context_pending (NULL)) {
- g_main_context_iteration (NULL, FALSE);
- }
- else {
- g_usleep (50 * 1000);
- time += 50 * 1000;
- }
- factory = bus_factory_proxy_get_from_engine (engine_desc);
- if (factory != NULL) {
- break;
- }
- }
- }
- factory = bus_factory_proxy_get_from_engine (engine_desc);
}
- if (factory == NULL)
- return;
+ engine = bus_ibus_impl_create_engine (engine_desc);
- engine = bus_factory_proxy_create_engine (factory, engine_desc);
-
- if (engine == NULL)
+ if (engine == NULL) {
return;
+ }
bus_input_context_set_engine (context, engine);
g_object_unref (engine);
@@ -600,7 +646,47 @@ static void
_context_request_next_engine_cb (BusInputContext *context,
BusIBusImpl *ibus)
{
+ BusEngineProxy *engine;
+ IBusEngineDesc *desc;
+ IBusEngineDesc *next_desc = NULL;
+ GList *p;
+
+ engine = bus_input_context_get_engine (context);
+ if (engine == NULL) {
+ _context_request_engine_cb (context, NULL, ibus);
+ return;
+ }
+
+ desc = bus_engine_proxy_get_desc (engine);
+
+ p = g_list_find (ibus->register_engine_list, desc);
+ if (p != NULL) {
+ p = p->next;
+ }
+ if (p == NULL) {
+ p = g_list_find (ibus->engine_list, desc);
+ if (p != NULL) {
+ p = p->next;
+ }
+ }
+ if (p != NULL) {
+ next_desc = (IBusEngineDesc*) p->data;
+ }
+ else {
+ if (ibus->register_engine_list) {
+ next_desc = (IBusEngineDesc *)ibus->register_engine_list->data;
+ }
+ else if (ibus->engine_list) {
+ next_desc = (IBusEngineDesc *)ibus->engine_list->data;
+ }
+ }
+
+ if (next_desc != NULL) {
+ engine = bus_ibus_impl_create_engine (next_desc);
+ bus_input_context_set_engine (context, engine);
+ g_object_unref (engine);
+ }
}
static void
diff --git a/bus/inputcontext.c b/bus/inputcontext.c
index 6ba7322..d857479 100644
--- a/bus/inputcontext.c
+++ b/bus/inputcontext.c
@@ -1022,7 +1022,7 @@ bus_input_context_ibus_message (BusInputContext *context,
gboolean
-bus_input_context_is_focus (BusInputContext *context)
+bus_input_context_has_focus (BusInputContext *context)
{
g_assert (BUS_IS_INPUT_CONTEXT (context));
@@ -1425,7 +1425,6 @@ bus_input_context_disable (BusInputContext *context)
BusInputContextPrivate *priv;
priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
-
if (priv->engine) {
if (priv->has_focus) {
bus_engine_proxy_focus_out (priv->engine);
@@ -1443,6 +1442,17 @@ bus_input_context_disable (BusInputContext *context)
priv->enabled = FALSE;
}
+gboolean
+bus_input_context_is_enabled (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ return priv->enabled;
+}
+
const static struct {
const gchar *name;
GCallback callback;
@@ -1492,7 +1502,6 @@ void
bus_input_context_set_engine (BusInputContext *context,
BusEngineProxy *engine)
{
-
g_assert (BUS_IS_INPUT_CONTEXT (context));
BusInputContextPrivate *priv;
@@ -1517,12 +1526,29 @@ bus_input_context_set_engine (BusInputContext *context,
context);
}
bus_engine_proxy_set_cursor_location (priv->engine, priv->x, priv->y, priv->w, priv->h);
+ if (priv->enabled) {
+ bus_engine_proxy_enable (priv->engine);
+ if (priv->has_focus) {
+ bus_engine_proxy_focus_in (priv->engine);
+ }
+ }
}
g_signal_emit (context,
context_signals[ENGINE_CHANGED],
0);
}
+BusEngineProxy *
+bus_input_context_get_engine (BusInputContext *context)
+{
+ g_assert (BUS_IS_INPUT_CONTEXT (context));
+
+ BusInputContextPrivate *priv;
+ priv = BUS_INPUT_CONTEXT_GET_PRIVATE (context);
+
+ return priv->engine;
+}
+
static gboolean
bus_input_context_filter_keyboard_shortcuts (BusInputContext *context,
guint keyval,
@@ -1549,7 +1575,6 @@ bus_input_context_filter_keyboard_shortcuts (BusInputContext *context,
keyval,
modifiers,
0);
-
if (event == trigger) {
if (priv->engine == NULL) {
g_signal_emit (context, context_signals[REQUEST_ENGINE], 0, NULL);
@@ -1569,9 +1594,17 @@ bus_input_context_filter_keyboard_shortcuts (BusInputContext *context,
return TRUE;
}
else if (event == next_factory) {
+ g_signal_emit (context, context_signals[REQUEST_NEXT_ENGINE], 0);
+ if (priv->engine && !priv->enabled) {
+ bus_input_context_enable (context);
+ }
return TRUE;
}
else if (event == prev_factory) {
+ g_signal_emit (context, context_signals[REQUEST_PREV_ENGINE], 0);
+ if (priv->engine && !priv->enabled) {
+ bus_input_context_enable (context);
+ }
return TRUE;
}
else
diff --git a/bus/inputcontext.h b/bus/inputcontext.h
index edebdc0..537cbef 100644
--- a/bus/inputcontext.h
+++ b/bus/inputcontext.h
@@ -61,18 +61,19 @@ struct _BusInputContextClass {
GType bus_input_context_get_type (void);
BusInputContext *bus_input_context_new (BusConnection *connection,
const gchar *client);
-gboolean bus_input_context_is_focus (BusInputContext *context);
void bus_input_context_focus_in (BusInputContext *context);
void bus_input_context_focus_out (BusInputContext *context);
-void bus_input_context_enable_or_disable(BusInputContext *context);
+gboolean bus_input_context_has_focus (BusInputContext *context);
void bus_input_context_enable (BusInputContext *context);
void bus_input_context_disable (BusInputContext *context);
+gboolean bus_input_context_is_enabled (BusInputContext *context);
void bus_input_context_page_up (BusInputContext *context);
void bus_input_context_page_down (BusInputContext *context);
void bus_input_context_cursor_up (BusInputContext *context);
void bus_input_context_cursor_down (BusInputContext *context);
void bus_input_context_set_engine (BusInputContext *context,
BusEngineProxy *factory);
+BusEngineProxy *bus_input_context_get_engine (BusInputContext *context);
void bus_input_context_property_activate(BusInputContext *context,
const gchar *prop_name,
gint prop_state);