diff --git a/.changes/README.md b/.changes/README.md index 318217075..ac69427f5 100644 --- a/.changes/README.md +++ b/.changes/README.md @@ -55,8 +55,10 @@ The body is capped at 400 characters — depth belongs in the blog post. gives it a short, poster-worthy name. The 60-character cap keeps it roughly to one line on the hero card; card text wraps by estimated width, so a headline of unusually wide glyphs may still wrap or ellipsize rather than overflow. Highlights lead the Telegram/Reddit -announcements (everything else collapses into a "+N more" counter) and become -ready-made section headings in the blog scaffold. Set it on the two or three +announcements (everything else collapses into a "+N more" counter) and open the +blog scaffold: a row in its "What changed" table and a `##` section ahead of +the themed sections, while fixes without a highlight collapse under a spoiler +there. Set it on the two or three changes worth announcing — a release where everything is a highlight has none. Not allowed on `type: internal`. diff --git a/.changes/embedded-mpv-extra-options-reconnect.md b/.changes/embedded-mpv-extra-options-reconnect.md new file mode 100644 index 000000000..8e5d60152 --- /dev/null +++ b/.changes/embedded-mpv-extra-options-reconnect.md @@ -0,0 +1,11 @@ +--- +type: feature +area: embedded-mpv +highlight: Embedded MPV reconnects dropped streams +--- + +The embedded MPV player now reloads a live stream that drops mid-playback on +its own, with increasing delays and an "attempt N of 6" line instead of a +dead error screen; a new Settings > Playback toggle turns this off. The same +section gains an advanced field for extra libmpv options (one key=value per +line) that applies on every engine, with a short network timeout on by default. diff --git a/.changes/playback-shortcuts-after-button-click.md b/.changes/playback-shortcuts-after-button-click.md new file mode 100644 index 000000000..0067f1a7a --- /dev/null +++ b/.changes/playback-shortcuts-after-button-click.md @@ -0,0 +1,10 @@ +--- +type: fix +area: playback +--- + +Keyboard shortcuts work again right after you click a button in the built-in +player controls. Previously the clicked button kept the keyboard: after +clicking fullscreen, Space left fullscreen instead of pausing, and the seek, +volume and mute keys did nothing until you clicked the video. Applies to the +shared controls in the web players and the Embedded MPV frame-copy engine. diff --git a/.changes/playback-videojs-shortcuts-after-button-click.md b/.changes/playback-videojs-shortcuts-after-button-click.md new file mode 100644 index 000000000..6a9e38625 --- /dev/null +++ b/.changes/playback-videojs-shortcuts-after-button-click.md @@ -0,0 +1,10 @@ +--- +type: fix +area: playback +--- + +With IPTVnator's shared controls turned off, the Video.js player's keyboard +shortcuts now work again right after you click a button in its control bar. +Previously the clicked button kept the keyboard: after clicking fullscreen, +Space left fullscreen instead of pausing, and the seek, volume and mute keys +did nothing until you clicked the video. diff --git a/.changes/shell-startup-window-mode.md b/.changes/shell-startup-window-mode.md new file mode 100644 index 000000000..fbe45baa0 --- /dev/null +++ b/.changes/shell-startup-window-mode.md @@ -0,0 +1,10 @@ +--- +type: feature +area: shell +issues: [1455] +--- + +Settings → General has a new "Window on startup" option: open the desktop app +at its last size, maximized, or fullscreen — handy on a TV or HTPC. Starting +with `--fullscreen` forces a single fullscreen launch without changing the +setting, and F11 now toggles fullscreen anywhere in the app. diff --git a/.changes/stalker-keep-live-playback-on-category-switch.md b/.changes/stalker-keep-live-playback-on-category-switch.md new file mode 100644 index 000000000..a6ae14ae9 --- /dev/null +++ b/.changes/stalker-keep-live-playback-on-category-switch.md @@ -0,0 +1,9 @@ +--- +type: fix +area: stalker +--- + +In Stalker portals, switching the Live TV or radio category in the sidebar no +longer stops the channel that is playing. The category only changes which +channels are listed, matching how Xtream portals and M3U playlists already +behave. diff --git a/AGENTS.md b/AGENTS.md index 73276dca9..f3ac937ef 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -213,7 +213,18 @@ Key files: discarded on the first bar focus event it is asked about or on any `keydown`, a `pointerdown` inside the bar releases a keyboard pin, and a `keydown` bubbling out of a bar control re-pins it, since operating a - focused control produces no focus event. Contract: + focused control produces no focus event. A completed pointer click then + releases the focus it left on the control (`onBarClick` → + `ControlsSurface.releasePointerFocus`, attributed by `wasPointerClick`: + non-empty click `pointerType`, else a recent press inside the clicked + element), because a focused control captures the keyboard: Space and + Enter re-activated the clicked button and `ControlsShortcuts` yields to + any interactive element in the key's path, so after a click on fullscreen + Space left fullscreen instead of pausing. Keyboard activation (empty + `pointerType`) keeps focus, only buttons and range sliders are released, + Chromium keeps its sequential-focus starting point at the blurred control + so Tab continues from it, and the volume popover ignores the release's + `focusout` (`wasPointerFocusRelease`). Contract: `docs/architecture/player-controls-contract.md` (auto-hide paragraph). - Persisted `Settings.webPlayerSharedControls` is default-ON (absent stored values coerce with `!== false`; only an explicit false opts out to the legacy @@ -446,7 +457,27 @@ Key files: path keeps the existing Video.js skin and legacy series navigation unchanged (still without `userActions.hotkeys`), while the playback keyboard shortcuts attach through `LegacyPlayerShortcuts` and drive the player API so the - vendor control bar stays in sync (`vjs-legacy-shortcuts.ts`). + vendor control bar stays in sync (`vjs-legacy-shortcuts.ts`). That chrome + also releases the focus a pointer interaction leaves on a control + (`vjs-pointer-focus-release.ts`, sharing `pointer-focus-release.ts`'s + `blurFocusedControl` with `ControlsSurface`): a focused Video.js component + stops every key before the document and turns Space/Enter into a click, so + after a click on fullscreen Space left fullscreen instead of pausing. It is + driven mainly by `focusin`, not the click, because choosing a menu item + moves focus to the menu button a tick later and that click never bubbles to + the shell: an eligible control (button/`role=button`/slider, never a menu + item) is released when its focus is attributable to a recent shell + `pointerdown` not yet ended by a document `keydown`, so `Tab` focus is kept. + A `click` runs the same release for a control clicked while already focused + (Tab, then a mouse click), which fires no `focusin`. The release is scoped + to `.vjs-control-bar`, so the caption-settings dialog (a modal sibling of + the bar) keeps its focus trap. Menu buttons live in the bar and are not + exempt: a popup is navigated through its focused item, so releasing the + button never disturbs an open menu, and the button focus a pointer moves + through (open, item selection, toggling an open menu shut) is released so + Space works again after the menu closes. ArtPlayer + (non-focusable divs) and the native HTML5 controls (focus lands on the + `