Add isf lazy launch feature 53/41653/1
authorLi Zhang <li2012.zhang@samsung.com>
Thu, 2 Apr 2015 13:32:58 +0000 (21:32 +0800)
committerLi Zhang <li2012.zhang@samsung.com>
Wed, 17 Jun 2015 09:15:00 +0000 (17:15 +0800)
Change-Id: Iefba06e5e5d86eff969f604730eb331275c9d651
Signed-off-by: Li Zhang <li2012.zhang@samsung.com>
Makefile.am
configure.ac
ism/extras/efl_immodule/isf_imf_context.cpp
ism/src/isf_imcontrol_client.cpp

index 3dbd39c..acd76e4 100644 (file)
@@ -57,9 +57,12 @@ pkgconfig_DATA          = isf.pc scim.pc \
                          $(GTK_UTILS_PKGCONFIG)
 
 
+if ISF_INSTALL_SYSTEMD_SCRIPT
+SYSTEMD_SCRIPT = scim.service
+endif
 # $(libdir) will be /usr/lib64 on x86_64 arch, so hard-coded.
 systemduserunitdir = /usr/lib/systemd/user
-systemduserunit_DATA = scim.service
+systemduserunit_DATA = $(SYSTEMD_SCRIPT)
 
 ACLOCAL_AMFLAGS = -I ism/m4
 
@@ -72,5 +75,7 @@ uninstall-local:
        rm -rf @SCIM_MODULE_PATH@
 
 install-data-hook:
+if ISF_INSTALL_SYSTEMD_SCRIPT
        $(mkinstalldirs) $(DESTDIR)$(systemduserunitdir)/default.target.wants
        ln -sf ../scim.service $(DESTDIR)$(systemduserunitdir)/default.target.wants/scim.service
+endif
index a626cb8..82531c4 100755 (executable)
@@ -498,6 +498,11 @@ AC_ARG_ENABLE(multiwindow-support,
               enable_multiwindow_support=no,
               enable_multiwindow_support=yes)
 
+AC_ARG_ENABLE(lazy-launch,
+              [  --enable-lazy-launch      Launch ISF when focusing in entry],
+              enable_lazy_launch=yes,
+              enable_lazy_launch=no)
+
 if test "$have_x" = "yes"; then
   SCIM_BUILD_X11_UTILS=1
   enable_x11_utils=yes
@@ -648,6 +653,13 @@ fi
 AM_CONDITIONAL(HAVE_X,
                 [test "$have_x" = "yes"])
 
+if test "$enable_lazy_launch" = "yes"; then
+  AC_DEFINE(ENABLE_LAZY_LAUNCH,1,[Launch ISF when focusing in entry])
+  ISF_INSTALL_SYSTEMD_SCRIPT=0
+else
+  ISF_INSTALL_SYSTEMD_SCRIPT=1
+fi
+
 AM_CONDITIONAL(SCIM_LD_VERSION_SCRIPT,
                 [test "$enable_ld_version_script" = "yes"])
 
@@ -708,6 +720,9 @@ AM_CONDITIONAL(ISF_BUILD_MINICONTROL,
 AM_CONDITIONAL(ISF_BUILD_DB_UTIL,
                 [test "$ISF_HAS_DB_UTIL" = "yes"])
 
+AM_CONDITIONAL(ISF_INSTALL_SYSTEMD_SCRIPT,
+                [test "$enable_lazy_launch" = "no"])
+
 AC_SUBST(SCIM_BUILD_TESTS)
 AC_SUBST(SCIM_BUILD_CONFIG_SIMPLE)
 AC_SUBST(SCIM_BUILD_CONFIG_SOCKET)
@@ -725,6 +740,7 @@ AC_SUBST(ISF_BUILD_EFL_IMMODULE)
 AC_SUBST(ISF_BUILD_PANEL_EFL)
 AC_SUBST(ISF_BUILD_WITH_GCONF)
 AC_SUBST(ISF_BUILD_DB_UTIL)
+AC_SUBST(ISF_INSTALL_SYSTEMD_SCRIPT)
 
 ISF_BUILDING_DLL="-DISF_BUILDING_DLL"
 AC_SUBST(ISF_BUILDING_DLL)
@@ -818,5 +834,6 @@ Module options:
 
   Enable TrayIcon          $enable_tray_icon
   Enable MultiWindow       $enable_multiwindow_support
+  Enable LazyLaunch        $enable_lazy_launch
 ])
 
index 2331415..b6c3609 100644 (file)
@@ -373,7 +373,6 @@ static IMEngineInstancePointer                          _fallback_instance;
 PanelClient                                             _panel_client;
 static int                                              _panel_client_id            = 0;
 
-static bool                                             _panel_initialized          = false;
 static int                                              _active_helper_option       = 0;
 
 static Ecore_Fd_Handler                                *_panel_iochannel_read_handler = 0;
@@ -1135,39 +1134,15 @@ imengine_layout_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout
     }
 }
 
-/* Public functions */
-/**
- * isf_imf_context_new
- *
- * This function will be called by Ecore IMF.
- * Create a instance of type EcoreIMFContextISF.
- *
- * Return value: A pointer to the newly created EcoreIMFContextISF instance
- */
-EAPI EcoreIMFContextISF *
-isf_imf_context_new (void)
+static void
+_scim_initialize (void)
 {
-    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
-
-    int val;
-
-    EcoreIMFContextISF *context_scim = new EcoreIMFContextISF;
-    if (context_scim == NULL) {
-        std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n";
-        return NULL;
-    }
-
-    if (_context_count == 0) {
-        _context_count = getpid () % 50000;
-    }
-    context_scim->id = _context_count++;
-
     if (!_scim_initialized) {
+        _scim_initialized = true;
         ecore_x_init (NULL);
         initialize ();
-        _scim_initialized = true;
         isf_imf_input_panel_init ();
-
+        int val;
         /* get autoperiod allow vconf value */
         if (vconf_get_bool (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, &val) == 0) {
             if (val == EINA_TRUE)
@@ -1189,7 +1164,53 @@ isf_imf_context_new (void)
 
         vconf_notify_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb, NULL);
     }
+}
+
+static void
+_scim_finalize (void)
+{
+    if (_scim_initialized) {
+        _scim_initialized = false;
+
+        LOGD ("immodule shutdown\n");
+
+        vconf_ignore_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb);
+        vconf_ignore_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb);
+        vconf_ignore_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb);
+
+        isf_imf_input_panel_shutdown ();
+        finalize ();
+        ecore_x_shutdown ();
+    }
+}
+
+/* Public functions */
+/**
+ * isf_imf_context_new
+ *
+ * This function will be called by Ecore IMF.
+ * Create a instance of type EcoreIMFContextISF.
+ *
+ * Return value: A pointer to the newly created EcoreIMFContextISF instance
+ */
+EAPI EcoreIMFContextISF *
+isf_imf_context_new (void)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    EcoreIMFContextISF *context_scim = new EcoreIMFContextISF;
+    if (context_scim == NULL) {
+        std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n";
+        return NULL;
+    }
 
+    if (_context_count == 0) {
+        _context_count = getpid () % 50000;
+    }
+    context_scim->id = _context_count++;
+#if !(ENABLE_LAZY_LAUNCH)
+     _scim_initialize ();
+#endif
     return context_scim;
 }
 
@@ -1205,19 +1226,8 @@ isf_imf_context_shutdown (void)
     SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
     ConfigBase::set (0);
     _default_instance.reset();
-    if (_scim_initialized) {
-        _scim_initialized = false;
+    _scim_finalize ();
 
-        LOGD ("immodule shutdown\n");
-
-        vconf_ignore_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb);
-        vconf_ignore_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb);
-        vconf_ignore_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb);
-
-        isf_imf_input_panel_shutdown ();
-        finalize ();
-        ecore_x_shutdown ();
-    }
 }
 
 EAPI void
