Part 1 of XKB support.
authorJames Su <james.su@gmail.com>
Tue, 4 May 2010 04:34:57 +0000 (21:34 -0700)
committerPeng Huang <shawn.p.huang@gmail.com>
Tue, 1 Jun 2010 03:39:37 +0000 (11:39 +0800)
This change includes:
1. Adds hotkey for switching to previous engine (renaming the old unused "prev_engine" to previous_engine).
2. Renames next_engine hotkey to next_engine_in_menu.
3. Saves/loads current and previous global engine names to/from config.
4. Adds enable_by_default config to enable the input method by default.
5. Moves hotkey filter function from inputcontext.c into ibusimpl.c.

bus/ibusimpl.c
bus/ibusimpl.h
bus/inputcontext.c
data/ibus.schemas.in

index 7735929..4ba91a7 100644 (file)
@@ -56,6 +56,13 @@ static void     bus_ibus_impl_add_factory       (BusIBusImpl        *ibus,
                                                  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);
@@ -65,6 +72,9 @@ static void     bus_ibus_impl_set_use_sys_layout
 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,
@@ -76,6 +86,20 @@ static void     bus_ibus_impl_registry_changed  (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 *
@@ -164,18 +188,18 @@ bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
 }
 
 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);
 }
 
@@ -234,12 +258,21 @@ bus_ibus_impl_set_use_sys_layout (BusIBusImpl *ibus,
 }
 
 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
