Focus: defer focus border until first directional navigation#173
Conversation
|
Would indeed be nice to find a solution for this and I guess it would work but indeed:
...but I was thinking, how about on all devices, we still add the widget to the focusgroup, but don't do anything with the border (no set_style_border_color etc) until the user uses "move_focus_direction" , meaning they pushed the joystick? So first they don't see anything special, but as soon as they press the joystick once the set_style_border_color , set_style_border_width , set_style_border_opa and set_style_radius are applied so it behaves as normal? |
Per review feedback on MicroPythonOS#173: instead of skipping add_focus_border() on touch devices (which mishandled hybrid touch+keypad devices), keep adding every widget to the focus group but don't draw the border until the user actually navigates by direction. _focus_border_handler() is a no-op until enable_focus_borders() is called, which move_focus_direction() does on the first joystick/keypad press: - touch-only UIs (focus by tapping) never show a stray ring - keypad/encoder devices show it the moment they navigate - hybrid devices show it only once the joystick is actually used - CHANGELOG: Frameworks entry - tests/test_focus_border_deferred.py: no-border-until-nav unit test
7b8eafd to
0af5dcc
Compare
|
Good call — adopted your approach. Pushed a rewrite (force-update, rebased onto current Instead of skipping
Behavior:
Testing: |
Make
add_focus_border()(mpos/ui/focus.py) skip the focus ring on pointer/touch devices.Why
add_focus_border()draws a focus highlight and adds the widget to the default focus group — a navigation aid for keypad/encoder devices, where it shows which widget the moving highlight is on. On a pointer/touch UI there is no moving highlight: the ring only appears after a tap and then lingers around the tapped widget.Concretely, this is why the Lightning Piggy balance shows a gold rectangle after you tap it (the balance is
add_focus_border-ed in 0.6.0, and tapping it cycles the denomination). On a touchscreen that ring is visual noise, not a cue.What
InputManager.has_pointer()(no new detection).CLICKABLEflag / click handlers, which are independent of the focus group.has_pointer()is False there, so the border is added exactly as before.Hybrid devices (both touch and a keypad) would also skip the ring; that edge case can be refined later if needed — flagging it explicitly rather than silently.
Testing
tests/test_focus_border_touch.pyadded: assertsadd_focus_border()registers no callbacks whenInputManager.has_pointer()is patched True.InputManager.has_pointer()returns True on a real touchscreen device (ESP32-S3), so the guard fires there../tests/unittest.shlocally — it needs a freshly built desktop binary with this change and my local build is stale. Please run./tests/unittest.sh tests/test_focus_border_touch.pyin CI / on a current build.Merge checklist
add_focus_borderbehavior is now device-conditional; happy to add a note if there is a docs page for it.