Page MenuHomePhabricator

Focus: custom_chain / explicit order setting
Closed, ResolvedPublic

Description

What should happen with them ?

bu5hm4n created this task.Oct 10 2017, 6:03 AM
bu5hm4n triaged this task as High priority.Nov 30 2017, 1:05 PM

@bu5hm4n
I want to get the idea about how to support legacy focus custom chain.
Do you have any plan for that ?

The idea is to check in elm_win.c before the efl_ui_focus_manager_move call, if there are custom targets set, and if so, move it by hand there, and dont even call efl_ui_focus stuff.

https://git.enlightenment.org/core/efl.git/log/?h=devs/bu5hm4n/legacy-fixes

  • Thats a POC for normal next setting.
  • How should the custom chain stuff work ? this looks so unincredible inconsistent, is there some description how that should work ?
  • I dont have tests, so i cannot test my POC...
jpeg renamed this task from custom_chain / explisit order setting to Focus: custom_chain / explicit order setting.Jan 18 2018, 2:01 AM
YOhoho added a comment.Feb 5 2018, 3:44 PM

what do you think of using composition_elements_set? it looks similar to focus custom chain.

YOhoho added a comment.Feb 6 2018, 4:26 AM

what do you think of using composition_elements_set? it looks similar to focus custom chain.

focus custom chain only applied to container. now container implements focus_composition to control children order. I think if api can control the children order, it is able to implement focus_custom_chain. It is custom_elements_set.

YOhoho added a comment.EditedFeb 8 2018, 8:25 PM

if it use composition_elements to support custom_focus_chain, we may consider some points.
first, widget need to implements composition_prepare for recovery previous tree order. unset function call composition_prepare.
second, a widget that returns TRUE in the elm_widget_focus_next_manager_is could use focus custom chain on legacy focus. but now some of the widgets don't implement focus_composition. so they can't call focus custom chain function. focus_composition is necessary if you want to support custom chain.

return value of elm_widget_focus_next_manager_isimplement Efl.Ui.Focus.Composition
elm_progressbar00
elm_button00
elm_actionslider00
elm_code_widget00
elm_flipselector00
elm_widget00
efl_ui_text00
elm_label00
elm_separator00
elm_entry00
elm_slider00
efl_ui_video00
elm_slideshow00
elm_calendar01
elm_naviframe10
elm_panes10
elm_notify10
elc_fileselector10
efl_ui_win10
elc_popup10
elc_ctxpopup10
efl_ui_flip10
elm_bubble10
elm_hover10
efl_ui_box10
efl_ui_grid10
elm_scroller10
elm_inwin10
elc_fileselector_entry10
efl_ui_frame10
efl_ui_clock10
elm_panel10
elm_box11
elm_table11
elm_grid11
elm_indexdepend on access mode0
elm_listdepend on access mode0
elc_multibuttonentrydepend on access mode0
elm_diskselectordepend on access mode0
elm_segment_controldepend on access mode0
elm_clockdepend on access mode1
elm_gengriddepend on access mode1
elm_genlistdepend on access mode1
elm_colorselectordepend on access mode1
elm_toolbardepend on access mode1
elm_spinnerdepend on access mode1
elm_layoutdepend on 'can_focus'0
efl_ui_spin_buttondoes not have1

edit:
sorry, this is wrong. only four container widgets supported focus custom chain. elm_box, elm_table, elm_grid and elm_layout.

Mhmmm i have commented on the revision, short version here: I am not too sure if the compoistion class is the right place for this.

More precice: Take a look what i have done in my POC, you can just check efl_ui_win if there is a custom chain, and either follow that path, OR use the new codepath :)

@bu5hm4n
I'm trying to write a code to support custom chain and explicit order setting with your POC. but i have some trouble and question.

We need to consider that logical node can have explicit order. it may impossible with your POC. there are two solutions i thought.

  • we can directly touch focus tree in efl_ui_win.c. but it break encapsulation and need similar DFS logic focus_manager_calc have.
  • we can check whether there is explicit order of the node in the focus manager logic. i know you don't want to add 'custom focus order' code in the focus manager. but it might be needed for backward compatibility.
  • How should the custom chain stuff work ? this looks so unincredible inconsistent, is there some description how that should work ?

legacy focus move:

  1. check whether object have explicit order.
  2. check whether object have custom chain.
  3. move following subobject tree.

note that if there is custom chain, only object which exist in the custom chain can be focuesd.

The idea is to check in elm_win.c before the efl_ui_focus_manager_move call, if there are custom targets set, and if so, move it by hand there, and dont even call efl_ui_focus stuff.

there is example to explain problem i have.


(red line is custom chain)

original focus order is btn1 -> box1(logical) -> btn2 -> btn3 -> box2(logical) -> btn4
after custom chain applied, focus order i expected is btn1 -> box1(logical) -> btn3 -> btn2 -> box2(logical) -> btn4

but when btn2 is focued, next focused object is btn3 again because of efl_ui_focus_manager_move.
is there a way to get next object in the end of custom chain?

Well, i would like to keep the idea of keeping that stuff out of the new stuff.

Possible solution to your problem:
We can add a api that will just return the next element according to DFS, even if it is a logical node. Then check for a logical order on that one and continue.

Does that answer your questions ?

Yes, i think we can implement focus chain and explicit order setting in elm_win using that API :D
Does the api have a parameter as specific node?
Because i want to know a next object from focus parent.

YOhoho added a comment.Mar 6 2018, 4:27 PM

Here is unit test for custom chain :)
P212

I like the design of the testsuite, we could think about refactoring some of the things into theire own header, since they look usefull for other things too!

bu5hm4n moved this task from Backlog to API-Regression on the Efl.Ui.Focus board.Apr 11 2018, 8:17 AM

Okay, @YOhoho can you recheck your testsuite?

The testcase focus_chain_down does not seem to make sense to me. Shouldnt the test case look like:

START_TEST(focus_chain_down)
{
   elm_object_focus_set(btn, EINA_TRUE);
   ck_assert_ptr_eq(elm_object_focused_object_get(win), btn);

#define FOCUS_DOWN_CHECK(cmp) \
   elm_object_focus_next(win, ELM_FOCUS_DOWN); \
   ck_assert_ptr_eq(elm_object_focused_object_get(win), cmp)

   FOCUS_DOWN_CHECK(btn1[0]);
   //ck_assert_ptr_ne(elm_object_focused_object_get(win), btn1[0]);
   FOCUS_DOWN_CHECK(btn2[1]);
   FOCUS_DOWN_CHECK(btn2[2]);
   FOCUS_DOWN_CHECK(btn3[0]);
   FOCUS_DOWN_CHECK(btn3[1]);
   FOCUS_DOWN_CHECK(btn3[2]);
   FOCUS_DOWN_CHECK(btn3[3]);
   FOCUS_DOWN_CHECK(btn3[3]);

#undef FOCUS_DOWN_CHECK
}
END_TEST
YOhoho added a comment.EditedApr 13 2018, 11:02 PM

Okay, @YOhoho can you recheck your testsuite?

The testcase focus_chain_down does not seem to make sense to me. Shouldnt the test case look like:

START_TEST(focus_chain_down)
{
   elm_object_focus_set(btn, EINA_TRUE);
   ck_assert_ptr_eq(elm_object_focused_object_get(win), btn);

#define FOCUS_DOWN_CHECK(cmp) \
   elm_object_focus_next(win, ELM_FOCUS_DOWN); \
   ck_assert_ptr_eq(elm_object_focused_object_get(win), cmp)

   FOCUS_DOWN_CHECK(btn1[0]);
   //ck_assert_ptr_ne(elm_object_focused_object_get(win), btn1[0]);
   FOCUS_DOWN_CHECK(btn2[1]);
   FOCUS_DOWN_CHECK(btn2[2]);
   FOCUS_DOWN_CHECK(btn3[0]);
   FOCUS_DOWN_CHECK(btn3[1]);
   FOCUS_DOWN_CHECK(btn3[2]);
   FOCUS_DOWN_CHECK(btn3[3]);
   FOCUS_DOWN_CHECK(btn3[3]);

#undef FOCUS_DOWN_CHECK
}
END_TEST
custom_chain = eina_list_append(custom_chain, bx2);
custom_chain = eina_list_append(custom_chain, btn);
custom_chain = eina_list_append(custom_chain, bx3);
elm_object_focus_custom_chain_set(bx_main, custom_chain);
custom_chain = NULL;

Because bx1 which contain btn1[0] is not in focus chain.
If widget is not in the focus chain, it can't get focus using key move except case that the widget have focus_next_object.
Same to btn3[2]

