feat(Touchscreen): edge-swipe gesture detection for handheld#571
Open
honjow wants to merge 8 commits intoShadowBlip:mainfrom
Open
feat(Touchscreen): edge-swipe gesture detection for handheld#571honjow wants to merge 8 commits intoShadowBlip:mainfrom
honjow wants to merge 8 commits intoShadowBlip:mainfrom
Conversation
Add Touchscreen as a new top-level Capability variant with Touch and Gesture sub-types. Gesture covers single-finger edge-swipe directions (SwipeLeft/Right/Up/Down) with optional zone qualifiers (Top/Bottom). Update InputValue translation, evdev/dbus event enums, and capability map config to handle the new types.
… replay Implement single-finger edge-swipe gesture detection in the touchscreen source device: - Detect swipes starting from left/right/top/bottom screen edges - Optional exclusive grab mode: suppresses raw touch events while a gesture is being evaluated, replaying them as a tap if no gesture is confirmed - Orientation config to rotate coordinates for rotated displays - TouchscreenConfig extended with grab and orientation fields
…le mapping - Pass Touchscreen capability events through translate_event so they can be mapped to gamepad buttons via device profiles - Bypass intercept-mode checks for touchscreen events (gesture handling is always active) - Add Touchscreen capability to the output capability lists of DualSense, SteamDeckUhid and UnifiedGamepad target devices
Map SwipeRight:Bottom to Guide and SwipeLeft:Bottom to QuickAccess in the default profile, matching hhd-style Steam/QAM gestures. Update composite_device_v1.json to add grab field to TouchscreenConfig. Update device_profile_v1.json to include Touchscreen gesture capability definitions.
Button press+release pairs arriving within 80ms now have their release delayed at the TargetDriver layer, so all target devices benefit automatically. Previously this logic only existed in steam_deck. Add ScheduledNativeEvent::event() accessor to support filtering scheduled events during ClearState. Also clear pending button events when ClearState is called to avoid ghost releases after intercept mode resets device state.
…NEXPLAYER X1 GPD Win5: enable touchscreen source with grab mode. ONEXPLAYER X1 Mini: enable touchscreen source with grab mode and left orientation (display is rotated 90 degrees).
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
Adds single-finger edge-swipe gesture detection to the touchscreen source device, allowing touchscreen edges to be mapped to gamepad buttons via device profiles — enabling gestures like swiping from the left edge to open the Steam menu, or from the right edge to open the Quick Access Menu, without requiring changes to the compositor.
Tested and verified on GPD Win5 and ONEXPLAYER X1 Mini.
How gesture detection works
Touch coordinates are normalized to
[0.0, 1.0]. A gesture is recognized when the touch starts within 3% of a screen edge, travels inward by at least 12%, and completes within 400 ms.Gesture names describe the direction of finger movement (e.g. swiping inward from the left edge moves rightward →
SwipeRight). Each direction carries aTop/Bottomzone qualifier split at 33% along the perpendicular axis.Default profile mappings:
SwipeRight:BottomGuideSwipeLeft:BottomQuickAccessTwo operating modes: passthrough vs. grab
Passthrough (
grab: false, default): Raw touch events are forwarded normally alongside any gesture events. Suitable for desktop use; avoid in game compositors as gestures will also register as taps.Grab (
grab: true): The touchscreen is exclusively captured viaEVIOCGRAB. Touches starting within 1% of an edge are held back until the gesture outcome is known — confirmed gestures suppress the touch, unconfirmed ones replay it as a normal tap. Multi-finger touch immediately cancels gesture detection and passes all events through. IfEVIOCGRABfails, the source falls back to passthrough with a warning.Grab mode is recommended for devices running a game compositor such as Gamescope.
Why MIN_FRAME_TIME was moved to TargetDriver
Gesture detection emits press and release nearly simultaneously. Without a minimum press duration, both events fall within a single HID poll interval and the compositor sees a report where the button was never pressed.
steam_deckalready handled this with an 80 ms minimum, but only for itself. This PR moves the enforcement intoTargetDriverso every target benefits automatically, and removes the now-redundantsteam_deckimplementation.