Skip to content

fix(details): keep the page focus ring off after pointer focus - #2189

Merged
4gray merged 6 commits into
4gray:masterfrom
marinionroids:fix/details-pointer-focus-ring
Nov 12, 2026
Merged

4gray merged 6 commits into
4gray:masterfrom
marinionroids:fix/details-pointer-focus-ring

Conversation

@marinionroids

Copy link
Copy Markdown
Contributor

Fixes #2170.

What changed

  • PortalDetailShellComponent records, when its host receives focus, whether Chromium already treats that focus as :focus-visible. A pointer focus sets shell-host--pointer-focus, and &.shell-host--pointer-focus:focus-visible { outline: none; } keeps the ring off for that focus. Keyboard (Tab) focus, and entry focus after keyboard navigation, still draw the ring.
  • A window blur/refocus keeps the verdict. The shell stays document.activeElement across it, so the returning focus event does not re-read :focus-visible, which the earlier keypress has already promoted.
  • Two regression tests in portal-detail-shell.component.spec.ts. Both fail on master and pass with this change.
  • Release note: .changes/details-player-focus-ring.md.

Why

The detail shell host is focusable (tabindex="0", role="region") and owns the page scroll. Clicking anywhere inside it that is not a control (the inline player's video, the hero, the episode list) focuses the host without a ring. Chromium then promotes the already-focused element to :focus-visible on the next keypress. ArrowLeft/ArrowRight are not handled by onScrollKey, so they reach the player's seek shortcut, and the host's :focus-visible ring outlines the whole page: player, header and episode list, as reported. The shell is shared, so this also applies to Xtream series/VOD, M3U VOD, downloads, recordings and collection detail.

Reproduced in headless Chrome over CDP with the app's global focus CSS and the main[tabindex=-1] > app-portal-detail-shell[tabindex=0] structure:

Scenario master this PR
click into the page, ArrowRight ring around the page no ring
Tab to the page (and then ArrowRight) ring ring
click, ArrowRight, switch tab away and back ring no ring
click, ArrowRight, focus drops to body, script refocus (unwind() after Escape) ring ring (the last input was the keyboard, browse state)

Release note

  • Added a note under .changes/
  • Not needed (test-only, docs, CI, or a refactor with no behavior change)

Checks

  • Tests added or updated for the changed behavior

  • pnpm run lint and the affected pnpm nx test <project> pass

  • jest libs/ui/components/src/lib/portal-detail-shell: 31 tests passed. The two new tests fail on master.

  • Full components project: 2 suites fail (channel-scroll-focus.directive.spec.ts, season-container.component.spec.ts), and they fail the same way on master.

  • pnpm nx lint components: 0 errors. Changed files are Prettier-clean.

  • node tools/nx/check-focus-visible.mjs and check-focus-ring-colour.mjs: pass.

  • pnpm run release:notes:validate: valid.

Not run: Electron E2E. A "click the shell, press ArrowRight, expect no outline" case would fit next to expectNoRingAfterClick in apps/electron-backend-e2e/src/keyboard-focus-ring.e2e.ts, and I'm happy to add it if you want it in this PR. I also couldn't run the Codex/Greptile local review gate from AGENTS.md, because I don't have those CLIs as an outside contributor.

🤖 Generated with Claude Code

Clicking into a detail page focuses its scroll region (the shell host,
tabindex 0). Chromium promotes that pointer focus to :focus-visible on the
next keypress, so arrow-key seeking during inline playback outlined the
whole page in windowed mode.

Record whether focus arrived by pointer and suppress the ring for that
focus; keyboard (Tab) focus keeps it. A window blur/refocus keeps the
verdict, since the shell stays the active element across it.

Closes 4gray#2170.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable defects were found.

Summary

Keeps the detail page’s focus ring hidden after pointer focus, including later seek keys and window refocus.

  • Detail pages keep the focus ring off after pointer focus and seeking.

No actionable issues were found. Tests and visual checks were not run during this review.

Reviews (5) · Last reviewed commit: "Merge master into the detail focus fix" · Reviewed by Greptile

@4gray

4gray commented Nov 11, 2026

Copy link
Copy Markdown
Owner

@codex review

@4gray

4gray commented Nov 11, 2026

Copy link
Copy Markdown
Owner

@greptileai

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T06:16:28.040284Z 7276a9b Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 12449710a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@codecov

codecov Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.60%. Comparing base (07d14e8) to head (7276a9b).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff            @@
##           master    #2189    +/-   ##
========================================
  Coverage   81.60%   81.60%            
========================================
  Files        1884     1884            
  Lines       98518    98533    +15     
  Branches    23705    22973   -732     
========================================
+ Hits        80392    80407    +15     
  Misses      11103    11103            
  Partials     7023     7023            
Flag Coverage Δ
unit 81.60% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@4gray

4gray commented Nov 11, 2026

Copy link
Copy Markdown
Owner

@codex review

@4gray

4gray commented Nov 11, 2026

Copy link
Copy Markdown
Owner

@greptileai

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: f2cc494a7c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Expose the clipboard helper through a dedicated services entry point so only the lazy Xtream details and download actions import it. On the PR merge tree, renderer.initialBytes drops from 1,200,590 to 1,200,062 bytes against the unchanged 1,200,301-byte limit.
@4gray

4gray commented Nov 11, 2026

Copy link
Copy Markdown
Owner

@greptileai

@4gray

4gray commented Nov 11, 2026

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: 35808525f1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@4gray

4gray commented Nov 12, 2026

Copy link
Copy Markdown
Owner

@greptileai

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 7276a9baaf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@4gray
4gray merged commit a2dd8f3 into 4gray:master Nov 12, 2026
45 of 46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Bright select box shows around center video pane when using arrow keys to skip

2 participants