fix(player): keep the remote on the player surface after a window switch (#1797)
Returning to the desktop window with the chrome still up left arrow keys navigating the OSD instead of seeking: the first press seeked and silently moved focus onto Play/Pause, and every press after that walked the buttons. A window blur drops Flutter's primary focus to the root scope, so the player screen's reclaim parks it on its own node. The only handoff back down to the controls was the chrome visible->hidden transition, so with the OSD up nothing reclaimed it -- hence the reported workarounds of letting the controls hide, or moving the pointer off the player and back. Pointer exit normally hides the chrome and masks this, which is why it only shows when the pointer stays over the player while another window takes focus. Hand the surface back on window re-activation, next to the existing hide-path claim, and rename the helper since it is no longer hidden-chrome specific. The claim runs synchronously because a platform callback is not guaranteed to be followed by a frame; the screen's reclaim re-tests hasFocus when it runs, so the two no longer compete. Also gate the screen's self-heal so a directional key no longer pulls focus into the OSD when "Video Player Navigation" is off -- Tab and select keep their path in, which the ungated return value would otherwise consume with nowhere to go.
This commit is contained in:
@@ -2127,8 +2127,14 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> with WidgetsBindin
|
||||
}
|
||||
// Self-heal: if this node itself has primary focus (no descendant
|
||||
// focused, e.g. after controls auto-hide), redirect to first descendant.
|
||||
// Arrows stay playback shortcuts on desktop unless the viewer opted into
|
||||
// player navigation; only Tab/select may deliberately pull focus into
|
||||
// the OSD (#1797). Consuming navigation keys either way keeps them from
|
||||
// leaking to the route below.
|
||||
if (node.hasPrimaryFocus) {
|
||||
if (event.isActionable) {
|
||||
final claimsChrome =
|
||||
!event.logicalKey.isDpadDirection || _videoPlayerNavigationEnabled || PlatformDetector.isTV();
|
||||
if (event.isActionable && claimsChrome) {
|
||||
_chromeController.show(focusTarget: PlayerChromeFocusTarget.playPause);
|
||||
}
|
||||
return event.logicalKey.isNavigationKey ? KeyEventResult.handled : KeyEventResult.ignored;
|
||||
|
||||
Reference in New Issue
Block a user