Support groupping for option window 99/246899/1
authorJihoon Kim <jihoon48.kim@samsung.com>
Mon, 2 Nov 2020 12:15:00 +0000 (21:15 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Thu, 5 Nov 2020 05:09:57 +0000 (14:09 +0900)
Change-Id: Icaabb805b197ff8f73681400f12c427a17879d59
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
src/Makefile.am
src/e_mod_input_method_manager.c [new file with mode: 0644]
src/e_mod_input_method_manager.h [new file with mode: 0644]
src/e_mod_main.c

index 1d6c388..60b4ec0 100644 (file)
@@ -8,6 +8,7 @@ pkgdir                 = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH
 pkg_LTLIBRARIES        = module.la
 module_la_SOURCES      = e_mod_main.c \
                          e_mod_input_panel.c \
+                         e_mod_input_method_manager.c \
                          wti_log.c
 module_la_LIBADD       =
 module_la_CFLAGS       = @WAYLAND_CFLAGS@ @ENLIGHTENMENT_CFLAGS@ @EEZE_CFLAGS@ @ECORE_CFLAGS@ @EINA_CFLAGS@ @VCONF_CFLAGS@ @CAPI_SYSTEM_INFO_CFLAGS@ -DHAVE_WAYLAND_ONLY -DHAVE_WAYLAND
diff --git a/src/e_mod_input_method_manager.c b/src/e_mod_input_method_manager.c
new file mode 100644 (file)
index 0000000..8194e2e
--- /dev/null
@@ -0,0 +1,166 @@
+#define E_COMP_WL
+#include "e.h"
+#include "e_mod_main.h"
+#include "e_mod_input_method_manager.h"
+#include <Ecore.h>
+#include <input-method-server-protocol.h>
+
+const unsigned int MAX_COUNT_TRANSIENT_FOR = 6;
+
+typedef struct _E_Input_Method_Mgr E_Input_Method_Mgr;
+
+struct _E_Input_Method_Mgr
+{
+   struct wl_global *global;
+   struct wl_resource *resource;
+};
+
+static uint32_t g_parent_pid = 0;
+static uint32_t g_child_pid = 0;
+static Ecore_Timer *g_transient_timer = NULL;
+static uint32_t g_transient_timer_count = 0;
+
+static E_Client *find_visible_ec_by_pid(uint32_t pid);
+
+static Eina_Bool
+_e_input_method_manager_set_transient_for(uint32_t parent_pid, uint32_t child_pid)
+{
+   E_Client *parent_ec = find_visible_ec_by_pid(parent_pid);
+   E_Client *child_ec = find_visible_ec_by_pid(child_pid);
+
+   if (parent_ec && child_ec)
+     {
+        e_policy_stack_transient_for_set(child_ec, parent_ec);
+        LOGI("Succeeded to set transient for");
+        return EINA_TRUE;
+     }
+
+   return EINA_FALSE;
+}
+
+static Eina_Bool
+_transient_for_timer_handler(void *data)
+{
+   if (g_parent_pid == 0 || g_child_pid == 0)
+     {
+        g_transient_timer = NULL;
+        g_transient_timer_count = 0;
+        return ECORE_CALLBACK_CANCEL;
+     }
+
+   if (g_transient_timer_count > MAX_COUNT_TRANSIENT_FOR)
+     {
+        g_transient_timer = NULL;
+        g_transient_timer_count = 0;
+        return ECORE_CALLBACK_CANCEL;
+     }
+
+   g_transient_timer_count++;
+
+   if (_e_input_method_manager_set_transient_for(g_parent_pid, g_child_pid))
+     {
+        g_transient_timer = NULL;
+        g_parent_pid = 0;
+        g_child_pid = 0;
+        g_transient_timer_count = 0;
+
+        return ECORE_CALLBACK_CANCEL;
+     }
+   else
+     return ECORE_CALLBACK_RENEW;
+}
+
+static E_Client *find_visible_ec_by_pid(uint32_t pid)
+{
+   E_Client *ec;
+   Eina_List *l = NULL;
+
+   EINA_LIST_FOREACH(e_comp->clients, l, ec)
+     {
+        if (!ec) continue;
+        if (e_object_is_del(E_OBJECT(ec))) continue;
+        if (ec->netwm.pid != pid) continue;
+
+        LOGI("pid(%d), name(%s), win(%x), visible(%d)", ec->netwm.pid, e_client_util_name_get(ec), e_client_util_win_get(ec), ec->visible);
+
+        if (ec->y == 0 && ec->visible && ec->vkbd.vkbd == 0)
+          return ec;
+     }
+
+   LOGW("No found ec for pid(%d)", pid);
+
+   return NULL;
+}
+
+static void
+_e_input_method_manager_cb_set_transient_for(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t parent_pid, uint32_t child_pid)
+{
+   LOGI("parent pid(%u), child pid(%u)", parent_pid, child_pid);
+
+   g_parent_pid = parent_pid;
+   g_child_pid = child_pid;
+
+   if (!_e_input_method_manager_set_transient_for(parent_pid, child_pid))
+     {
+        if (!g_transient_timer)
+          {
+             g_transient_timer_count = 0;
+             g_transient_timer = ecore_timer_add(0.3, _transient_for_timer_handler, NULL);
+          }
+     }
+}
+
+static const struct wl_input_method_manager_interface _e_input_method_manager_interface =
+{
+   _e_input_method_manager_cb_set_transient_for,
+};
+
+static void
+_e_input_method_manager_unbind(struct wl_resource *resource)
+{
+   if (g_transient_timer)
+     {
+        ecore_timer_del(g_transient_timer);
+        g_transient_timer = NULL;
+     }
+}
+
+static void
+_e_input_method_manager_cb_bind(struct wl_client *client, void *data, uint32_t version EINA_UNUSED, uint32_t id)
+{
+   E_Input_Method_Mgr *input_method_mgr = data;
+
+   input_method_mgr->resource =
+      wl_resource_create(client,
+                         &wl_input_method_manager_interface, 1, id);
+
+   if (input_method_mgr->resource)
+     wl_resource_set_implementation(input_method_mgr->resource,
+                                    &_e_input_method_manager_interface,
+                                    input_method_mgr, _e_input_method_manager_unbind);
+}
+
+Eina_Bool
+e_input_method_manager_create(void)
+{
+   E_Input_Method_Mgr *input_method_mgr;
+
+   if (!(input_method_mgr = E_NEW(E_Input_Method_Mgr, 1)))
+     {
+        ERR("Could not allocate space for Input_Method_Manager");
+        return EINA_FALSE;
+     }
+
+   input_method_mgr->global =
+      wl_global_create(e_comp_wl->wl.disp,
+                       &wl_input_method_manager_interface, 1,
+                       input_method_mgr, _e_input_method_manager_cb_bind);
+
+   if (!input_method_mgr->global)
+     {
+        free(input_method_mgr);
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
diff --git a/src/e_mod_input_method_manager.h b/src/e_mod_input_method_manager.h
new file mode 100644 (file)
index 0000000..211bfa9
--- /dev/null
@@ -0,0 +1,3 @@
+#include <stdio.h>
+
+Eina_Bool e_input_method_manager_create(void);
index 9581d17..a9cd37d 100644 (file)
@@ -1,6 +1,7 @@
 #define E_COMP_WL
 #include "e.h"
 #include "e_mod_main.h"
+#include "e_mod_input_method_manager.h"
 #include <text-server-protocol.h>
 #include <input-method-server-protocol.h>
 #include <vconf.h>
@@ -2583,6 +2584,9 @@ e_modapi_init(E_Module *m)
    if (!_e_text_input_manager_create())
      goto err;
 
+   if (!e_input_method_manager_create())
+     goto err;
+
    E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_RESIZE, _e_text_input_method_context_cb_client_resize, NULL);
 
    if (vconf_notify_key_changed(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, _keyboard_mode_changed_cb, NULL) != 0)