Skip to content

Add mouse fallback for controller bottom hints#621

Open
ap0ught wants to merge 4 commits into
OpenCloudGaming:mainfrom
ap0ught:capy/controller-bottom-hints-mouse-fallback
Open

Add mouse fallback for controller bottom hints#621
ap0ught wants to merge 4 commits into
OpenCloudGaming:mainfrom
ap0ught:capy/controller-bottom-hints-mouse-fallback

Conversation

@ap0ught

@ap0ught ap0ught commented Jul 9, 2026

Copy link
Copy Markdown

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

    • Improved controller navigation across the home, search, settings, and loading screens.
    • Added controller-friendly actions for launching content, switching pages, opening search, and returning to previous screens.
    • Added clear back-navigation context and controller-styled controls in Settings.
    • Added controller support for canceling loading and closing Settings.
  • Bug Fixes

    • Improved controller input handling when gamepad buttons or axes are unavailable.
    • Refined overlay layering, spacing, and interactive hint behavior.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ea22c909-73ce-41c3-9a23-fbcbde717378

📥 Commits

Reviewing files that changed from the base of the PR and between 8d41360 and e034cf8.

📒 Files selected for processing (2)
  • opennow-stable/src/renderer/src/components/HomePage.tsx
  • opennow-stable/src/renderer/src/components/SettingsPage.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • opennow-stable/src/renderer/src/components/HomePage.tsx
  • opennow-stable/src/renderer/src/components/SettingsPage.tsx

📝 Walkthrough

Walkthrough

This 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.

Changes

Controller Mode Overlay Interactivity

Layer / File(s) Summary
Gamepad button bitmask utility fix
opennow-stable/src/renderer/src/utils/controllerGamepad.ts
Uses nullish-coalescing defaults for pad.buttons and pad.axes while preserving the existing mapping logic.
HomePage controller hint buttons and search back action
opennow-stable/src/renderer/src/components/HomePage.tsx, opennow-stable/src/renderer/src/styles.css
Wires controller hints and search back behavior to buttons, with CSS enabling pointer interaction, hint states, overlay stacking, and search action layout.
StreamLoading controller-mode cancel handling
opennow-stable/src/renderer/src/components/StreamLoading.tsx
Adds controller-mode gamepad cancellation, Escape-key cancellation, effect cleanup, and controller-style cancel labeling.
SettingsPage controller-mode close and footer
opennow-stable/src/renderer/src/components/SettingsPage.tsx, opennow-stable/src/renderer/src/styles.css
Adds controller-aware close handling, return-page labeling, a sidebar back footer, and corresponding footer styles.
App.tsx prop wiring
opennow-stable/src/renderer/src/App.tsx
Passes controller mode to StreamLoading and SettingsPage, along with the localized SettingsPage return label.

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()
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the main change: adding mouse fallback for controller bottom hints.
Linked Issues check ✅ Passed The PR makes the overlay hints clickable buttons and adds controller-mode pointer handling, which addresses #620's mouse-click requirement.
Out of Scope Changes check ✅ Passed The added settings, loading, and CSS changes are all tied to controller-mode UX and overlay interaction, with no clearly unrelated scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ap0ught ap0ught marked this pull request as ready for review July 9, 2026 19:50
Copilot AI review requested due to automatic review settings July 9, 2026 19:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-hint so mouse clicks can trigger the hinted actions.
  • Converted controller bottom hints in HomePage and LibraryPage from non-interactive <div>s to clickable <button>s, and added a controller-mode cancel affordance in StreamLoading / SettingsPage.
  • Refactored gamepad button reading to use local buttons/axes arrays 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">
Comment on lines +460 to +464
@@ -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>
Comment on lines +2433 to +2447
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);
};

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 win

Gamepad variant-cycle binding lost after reassigning menu to page navigation.

cycleControllerVariant is destructured at line 447 but never invoked anywhere in handleGamepadFrame. Previously menu triggered it; that binding was replaced by onNextControllerPage?.() at line 464 and nothing else took over cycling the variant via an actual gamepad. The Y-hint button and keyboard m/y still call cycleFocusedVariant, 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

📥 Commits

Reviewing files that changed from the base of the PR and between 8faa6d5 and 8d41360.

📒 Files selected for processing (7)
  • opennow-stable/src/renderer/src/App.tsx
  • opennow-stable/src/renderer/src/components/HomePage.tsx
  • opennow-stable/src/renderer/src/components/LibraryPage.tsx
  • opennow-stable/src/renderer/src/components/SettingsPage.tsx
  • opennow-stable/src/renderer/src/components/StreamLoading.tsx
  • opennow-stable/src/renderer/src/styles.css
  • opennow-stable/src/renderer/src/utils/controllerGamepad.ts

Comment thread opennow-stable/src/renderer/src/components/HomePage.tsx Outdated
Comment thread opennow-stable/src/renderer/src/components/SettingsPage.tsx
Comment thread opennow-stable/src/renderer/src/components/SettingsPage.tsx
@capy-ai

capy-ai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

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.

@ap0ught

ap0ught commented Jul 10, 2026

Copy link
Copy Markdown
Author

A few review notes that may help clarify the controller-mode changes:

  • HomePage: the Y hint now triggers variant cycling, but the label still reads "Filter". That’s a small UX mismatch and may confuse controller users.
  • HomePage: the "More Options" hint currently advances to the next controller page. If that’s intentional, the label/icon could be updated to match the new action; otherwise it feels like the wrong mapping for the current copy.
  • StreamLoading: there are a couple of computed values that aren’t used yet (, ). Not blocking, but cleaning them up would make the diff a bit tighter.

Overall, the controller mouse-fallback work looks solid, and I like that the new UI elements match the controller affordances more closely.

@ap0ught

ap0ught commented Jul 10, 2026

Copy link
Copy Markdown
Author

Small cleanup note: in StreamLoading, the newly introduced locals activeAdDurationSeconds and gracePeriodSeconds look unused right now. Not blocking, but removing them would tighten the diff a bit.

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.

Mouse clicks do not reach in-stream overlay controls (ABXY / More Options) while pointer lock is active

2 participants