0009_input: add initial test case codes for keygrab 57/182957/3
authorJengHyun Kang <jhyuni.kang@samsung.com>
Fri, 29 Jun 2018 06:55:28 +0000 (15:55 +0900)
committerJeongHyun Kang <jhyuni.kang@samsung.com>
Tue, 17 Jul 2018 09:39:19 +0000 (09:39 +0000)
Change-Id: Ifbdccff69ff08fc941ac800ebd39557f8c9eb2dd

src/Makefile.am
src/e_test_event.cpp
src/e_test_event.h
src/e_test_util.h
src/e_test_win.cpp
src/testcase/0009_input.cpp [new file with mode: 0644]

index c268992..bbcd04c 100644 (file)
@@ -17,7 +17,8 @@ testcase/0004_transient_for.cpp \
 testcase/0005_notification.cpp \
 testcase/0006_tzsh.cpp \
 testcase/0007_rotation.cpp \
-testcase/0008_focus.cpp
+testcase/0008_focus.cpp \
+testcase/0009_input.cpp
 
 e_test_runner_SOURCES = \
 e_test_main.cpp \
@@ -35,7 +36,8 @@ testcase/0004_transient_for.cpp \
 testcase/0005_notification.cpp \
 testcase/0006_tzsh.cpp \
 testcase/0007_rotation.cpp \
-testcase/0008_focus.cpp
+testcase/0008_focus.cpp \
+testcase/0009_input.cpp
 
 MAINTAINERCLEANFILES = \
 Makefile.in
index 6323159..6fe98e3 100644 (file)
@@ -28,6 +28,14 @@ static void _cb_signal_stack_changed(void *data, const Eldbus_Message *msg);
 static void _cb_signal_win_rot_changed(void *data, const Eldbus_Message *msg);
 static void _cb_signal_focus_changed(void *data, const Eldbus_Message *msg);
 
+/* callbacks - ecore */
+static Eina_Bool _cb_ecore_key(void *data, int type, void *event);
+static Eina_Bool _cb_key_delay_timer(void *data);
+
+/* callbacks - evas */
+static void _cb_evas_key_down(void * data, Evas * evas, Evas_Object * obj, void * event_info);
+static void _cb_evas_key_up(void * data, Evas * evas, Evas_Object * obj, void * event_info);
+
 /* callbacks - timer */
 static Eina_Bool _cb_work_timeout(void *data);
 static Eina_Bool _ev_wait_timeout(void *data);
@@ -82,7 +90,7 @@ etRunner::init()
    EINA_SAFETY_ON_FALSE_RETURN_VAL(res, EINA_FALSE);
 
    // init input generator
-   inputGenerator = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN);
+   inputGenerator = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN | EFL_UTIL_INPUT_DEVTYPE_KEYBOARD);
 
    return EINA_TRUE;
 }
@@ -652,6 +660,65 @@ etRunner::generateMouseUp(int x, int y)
 }
 
 Eina_Bool
+etRunner::generateKeyPress(const char *keyname)
+{
+   // Using efl_util_input_generate instead of generate event by eldbus
+   int ret = EFL_UTIL_ERROR_NONE;
+
+   if (inputGenerator == NULL)
+     {
+        inputGenerator = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN);
+        work();
+     }
+
+   ret = efl_util_input_generate_key(inputGenerator,
+                                       keyname,
+                                       1);
+   if (ret != EFL_UTIL_ERROR_NONE)
+     {
+        efl_util_input_deinitialize_generator(inputGenerator);
+        inputGenerator = NULL;
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+Eina_Bool
+etRunner::generateKeyRelease(const char *keyname)
+{
+   // Using efl_util_input_generate instead of generate event by eldbus
+   int ret = EFL_UTIL_ERROR_NONE;
+
+   if (inputGenerator == NULL)
+     {
+        inputGenerator = efl_util_input_initialize_generator(EFL_UTIL_INPUT_DEVTYPE_TOUCHSCREEN);
+        work();
+     }
+
+   ret = efl_util_input_generate_key(inputGenerator,
+                                       keyname,
+                                       0);
+   if (ret != EFL_UTIL_ERROR_NONE)
+     {
+        efl_util_input_deinitialize_generator(inputGenerator);
+        inputGenerator = NULL;
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+void
+etRunner::generateKeyEvent(const char *keyname, double delay)
+{
+   this->ev.key.timer = ecore_timer_add(delay,
+                                        _cb_key_delay_timer,
+                                        this);
+}
+
+
+Eina_Bool
 etRunner::freezeEvent()
 {
    Eldbus_Pending *p = NULL;
@@ -684,7 +751,8 @@ etRunner::thawEvent()
 Eina_Bool
 etRunner::waitEvent(E_TC_Event_Type ev_type)
 {
-   Eldbus_Signal_Handler *sh;
+   Eldbus_Signal_Handler *sh = NULL;
+   Ecore_Event_Handler *eh = NULL, *eh2 = NULL;
    Eina_Bool res = EINA_FALSE;
 
    EINA_SAFETY_ON_FALSE_RETURN_VAL((E_TC_EVENT_TYPE_NONE < ev_type), res);
@@ -729,6 +797,24 @@ etRunner::waitEvent(E_TC_Event_Type ev_type)
          EINA_SAFETY_ON_NULL_GOTO(sh, finish);
          break;
 
+      case E_TC_EVENT_TYPE_INPUT_ECORE_KEY:
+         eh = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _cb_ecore_key, this);
+         EINA_SAFETY_ON_NULL_GOTO(eh, finish);
+         eh2 = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _cb_ecore_key, this);
+         EINA_SAFETY_ON_NULL_GOTO(eh, finish);
+
+         this->ev.key.state = EINA_FALSE;
+         this->generateKeyEvent(this->ev.key.name, 1.0);
+         break;
+
+      case E_TC_EVENT_TYPE_INPUT_EVAS_KEY:
+         evas_object_event_callback_add(this->ev.key.win, EVAS_CALLBACK_KEY_DOWN, _cb_evas_key_down, this);
+         evas_object_event_callback_add(this->ev.key.win, EVAS_CALLBACK_KEY_UP, _cb_evas_key_up, this);
+
+         this->ev.key.state = EINA_FALSE;
+         this->generateKeyEvent(this->ev.key.name, 1.0);
+         break;
+
       default:
          goto finish;
          break;
@@ -749,7 +835,11 @@ etRunner::waitEvent(E_TC_Event_Type ev_type)
         ev.expire_timer = NULL;
      }
 
-   eldbus_signal_handler_del(sh);
+   if (sh) eldbus_signal_handler_del(sh);
+   if (eh) ecore_event_handler_del(eh);
+   if (eh2) ecore_event_handler_del(eh2);
+   evas_object_event_callback_del(this->ev.key.win, EVAS_CALLBACK_KEY_DOWN, _cb_evas_key_down);
+   evas_object_event_callback_del(this->ev.key.win, EVAS_CALLBACK_KEY_UP, _cb_evas_key_up);
 
    res = (ev.response == ev.request);
    EINA_SAFETY_ON_FALSE_GOTO(res, finish);
@@ -1199,3 +1289,81 @@ _ev_wait_timeout(void *data)
 
    return ECORE_CALLBACK_DONE;
 }
+
+static Eina_Bool
+_cb_ecore_key(void *data, int type, void *event)
+{
+   Ecore_Event_Key *ev = (Ecore_Event_Key *)event;
+   etRunner *runner = (etRunner *)data;
+
+   if (!strncmp(runner->ev.key.name, ev->keyname, strlen(ev->keyname)))
+     {
+        if (runner->ev.key.state == EINA_FALSE &&
+            type == ECORE_EVENT_KEY_DOWN)
+          {
+             runner->ev.key.state = EINA_TRUE;
+          }
+        else if (runner->ev.key.state == EINA_TRUE &&
+            type == ECORE_EVENT_KEY_UP)
+          {
+             runner->ev.response = runner->ev.request;
+             runner->ev.key.state = EINA_FALSE;
+             elm_exit();
+          }
+     }
+
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_cb_evas_key_down(void *data, Evas * evas, Evas_Object * obj, void * event_info)
+{
+   Evas_Event_Key_Down *ev;
+   etRunner *runner = (etRunner *)data;
+
+   ev = (Evas_Event_Key_Down *)event_info;
+
+   if (!strncmp(runner->ev.key.name, ev->keyname, strlen(ev->keyname)))
+     {
+        if (runner->ev.key.state == EINA_FALSE &&
+            runner->ev.key.win == obj)
+          {
+             runner->ev.key.state = EINA_TRUE;
+          }
+     }
+}
+
+static void
+_cb_evas_key_up(void * data, Evas * evas, Evas_Object * obj, void * event_info)
+{
+   Evas_Event_Key_Up *ev;
+   etRunner *runner = (etRunner *)data;
+
+   ev = (Evas_Event_Key_Up *)event_info;
+
+   if (!strncmp(runner->ev.key.name, ev->keyname, strlen(ev->keyname)))
+     {
+        if (runner->ev.key.state == EINA_TRUE &&
+            runner->ev.key.win == obj)
+          {
+             runner->ev.response = runner->ev.request;
+             runner->ev.key.state = EINA_FALSE;
+             runner->ev.key.win = NULL;
+             elm_exit();
+          }
+     }
+}
+
+static Eina_Bool
+_cb_key_delay_timer(void *data)
+{
+   etRunner *runner = (etRunner *)data;
+
+   runner->generateKeyPress(runner->ev.key.name);
+   runner->generateKeyRelease(runner->ev.key.name);
+
+   runner->ev.key.timer = NULL;
+
+   return ECORE_CALLBACK_CANCEL;
+}
+
index ae961e9..5672363 100644 (file)
@@ -59,6 +59,13 @@ public: /* TODO: make it hidden */
         Ecore_Timer *expire_timer;
         E_TC_Event_Type request;
         E_TC_Event_Type response;
+        struct
+          {
+             Eina_Stringshare *name;
+             Eina_Bool state;
+             Evas_Object *win;
+             Ecore_Timer *timer;
+          } key;
      } ev;
 
 public:
@@ -100,6 +107,9 @@ public:
    Eina_Bool     generateMouseDown(int x, int y);
    Eina_Bool     generateMouseMove(int x, int y);
    Eina_Bool     generateMouseUp(int x, int y);
+   Eina_Bool     generateKeyPress(const char *key);
+   Eina_Bool     generateKeyRelease(const char *key);
+   void          generateKeyEvent(const char *keyname, double delay);
    Eina_Bool     freezeEvent();
    Eina_Bool     thawEvent();
    Eina_Bool     waitEvent(E_TC_Event_Type ev);
index 5591adb..83e404c 100644 (file)
@@ -74,6 +74,8 @@ typedef enum _E_TC_Event_Type
    E_TC_EVENT_TYPE_STACK_BELOW,
    E_TC_EVENT_TYPE_WINDOW_ROTATION_CHANGE,
    E_TC_EVENT_TYPE_FOCUS_CHANGED,
+   E_TC_EVENT_TYPE_INPUT_ECORE_KEY,
+   E_TC_EVENT_TYPE_INPUT_EVAS_KEY,
    E_TC_EVENT_TYPE_MAX
 } E_TC_Event_Type;
 
