Add mouse fallback for controller bottom hints#621
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis PR adds controller-mode close handling to StreamLoading and SettingsPage, converts HomePage controller hints and search back controls into buttons, updates related styling, wires new props through App.tsx, and makes gamepad bitmask reading tolerate missing button or axis arrays. ChangesController Mode Overlay Interactivity
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Gamepad
participant StreamLoading
participant SettingsPage
Gamepad->>StreamLoading: west button pressed
StreamLoading->>StreamLoading: onCancel()
Gamepad->>SettingsPage: west button pressed
SettingsPage->>SettingsPage: check prompts
SettingsPage->>SettingsPage: onClose()
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR aims to make the controller-mode “bottom hint” controls clickable with the mouse (not just via gamepad), addressing the reported in-stream overlay click-through issue while input capture/pointer lock is active.
Changes:
- Enabled pointer events and added “button-like” styling for
.controller-bottom-hints/.controller-hintso mouse clicks can trigger the hinted actions. - Converted controller bottom hints in
HomePageandLibraryPagefrom non-interactive<div>s to clickable<button>s, and added a controller-mode cancel affordance inStreamLoading/SettingsPage. - Refactored gamepad button reading to use local
buttons/axesarrays defensively.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| opennow-stable/src/renderer/src/utils/controllerGamepad.ts | Small refactor to read buttons/axes via local arrays. |
| opennow-stable/src/renderer/src/styles.css | Enables pointer events for bottom hints and adds hover/active styling; adjusts overlay layout/styling. |
| opennow-stable/src/renderer/src/components/StreamLoading.tsx | Adds controller-mode cancel hint and keyboard/controller cancellation handling. |
| opennow-stable/src/renderer/src/components/SettingsPage.tsx | Adds a “back/cancel” footer and controller-mode close handling. |
| opennow-stable/src/renderer/src/components/LibraryPage.tsx | Converts bottom hints to clickable buttons (mouse fallback). |
| opennow-stable/src/renderer/src/components/HomePage.tsx | Converts bottom hints to clickable buttons (mouse fallback) and adjusts controller navigation bindings. |
| opennow-stable/src/renderer/src/App.tsx | Wires controllerMode and returnPageLabel into StreamLoading / SettingsPage. |
| @@ -651,10 +651,26 @@ | |||
| </div> | |||
|
|
|||
| <div className="controller-bottom-hints" aria-hidden="true"> | |||
| @@ -461,7 +461,7 @@ | |||
| if (pressed & controllerButton.west) setControllerSearchOpen(true); | |||
| if (pressed & controllerButton.leftShoulder) onPreviousControllerPage?.(); | |||
| if (pressed & controllerButton.rightShoulder) onNextControllerPage?.(); | |||
| if (pressed & controllerButton.menu) cycleControllerVariant(); | |||
| if (pressed & controllerButton.menu) onNextControllerPage?.(); | |||
| </button> | ||
| <button type="button" className="controller-hint" onClick={cycleFocusedVariant}> | ||
| <span className="controller-button controller-button--y">Y</span> | ||
| <span>{t("library.filter")}</span> |
| )} | ||
| </section> | ||
|
|
||
| <div className="controller-bottom-hints" aria-hidden="true"> |
| ))} | ||
| </div> | ||
| <div className="settings-sidebar-footer"> | ||
| <span className="settings-footer-kicker">{t("settings.backTo")}</span> |
| let frameId: number | null = null; | ||
| const readButtons = (): number => { | ||
| const pad = navigator.getGamepads?.().find((gamepad): gamepad is Gamepad => Boolean(gamepad)); | ||
| return readControllerGamepadButtons(pad); | ||
| }; | ||
|
|
||
| const handleFrame = () => { | ||
| if (!nativeStreamerEnablePromptVisible && !zortosCommunityProxyPromptVisible) { | ||
| const buttons = readButtons(); | ||
| if (buttons & controllerButton.west) { | ||
| onClose(); | ||
| } | ||
| } | ||
| frameId = window.requestAnimationFrame(handleFrame); | ||
| }; |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
opennow-stable/src/renderer/src/components/HomePage.tsx (1)
444-470: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winGamepad variant-cycle binding lost after reassigning
menuto page navigation.
cycleControllerVariantis destructured at line 447 but never invoked anywhere inhandleGamepadFrame. Previouslymenutriggered it; that binding was replaced byonNextControllerPage?.()at line 464 and nothing else took over cycling the variant via an actual gamepad. The Y-hint button and keyboardm/ystill callcycleFocusedVariant, but a real controller's Y/north button no longer does anything — this contradicts the linked issue's requirement to preserve existing gamepad behavior.🐛 Proposed fix: rebind north (Y) to variant cycling
if (pressed & controllerButton.rightShoulder) onNextControllerPage?.(); if (pressed & controllerButton.menu) onNextControllerPage?.(); + if (pressed & controllerButton.north) cycleControllerVariant(); if (pressed & controllerButton.up) focusControllerTile(rowIndex - 1, columnIndex);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@opennow-stable/src/renderer/src/components/HomePage.tsx` around lines 444 - 470, The gamepad variant-cycle behavior is missing in handleGamepadFrame because cycleControllerVariant is destructured from controllerInputStateRef.current but never used after menu was reassigned to page navigation. Restore the controller’s north/Y binding by invoking cycleControllerVariant from the appropriate button check in HomePage’s gamepad handler, while keeping the existing page navigation bindings on menu or shoulder buttons intact. Make sure the fix preserves the previous controller behavior without changing the keyboard or hint-button variant cycling paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@opennow-stable/src/renderer/src/components/HomePage.tsx`:
- Around line 653-674: The controller hints container is still marked with
aria-hidden="true" even though it now contains interactive fallback buttons, so
remove that attribute or apply it only when the entire control group is
non-interactive. Update the controller-bottom-hints wrapper in HomePage so the
real buttons (launchFocusedTile, onPreviousControllerPage, cycleFocusedVariant,
setControllerSearchOpen, and onNextControllerPage) remain exposed to assistive
technologies and are not hidden by an ancestor.
In `@opennow-stable/src/renderer/src/components/SettingsPage.tsx`:
- Around line 2430-2456: The controller button handling in SettingsPage’s
useEffect is missing edge detection, so onClose() is called every animation
frame while the west button is held. Update the handleFrame/readButtons logic to
match the press-only behavior used in HomePage and StreamLoading by tracking
previousButtons and only invoking onClose() when west transitions from unpressed
to pressed. Keep the fix localized to the SettingsPage effect and preserve the
existing requestAnimationFrame cleanup.
- Around line 2515-2522: The settings footer back button in SettingsPage still
renders the controller-style X badge unconditionally, even when controllerMode
is off. Update the button markup in SettingsPage to follow the same conditional
rendering pattern used for the equivalent visual element in StreamLoading so the
controller badge only appears in controller mode and mouse/keyboard users see
the non-controller variant instead.
---
Outside diff comments:
In `@opennow-stable/src/renderer/src/components/HomePage.tsx`:
- Around line 444-470: The gamepad variant-cycle behavior is missing in
handleGamepadFrame because cycleControllerVariant is destructured from
controllerInputStateRef.current but never used after menu was reassigned to page
navigation. Restore the controller’s north/Y binding by invoking
cycleControllerVariant from the appropriate button check in HomePage’s gamepad
handler, while keeping the existing page navigation bindings on menu or shoulder
buttons intact. Make sure the fix preserves the previous controller behavior
without changing the keyboard or hint-button variant cycling paths.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 61aef30f-38db-4edf-b43a-e6388e9cb005
📒 Files selected for processing (7)
opennow-stable/src/renderer/src/App.tsxopennow-stable/src/renderer/src/components/HomePage.tsxopennow-stable/src/renderer/src/components/LibraryPage.tsxopennow-stable/src/renderer/src/components/SettingsPage.tsxopennow-stable/src/renderer/src/components/StreamLoading.tsxopennow-stable/src/renderer/src/styles.cssopennow-stable/src/renderer/src/utils/controllerGamepad.ts
|
Capy auto-review is paused for this organization because the usage-cycle auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews. |
|
A few review notes that may help clarify the controller-mode changes:
Overall, the controller mouse-fallback work looks solid, and I like that the new UI elements match the controller affordances more closely. |
|
Small cleanup note: in StreamLoading, the newly introduced locals |
Closes #620
I have tested this locally on my linux machine with a controller and also clicking on the buttons presented.
Basicly the reason I opened this was in big picture mode it was too tempting of a target to not be able to click the buttons with the mouse then pickup the controller to navigate the same way.
ENJOY
Summary by CodeRabbit
New Features
Bug Fixes