@@ -1231,35 +1241,6 @@ isf_imf_context_add (Ecore_IMF_Context *ctx)
 
     context_scim->impl = NULL;
 
-    if (_backend.null ())
-        return;
-
-    IMEngineInstancePointer si;
-
-    // Use the default instance if "shared input method" mode is enabled.
-    if (_shared_input_method && !_default_instance.null ()) {
-        si = _default_instance;
-        SCIM_DEBUG_FRONTEND(2) << "use default instance: " << si->get_id () << " " << si->get_factory_uuid () << "\n";
-    }
-
-    // Not in "shared input method" mode, or no default instance, create an instance.
-    if (si.null ()) {
-        IMEngineFactoryPointer factory = _backend->get_default_factory (_language, "UTF-8");
-        if (factory.null ()) return;
-        si = factory->create_instance ("UTF-8", _instance_count++);
-        if (si.null ()) return;
-        LOGD ("create_instance: %s",si->get_factory_uuid ().c_str ());
-        attach_instance (si);
-        SCIM_DEBUG_FRONTEND(2) << "create new instance: " << si->get_id () << " " << si->get_factory_uuid () << "\n";
-    }
-
-    // If "shared input method" mode is enabled, and there is no default instance,
-    // then store this instance as default one.
-    if (_shared_input_method && _default_instance.null ()) {
-        SCIM_DEBUG_FRONTEND(2) << "update default instance.\n";
-        _default_instance = si;
-    }
-
     context_scim->ctx                       = ctx;
     context_scim->impl                      = new_ic_impl (context_scim);
     if (context_scim->impl == NULL) {
@@ -1267,7 +1248,6 @@ isf_imf_context_add (Ecore_IMF_Context *ctx)
         return;
     }
 
-    context_scim->impl->si                  = si;
     context_scim->impl->client_window       = 0;
     context_scim->impl->client_canvas       = NULL;
     context_scim->impl->preedit_caret       = 0;
@@ -1292,11 +1272,6 @@ isf_imf_context_add (Ecore_IMF_Context *ctx)
     if (_shared_input_method)
         context_scim->impl->is_on = _config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on);
 
-    _panel_client.prepare (context_scim->id);
-    _panel_client.register_input_context (context_scim->id, si->get_factory_uuid ());
-    set_ic_capabilities (context_scim);
-    _panel_client.send ();
-
     SCIM_DEBUG_FRONTEND(2) << "input context created: id = " << context_scim->id << "\n";
 }
 
@@ -1461,10 +1436,9 @@ isf_imf_context_focus_in (Ecore_IMF_Context *ctx)
 
     if (!context_scim)
         return;
