Repository navigation
fix(stream-menu): keep the mouse working while the menu is up - #4
Open
thewhoareyou wants to merge 1 commit into
Open
thewhoareyou wants to merge 1 commit into
thewhoareyou wants to merge 1 commit into
Conversation
Releasing pointer capture for the overlay menu and asking for it back leaves some devices, Samsung's Android 10 input stack in particular, with no mouse motion at all even though the window stays registered as the capture owner. The menu now keeps capture and shows its own cursor: the captured deltas move it and button presses become touches on the sheet, so tiles click and a press off the sheet still dismisses the menu. Two Samsung quirks are handled on the way: captured motion arrives as source 0x20004, a trackball-classed variant of SOURCE_MOUSE_RELATIVE, and events only flow while the captured view also holds view focus, so the sheet and its tiles no longer take focus from touches and the stream view gets focus back whenever it strays. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This was referenced Nov 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Opening the in-stream overlay menu while a Bluetooth/USB mouse is captured leaves the mouse dead: the menu is a view in the same window, so pointer capture stays held — the cursor stays hidden and clicks go to the host, not the sheet. Releasing capture fixes the click but, on Samsung's Android 10 input stack, re-acquiring it afterwards leaves the window registered as the capture owner while no motion events ever reach it again.
This keeps pointer capture held and gives the menu its own cursor instead:
OverlayMenuView.show()fires a newonMenuOpened()listener callback;Gameuses open/close to enter and leave a software-cursor mode.pointer_arrowasset) and button transitions become touch events dispatched at its position — tiles get normal click handling, scroll views drag, and a press off the sheet dismisses the menu.handleMotionEventconsumes pointer/touch events while the menu is up so nothing leaks to the host; hover passes through so the system keeps tracking a free pointer when capture is off.OverlayMenuViewno longer steals view focus:requestFocus()is removed fromshow()and the sheet and tiles are no longer focusable in touch mode. On Samsung's stack, captured-pointer events only reach the view holding both capture and focus — a menu tile taking focus for its nav highlight was silently cutting off all mouse motion.Gamealso puts focus back on the stream view whenever it strays while capture is held.0x20004—SOURCE_MOUSE_RELATIVE's device bits over a trackball class byte rather than AOSP's pointer class.AndroidNativePointerCaptureProvidernow classifies on the device bits, so those events are recognised as relative mouse motion.onWindowFocusChangedand the device-added path no longer re-capture while the cursor was deliberately freed (isCursorVisible).Test plan
Verified on a Galaxy Tab S9+ (Android 15 / One UI 7, Samsung input stack) with a Logitech MX Anywhere 3 over Bluetooth, streaming from Vibepollo:
testNonRootDebugUnitTest— new regression tests pass (menuShouldUseSoftwareCursordecision matrix,isRelativeMouseSourceclassification);lintNonRootDebugcleanNote: on this Samsung stack the release → re-acquire path was shown unreliable by logcat (kernel keeps emitting
REL_X/Y, the dispatcher reports the app as capture owner, yet no motion reaches it). The software-cursor approach avoids that transition entirely.Generated with Devin