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
This commit is contained in:
Carsten Haitzler 2015-03-04 17:47:54 +09:00
parent b0f969dd2a
commit 17ffbd6448
10 changed files with 172 additions and 9 deletions

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -1584,6 +1584,30 @@ _status_config_focus_autoscroll_changed_cb(void *data EINA_UNUSED,
elm_config_focus_autoscroll_mode_set(elm_radio_value_get(obj));
}
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<br/>"
"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);

View File

@ -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)
{

View File

@ -1723,6 +1723,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

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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)
{