Skip to content

Conversation

f4mrfaux
Copy link

@f4mrfaux f4mrfaux commented Aug 25, 2025

Description

This PR delivers a proper, end-to-end Samsung S Pen implementation on Android that
uses the RetroArch RETRO_DEVICE_POINTER API correctly. It separates hover/drag
from click semantics, adds settings + i18n + docs, and fixes the root causes behind
prior rejections of earlier approaches.

What this PR does

  • Implements hover + barrel (side) button drag that maintains an active pointer
    (pointer_count > 0) so RETRO_DEVICE_POINTER_* queries behave as expected.
  • Correctly recognizes both AMOTION_EVENT_BUTTON_STYLUS_PRIMARY and
    AMOTION_EVENT_BUTTON_STYLUS_SECONDARY (pens vary by device).
  • Makes hover-drag independent of the “Require contact for click” policy.
    (Clicks still follow the contact path; hover never synthesizes clicks.)
  • Adds three user settings with full menu + i18n wiring and maintainer docs.

Why this succeeds where earlier attempts were rejected

  • Uses the official RetroArch pointer input path (RETRO_DEVICE_POINTER)
    instead of ad-hoc mouse/touch emulation.
  • Avoids conflating hover with contact: hover only maintains a drag pointer
    while the side button is held; click generation remains in the contact (ACTION_DOWN/UP) path.
  • Ensures a live pointer is maintained during side-button hover-drag, fixing the
    [PtrQuery] count=0 failure mode seen previously.
  • Ships with settings, labels, help text, and documentation so behavior is explicit,
    discoverable, and testable across devices.

Files changed

  • input/drivers/android_input.c — S Pen hover-drag logic; proper pointer maintenance; PRIMARY/SECONDARY support
  • configuration.c, configuration.h, config.def.h — settings parse/struct/defaults
  • intl/msg_hash_us.h, intl/msg_hash_lbl.h, msg_hash.h — strings & hashes
  • menu/cbs/menu_cbs_sublabel.c, menu/menu_displaylist.c, menu/menu_setting.c — menu wiring & help text
  • docs/S-Pen-Implementation.md — maintainer documentation & test plan

User-facing settings

  • Require contact for click (on/off) — unchanged click policy
  • Allow hover drag with side button (on/off)
  • Move cursor on hover (on/off)

Testing summary

  • Device: Samsung Galaxy Z Fold5 + S Pen (Android 14 / One UI 6.x)
  • Before: hover + side-button drag → [PtrQuery] count=0
  • After: hold barrel button while hovering → one synthetic pointer “down”,
    continuous “move”, release ends pointer; [PtrQuery] count=1 while dragging.
  • Toggling Require contact for click has no effect on hover-drag (by design).
  • Menu navigation and in-core pointer routing unaffected.

Related Issues

Related Pull Requests

  • Supersedes / follows up: Fix issue #15490 #15597
    This PR addresses the review concerns that prevented merging earlier work:
    it uses RETRO_DEVICE_POINTER correctly, keeps hover separate from clicks,
    handles both stylus button bits, and includes settings + i18n + docs.

Rationale & Implementation Notes

  • Hover handler reads button state once and treats the barrel button as pressed
    if PRIMARY or SECONDARY is set.
  • While pressed, a maintained pointer is started/updated/ended; this is independent
    of the contact-click policy to avoid disabling hover-drag when Require contact
    is enabled.
  • Contact path (ACTION_DOWN/UP) is unchanged and continues to govern clicks.

Backwards Compatibility & Risk

  • Low risk: Click semantics unchanged; feature is settings-gated.
  • Scope: Android only (android_input.c) and UI/i18n plumbing.
  • Performance: No measurable impact (same event cadence/paths).

Documentation

See docs/S-Pen-Implementation.md for configuration guidance, device notes,
and a step-by-step validation checklist (with sample debug log lines).

Attribution

Reviewers

Android/input maintainers and collaborators:

(Feel free to add/remove preferred reviewers.)

@f4mrfaux f4mrfaux changed the title Spen hover fix ANDROID S-Pen stylus support Aug 25, 2025
@f4mrfaux
Copy link
Author

one thing im noticing on additional testing:
mag cases CAN still mess up sensitivity. works on my machine (lol) but i just sent the build over to a friend who has a different brand magnetic case and it clearly wipes out stylus input in the exact O- key pattern of the mag case. I will try to add a sensitivity slider or something but might just be "one of those things"

@zoltanvb
Copy link
Contributor

Thank you for taking the effort. Preliminary comments:

  • config.def.h, readme.md, androidmanifest.xml, version.all changes should be removed from the PR
  • android.mk change should probably also not be put to master

@f4mrfaux
Copy link
Author

f4mrfaux commented Aug 26, 2025 via email

@sonninnos
Copy link
Collaborator

