From 245a04cc44911efe4243e2cb0451f20c4d929217 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 30 Aug 2017 17:55:51 +0200 Subject: [PATCH] efl_ui_focus_manager: reset focus stack once we are changing redirect ref T5923 --- src/lib/elementary/efl_ui_focus_manager.eo | 7 +++ .../elementary/efl_ui_focus_manager_calc.c | 48 ++++++++++++++++--- .../elementary/efl_ui_focus_manager_calc.eo | 1 + 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/lib/elementary/efl_ui_focus_manager.eo b/src/lib/elementary/efl_ui_focus_manager.eo index 2bb08625e3..546f9c38e1 100644 --- a/src/lib/elementary/efl_ui_focus_manager.eo +++ b/src/lib/elementary/efl_ui_focus_manager.eo @@ -125,6 +125,13 @@ interface Efl.Ui.Focus.Manager { ]] return : Efl.Ui.Focus.Object; [[Last object]] } + reset_history { + [[Reset the history stack of this manager object. + This means the most upper element will be unfocused, all other elements will be removed from the remembered before. + + To not break the assertion that there should be always a focused element, you should focus a other element immidiatly after calling that. + ]] + } } events { redirect,changed : Efl.Ui.Focus.Manager; [[Emitted when the redirect diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c index b9aed0b917..e0b33cd7b6 100644 --- a/src/lib/elementary/efl_ui_focus_manager_calc.c +++ b/src/lib/elementary/efl_ui_focus_manager_calc.c @@ -1189,6 +1189,8 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_focus_set(Eo *obj, Efl_Ui_Focus_ Node *node; Node *old_focus; Efl_Ui_Focus_Manager *redirect_manager; + Eo *focusable; + Node_Type type; EINA_SAFETY_ON_NULL_RETURN(focus); @@ -1217,11 +1219,16 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_focus_set(Eo *obj, Efl_Ui_Focus_ if (pd->redirect) { + //reset the history of that manager + efl_ui_focus_manager_reset_history(pd->redirect); + //first unset the redirect efl_ui_focus_manager_redirect_set(obj, NULL); } redirect_manager = node->redirect_manager; + type = node->type; + focusable = node->focusable; if (node->type == NODE_TYPE_NORMAL) { @@ -1245,18 +1252,31 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_focus_set(Eo *obj, Efl_Ui_Focus_ efl_event_callback_call(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUSED, focusable); node = NULL; } - else if (node->redirect_manager) - { - Efl_Ui_Focus_Object *root; - - root = efl_ui_focus_manager_root_get(node->redirect_manager); - efl_ui_focus_manager_focus_set(node->redirect_manager, root); - } //now check if this is also a listener object if (redirect_manager) { + efl_ui_focus_manager_reset_history(pd->redirect); + + //first set the redirect efl_ui_focus_manager_redirect_set(obj, redirect_manager); + + if (type == NODE_TYPE_ONLY_LOGICAL) + { + //focus the root to just get the next regular element + //FIXME it would be good to make that depending on the focus move directions + //so we can take the last regular item in the logical tree for the PREVIOUS move + Efl_Ui_Focus_Object *root; + + root = efl_ui_focus_manager_root_get(redirect_manager); + efl_ui_focus_manager_focus_set(redirect_manager, root); + } + else + { + //or just focus the focusable itself in the other manager + efl_ui_focus_manager_focus_set(redirect_manager, focusable); + } + } } @@ -1456,4 +1476,18 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_logical_end(Eo *obj EINA_UNUSED, return child ? child->focusable : NULL; } + +EOLIAN static void +_efl_ui_focus_manager_calc_efl_ui_focus_manager_reset_history(Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Calc_Data *pd) +{ + Node *last; + + if (!pd->focus_stack) return; + + last = eina_list_last_data_get(pd->focus_stack); + efl_ui_focus_object_focus_set(last->focusable, EINA_FALSE); + + pd->focus_stack = eina_list_free(pd->focus_stack); +} + #include "efl_ui_focus_manager_calc.eo.c" diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.eo b/src/lib/elementary/efl_ui_focus_manager_calc.eo index fec5875f4a..2b78b259ac 100644 --- a/src/lib/elementary/efl_ui_focus_manager_calc.eo +++ b/src/lib/elementary/efl_ui_focus_manager_calc.eo @@ -98,6 +98,7 @@ class Efl.Ui.Focus.Manager.Calc (Efl.Object, Efl.Ui.Focus.Manager) { Efl.Ui.Focus.Manager.root {set; get;} Efl.Ui.Focus.Manager.fetch; Efl.Ui.Focus.Manager.logical_end; + Efl.Ui.Focus.Manager.reset_history; Efl.Object.constructor; Efl.Object.finalize; Efl.Object.provider_find;