Skip to content

[UI] Focus escapes every panel: SpotlightContainerDecorator ignores restrict passed in its config #440

Description

@Kisnov

Moonfin version

2.8.2

Platform

Tizen (Samsung)

Platform version

Tizen 9 — firmware T-KSU2EDDEUC-0090-2130.0

TV model

TU43DU7105KXXC (43", 3840x2160)

Where does it happen?

Library — the Sort & Filter panel and the settings panel beside it, but the cause is repo-wide.

Input method

D-pad / remote

Steps to reproduce

  1. Open a library and open the Sort & Filter panel.
  2. From the first row, press Up — focus leaves the panel and lands on the poster grid / letter strip behind it.
  3. Press Left from anywhere in the panel — focus leaves the same way.
  4. The settings panel next to it behaves identically.

Expected: the panel is declared restrict: 'self-only', so 5-way should stay inside until the panel is dismissed.

Photo or video of the problem

It is easy to check. I can attach vid if needed


Cause

SpotlightContainerDecorator never reads restrict from its config object. It takes the value from the spotlightRestrict prop, which defaults to 'self-first':

// @enact/spotlight/SpotlightContainerDecorator/SpotlightContainerDecorator.js
spotlightRestrict = props.spotlightRestrict === void 0 ? 'self-first' : props.spotlightRestrict,
...
useSpotlightContainer({, restrict: spotlightRestrict, containerConfig,})

and useSpotlightContainer then applies it with setProps({…, restrict}), which overwrites whatever containerConfig carried.

So this, which is how nearly every container in the app is written:

const SortPanelContainer = SpotlightContainerDecorator({enterTo: 'last-focused', restrict: 'self-only'}, 'div');

silently runs as self-first. enterTo is unaffected — it rides through containerConfig and still works — which is why the panels behave correctly in every other respect and this has gone unnoticed.

self-first means prefer elements inside, but leave when there is nothing that way, which is exactly the reported behaviour: up from the top row leaves, left leaves.

Scope

count
Containers passing restrict: in the HOC config (ignored) 56, across 39 files
Containers passing spotlightRestrict as a prop (works) 4

The four that do it correctly are ServerMessagesDialog, UpdateNotification, and NextEpisodeContainer in both players — and those are the ones that do not leak focus. That contrast is the clearest evidence for the diagnosis.

Suggested fix

Pass it as a prop on the element:

<SortPanelContainer spotlightRestrict="self-only" >

The config key can stay or go; it does nothing either way. Worth deciding whether to fix all 56 at once or start with the panels where focus escaping is most disruptive (Library filter panel, settings panel, dialogs) and verify on a real set first — the change alters 5-way behaviour app-wide, so it wants testing on a panel rather than only reasoning.

Happy to open the PR.

Not caused by #439

Reproduces with no search field present and with every facet section collapsed. Raised while testing that PR, but it predates it.

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Missing ScreenshotUI bug reported without a photo or recording of the screenTizen

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions