From 17ffbd644821df254bc699fffbab272990d52517 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Wed, 4 Mar 2015 17:47:54 +0900 Subject: [PATCH] elm - focus feature - add config option to automatically show/hide focus this adds logic in elm widget and elm win to figure out how to automatically show a focus hilight when switching focus, or to hide it. this really should be the default mode, thus in all default profiles (default, standard, mobile) it's turned on. this means if you tab or shif+tab or use arrow keys to switch focus, the focus hilight will magicallly appear. click with a mouse to change focus and it'll disappear assuming you want to use the mouse to do things. If focus is explicitly turned on in config or in the window by api, then this has no effect and focus will remain on all the time. this adds apis to change these config values and options in the default elm config tool to swizzle them as well as config upgrade handling for existing configs. @feature --- legacy/elementary/config/default/base.src.in | 4 ++- legacy/elementary/config/mobile/base.src.in | 4 ++- legacy/elementary/config/standard/base.src.in | 4 ++- legacy/elementary/src/bin/config.c | 34 +++++++++++++++++++ legacy/elementary/src/lib/elm_config.c | 32 ++++++++++++++++++ legacy/elementary/src/lib/elm_config.h | 48 +++++++++++++++++++++++++++ legacy/elementary/src/lib/elm_priv.h | 4 ++- legacy/elementary/src/lib/elm_widget.c | 4 +++ legacy/elementary/src/lib/elm_widget.h | 2 ++ legacy/elementary/src/lib/elm_win.c | 45 ++++++++++++++++++++++--- 10 files changed, 172 insertions(+), 9 deletions(-) diff --git a/legacy/elementary/config/default/base.src.in b/legacy/elementary/config/default/base.src.in index e29aeb2..a0245f3 100644 --- a/legacy/elementary/config/default/base.src.in +++ b/legacy/elementary/config/default/base.src.in @@ -1,5 +1,5 @@ group "Elm_Config" struct { - value "config_version" int: 131073; + value "config_version" int: 131074; value "engine" string: ""; value "vsync" uchar: 0; value "thumbscroll_enable" uchar: 1; @@ -94,6 +94,8 @@ group "Elm_Config" struct { value "audio_mute_input" uchar: 0; value "audio_mute_alert" uchar: 0; value "audio_mute_all" uchar: 0; + value "win_auto_focus_enable" uchar: 1; + value "win_auto_focus_animate" uchar: 1; group "color_palette" list { group "Elm_Custom_Palette" struct { value "palette_name" string: "default"; diff --git a/legacy/elementary/config/mobile/base.src.in b/legacy/elementary/config/mobile/base.src.in index ee09115..e9db0a2 100644 --- a/legacy/elementary/config/mobile/base.src.in +++ b/legacy/elementary/config/mobile/base.src.in @@ -1,5 +1,5 @@ group "Elm_Config" struct { - value "config_version" int: 131073; + value "config_version" int: 131074; value "engine" string: ""; value "vsync" uchar: 0; value "thumbscroll_enable" uchar: 1; @@ -98,6 +98,8 @@ group "Elm_Config" struct { value "audio_mute_input" uchar: 0; value "audio_mute_alert" uchar: 0; value "audio_mute_all" uchar: 0; + value "win_auto_focus_enable" uchar: 1; + value "win_auto_focus_animate" uchar: 1; group "color_palette" list { group "Elm_Custom_Palette" struct { value "palette_name" string: "default"; diff --git a/legacy/elementary/config/standard/base.src.in b/legacy/elementary/config/standard/base.src.in index 2ee0271..9cae3a1 100644 --- a/legacy/elementary/config/standard/base.src.in +++ b/legacy/elementary/config/standard/base.src.in @@ -1,5 +1,5 @@ group "Elm_Config" struct { - value "config_version" int: 131073; + value "config_version" int: 131074; value "engine" string: ""; value "vsync" uchar: 0; value "thumbscroll_enable" uchar: 0; @@ -95,6 +95,8 @@ group "Elm_Config" struct { value "audio_mute_input" uchar: 0; value "audio_mute_alert" uchar: 0; value "audio_mute_all" uchar: 0; + value "win_auto_focus_enable" uchar: 1; + value "win_auto_focus_animate" uchar: 1; group "color_palette" list { group "Elm_Custom_Palette" struct { value "palette_name" string: "default"; diff --git a/legacy/elementary/src/bin/config.c b/legacy/elementary/src/bin/config.c index 85f1743..1663d4d 100644 --- a/legacy/elementary/src/bin/config.c +++ b/legacy/elementary/src/bin/config.c @@ -1585,6 +1585,30 @@ _status_config_focus_autoscroll_changed_cb(void *data EINA_UNUSED, } static void +_config_focus_auto_show_cb(void *data EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + Eina_Bool cf = elm_config_window_auto_focus_enable_get(); + Eina_Bool val = elm_check_state_get(obj); + + if (cf == val) return; + elm_config_window_auto_focus_enable_set(val); + elm_config_all_flush(); +} + +static void +_config_focus_auto_animate_cb(void *data EINA_UNUSED, Evas_Object *obj, + void *event_info EINA_UNUSED) +{ + Eina_Bool cf = elm_config_window_auto_focus_animate_get(); + Eina_Bool val = elm_check_state_get(obj); + + if (cf == val) return; + elm_config_window_auto_focus_animate_set(val); + elm_config_all_flush(); +} + +static void _status_config_focus(Evas_Object *win, Evas_Object *naviframe) { @@ -1618,6 +1642,16 @@ _status_config_focus(Evas_Object *win, _config_focus_item_select_on_focus_cb, NULL); elm_check_state_set(ck, elm_config_item_select_on_focus_disabled_get()); + CHECK_ADD("Enable Automatic focus display", + "Set whether enable/disable focus highlight automatically.", + _config_focus_auto_show_cb, NULL); + elm_check_state_set(ck, elm_config_window_auto_focus_enable_get()); + CHECK_ADD("Enable Automatic focus animation", + "Set whether enable/disable focus highlight animation
" + "automatically when automatic focus shows.", + _config_focus_auto_animate_cb, NULL); + elm_check_state_set(ck, elm_config_window_auto_focus_enable_get()); + fr = elm_frame_add(bx); elm_object_text_set(fr, "Focus Autoscroll Mode"); evas_object_size_hint_weight_set(fr, EVAS_HINT_EXPAND, 0.0); diff --git a/legacy/elementary/src/lib/elm_config.c b/legacy/elementary/src/lib/elm_config.c index 1d6aa75..b11bb0b 100644 --- a/legacy/elementary/src/lib/elm_config.c +++ b/legacy/elementary/src/lib/elm_config.c @@ -589,6 +589,8 @@ _desc_init(void) ELM_CONFIG_VAL(D, T, audio_mute_all, T_UCHAR); ELM_CONFIG_LIST(D, T, bindings, _config_bindings_widget_edd); ELM_CONFIG_VAL(D, T, atspi_mode, T_UCHAR); + ELM_CONFIG_VAL(D, T, win_auto_focus_enable, T_UCHAR); + ELM_CONFIG_VAL(D, T, win_auto_focus_animate, T_UCHAR); #undef T #undef D #undef T_INT @@ -1610,6 +1612,8 @@ _config_load(void) _elm_config->audio_mute_input = 0; _elm_config->audio_mute_alert = 0; _elm_config->audio_mute_all = 0; + _elm_config->win_auto_focus_enable = 1; + _elm_config->win_auto_focus_animate = 1; _elm_config->atspi_mode = ELM_ATSPI_MODE_OFF; } @@ -1830,6 +1834,10 @@ _config_update(void) /* we also need to update for property changes in the root window * if needed, but that will be dependent on new properties added * with each version */ + IFCFG(0x0002) + _elm_config->win_auto_focus_enable = tcfg->win_auto_focus_enable;; + _elm_config->win_auto_focus_animate = tcfg->win_auto_focus_animate; + IFCFGEND /** * Fix user config for current ELM_CONFIG_EPOCH here. @@ -3155,6 +3163,30 @@ elm_config_audio_mute_set(Edje_Channel channel, Eina_Bool mute) edje_audio_channel_mute_set(channel, mute); } +EAPI Eina_Bool +elm_config_window_auto_focus_enable_get(void) +{ + return _elm_config->win_auto_focus_enable; +} + +EAPI void +elm_config_window_auto_focus_enable_set(Eina_Bool enable) +{ + _elm_config->win_auto_focus_enable = enable; +} + +EAPI Eina_Bool +elm_config_window_auto_focus_animate_get(void) +{ + return _elm_config->win_auto_focus_animate; +} + +EAPI void +elm_config_window_auto_focus_animate_set(Eina_Bool enable) +{ + _elm_config->win_auto_focus_animate = enable; +} + EAPI void elm_config_all_flush(void) { diff --git a/legacy/elementary/src/lib/elm_config.h b/legacy/elementary/src/lib/elm_config.h index aa1e1b0..6b625b8 100644 --- a/legacy/elementary/src/lib/elm_config.h +++ b/legacy/elementary/src/lib/elm_config.h @@ -1724,6 +1724,54 @@ EAPI Eina_Bool elm_config_audio_mute_get(Edje_Channel channel); EAPI void elm_config_audio_mute_set(Edje_Channel channel, Eina_Bool mute); /** + * Get the auto focus enable flag + * + * This determines if elementary will show a focus box indicating the focused + * widget automatically if keyboard controls like "Tab" are used to switch + * focus between widgets. Mouse or touch control will hide this auto shown + * focus, unless focus display has been expliccitly forced on for the window. + * + * @return The enabled state for auto focus display + * @since 1.14 + */ +EAPI Eina_Bool elm_config_window_auto_focus_enable_get(void); + +/** + * Set the auto focus enabled state + * + * This determines if elementary will show a focus box indicating the focused + * widget automatically if keyboard controls like "Tab" are used to switch + * focus between widgets. Mouse or touch control will hide this auto shown + * focus, unless focus display has been expliccitly forced on for the window. + * + * @param enable the auto focus display enabled state + * @since 1.14 + */ +EAPI void elm_config_window_auto_focus_enable_set(Eina_Bool enable); + +/** + * Get the auto focus animate flag + * + * If auto focus - see elm_config_window_auto_focus_enable_set() , is enabled + * then this will determine if the focus display will be animated or not. + * + * @return The enabled state for auto focus animation + * @since 1.14 + */ +EAPI Eina_Bool elm_config_window_auto_focus_animate_get(void); + +/** + * Set the auto focus animation flag + * + * If auto focus - see elm_config_window_auto_focus_enable_set() , is enabled + * then this will determine if the focus display will be animated or not. + * + * @param enable the auto focus animation state + * @since 1.14 + */ +EAPI void elm_config_window_auto_focus_animate_set(Eina_Bool enable); + +/** * @defgroup ATSPI AT-SPI2 Accessibility * @ingroup Elementary * diff --git a/legacy/elementary/src/lib/elm_priv.h b/legacy/elementary/src/lib/elm_priv.h index dbfb8cb..1ddf9aa 100644 --- a/legacy/elementary/src/lib/elm_priv.h +++ b/legacy/elementary/src/lib/elm_priv.h @@ -123,7 +123,7 @@ struct _Elm_Theme * the users config doesn't need to be wiped - simply new values need * to be put in */ -#define ELM_CONFIG_FILE_GENERATION 0x0001 +#define ELM_CONFIG_FILE_GENERATION 0x0002 #define ELM_CONFIG_VERSION_EPOCH_OFFSET 16 #define ELM_CONFIG_VERSION ((ELM_CONFIG_EPOCH << ELM_CONFIG_VERSION_EPOCH_OFFSET) | \ ELM_CONFIG_FILE_GENERATION) @@ -286,6 +286,8 @@ struct _Elm_Config unsigned char audio_mute_input; unsigned char audio_mute_alert; unsigned char audio_mute_all; + unsigned char win_auto_focus_enable; + unsigned char win_auto_focus_animate; Eina_List *bindings; Eina_Bool atspi_mode; diff --git a/legacy/elementary/src/lib/elm_widget.c b/legacy/elementary/src/lib/elm_widget.c index c4d2d69..39e3c32 100644 --- a/legacy/elementary/src/lib/elm_widget.c +++ b/legacy/elementary/src/lib/elm_widget.c @@ -3822,8 +3822,12 @@ elm_widget_focus_mouse_up_handle(Evas_Object *obj) EOLIAN static void _elm_widget_focus_mouse_up_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED) { + Evas_Object *top; + if (!obj) return; if (!_is_focusable(obj)) return; + top = elm_widget_top_get(obj); + if (top && eo_isa(top, ELM_WIN_CLASS)) _elm_win_focus_auto_hide(top); elm_widget_focus_steal(obj); } diff --git a/legacy/elementary/src/lib/elm_widget.h b/legacy/elementary/src/lib/elm_widget.h index 67cddb0..96a9444 100644 --- a/legacy/elementary/src/lib/elm_widget.h +++ b/legacy/elementary/src/lib/elm_widget.h @@ -534,6 +534,8 @@ void _elm_win_focus_highlight_in_theme_update(Evas_Object *obj, void _elm_win_focus_highlight_signal_emit(Evas_Object *obj, const char *emission, const char *source); void _elm_win_focus_highlight_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb _focus_highlight_signal_cb, void *data); void _elm_win_focus_highlight_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, Edje_Signal_Cb _focus_highlight_signal_cb); +void _elm_win_focus_auto_show(Evas_Object *obj); +void _elm_win_focus_auto_hide(Evas_Object *obj); EAPI void _elm_access_clear(Elm_Access_Info *ac); EAPI void _elm_access_text_set(Elm_Access_Info *ac, int type, const char *text); diff --git a/legacy/elementary/src/lib/elm_win.c b/legacy/elementary/src/lib/elm_win.c index 0056bd7..1bfdd93 100644 --- a/legacy/elementary/src/lib/elm_win.c +++ b/legacy/elementary/src/lib/elm_win.c @@ -166,6 +166,8 @@ struct _Elm_Win_Data Eina_Bool animate : 1; /* set true when the focus highlight animate is enabled */ Eina_Bool animate_supported : 1; /* set true when the focus highlight animate is supported by theme */ Eina_Bool geometry_changed : 1; + Eina_Bool auto_enabled : 1; + Eina_Bool auto_animate : 1; } focus_highlight; Evas_Object *icon; @@ -967,7 +969,7 @@ _elm_win_focus_highlight_reconfigure_job(void *data) (sd->obj, fobj, "focus_highlight", "top", str); sd->focus_highlight.theme_changed = EINA_FALSE; - if (sd->focus_highlight.animate) + if ((sd->focus_highlight.animate) || (sd->focus_highlight.auto_animate)) { str = edje_object_data_get(sd->focus_highlight.fobj, "animate"); sd->focus_highlight.animate_supported = ((str) && (!strcmp(str, "on"))); @@ -1386,7 +1388,10 @@ static Eina_Bool _key_action_move(Evas_Object *obj, const char *params) { const char *dir = params; + Evas_Object *top; + top = elm_widget_top_get(obj); + if (top && eo_isa(top, ELM_WIN_CLASS)) _elm_win_focus_auto_show(top); if (!strcmp(dir, "previous")) elm_widget_focus_cycle(obj, ELM_FOCUS_PREVIOUS); else if (!strcmp(dir, "next")) @@ -4864,7 +4869,7 @@ _elm_win_focus_highlight_enabled_set(Eo *obj EINA_UNUSED, Elm_Win_Data *sd, Eina sd->focus_highlight.enabled = enabled; - if (sd->focus_highlight.enabled) + if ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)) _elm_win_focus_highlight_init(sd); else _elm_win_focus_highlight_shutdown(sd); @@ -5109,7 +5114,7 @@ void _elm_win_focus_highlight_signal_emit(Evas_Object *obj, const char *emission, const char *source) { ELM_WIN_DATA_GET(obj, sd); - if (sd->focus_highlight.enabled) + if ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)) edje_object_signal_emit(sd->focus_highlight.fobj, emission, source); } @@ -5119,7 +5124,8 @@ _elm_win_focus_highlight_signal_callback_add(Evas_Object *obj, const char *emiss void *data) { ELM_WIN_DATA_GET(obj, sd); - if (sd->focus_highlight.enabled && sd->focus_highlight.fobj) + if (((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)) + && (sd->focus_highlight.fobj)) edje_object_signal_callback_add(sd->focus_highlight.fobj, emission, source, _focus_highlight_signal_cb, data); } @@ -5128,7 +5134,8 @@ _elm_win_focus_highlight_signal_callback_del(Evas_Object *obj, const char *emiss const char *source, Edje_Signal_Cb _focus_highlight_signal_cb) { ELM_WIN_DATA_GET(obj, sd); - if (sd->focus_highlight.enabled && sd->focus_highlight.fobj) + if (((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)) + && (sd->focus_highlight.fobj)) edje_object_signal_callback_del(sd->focus_highlight.fobj, emission, source, _focus_highlight_signal_cb); } @@ -5143,6 +5150,34 @@ _elm_win_focus_highlight_start(Evas_Object *obj) _elm_win_focus_highlight_reconfigure_job(obj); } +void +_elm_win_focus_auto_show(Evas_Object *obj) +{ + ELM_WIN_DATA_GET(obj, sd); + Eina_Bool pfocus = (sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled); + sd->focus_highlight.auto_enabled = _elm_config->win_auto_focus_enable; + sd->focus_highlight.auto_animate = _elm_config->win_auto_focus_animate; + if (pfocus != ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))) + { + if ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled)) + _elm_win_focus_highlight_init(sd); + } +} + +void +_elm_win_focus_auto_hide(Evas_Object *obj) +{ + ELM_WIN_DATA_GET(obj, sd); + Eina_Bool pfocus = (sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled); + sd->focus_highlight.auto_enabled = EINA_FALSE; + sd->focus_highlight.auto_animate = EINA_FALSE; + if (pfocus != ((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))) + { + if (!((sd->focus_highlight.enabled) || (sd->focus_highlight.auto_enabled))) + _elm_win_focus_highlight_shutdown(sd); + } +} + EAPI Ecore_Window elm_win_window_id_get(const Evas_Object *obj) { -- 2.7.4