P212 is passed on 2cd1326c8d5407e2e89f01ba4b1f6c7ab6211fc3 (before implement focus manager)

WHAT?!

The chain (the construct that is used to build a logical tree) is used for the target finding of up/down/right/left ?

Even more, setting the relation from obj-(up)->next does not imply next-(down)->obj ?!

YOhoho added a comment.EditedApr 14 2018, 9:02 AM

WHAT?!

The chain (the construct that is used to build a logical tree) is used for the target finding of up/down/right/left ?

Sorry, i didn't understand the question.
Legacy focus doesn't have logical tree. It just used widget tree.

Even more, setting the relation from obj-(up)->next does not imply next-(down)->obj ?!

Yes, you can set next-(down)->another obj.

bu5hm4n added a subscriber: cedric.Apr 15 2018, 1:46 AM

Yeah sure, but the widget tree is used for getting calculating the relations up up down right / left ?!

Additionally: All the rewrite work was done to have NO possibility to get a widget that can get focus but is unable to be reached by focus movements. Maybe @cedric can jump in here, but that is not easily possible, nor am I a big fan of that, What are we doing when focus comes via mouse into the widget, and you press tab ? Where is the subtree contained ? where do we continue if the widget is dislocated in the tree ? That creates more and more questions than it solves.

More questions:

Lets say you set the Customchain C on the widget A

What happens if:

  • C contains a widget that is not part of the subchildren of A ?
  • C contains a evas object that is not a widget ? I think i cannot garantee that focus will not be stuck then.
  • What happens if I add a widget like box to C but the box does not have children ?

More questions:

Lets say you set the Customchain C on the widget A

What happens if:

  • C contains a widget that is not part of the subchildren of A ?
  • The subchildren that aren't part of A is ignored. note that the subchildren aren't contained grandchildren.
  • C contains a evas object that is not a widget ? I think i cannot garantee that focus will not be stuck then.
  • Legacy focus logic does not consider evas_object that is not a widget. so, it is ignored.
  • What happens if I add a widget like box to C but the box does not have children ?
  • Because a Box can't get focus, The box is ignored if it does not have focusable children.

this is example

         A 
    / | | | \
   B  D E  F G
  /\
 H  I

CustomChain C on the widget A -> [H-G-E-D-F]
D is evas_object_rectangle.
E is box that does not have children.
  • focus cycle using tab key is [A-G-F-A-G-F-...]
    • H, I can't get focus because B is not in CustomChain C.
    • D can't get focus because D is not widget.
    • E can't get focus because E(Box) doesn't have focusable children.

Okay, that is actually good news,

the only thing that is still up for Diskussion: what happens when legacy code just makes a node unreachable by not containing it in the custom chain? Is it acceptable for you to have them added to the end of the custom chain, or the API user can disable them via elm object tree unfocusable ?

A unreachable node by not containing in the custom chain is unfocusable, and you can add them to the end of the custom chain if they are part of subobject of custom chain's parent.
If API user set tree_unfocusable to true for them, they can't get focus even though they are in custom chain.

bu5hm4n added a comment.EditedApr 17 2018, 1:45 AM

This does somehow not answer your my question.

Lets say I have a custom chain C for widget A, w1, w2 are not part of that chain, but children of A.
Right now this means for me i have to unregister w1 and w2. Which means they are not able to be focused at all. Not even with the mouse.
Setting w1 by hand into a relation with some other widget however triggers them to be focusable, even by arrow keys and tabs. Is that accaptable for you ?

I want to keep this assertion:

  • A widget is focusable <=> accessable via tab / arrow / mouseclicks

Is this acceptable for you ?

@YOhoho https://git.enlightenment.org/core/efl.git/log/?h=devs/bu5hm4n/focus_for_hq

This seems to work good for me, there are a few FIXMEs i want to repair, and a few ERRs that i want to implement.
Can you give it a try if it is breaking something ? Or unexpected things are happening?

It seems that focus_chain_append, prepend is not working. I think it need to call some functions _full_eval_children, _flush_manager..
I tested on elementary_test -to 'focus custom chain'

Can you recheck ?

bu5hm4n edited projects, added Restricted Project; removed Efl.Ui.Focus, efl.Jun 12 2018, 12:05 AM