index 57810da..f847cac 100644 (file)
@@ -27,8 +27,8 @@ etWin::init(etWin *parent,
             Eina_Bool usr_geom,
             E_TC_Win_Color color)
 {
-   Evas_Object *bg = NULL;
    int screen_width = 0, screen_height = 0;
+   Evas_Object *bg = NULL;
 
    parent = parent;
 
diff --git a/src/testcase/0009_input.cpp b/src/testcase/0009_input.cpp
new file mode 100644 (file)
index 0000000..86029ff
--- /dev/null
@@ -0,0 +1,292 @@
+#include "e_test_event.h"
+#include "e_test_base.h"
+#include <Ecore_Wl2.h>
+
+class etTestInput : public ::etTCBase
+{
+public:
+   etTestInput() { };
+   ~etTestInput() { };
+
+protected:
+   etWin *tw_shared = NULL;
+   etWin *tw_topposition = NULL;
+   etWin *tw_orexcl = NULL;
+   etWin *tw_excl = NULL;
+};
+
+TEST_F(etTestInput, keygrab_nowin_shared)
+{
+   Eina_Bool ret = EINA_FALSE;
+   ret = ecore_wl2_window_keygrab_set(NULL, "XF86Menu", 0, 0, 0, ECORE_WL2_WINDOW_KEYGRAB_SHARED);
+   ASSERT_TRUE(ret);
+
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_ECORE_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+   etRunner::get().ev.key.name = NULL;
+
+   ret = ecore_wl2_window_keygrab_unset(NULL, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+}
+
+TEST_F(etTestInput, keygrab_nowin_orexcl)
+{
+   Eina_Bool ret = EINA_FALSE;
+   ret = ecore_wl2_window_keygrab_set(NULL, "XF86Menu", 0, 0, 0, ECORE_WL2_WINDOW_KEYGRAB_OVERRIDE_EXCLUSIVE);
+   ASSERT_TRUE(ret);
+
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_ECORE_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+   etRunner::get().ev.key.name = NULL;
+
+   ret = ecore_wl2_window_keygrab_unset(NULL, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+}
+
+TEST_F(etTestInput, keygrab_nowin_excl)
+{
+   Eina_Bool ret = EINA_FALSE;
+   ret = ecore_wl2_window_keygrab_set(NULL, "XF86Menu", 0, 0, 0, ECORE_WL2_WINDOW_KEYGRAB_EXCLUSIVE);
+   ASSERT_TRUE(ret);
+
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_ECORE_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+   etRunner::get().ev.key.name = NULL;
+
+   ret = ecore_wl2_window_keygrab_unset(NULL, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+}
+
+TEST_F(etTestInput, keygrab_win_shared)
+{
+   Eina_Bool ret = EINA_FALSE;
+
+   tw_shared = initNormalWin("TCWin_SharedGrab", EINA_TRUE, EINA_FALSE);
+   ASSERT_TRUE(tw_shared != NULL) << "failed to initiation window";
+
+   ret = elm_win_keygrab_set(tw_shared->elm_win, "XF86Menu", 0, 0, 0, ELM_WIN_KEYGRAB_SHARED);
+   ASSERT_TRUE(ret);
+   ret = evas_object_key_grab(tw_shared->elm_win, "XF86Menu", 0, 0, EINA_FALSE);
+   ASSERT_TRUE(ret);
+
+   etRunner::get().ev.key.win = tw_shared->elm_win;
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+   ret = etRunner::get().setWinStack(tw_shared, NULL, EINA_FALSE);
+   etRunner::get().waitEvent(E_TC_EVENT_TYPE_FOCUS_CHANGED);
+   ASSERT_TRUE(ret);
+
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_EVAS_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+   etRunner::get().ev.key.name = NULL;
+   etRunner::get().ev.key.win = NULL;
+
+   evas_object_key_ungrab(tw_shared->elm_win, "XF86Menu", 0, 0);
+   ret = elm_win_keygrab_unset(tw_shared->elm_win, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+}
+
+TEST_F(etTestInput, keygrab_win_orexcl)
+{
+   Eina_Bool ret = EINA_FALSE;
+
+   tw_orexcl = initNormalWin("TCWin_OrexclGrab", EINA_TRUE, EINA_FALSE);
+   ASSERT_TRUE(tw_orexcl != NULL) << "failed to initiation window";
+
+   ret = elm_win_keygrab_set(tw_orexcl->elm_win, "XF86Menu", 0, 0, 0, ELM_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE);
+   ASSERT_TRUE(ret);
+   ret = evas_object_key_grab(tw_orexcl->elm_win, "XF86Menu", 0, 0, EINA_TRUE);
+   ASSERT_TRUE(ret);
+
+   etRunner::get().ev.key.win = tw_orexcl->elm_win;
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+   ret = etRunner::get().setWinStack(tw_orexcl, NULL, EINA_FALSE);
+   etRunner::get().waitEvent(E_TC_EVENT_TYPE_FOCUS_CHANGED);
+   ASSERT_TRUE(ret);
+
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_EVAS_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+   etRunner::get().ev.key.name = NULL;
+   etRunner::get().ev.key.win = NULL;
+
+   evas_object_key_ungrab(tw_orexcl->elm_win, "XF86Menu", 0, 0);
+   ret = elm_win_keygrab_unset(tw_orexcl->elm_win, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+}
+
+TEST_F(etTestInput, keygrab_win_excl)
+{
+   Eina_Bool ret = EINA_FALSE;
+
+   tw_excl = initNormalWin("TCWin_ExclGrab", EINA_TRUE, EINA_FALSE);
+   ASSERT_TRUE(tw_excl != NULL) << "failed to initiation window";
+
+   ret = elm_win_keygrab_set(tw_excl->elm_win, "XF86Menu", 0, 0, 0, ELM_WIN_KEYGRAB_EXCLUSIVE);
+   ASSERT_TRUE(ret);
+   ret = evas_object_key_grab(tw_excl->elm_win, "XF86Menu", 0, 0, EINA_TRUE);
+   ASSERT_TRUE(ret);
+
+   etRunner::get().ev.key.win = tw_excl->elm_win;
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+   ret = etRunner::get().setWinStack(tw_excl, NULL, EINA_FALSE);
+   etRunner::get().waitEvent(E_TC_EVENT_TYPE_FOCUS_CHANGED);
+   ASSERT_TRUE(ret);
+
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_EVAS_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+   etRunner::get().ev.key.name = NULL;
+   etRunner::get().ev.key.win = NULL;
+
+   evas_object_key_ungrab(tw_excl->elm_win, "XF86Menu", 0, 0);
+   ret = elm_win_keygrab_unset(tw_excl->elm_win, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+}
+
+TEST_F(etTestInput, keygrab_win_topposition)
+{
+   Eina_Bool ret = EINA_FALSE;
+
+   tw_topposition = initNormalWin("TCWin_ToppositionGrab", EINA_TRUE, EINA_TRUE);
+   ASSERT_TRUE(tw_topposition != NULL) << "failed to initiation window";
+
+   ecore_evas_focus_skip_set(ecore_evas_ecore_evas_get(evas_object_evas_get(tw_topposition->elm_win)), EINA_TRUE);
+
+   ret = elm_win_keygrab_set(tw_topposition->elm_win, "XF86Menu", 0, 0, 0, ELM_WIN_KEYGRAB_TOPMOST);
+   ASSERT_TRUE(ret);
+   ret = evas_object_key_grab(tw_topposition->elm_win, "XF86Menu", 0, 0, EINA_FALSE);
+   ASSERT_TRUE(ret);
+
+   etRunner::get().ev.key.win = tw_topposition->elm_win;
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_EVAS_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+   etRunner::get().ev.key.name = NULL;
+   etRunner::get().ev.key.win = NULL;
+
+   evas_object_key_ungrab(tw_topposition->elm_win, "XF86Menu", 0, 0);
+   ret = elm_win_keygrab_unset(tw_topposition->elm_win, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+}
+
+TEST_F(etTestInput, keygrab_win)
+{
+   Eina_Bool ret = EINA_FALSE;
+
+   tw_shared = initNormalWin("TCWin_SharedGrab", EINA_TRUE, EINA_FALSE);
+   ASSERT_TRUE(tw_shared != NULL) << "failed to initiation window";
+
+   tw_orexcl = initNormalWin("TCWin_OrexclGrab", EINA_TRUE, EINA_FALSE);
+   ASSERT_TRUE(tw_orexcl != NULL) << "failed to initiation window";
+
+   tw_excl = initNormalWin("TCWin_ExclGrab", EINA_TRUE, EINA_FALSE);
+   ASSERT_TRUE(tw_excl != NULL) << "failed to initiation window";
+
+   tw_topposition = initNormalWin("TCWin_ToppositionGrab", EINA_TRUE, EINA_TRUE);
+   ASSERT_TRUE(tw_topposition != NULL) << "failed to initiation window";
+
+   ecore_evas_focus_skip_set(ecore_evas_ecore_evas_get(evas_object_evas_get(tw_topposition->elm_win)), EINA_TRUE);
+
+   ret = elm_win_keygrab_set(tw_excl->elm_win, "XF86Menu", 0, 0, 0, ELM_WIN_KEYGRAB_EXCLUSIVE);
+   ASSERT_TRUE(ret);
+   ret = evas_object_key_grab(tw_excl->elm_win, "XF86Menu", 0, 0, EINA_TRUE);
+   ASSERT_TRUE(ret);
+
+   ret = elm_win_keygrab_set(tw_orexcl->elm_win, "XF86Menu", 0, 0, 0, ELM_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE);
+   ASSERT_TRUE(ret);
+   ret = evas_object_key_grab(tw_orexcl->elm_win, "XF86Menu", 0, 0, EINA_TRUE);
+   ASSERT_TRUE(ret);
+
+   ret = elm_win_keygrab_set(tw_topposition->elm_win, "XF86Menu", 0, 0, 0, ELM_WIN_KEYGRAB_TOPMOST);
+   ASSERT_TRUE(ret);
+   ret = evas_object_key_grab(tw_topposition->elm_win, "XF86Menu", 0, 0, EINA_FALSE);
+   ASSERT_TRUE(ret);
+
+   ret = elm_win_keygrab_set(tw_shared->elm_win, "XF86Menu", 0, 0, 0, ELM_WIN_KEYGRAB_SHARED);
+   ASSERT_TRUE(ret);
+   ret = evas_object_key_grab(tw_shared->elm_win, "XF86Menu", 0, 0, EINA_FALSE);
+   ASSERT_TRUE(ret);
+
+   ret = etRunner::get().setWinStack(tw_excl, NULL, EINA_FALSE);
+   etRunner::get().waitEvent(E_TC_EVENT_TYPE_FOCUS_CHANGED);
+   ASSERT_TRUE(ret);
+
+   ret = etRunner::get().setWinStack(tw_orexcl, NULL, EINA_FALSE);
+   etRunner::get().waitEvent(E_TC_EVENT_TYPE_FOCUS_CHANGED);
+   ASSERT_TRUE(ret);
+
+   ret = etRunner::get().setWinStack(tw_shared, NULL, EINA_FALSE);
+   etRunner::get().waitEvent(E_TC_EVENT_TYPE_FOCUS_CHANGED);
+   ASSERT_TRUE(ret);
+
+   // test exclusive grab
+   etRunner::get().ev.key.win = tw_excl->elm_win;
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_EVAS_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+
+   evas_object_key_ungrab(tw_excl->elm_win, "XF86Menu", 0, 0);
+   ret = elm_win_keygrab_unset(tw_excl->elm_win, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+
+   // test override exclusive grab
+   etRunner::get().ev.key.win = tw_orexcl->elm_win;
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_EVAS_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+
+   evas_object_key_ungrab(tw_orexcl->elm_win, "XF86Menu", 0, 0);
+   ret = elm_win_keygrab_unset(tw_orexcl->elm_win, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+
+   // test top position grab
+   etRunner::get().ev.key.win = tw_topposition->elm_win;
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_EVAS_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+
+   evas_object_key_ungrab(tw_topposition->elm_win, "XF86Menu", 0, 0);
+   ret = elm_win_keygrab_unset(tw_topposition->elm_win, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+
+   // test shared grab
+   etRunner::get().ev.key.win = tw_shared->elm_win;
+   etRunner::get().ev.key.name = eina_stringshare_add("XF86Menu");
+
+   ret = etRunner::get().waitEvent(E_TC_EVENT_TYPE_INPUT_EVAS_KEY);
+   ASSERT_TRUE(ret);
+
+   eina_stringshare_del(etRunner::get().ev.key.name);
+
+   evas_object_key_ungrab(tw_shared->elm_win, "XF86Menu", 0, 0);
+   ret = elm_win_keygrab_unset(tw_shared->elm_win, "XF86Menu", 0, 0);
+   ASSERT_TRUE(ret);
+   
+   etRunner::get().ev.key.name = NULL;
+   etRunner::get().ev.key.win = NULL;
+}