BusFactoryProxy *factory);
static void bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
GValue *value);
+static void bus_ibus_impl_set_next_engine_in_menu
+ (BusIBusImpl *ibus,
+ GValue *value);
+static void bus_ibus_impl_set_previous_engine
+ (BusIBusImpl *ibus,
+ GValue *value);
+
static void bus_ibus_impl_set_preload_engines
(BusIBusImpl *ibus,
GValue *value);
static void bus_ibus_impl_set_embed_preedit_text
(BusIBusImpl *ibus,
GValue *value);
+static void bus_ibus_impl_set_enable_by_default
+ (BusIBusImpl *ibus,
+ GValue *value);
static void bus_ibus_impl_set_use_global_engine
(BusIBusImpl *ibus,
static void _factory_destroy_cb (BusFactoryProxy *factory,
BusIBusImpl *ibus);
+static void bus_ibus_impl_set_context_engine(BusIBusImpl *ibus,
+ BusInputContext *context,
+ BusEngineProxy *engine);
+
+static gchar *bus_ibus_impl_load_global_engine_name_from_config
+ (BusIBusImpl *ibus);
+static void bus_ibus_impl_save_global_engine_name_to_config
+ (BusIBusImpl *ibus);
+
+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);
+
G_DEFINE_TYPE(BusIBusImpl, bus_ibus_impl, IBUS_TYPE_SERVICE)
BusIBusImpl *
}
static void
-bus_ibus_impl_set_next_engine (BusIBusImpl *ibus,
- GValue *value)
+bus_ibus_impl_set_next_engine_in_menu (BusIBusImpl *ibus,
+ GValue *value)
{
- GQuark hotkey = g_quark_from_static_string ("next-engine");
+ GQuark hotkey = g_quark_from_static_string ("next-engine-in-menu");
bus_ibus_impl_set_hotkey (ibus, hotkey, value);
}
static void
-bus_ibus_impl_set_prev_engine (BusIBusImpl *ibus,
- GValue *value)
+bus_ibus_impl_set_previous_engine (BusIBusImpl *ibus,
+ GValue *value)
{
- GQuark hotkey = g_quark_from_static_string ("prev-engine");
+ GQuark hotkey = g_quark_from_static_string ("previous-engine");
bus_ibus_impl_set_hotkey (ibus, hotkey, value);
}
}
static void
-bus_ibus_impl_set_embed_preedit_text (BusIBusImpl *ibus,
- GValue *value){
+bus_ibus_impl_set_embed_preedit_text (BusIBusImpl *ibus,
+ GValue *value)
+{
if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
ibus->embed_preedit_text = g_value_get_boolean (value);
}
+}
+static void
+bus_ibus_impl_set_enable_by_default (BusIBusImpl *ibus,
+ GValue *value)
+{
+ if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
+ ibus->enable_by_default = g_value_get_boolean (value);
+ }
}
static void
/* turn off use_global_engine option */
bus_ibus_impl_set_global_engine (ibus, NULL);
ibus->use_global_engine = FALSE;
+
+ g_free (ibus->global_previous_engine_name);
}
}
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 },
+ /* Only for backward compatibility, shall be removed later. */
+ { "general/hotkey", "next_engine", bus_ibus_impl_set_next_engine_in_menu },
+ { "general/hotkey", "next_engine_in_menu", bus_ibus_impl_set_next_engine_in_menu },
+ /* Only for backward compatibility, shall be removed later. */
+ { "general/hotkey", "prev_engine", bus_ibus_impl_set_previous_engine },
+ { "general/hotkey", "previous_engine", bus_ibus_impl_set_previous_engine },
{ "general", "preload_engines", bus_ibus_impl_set_preload_engines },
{ "general", "use_system_keyboard_layout", bus_ibus_impl_set_use_sys_layout },
{ "general", "use_global_engine", bus_ibus_impl_set_use_global_engine },
{ "general", "embed_preedit_text", bus_ibus_impl_set_embed_preedit_text },
+ { "general", "enable_by_default", bus_ibus_impl_set_enable_by_default },
};
for (i = 0; i < G_N_ELEMENTS (entries); i++) {
gchar *key;
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/hotkey", "trigger", bus_ibus_impl_set_trigger },
+ /* Only for backward compatibility, shall be removed later. */
+ { "general/hotkey", "next_engine", bus_ibus_impl_set_next_engine_in_menu },
+ { "general/hotkey", "next_engine_in_menu", bus_ibus_impl_set_next_engine_in_menu },
+ /* Only for backward compatibility, shall be removed later. */
+ { "general/hotkey", "prev_engine", bus_ibus_impl_set_previous_engine },
+ { "general/hotkey", "previous_engine", bus_ibus_impl_set_previous_engine },
{ "general", "preload_engines", bus_ibus_impl_set_preload_engines },
{ "general", "use_system_keyboard_layout", bus_ibus_impl_set_use_sys_layout },
{ "general", "use_global_engine", bus_ibus_impl_set_use_global_engine },
{ "general", "embed_preedit_text", bus_ibus_impl_set_embed_preedit_text },
+ { "general", "enable_by_default", bus_ibus_impl_set_enable_by_default },
};
for (i = 0; i < G_N_ELEMENTS (entries); i++) {
ibus->use_sys_layout = FALSE;
ibus->embed_preedit_text = TRUE;
+ ibus->enable_by_default = FALSE;
ibus->use_global_engine = FALSE;
ibus->global_engine = NULL;
+ ibus->global_previous_engine_name = NULL;
bus_ibus_impl_reload_config (ibus);
ibus->global_engine = NULL;
}
+ g_free (ibus->global_previous_engine_name);
+
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));
" <arg name=\"data\" direction=\"in\" type=\"v\"/>\n"
" <arg name=\"data\" direction=\"out\" type=\"v\"/>\n"
" </method>\n"
+ " <method name=\"GetUseSysLayout\">\n"
+ " <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n"
+ " </method>\n"
" <signal name=\"RegistryChanged\">\n"
" </signal>\n"
" </interface>\n"
g_return_if_fail (bus_input_context_has_focus (context));
if (engine_name == NULL || engine_name[0] == '\0') {
- /* request default engine */
- if (ibus->register_engine_list) {
- engine_desc = (IBusEngineDesc *)ibus->register_engine_list->data;
- }
- else if (ibus->engine_list) {
- engine_desc = (IBusEngineDesc *)ibus->engine_list->data;
+ /* Use global engine if possible. */
+ if (ibus->use_global_engine) {
+ if (ibus->global_engine) {
+ bus_ibus_impl_set_context_engine (ibus, context, ibus->global_engine);
+ return;
+ }
+ else {
+ engine_name = bus_ibus_impl_load_global_engine_name_from_config (ibus);
+ if (engine_name) {
+ engine_desc = _find_engine_desc_by_name (ibus, engine_name);
+ g_free (engine_name);
+ }
+ }
}
+ /* request default engine */
+ if (!engine_desc) {
+ if (ibus->register_engine_list) {
+ engine_desc = (IBusEngineDesc *)ibus->register_engine_list->data;
+ }
+ else if (ibus->engine_list) {
+ engine_desc = (IBusEngineDesc *)ibus->engine_list->data;
+ }
+ }
}
else {
/* request engine by name */
if (engine_desc != NULL) {
engine = bus_ibus_impl_create_engine (engine_desc);
if (engine != NULL) {
- bus_input_context_set_engine (context, engine);
+ bus_ibus_impl_set_context_engine (ibus, context, engine);
}
}
}
static void
-_context_request_next_engine_cb (BusInputContext *context,
- BusIBusImpl *ibus)
+bus_ibus_impl_context_request_next_engine_in_menu (BusIBusImpl *ibus,
+ BusInputContext *context)
{
BusEngineProxy *engine;
IBusEngineDesc *desc;
if (next_desc != NULL) {
engine = bus_ibus_impl_create_engine (next_desc);
if (engine != NULL) {
- bus_input_context_set_engine (context, engine);
+ bus_ibus_impl_set_context_engine (ibus, context, engine);
}
}
}
static void
-_context_request_prev_engine_cb (BusInputContext *context,
- BusIBusImpl *ibus)
+bus_ibus_impl_context_request_previous_engine (BusIBusImpl *ibus,
+ BusInputContext *context)
{
+ gchar *engine_name = NULL;
+ if (!ibus->use_global_engine) {
+ engine_name = (gchar *) g_object_get_data (G_OBJECT (context), "previous-engine-name");
+ }
+ else {
+ if (!ibus->global_previous_engine_name) {
+ ibus->global_previous_engine_name = bus_ibus_impl_load_global_previous_engine_name_from_config (ibus);
+ }
+ engine_name = ibus->global_previous_engine_name;
+ }
+ _context_request_engine_cb (context, engine_name, ibus);
}
static void
return;
}
+ g_free (ibus->global_previous_engine_name);
+ ibus->global_previous_engine_name = NULL;
if (ibus->global_engine) {
+ /* Save the current global engine's name as previous engine. */
+ ibus->global_previous_engine_name = g_strdup (bus_engine_proxy_get_desc (ibus->global_engine)->name);
+
ibus_object_destroy ((IBusObject *)ibus->global_engine);
/* global_engine should be NULL */
g_assert (ibus->global_engine == NULL);
g_signal_connect (ibus->global_engine, "destroy",
G_CALLBACK (_global_engine_destroy_cb), ibus);
}
+
+ bus_ibus_impl_save_global_engine_name_to_config (ibus);
+ bus_ibus_impl_save_global_previous_engine_name_to_config (ibus);
+}
+
+static void
+bus_ibus_impl_set_context_engine (BusIBusImpl *ibus,
+ BusInputContext *context,
+ BusEngineProxy *engine) {
+ g_object_set_data (G_OBJECT (context), "previous-engine-name", NULL);
+
+ /* If use_global_engine is disabled, then we need to save the previous engine
+ * of each input context. */
+ if (!ibus->use_global_engine) {
+ BusEngineProxy *previous_engine = bus_input_context_get_engine (context);
+ if (previous_engine) {
+ g_object_set_data_full (G_OBJECT (context), "previous-engine-name",
+ g_strdup (bus_engine_proxy_get_desc (previous_engine)->name),
+ g_free);
+ }
+ }
+
+ bus_input_context_set_engine (context, engine);
}
static void
{
BusEngineProxy *engine;
- if (context != ibus->focused_context ||
- ibus->use_global_engine != TRUE) {
+ if (context != ibus->focused_context || !ibus->use_global_engine) {
return;
}
/* If the use_global_engine option is enabled,
* the global engine shoule be detached from the focused context. */
if (ibus->use_global_engine) {
- bus_input_context_set_engine (context, NULL);
+ bus_ibus_impl_set_context_engine (ibus, context, NULL);
}
g_object_unref (context);
* - Set the context's enabled state according to the saved state.
* Note: we get this signal only if the context supports IBUS_CAP_FOCUS. */
if (ibus->use_global_engine) {
- bus_input_context_set_engine (context, ibus->global_engine);
- if (ibus->global_engine &&
- bus_engine_proxy_is_enabled (ibus->global_engine)) {
- bus_input_context_enable (context);
+ if (!ibus->global_engine) {
+ bus_ibus_impl_set_global_engine (ibus, bus_input_context_get_engine (context));
+ }
+ else {
+ bus_ibus_impl_set_context_engine (ibus, context, ibus->global_engine);
+ if (ibus->global_engine && bus_engine_proxy_is_enabled (ibus->global_engine)) {
+ bus_input_context_enable (context);
+ }
}
}
GCallback callback;
} signals [] = {
{ "request-engine", G_CALLBACK (_context_request_engine_cb) },
- { "request-next-engine", G_CALLBACK (_context_request_next_engine_cb) },
- { "request-prev-engine", G_CALLBACK (_context_request_prev_engine_cb) },
{ "engine-changed", G_CALLBACK (_context_engine_changed_cb) },
{ "focus-in", G_CALLBACK (_context_focus_in_cb) },
{ "focus-out", G_CALLBACK (_context_focus_out_cb) },
ibus);
}
+ if (ibus->enable_by_default) {
+ bus_input_context_enable (context);
+ }
+
path = ibus_service_get_path ((IBusService *) context);
reply = ibus_message_new_method_return (message);
ibus_message_append_args (reply,
return reply;
}
+static IBusMessage *
+_ibus_get_use_sys_layout (BusIBusImpl *ibus,
+ IBusMessage *message,
+ BusConnection *connection)
+{
+ IBusMessage *reply;
+ IBusMessageIter src, dst;
+
+ reply = ibus_message_new_method_return (message);
+ ibus_message_append_args (reply,
+ G_TYPE_BOOLEAN, &ibus->use_sys_layout,
+ G_TYPE_INVALID);
+
+ return reply;
+}
+
static gboolean
bus_ibus_impl_ibus_message (BusIBusImpl *ibus,
BusConnection *connection,
{ IBUS_INTERFACE_IBUS, "ListActiveEngines", _ibus_list_active_engines },
{ IBUS_INTERFACE_IBUS, "Exit", _ibus_exit },
{ IBUS_INTERFACE_IBUS, "Ping", _ibus_ping },
+ { IBUS_INTERFACE_IBUS, "GetUseSysLayout", _ibus_get_use_sys_layout },
};
ibus_message_set_sender (message, bus_connection_get_unique_name (connection));
ibus_message_unref (message);
}
+
+
+gboolean
+bus_ibus_impl_filter_keyboard_shortcuts (BusIBusImpl *ibus,
+ BusInputContext *context,
+ guint keyval,
+ guint modifiers,
+ guint prev_keyval,
+ guint prev_modifiers)
+{
+ static GQuark trigger = 0;
+ static GQuark next = 0;
+ static GQuark previous = 0;
+
+ 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);
+
+ if (event == trigger) {
+ gboolean enabled = bus_input_context_is_enabled (context);
+ if (enabled) {
+ bus_input_context_disable (context);
+ }
+ else {
+ bus_input_context_enable (context);
+ }
+ return (enabled != bus_input_context_is_enabled (context));
+ }
+ if (event == next) {
+ if (bus_input_context_is_enabled(context)) {
+ bus_ibus_impl_context_request_next_engine_in_menu (ibus, context);
+ }
+ else {
+ bus_input_context_enable (context);
+ }
+ return TRUE;
+ }
+ if (event == previous) {
+ if (bus_input_context_is_enabled(context)) {
+ bus_ibus_impl_context_request_previous_engine (ibus, context);
+ }
+ else {
+ bus_input_context_enable (context);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gchar*
+bus_ibus_impl_load_global_engine_name_from_config (BusIBusImpl *ibus)
+{
+ GValue value = { 0 };
+ gchar *global_engine_name = NULL;
+
+ g_assert (IBUS_IS_CONFIG (ibus->config));
+
+ if (ibus_config_get_value (ibus->config, "general", "global_engine", &value) &&
+ G_VALUE_TYPE (&value) == G_TYPE_STRING) {
+ global_engine_name = g_value_dup_string (&value);
+ g_value_unset (&value);
+ }
+
+ return global_engine_name;
+}
+
+static void
+bus_ibus_impl_save_global_engine_name_to_config (BusIBusImpl *ibus)
+{
+ g_assert (IBUS_IS_CONFIG (ibus->config));
+
+ if (ibus->use_global_engine && ibus->global_engine) {
+ GValue value = { 0 };
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_static_string (&value, bus_engine_proxy_get_desc (ibus->global_engine)->name);
+
+ ibus_config_set_value (ibus->config, "general", "global_engine", &value);
+ g_value_unset (&value);
+ }
+}
+
+static gchar*
+bus_ibus_impl_load_global_previous_engine_name_from_config (BusIBusImpl *ibus)
+{
+ GValue value = { 0 };
+ gchar *global_previous_engine_name = NULL;
+
+ g_assert (IBUS_IS_CONFIG (ibus->config));
+
+ if (ibus_config_get_value (ibus->config, "general", "global_previous_engine", &value) &&
+ G_VALUE_TYPE (&value) == G_TYPE_STRING) {
+ global_previous_engine_name = g_value_dup_string (&value);
+ g_value_unset (&value);
+ }
+
+ return global_previous_engine_name;
+}
+
+static void
+bus_ibus_impl_save_global_previous_engine_name_to_config (BusIBusImpl *ibus)
+{
+ g_assert (IBUS_IS_CONFIG (ibus->config));
+
+ if (ibus->use_global_engine && ibus->global_previous_engine_name) {
+ GValue value = { 0 };
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_static_string (&value, ibus->global_previous_engine_name);
+
+ ibus_config_set_value (ibus->config, "general", "global_previous_engine", &value);
+ g_value_unset (&value);
+ }
+}
DISABLED,
ENGINE_CHANGED,
REQUEST_ENGINE,
- REQUEST_NEXT_ENGINE,
- REQUEST_PREV_ENGINE,
LAST_SIGNAL,
};
1,
G_TYPE_STRING);
- context_signals[REQUEST_NEXT_ENGINE] =
- g_signal_new (I_("request-next-engine"),
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- ibus_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- context_signals[REQUEST_PREV_ENGINE] =
- g_signal_new (I_("request-prev-engine"),
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- ibus_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
text_empty = ibus_text_new_from_string ("");
g_object_ref_sink (text_empty);
lookup_table_empty = ibus_lookup_table_new (9, 0, FALSE, FALSE);
{
g_assert (BUS_IS_INPUT_CONTEXT (context));
+ if (!context->has_focus) {
+ context->enabled = TRUE;
+ /* TODO: Do we need to emit "enabled" signal? */
+ return;
+ }
+
if (context->engine == NULL) {
g_signal_emit (context, context_signals[REQUEST_ENGINE], 0, NULL);
}
context->enabled = TRUE;
- if (context->has_focus) {
- bus_engine_proxy_enable (context->engine);
- bus_engine_proxy_focus_in (context->engine);
- bus_engine_proxy_set_capabilities (context->engine, context->capabilities);
- bus_engine_proxy_set_cursor_location (context->engine, context->x, context->y, context->w, context->h);
- }
+ bus_engine_proxy_enable (context->engine);
+ bus_engine_proxy_focus_in (context->engine);
+ bus_engine_proxy_set_capabilities (context->engine, context->capabilities);
+ bus_engine_proxy_set_cursor_location (context->engine, context->x, context->y, context->w, context->h);
+
bus_input_context_send_signal (context,
"Enabled",
G_TYPE_INVALID);
{
g_assert (BUS_IS_INPUT_CONTEXT (context));
+ if (context->engine == engine)
+ return;
+
if (context->engine != NULL) {
bus_input_context_unset_engine (context);
}
gboolean retval = FALSE;
- static GQuark trigger;
- static GQuark next_factory;
- static GQuark prev_factory;
-
- GQuark event;
+ if (context->filter_release){
+ if(modifiers & IBUS_RELEASE_MASK) {
+ /* filter release key event */
+ return TRUE;
+ }
+ else {
+ /* stop filter release key event */
+ context->filter_release = FALSE;
+ }
+ }
if (keycode != 0 && !BUS_DEFAULT_IBUS->use_sys_layout) {
IBusKeymap *keymap = BUS_DEFAULT_KEYMAP;
}
}
- if (trigger == 0) {
- trigger = g_quark_from_static_string ("trigger");
- next_factory = g_quark_from_static_string ("next-engine");
- prev_factory = g_quark_from_static_string ("prev-engine");
- }
-
- if (context->filter_release){
- if(modifiers & IBUS_RELEASE_MASK) {
- /* filter release key event */
- return TRUE;
- }
- else {
- /* stop filter release key event */
- context->filter_release = FALSE;
- }
- }
-
- event = ibus_hotkey_profile_filter_key_event (BUS_DEFAULT_HOTKEY_PROFILE,
- keyval,
- modifiers,
- context->prev_keyval,
- context->prev_modifiers,
- 0);
+ retval = bus_ibus_impl_filter_keyboard_shortcuts (BUS_DEFAULT_IBUS,
+ context,
+ keyval,
+ modifiers,
+ context->prev_keyval,
+ context->prev_modifiers);
context->prev_keyval = keyval;
context->prev_modifiers = modifiers;
- if (event == trigger) {
- gboolean enabled = context->enabled;
-
- if (context->enabled) {
- bus_input_context_disable (context);
- }
- else {
- bus_input_context_enable (context);
- }
-
- retval = (enabled != context->enabled);
- }
- else if (event == next_factory) {
- if (context->engine == NULL || context->enabled == FALSE) {
- retval = FALSE;
- }
- else {
- g_signal_emit (context, context_signals[REQUEST_NEXT_ENGINE], 0);
- retval = TRUE;
- }
- }
- else if (event == prev_factory) {
- if (context->engine == NULL || context->enabled == FALSE) {
- retval = FALSE;
- }
- else {
- g_signal_emit (context, context_signals[REQUEST_PREV_ENGINE], 0);
- retval = TRUE;
- }
- }
-
if (retval == TRUE) {
/* begin filter release key event */
context->filter_release = TRUE;