-
-    if (!_panel_initialized)
-        panel_initialize ();
-
+#if ENABLE_LAZY_LAUNCH
+    _scim_initialize ();
+#endif
     SCIM_DEBUG_FRONTEND(1) << __FUNCTION__<< "(" << context_scim->id << ")...\n";
 
     if (_focused_ic) {
@@ -2271,8 +2245,7 @@ EAPI void isf_imf_context_imdata_set (Ecore_IMF_Context *ctx, const void* data,
 
     if (context_scim == NULL || data == NULL || length <= 0)
         return;
-
-    if (context_scim && context_scim->impl) {
+    if (context_scim->impl) {
         if (context_scim->impl->imdata)
             free (context_scim->impl->imdata);
 
@@ -3269,8 +3242,6 @@ panel_initialize (void)
             }
         }
 
-        _panel_initialized = true;
-
         return true;
     }
     std::cerr << "panel_initialize () failed!!!\n";
@@ -3282,7 +3253,6 @@ panel_finalize (void)
 {
     SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
 
-    _panel_initialized = false;
     _panel_client.close_connection ();
 
     if (_panel_iochannel_read_handler) {
@@ -3585,8 +3555,6 @@ finalize (void)
     _focused_ic = NULL;
     _ic_list = NULL;
 
-    _scim_initialized = false;
-
     _panel_client.reset_signal_handler ();
     panel_finalize ();
 }
index eac7e7f..578f470 100644 (file)
@@ -25,6 +25,8 @@
 #define Uses_SCIM_TRANSACTION
 #define Uses_ISF_IMCONTROL_CLIENT
 #define Uses_SCIM_PANEL_AGENT
+#define Uses_SCIM_IMENGINE_MODULE
+#define Uses_SCIM_HELPER_MODULE
 
 
 #include <string.h>
@@ -37,6 +39,88 @@ namespace scim
 
 typedef Signal1<void, int> IMControlClientSignalVoid;
 
+static bool check_panel (const String &display)
+{
+    SocketAddress address;
+    SocketClient client;
+
+    uint32 magic;
+
+    address.set_address (scim_get_default_panel_socket_address (display));
+
+    if (!client.connect (address))
+        return false;
+
+    if (!scim_socket_open_connection (magic,
+        String ("ConnectionTester"),
+        String ("Panel"),
+        client,
+        1000)) {
+        return false;
+    }
+
+    return true;
+}
+
+static bool
+check_socket_frontend (void)
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    SocketAddress address;
+    SocketClient client;
+
+    uint32 magic;
+
+    address.set_address (scim_get_default_socket_frontend_address ());
+
+    if (!client.connect (address)) {
+        std::cerr << "check_socket_frontend's connect () failed.\n";
+        return false;
+    }
+
+    if (!scim_socket_open_connection (magic,
+                                      String ("ConnectionTester"),
+                                      String ("SocketFrontEnd"),
+                                      client,
+                                      500)) {
+        std::cerr << "check_socket_frontend's scim_socket_open_connection () failed.\n";
+        return false;
+    }
+
+    return true;
+}
+
+static int
+launch_socket_frontend ()
+{
+    SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
+
+    std::vector<String>     engine_list;
+    std::vector<String>     helper_list;
+    std::vector<String>     load_engine_list;
+
+    std::vector<String>::iterator it;
+
+    std::cerr << "Launching a ISF daemon with Socket FrontEnd...\n";
+    //get modules list
+    scim_get_imengine_module_list (engine_list);
+    scim_get_helper_module_list (helper_list);
+
+    for (it = engine_list.begin (); it != engine_list.end (); it++) {
+        if (*it != "socket")
+            load_engine_list.push_back (*it);
+    }
+    for (it = helper_list.begin (); it != helper_list.end (); it++)
+        load_engine_list.push_back (*it);
+
+    return scim_launch (true,
+        "simple",
+        (load_engine_list.size () > 0 ? scim_combine_string_list (load_engine_list, ',') : "none"),
+        "socket",
+        NULL);
+}
+
 class IMControlClient::IMControlClientImpl
 {
     SocketClient                                m_socket_imclient2panel;
@@ -57,7 +141,6 @@ public:
     }
 
     int open_connection (void) {
-        String config = "";
         const char *p = getenv ("DISPLAY");
         String display;
         if (p) display = String (p);
@@ -75,10 +158,12 @@ public:
             ret2 = m_socket_panel2imclient.connect (addr);
             if (!ret) {
                 scim_usleep (100000);
-                /* Do not launch panel process here, let the SocketFrontend to create panel process */
-                /*
-                scim_launch_panel (true, config, display, NULL);
-                */
+#if ENABLE_LAZY_LAUNCH
+                if (!check_socket_frontend ())
+                    launch_socket_frontend ();
+                if (!check_panel (display))
+                    scim_launch_panel (true, "socket", display, NULL);
+#endif
                 for (int i = 0; i < 200; ++i) {
                     if (m_socket_imclient2panel.connect (addr)) {
                         ret = true;