@@ -271,6 +304,8 @@ bus_ibus_impl_set_use_global_engine (BusIBusImpl *ibus,
         /* 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);
     }
 }
 
@@ -356,12 +391,17 @@ 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 },
+        /* 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++) {
@@ -399,13 +439,18 @@ _config_value_changed_cb (IBusConfig  *config,
         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++) {
@@ -554,8 +599,10 @@ bus_ibus_impl_init (BusIBusImpl *ibus)
 
     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);
 
@@ -631,6 +678,8 @@ bus_ibus_impl_destroy (BusIBusImpl *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));
@@ -677,6 +726,9 @@ _ibus_introspect (BusIBusImpl     *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"
@@ -794,13 +846,29 @@ _context_request_engine_cb (BusInputContext *context,
     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 */
@@ -810,14 +878,14 @@ _context_request_engine_cb (BusInputContext *context,
     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;
@@ -858,16 +926,27 @@ _context_request_next_engine_cb (BusInputContext *context,
     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
@@ -894,7 +973,12 @@ bus_ibus_impl_set_global_engine (BusIBusImpl    *ibus,
         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);
@@ -906,6 +990,29 @@ bus_ibus_impl_set_global_engine (BusIBusImpl    *ibus,
         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
@@ -914,8 +1021,7 @@ _context_engine_changed_cb (BusInputContext *context,
 {
     BusEngineProxy *engine;
 
-    if (context != ibus->focused_context ||
-        ibus->use_global_engine != TRUE) {
+    if (context != ibus->focused_context || !ibus->use_global_engine) {
         return;
     }
 
@@ -953,7 +1059,7 @@ _context_focus_out_cb (BusInputContext    *context,
     /* 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);
@@ -989,10 +1095,14 @@ _context_focus_in_cb (BusInputContext *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);
+            }
         }
     }
 
@@ -1071,8 +1181,6 @@ _ibus_create_input_context (BusIBusImpl     *ibus,
         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) },
@@ -1090,6 +1198,10 @@ _ibus_create_input_context (BusIBusImpl     *ibus,
                           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,
@@ -1354,6 +1466,22 @@ _ibus_ping (BusIBusImpl     *ibus,
     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,
@@ -1383,6 +1511,7 @@ bus_ibus_impl_ibus_message (BusIBusImpl     *ibus,
         { 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));
@@ -1475,3 +1604,124 @@ bus_ibus_impl_registry_changed (BusIBusImpl *ibus)
     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);
+    }
+}
index 0152a21..7eda871 100644 (file)
@@ -75,6 +75,7 @@ struct _BusIBusImpl {
 
     gboolean use_sys_layout;
     gboolean embed_preedit_text;
+    gboolean enable_by_default;
 
     BusRegistry     *registry;
 
@@ -86,6 +87,7 @@ struct _BusIBusImpl {
 
     gboolean use_global_engine;
     BusEngineProxy  *global_engine;
+    gchar           *global_previous_engine_name;
 };
 
 struct _BusIBusImplClass {
@@ -108,5 +110,13 @@ IBusHotkeyProfile
 IBusKeymap      *bus_ibus_impl_get_keymap           (BusIBusImpl        *ibus);
 BusRegistry     *bus_ibus_impl_get_registry         (BusIBusImpl        *ibus);
 
+gboolean         bus_ibus_impl_filter_keyboard_shortcuts
+                                                    (BusIBusImpl        *ibus,
+                                                     BusInputContext    *context,
+                                                     guint               keyval,
+                                                     guint               modifiers,
+                                                     guint               prev_keyval,
+                                                     guint               prev_modifiers);
+
 G_END_DECLS
 #endif
index ca95d65..35d952d 100644 (file)
@@ -50,8 +50,6 @@ enum {
     DISABLED,
     ENGINE_CHANGED,
     REQUEST_ENGINE,
-    REQUEST_NEXT_ENGINE,
-    REQUEST_PREV_ENGINE,
     LAST_SIGNAL,
 };
 
@@ -430,26 +428,6 @@ bus_input_context_class_init (BusInputContextClass *klass)
             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);
@@ -1881,6 +1859,12 @@ bus_input_context_enable (BusInputContext *context)
 {
     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);
     }
@@ -1890,12 +1874,11 @@ bus_input_context_enable (BusInputContext *context)
 
     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);
@@ -1990,6 +1973,9 @@ bus_input_context_set_engine (BusInputContext *context,
 {
     g_assert (BUS_IS_INPUT_CONTEXT (context));
 
+    if (context->engine == engine)
+        return;
+
     if (context->engine != NULL) {
         bus_input_context_unset_engine (context);
     }
@@ -2038,11 +2024,16 @@ bus_input_context_filter_keyboard_shortcuts (BusInputContext    *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;
@@ -2055,63 +2046,15 @@ bus_input_context_filter_keyboard_shortcuts (BusInputContext    *context,
         }
     }
 
-    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;
index 1db51e1..4695d0b 100644 (file)
@@ -24,6 +24,8 @@
            <long>The shortcut keys for turning input method on or off</long>
       </locale>
     </schema>
+
+    <!-- For backward compatibility -->
     <schema>
       <key>/schemas/desktop/ibus/general/hotkey/next_engine</key>
       <applyto>/desktop/ibus/general/hotkey/next_engine</applyto>
       <default>[Alt+Shift_L]</default>
       <locale name="C">
         <short>Next engine shortcut keys</short>
-           <long>The shortcut keys for switching to next input method in the list</long>
+           <long>The shortcut keys for switching to the next input method in the list</long>
       </locale>
     </schema>
+
+    <schema>
+      <key>/schemas/desktop/ibus/general/hotkey/next_engine_in_menu</key>
+      <applyto>/desktop/ibus/general/hotkey/next_engine_in_menu</applyto>
+      <owner>ibus</owner>
+      <type>list</type>
+      <list_type>string</list_type>
+      <default>[Alt+Shift_L]</default>
+      <locale name="C">
+        <short>Next engine shortcut keys</short>
+           <long>The shortcut keys for switching to the next input method in the list</long>
+      </locale>
+    </schema>
+
+    <!-- For backward compatibility -->
     <schema>
       <key>/schemas/desktop/ibus/general/hotkey/prev_engine</key>
       <applyto>/desktop/ibus/general/hotkey/prev_engine</applyto>
       <default>[]</default>
       <locale name="C">
         <short>Prev engine shortcut keys</short>
-           <long>The shortcut keys for switching to next input method in the list</long>
+           <long>The shortcut keys for switching to the previous input method</long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/desktop/ibus/general/hotkey/previous_engine</key>
+      <applyto>/desktop/ibus/general/hotkey/previous_engine</applyto>
+      <owner>ibus</owner>
+      <type>list</type>
+      <list_type>string</list_type>
+      <default>[]</default>
+      <locale name="C">
+        <short>Prev engine shortcut keys</short>
+           <long>The shortcut keys for switching to the previous input method</long>
       </locale>
     </schema>
     <schema>
            <long>Share the same input method among all applications</long>
       </locale>
     </schema>
+
+    <schema>
+      <key>/schemas/desktop/ibus/general/enable_by_default</key>
+      <applyto>/desktop/ibus/general/enable_by_default</applyto>
+      <owner>ibus</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+        <short>Enable input method by default</short>
+           <long>Enable input method by default when the application gets input
+            focus</long>
+      </locale>
+    </schema>
   </schemalist>
 </gconfschemafile>