From 415a8440f8669cb2c987dd7bdd39f0474134ae15 Mon Sep 17 00:00:00 2001 From: Ji-Youn Park Date: Wed, 13 May 2015 20:57:36 +0900 Subject: [PATCH] elm_win: Add elm win key grab. If keyrouter support several keygrab mode, apps can use it. Conflicts: src/lib/elm_win.eo Signed-off-by: Jiyoun Park Change-Id: Ibe9879803e19525c34afba85926ef8b60ac76d79 origin: upstream --- src/bin/Makefile.am | 1 + src/bin/test.c | 2 + src/bin/test_win_keygrab.c | 243 +++++++++++++++++++++++++++++++++++++ src/lib/elm_win.c | 37 ++++++ src/lib/elm_win.eo | 30 +++++ src/lib/elm_win_common.h | 15 +++ 6 files changed, 328 insertions(+) create mode 100644 src/bin/test_win_keygrab.c diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 05faaf476..73c7df394 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -123,6 +123,7 @@ test_video.c \ test_weather.c \ test_web.c \ test_win_inline.c \ +test_win_keygrab.c \ test_win_socket.c \ test_win_plug.c \ test_win_state.c \ diff --git a/src/bin/test.c b/src/bin/test.c index a30109c2f..d03b1845a 100644 --- a/src/bin/test.c +++ b/src/bin/test.c @@ -214,6 +214,7 @@ void test_store(void *data, Evas_Object *obj, void *event_info); void test_sys_notify(void *data, Evas_Object *obj, void *event_info); void test_systray(void *data, Evas_Object *obj, void *event_info); void test_win_inline(void *data, Evas_Object *obj, void *event_info); +void test_win_keygrab(void *data, Evas_Object *obj, void *event_info); void test_win_socket(void *data, Evas_Object *obj, void *event_info); void test_win_plug(void *data, Evas_Object *obj, void *event_info); void test_win_wm_rotation(void *data, Evas_Object *obj, void *event_info); @@ -534,6 +535,7 @@ add_tests: ADD_TEST(NULL, "Window / Background", "Window Plug", test_win_plug); ADD_TEST(NULL, "Window / Background", "Window WM Rotation", test_win_wm_rotation); ADD_TEST(NULL, "Window / Background", "Window Standard/Dialog", test_win_dialog); + ADD_TEST(NULL, "Window / Background", "Window Keygrab Set", test_win_keygrab); //------------------------------// ADD_TEST(NULL, "Images", "Icon", test_icon); diff --git a/src/bin/test_win_keygrab.c b/src/bin/test_win_keygrab.c new file mode 100644 index 000000000..0bc476bbb --- /dev/null +++ b/src/bin/test_win_keygrab.c @@ -0,0 +1,243 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif +#include + + +struct _api_data +{ + Evas_Object *win; + Elm_Win_Keygrab_Mode mode; /* Mode of keygr */ + char keyname[PATH_MAX]; /* Keyname */ +}; + +typedef struct _api_data api_data; + +static void +_rdg_changed_cb(void *data EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + int mode = -1; + Elm_Win_Keygrab_Mode keygrab_mode = ELM_WIN_KEYGRAB_UNKNOWN; + api_data *api = data; + + mode = elm_radio_value_get(obj); + printf("radio group value : %d\n", mode); + + if (mode == 1) + { + keygrab_mode = ELM_WIN_KEYGRAB_SHARED; + printf("keygrab mode = ELM_WIN_KEYGRAB_SHARED\n"); + } + else if (mode == 2) + { + keygrab_mode = ELM_WIN_KEYGRAB_TOPMOST; + printf("keygrab mode = ELM_WIN_KEYGRAB_TOPMOST\n"); + } + else if (mode == 3) + { + keygrab_mode = ELM_WIN_KEYGRAB_EXCLUSIVE; + printf("keygrab mode = ELM_WIN_KEYGRAB_EXCLUSIVE\n"); + } + else if (mode == 4) + { + keygrab_mode = ELM_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE; + printf("keygrab mode = ELM_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE\n"); + } + else + { + keygrab_mode = ELM_WIN_KEYGRAB_UNKNOWN; + printf("keygrab mode = ELM_WIN_KEYGRAB_UNKNOWN\n"); + } + api->mode = keygrab_mode; +} + +static void +_entry_changed_cb(void *data , Evas_Object *obj, void *event_info EINA_UNUSED) +{ + api_data *api = data; + const char *str = elm_entry_entry_get(obj); + if (!str) return; + strcpy(api->keyname, str); + printf("entry: %s\n",str); +} + +static void +_cleanup_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + if (data) + free(data); +} + +static void +_set_bt_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Eina_Bool ret = EINA_FALSE; + api_data *api = data; + + ret = elm_win_keygrab_set(api->win, api->keyname, 0, 0, 0, api->mode); + printf("Keyname:\"%s\" mode:\"%d\" keygrab set. ret=%d\n", api->keyname, api->mode, ret); +} + +static void +_unset_bt_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Eina_Bool ret = EINA_FALSE; + api_data *api = data; + + ret = elm_win_keygrab_unset(api->win, api->keyname, 0, 0); + printf("Keyname:\"%s\" mode:\"%d\" keygrab unset. ret=%d.\n", api->keyname, api->mode, ret); +} + +static void +_group_1_create(Evas_Object *bx, api_data *api) +{ + Evas_Object *bx2, *fr, *lb, *en; + + fr = elm_frame_add(bx); + elm_object_text_set(fr, "Keygrab Keyname"); + evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_pack_end(bx, fr); + evas_object_show(fr); + + bx2 = elm_box_add(fr); + elm_object_content_set(fr, bx2); + evas_object_show(bx2); + + lb = elm_label_add(bx2); + elm_object_text_set(lb, " Keyname :"); + evas_object_size_hint_weight_set(lb, 0.0, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(lb, 0.0, EVAS_HINT_FILL); + elm_box_pack_end(bx2, lb); + evas_object_show(lb); + + en = elm_entry_add(bx2); + elm_entry_single_line_set(en, EINA_TRUE); + elm_entry_scrollable_set(en, EINA_TRUE); + evas_object_size_hint_weight_set(en, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(en, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_smart_callback_add(en, "changed,user", _entry_changed_cb, api); + elm_box_pack_end(bx2, en); + evas_object_show(en); + elm_object_focus_set(en, EINA_TRUE); + + +} + +static void +_group_2_create(Evas_Object *bx, api_data *api) +{ + Evas_Object *bx2, *fr, *rd, *rd1, *rd2, *rd3; + + fr = elm_frame_add(bx); + elm_object_text_set(fr, "Keygrab Mode"); + evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(fr, EVAS_HINT_FILL, EVAS_HINT_FILL); + elm_box_pack_end(bx, fr); + evas_object_show(fr); + + bx2 = elm_box_add(fr); + elm_object_content_set(fr, bx2); + elm_box_align_set(bx2, 0.0, 0.0); + evas_object_show(bx2); + + // Shared + rd = elm_radio_add(bx2); + elm_radio_state_value_set(rd, 1); + evas_object_size_hint_weight_set(rd, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(rd, EVAS_HINT_FILL, 0.5); + elm_object_text_set(rd, "Keygrab Shared Mode"); + elm_box_pack_end(bx2, rd); + evas_object_show(rd); + evas_object_smart_callback_add(rd, "changed", _rdg_changed_cb, api); + + // Topmost + rd1 = elm_radio_add(bx2); + elm_radio_state_value_set(rd1, 2); + evas_object_size_hint_weight_set(rd1, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(rd1, EVAS_HINT_FILL, 0.5); + elm_object_text_set(rd1, "Keygrab Topmost Mode"); + elm_radio_group_add(rd1, rd); + elm_box_pack_end(bx2, rd1); + evas_object_show(rd1); + evas_object_smart_callback_add(rd1, "changed", _rdg_changed_cb, api); + + // Exclusive + rd2 = elm_radio_add(bx2); + elm_radio_state_value_set(rd2, 3); + evas_object_size_hint_weight_set(rd2, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(rd2, EVAS_HINT_FILL, 0.5); + elm_object_text_set(rd2, "Keygrab Exclusive Mode"); + elm_radio_group_add(rd2, rd); + elm_box_pack_end(bx2, rd2); + evas_object_show(rd2); + evas_object_smart_callback_add(rd2, "changed", _rdg_changed_cb, api); + + //Override Exclusive + rd3 = elm_radio_add(bx2); + elm_radio_state_value_set(rd3, 4); + evas_object_size_hint_weight_set(rd3, EVAS_HINT_EXPAND, 0.0); + evas_object_size_hint_align_set(rd3, EVAS_HINT_FILL, 0.5); + elm_object_text_set(rd3, "Keygrab Override Exclusive Mode"); + elm_radio_group_add(rd3, rd); + elm_box_pack_end(bx2, rd3); + evas_object_show(rd3); + evas_object_smart_callback_add(rd3, "changed", _rdg_changed_cb, api); +} + +static void +_group_3_create(Evas_Object *bx, api_data *api) +{ + Evas_Object *bt; + + bt = elm_button_add(bx); + elm_object_text_set(bt, "Keygrab Set"); + elm_box_pack_end(bx, bt); + + evas_object_smart_callback_add(bt, "clicked", _set_bt_clicked, api); + evas_object_show(bt); + + + bt = elm_button_add(bx); + elm_object_text_set(bt, "Keygrab Unset"); + elm_box_pack_end(bx, bt); + evas_object_smart_callback_add(bt, "clicked", _unset_bt_clicked, api); + evas_object_show(bt); +} + +void +test_win_keygrab(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + Evas_Object *win, *bx, *bx1, *bx2; + + api_data *api = calloc(1, sizeof(api_data)); + + win = elm_win_util_standard_add("keygrab", "Keygrab"); + elm_win_autodel_set(win, EINA_TRUE); + evas_object_event_callback_add(win, EVAS_CALLBACK_FREE, _cleanup_cb, api); + + bx = elm_box_add(win); + evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, bx); + evas_object_show(bx); + + bx1 = elm_box_add(win); + evas_object_size_hint_weight_set(bx1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(bx, bx1); + elm_box_horizontal_set(bx1, EINA_TRUE); + evas_object_show(bx1); + + bx2 = elm_box_add(win); + evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_box_pack_end(bx, bx2); + elm_box_horizontal_set(bx2, EINA_TRUE); + evas_object_show(bx2); + + _group_1_create(bx1, api); + _group_2_create(bx1, api); + _group_3_create(bx2, api); + + evas_object_show(win); +} diff --git a/src/lib/elm_win.c b/src/lib/elm_win.c index aca2708d4..a09e6d3f4 100644 --- a/src/lib/elm_win.c +++ b/src/lib/elm_win.c @@ -4849,6 +4849,43 @@ _elm_win_illume_command_send(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Elm_Illume_C #endif } +EOLIAN static Eina_Bool +_elm_win_keygrab_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *key, Evas_Modifier_Mask modifiers EINA_UNUSED, Evas_Modifier_Mask not_modifiers EINA_UNUSED, int priority EINA_UNUSED, Elm_Win_Keygrab_Mode grab_mode) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef HAVE_ELEMENTARY_X + _internal_elm_win_xwindow_get(sd); + if (sd->x.xwin) + { + if (grab_mode == ELM_WIN_KEYGRAB_SHARED) + ret = ecore_x_window_keygrab_set(sd->x.xwin, key, 0, 0, 0, ECORE_X_WIN_KEYGRAB_SHARED); + else if (grab_mode == ELM_WIN_KEYGRAB_TOPMOST) + ret = ecore_x_window_keygrab_set(sd->x.xwin, key, 0, 0, 0, ECORE_X_WIN_KEYGRAB_TOPMOST); + else if (grab_mode == ELM_WIN_KEYGRAB_EXCLUSIVE) + ret = ecore_x_window_keygrab_set(sd->x.xwin, key, 0, 0, 0, ECORE_X_WIN_KEYGRAB_EXCLUSIVE); + else if (grab_mode == ELM_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE) + ret = ecore_x_window_keygrab_set(sd->x.xwin, key, 0, 0, 0, ECORE_X_WIN_KEYGRAB_EXCLUSIVE); + } + return ret; +#else + return ret; +#endif +} + +EOLIAN static Eina_Bool +_elm_win_keygrab_unset(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, const char *key, Evas_Modifier_Mask modifiers EINA_UNUSED, Evas_Modifier_Mask not_modifiers EINA_UNUSED) +{ + Eina_Bool ret = EINA_FALSE; +#ifdef HAVE_ELEMENTARY_X + _internal_elm_win_xwindow_get(sd); + if (sd->x.xwin) + ret = ecore_x_window_keygrab_unset(sd->x.xwin, key, 0, 0); + return ret; +#else + return ret; +#endif +} + EOLIAN static Evas_Object* _elm_win_inlined_image_object_get(Eo *obj EINA_UNUSED, Elm_Win_Data *sd) { diff --git a/src/lib/elm_win.eo b/src/lib/elm_win.eo index c6cfccf26..424b2b0b0 100644 --- a/src/lib/elm_win.eo +++ b/src/lib/elm_win.eo @@ -1350,6 +1350,36 @@ class Elm_Win (Elm_Widget, Elm_Interface_Atspi_Window, @in bool v; /*@ If true, center vertically. If false, do not change vertical location. */ } } + keygrab_set { + /*@ + Set keygrab value of the window + + This function grabs the @p key of window using @p grab_mode. + @ingroup Win */ + + return: bool; + params { + @in const(char)* key; /*@ This string is the keyname to grab. */ + @in Evas_Modifier_Mask modifiers; /*@ This is for the keymask feature. Currently this feature is not supported. */ + @in Evas_Modifier_Mask not_modifiers; /*@ This is for the keymask feature. Currently this feature is not supported. */ + @in int proirity; /*@ This is for the priority of keygrab. Currently this feature is not supported. */ + @in Elm_Win_Keygrab_Mode grab_mode; /*@ According to the grabmode, it can grab key differently */ + } + } + keygrab_unset { + /*@ + Unset keygrab value of the window + + This function unset keygrab value. Ungrab @p key of window. + @ingroup Win */ + + return: bool; + params { + @in const(char)* key; /*@ This string is the keyname to grab. */ + @in Evas_Modifier_Mask modifiers; /*@ This is for the keymask feature. Currently this feature is not supported. */ + @in Evas_Modifier_Mask not_modifiers; /*@ This is for the keymask feature. Currently this feature is not supported. */ + } + } } implements { class.constructor; diff --git a/src/lib/elm_win_common.h b/src/lib/elm_win_common.h index b1e16fbb0..986da557e 100644 --- a/src/lib/elm_win_common.h +++ b/src/lib/elm_win_common.h @@ -142,6 +142,21 @@ typedef enum ELM_ILLUME_COMMAND_CLOSE, /**< Closes the currently active window */ } Elm_Illume_Command; +/** + * Define the mode of keygrab. + * + * A window may send commands to the Keyrouter according this mode, + * and perform different actions. + */ +typedef enum +{ + ELM_WIN_KEYGRAB_UNKNOWN = 0, /**< Unknown keygrab mode */ + ELM_WIN_KEYGRAB_SHARED = (1 << 8), /**< Getting the grabbed-key together with the other client windows */ + ELM_WIN_KEYGRAB_TOPMOST = (1 << 9), /**< Getting the grabbed-key only when window is top of the stack */ + ELM_WIN_KEYGRAB_EXCLUSIVE = (1 << 10), /**< Getting the grabbed-key exclusively regardless of window's position */ + ELM_WIN_KEYGRAB_OVERRIDE_EXCLUSIVE = (1 << 11) /**< Getting the grabbed-key exclusively regardless of window's position. Being overrided the grab by the other client window */ +} Elm_Win_Keygrab_Mode; + /** * @typedef Elm_Win_Trap * -- 2.34.1