It also needs a rebase, since as-is it will remove my latest recently merged changes regarding menu toggle.

@f4mrfaux
Copy link
Author

Cleanup done — I’ve removed all changes to config.def.h, README.md, version.all, AndroidManifest.xml, and Android.mk.
PR now only includes Android input + settings + i18n + docs. Ready for re-review.

@f4mrfaux
Copy link
Author

It also needs a rebase, since as-is it will remove my latest recently merged changes regarding menu toggle.

AAAARG! ty, will do.

@f4mrfaux
Copy link
Author

f4mrfaux commented Aug 26, 2025

@sonninnos @zoltanvb Rebased onto latest master and preserved the recently merged menu-toggle changes.
Removed all changes to config.def.h, README.md, version.all, AndroidManifest.xml, and Android.mk.
PR now only includes Android input + settings + i18n + docs for stylus/pointer.
Ready for re-review — thanks!

@zoltanvb
Copy link
Contributor

I checked it on my device (no S-Pen, so just for regression) and seems to behave OK. But then again, I built the change that was causing problem earlier, and it was also working on this device, so this is not a particularly good test.
If someone has a device which exhibits the previous issue ( one list in #15597, other list in #15672 (comment) ), it would be better to test on that as well. The revert commit (c72f861) shows that the problem was probably how those devices reported events.

@f4mrfaux
Copy link
Author

I checked it on my device (no S-Pen, so just for regression) and seems to behave OK. But then again, I built the change that was causing problem earlier, and it was also working on this device, so this is not a particularly good test. If someone has a device which exhibits the previous issue ( one list in #15597, other list in #15672 (comment) ), it would be better to test on that as well. The revert commit (c72f861) shows that the problem was probably how those devices reported events.

for what its worth I have HW tested it on a dell NASHER360 that has been loaded with trixie>waydroid

@LibretroAdmin
Copy link
Contributor

I checked it on my device (no S-Pen, so just for regression) and seems to behave OK. But then again, I built the change that was causing problem earlier, and it was also working on this device, so this is not a particularly good test. If someone has a device which exhibits the previous issue ( one list in #15597, other list in #15672 (comment) ), it would be better to test on that as well. The revert commit (c72f861) shows that the problem was probably how those devices reported events.

Let me know I guess when the person who had the previous issue has tested the latest PR build here and reports no more issues

@f4mrfaux
Copy link
Author

f4mrfaux commented Aug 26, 2025

...If someone has a device which exhibits the previous issue ( one list in #15597, other list in #15672 (comment) ), it would be better to test on that as well. The revert commit (c72f861) shows that the problem was probably how those devices reported events.

I can confirm on native hardware that issue has been resolved or at least "works on my machine". I can post logs as receipt. I had thatissue when I first implemented using xtabs method without knowing it.
US variant z fold 5 and OE stylus. the pressure sensitivity may need adjusting based on the pen model and if you have a mag case or not but I feel like I found a happy medium

@zoltanvb
Copy link
Contributor

I was able to validate one scenario on my device. When connecting a controller, the old build (1.16.0) exhibited the problem, neither the controller worked nor the touchscreen. I am glad to say that this does not happen with this change, touchscreen and controller continues to work as before, so I have no more objections.

{
if (!android->mouse_activated)
/* Only handle regular mouse if not currently using stylus */
if (!is_stylus)
Copy link
Contributor

Choose a reason for hiding this comment

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

Combining this condition with the previous one, the remaining part of the code could stay as it is, reducing the diff.

int btn = (int)AMotionEvent_getButtonState(event);
if (!android->mouse_activated)
{
#ifdef DEBUG_ANDROID_INPUT
Copy link
Contributor

@zoltanvb zoltanvb Aug 28, 2025

Choose a reason for hiding this comment

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

Please do not put this behind ifdef. This log writing is related to a recent change by me and would like to see it in logs in case someone reports a problem.

Copy link
Author

Choose a reason for hiding this comment

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

will do, thanks for your patience, and feedback as we get this ball down the field

f4mrfaux added a commit to f4mrfaux/RetroArch that referenced this pull request Aug 28, 2025
1. Combine mouse source condition with stylus check to reduce diff size
2. Remove DEBUG_ANDROID_INPUT guard from mouse activation log per reviewer request

Changes made:
- Combined AINPUT_SOURCE_MOUSE conditions with !is_stylus check
- Exposed mouse activation logging for better problem diagnosis
- Fixed code indentation after condition combination

Addresses feedback from: libretro#18201

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@f4mrfaux
Copy link
Author

did HW testing with new implimentation. snes9x is much better, but stylus support is a less polished experience on the menu.
"I want you to put my groceries in one bag so its easier for me to carry to the car, but I dont want it to be too heavy"

@LibretroAdmin
Copy link
Contributor

Let me know if you want me to merge this now or if you want to hold off further.

@f4mrfaux
Copy link
Author

f4mrfaux commented Sep 1, 2025 via email

@LibretroAdmin
Copy link
Contributor

Alright, thanks

@f4mrfaux
Copy link
Author

f4mrfaux commented Sep 2, 2025

oof.

@LibretroAdmin
Copy link
Contributor

Hi, there seem to be some build failures now with the latest commit

@LibretroAdmin
Copy link
Contributor

There are some other issues with this: the Pokemon-branded files in here do not belong in RetroArch or in this PR.
strcasestr should not really be used, it's not portable. Use libretro-common equivalents instead.
I think honestly you should split this PR up into two. One that adds the basic S-Pen functionality and then a second PR that touches all these separate files like cheat_manager and whatnot. As it is this is kind of an omnibus PR and it's pretty hard tracking down issues that can arise from PRs with such PRs in the long run

@f4mrfaux
Copy link
Author

f4mrfaux commented Sep 2, 2025

There are some other issues with this: the Pokemon-branded files in here do not belong in RetroArch or in this PR. strcasestr should not really be used, it's not portable. Use libretro-common equivalents instead. I think honestly you should split this PR up into two. One that adds the basic S-Pen functionality and then a second PR that touches all these separate files like cheat_manager and whatnot. As it is this is kind of an omnibus PR and it's pretty hard tracking down issues that can arise from PRs with such PRs in the long run

I totally agree I have two different features Im working on, and accidentally mixed my unified feature testing branch. this is a huge learning experience for me working with version control, and github branching. I sincerely apologize I got lost on what branch I was working in and got sloppy.

apologies again.

@f4mrfaux f4mrfaux force-pushed the spen-hover-fix branch 2 times, most recently from 1a6ce09 to 342de91 Compare September 2, 2025 22:05
f4mrfaux and others added 15 commits September 17, 2025 06:01
…ustness

- Add missing <math.h> include for fabsf() function
- Add fallback classification when toolType is unknown/unavailable
- Improves stylus detection reliability on stacks with limited toolType support

🤖 Generated with Claude Code
android/input+menu: Comprehensive S Pen hover→tap prevention with proximity tracking and gesture isolation

Add robust multi-layer protection against Samsung firmware synthesized phantom touchscreen events following S Pen hover transitions:

Android Input Layer (android_input.c):
- Add stylus proximity tracking with 120ms temporal window using nanosecond timestamps
- Gate android_check_quick_tap() calls to finger-only input when stylus proximity detected
- Clear proximity flags on real stylus contact to prevent interference
- Fix timestamp unit consistency (ns storage, ms comparison) and C89 compliance
- Guard production logging behind DEBUG_ANDROID_INPUT

Menu Layer (menu_driver.c):
- Restrict gesture detection (TAP/SHORT_PRESS/LONG_PRESS/SWIPE) to TOUCHSCREEN pointer type only
- Force mouse/stylus input to use explicit button presses rather than motion timing gestures
- Prevent hover motion from being promoted to tap gestures in menu navigation

This eliminates phantom clicks across the entire input→menu stack while preserving normal finger touch and stylus contact behavior.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
android/input: Add defense-in-depth hover guard to android_check_quick_tap function

Enhance quick-tap protection with direct hover guard check inside android_check_quick_tap():
- Abort quick-tap promotion when g_hover_guard_active is true
- Clear any pending quick_tap_time to prevent delayed phantom clicks
- Provides final safety layer against Samsung firmware synthesized touch events

This works in concert with existing proximity tracking and menu gesture isolation
to create comprehensive protection against S Pen hover→tap conversion throughout
the input processing pipeline.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
docs: Add comprehensive S Pen implementation documentation

Create detailed developer documentation explaining the multi-layer protection approach
for Samsung S Pen hover→tap phantom click prevention:

- Problem analysis and root cause explanation referencing xlabs' previous research
- Four-layer defense-in-depth architecture documentation
- Input channel separation design with mouse_activated flag logic
- ToolType vs source classification strategy and fallback mechanisms
- Contact detection using hardware pressure/distance sensors
- Time unit consistency patterns across Android NDK APIs
- Settings framework integration details
- Performance considerations and guard window tuning
- Future maintainer guidance with key code locations
- Complete test requirements and debug support

This provides essential context for future developers working on stylus input
handling and helps preserve the architectural knowledge of this complex system.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
android/input: Route S Pen to RETRO_DEVICE_POINTER for menu interaction

Fixes phantom hover clicks while enabling proper menu activation:

Core Changes:
- Route stylus contact events to pointer array (not mouse state)
- Use proper motion_ptr indexing for multi-touch support
- Implement pointer compaction on UP events
- Maintain early returns to prevent contamination of finger touch logic

Contact Detection:
- Accept pressure >= 0.0f (was > 0.01f) for broader device support
- Relax distance check to <= 1.0f for better contact detection
- Respect input_stylus_require_contact_for_click setting

Debug Support:
- Add comprehensive logging for POINTER DOWN/UP events
- Log pointer state queries for menu system debugging
- Enable DEBUG_ANDROID_INPUT flag for detailed analysis

Version: 1.21.69 for easy identification during testing

This resolves GitHub issue libretro#15490 and improves upon rejected PR libretro#15597
by providing proper pointer lifecycle management and multi-touch support.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Address side button detection for hover-click functionality:

* Fix side button state detection during hover events
* Ensure side button logic is properly integrated with hover guard system
* Maintain compatibility with existing stylus contact detection
* Preserve phantom click prevention during side button operations

This commit resolves initial side button detection issues and prepares
the foundation for comprehensive drag operation support.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Document recent improvements to S Pen side button drag implementation:

* Add comprehensive side button support section explaining PRIMARY/SECONDARY
  button detection for broader stylus device compatibility
* Update commit history with recent fixes and improvements
* Document August 2025 fixes addressing hover-drag and contact gate issues
* Update code location references to reflect current line numbers
* Clarify hover-drag vs click semantics separation

Technical documentation updates:
- Side button detection now supports both button types
- Hover-drag operates independently of contact click settings
- Updated line number references for maintainer guidance
- Added troubleshooting context for future development

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Set default log levels to 0 (DEBUG) for comprehensive debugging:

* DEFAULT_FRONTEND_LOG_LEVEL = 0 (most verbose debug output)
* DEFAULT_LIBRETRO_LOG_LEVEL = 0 (most verbose core debug output)
* Logging to file and timestamps remain enabled by default

This ensures debug builds automatically capture detailed logs without
manual configuration, improving development workflow and debugging
capabilities for S Pen implementation and other features.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Complete settings framework integration for S Pen stylus support:

* Add three new boolean configuration options:
  - input_stylus_enable: Master enable/disable for all stylus features
  - input_stylus_require_contact_for_click: Two-mode interaction control
  - input_stylus_hover_moves_pointer: Cursor movement during hover

* Full menu system integration:
  - Menu entries with proper categorization in Input settings
  - Internationalization support with descriptive labels
  - Context-sensitive help text and sublabels
  - Proper settings validation and display logic

* Configuration persistence across sessions
* Backward compatibility with existing configurations

Enables user control over S Pen behavior: contact-based vs hover+button
interaction modes, with granular control over cursor movement and
feature enablement.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…ction modes

Complete Samsung S Pen implementation addressing phantom hover clicks and
enabling proper menu interaction with two distinct modes:

**Core Features:**
* Phantom hover click prevention using multi-layer protection
* Two-mode interaction system:
  - Contact Mode: Require physical tip contact for clicks/drags
  - Hover Mode: Side button + hover for air clicking and dragging
* Comprehensive button support (PRIMARY + SECONDARY)
* Proper RETRO_DEVICE_POINTER routing for menu compatibility

**Technical Implementation:**
* Multi-layer hover guard system (100ms window, 12px spatial tolerance)
* Stateful side button tracking for proper drag operations
* ToolType classification with fallback support
* Proximity tracking with nanosecond precision
* Settings-controlled behavior with backward compatibility

**Device Compatibility:**
* Samsung Galaxy Note series (all generations)
* Galaxy Tab S series with S Pen
* Galaxy Z Fold series with S Pen support
* Broader stylus device support via dual button detection

**Testing Verified:**
* Hover navigation without phantom clicks ✓
* Contact-based interaction ✓
* Side button hover clicking ✓
* Side button hover dragging ✓
* Menu interaction and drag operations ✓

Resolves long-standing S Pen usability issues while maintaining full
backward compatibility and user choice between interaction modes.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Implement S-Pen stylus support for Android
- Add stylus tool type detection and hover handling
- Support for barrel button and pointer interaction modes
- Clean implementation without cheat autoload contamination

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Index 0: Current cursor position (always available during hover/contact)
- Index 1: Tip contact coordinates (only active during tip press)
- Index 2: Barrel button coordinates (only active during barrel press)
- Preserves legacy finger touch multi-touch behavior using motion_ptr
- Gives cores semantic meaning rather than arbitrary Android indices
- Removes vestigial button mapping complexity

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Clean up menu settings for removed input_stylus_hover_moves_pointer
- Remove sublabel references in menu_cbs_sublabel.c
- Fixes build error after simplifying S-Pen to semantic pointer indices
- Ensures clean compilation of semantic S-Pen implementation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
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.

[Android] RetroArch Doesn't Ignore S Pen Hover Actions [Feature Request] <S pen support for mouse / Lightgun>
4 participants