Skip to content

ANDROID S-Pen stylus support#18201

Closed
f4mrfaux wants to merge 15 commits into
libretro:masterfrom
f4mrfaux:spen-hover-fix
Closed

ANDROID S-Pen stylus support#18201
f4mrfaux wants to merge 15 commits into
libretro:masterfrom
f4mrfaux:spen-hover-fix

Conversation

@f4mrfaux

@f4mrfaux f4mrfaux commented Aug 25, 2025

Copy link
Copy Markdown

Description

Focused, S-Pen-only re-submission of Android Samsung S-Pen stylus support, rebased onto current master.

This addresses the review that closed the earlier version of this PR. The branch has been split down to the S-Pen feature alone — the unrelated files (cheat_manager and other "omnibus" changes, the Pokémon-branded files, config.def.h) and the non-portable strcasestr usage are gone. It builds, and the history is two clean commits on top of current master.

What it does

  • Stylus input through the official RETRO_DEVICE_POINTER path — no ad-hoc mouse/touch emulation.
  • Phantom-tap suppression for Samsung pens (hover guard, proximity tracking, quick-tap gating, menu gesture isolation). Samsung firmware emits ghost touchscreen events on hover; these layers stop them from becoming clicks/strokes.
  • toolType-based stylus/finger classification with input-source fallback.
  • Contact detection (distance-based → instant cursor) separated from click detection (pressure-based, configurable). Hover never synthesizes a click.
  • Pointer index contract for cores: index 0 = cursor, 1 = tip contact, 2 = side button.
  • Both AMOTION_EVENT_BUTTON_STYLUS_PRIMARY and …_SECONDARY barrel buttons (devices vary).
  • Auto-hides the on-screen touch overlay while the pen is active (restored ~2 s after the last stylus event), since overlay hit-zones conflict with stylus taps.

Settings (Android only; menu + i18n wired)

  • input_stylus_enable — master switch (default ON)
  • input_stylus_require_contact_for_click — tip contact required for a click (default ON)
  • input_stylus_hover_moves_pointer — hover moves pointer without asserting PRESSED (default OFF)
  • input_stylus_pressure_sensitivity — click pressure threshold, 1–100 (default 70)

How prior review was addressed

  • Split into a single feature — S-Pen only; no cheat_manager/unrelated files.
  • No Pokémon-branded files.
  • No strcasestr (or other non-portable libc calls) introduced.
  • Builds — verified with an Android aarch64 debug build. Also fixed a config-persistence bug where input_stylus_pressure_sensitivity (a uint) was mistakenly registered among the bool settings, so it now saves/loads correctly.

Files changed

input/drivers/android_input.c, configuration.c, configuration.h, menu/menu_setting.c, menu/menu_displaylist.c, menu/cbs/menu_cbs_sublabel.c, menu/menu_driver.c, msg_hash.h, intl/msg_hash_lbl.h, intl/msg_hash_us.h, runloop.c, docs/S-Pen-Implementation.md.

Related issues

Credits

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

Copy link
Copy Markdown
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
Copy Markdown
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

f4mrfaux commented Aug 26, 2025 via email

Copy link
Copy Markdown
Author

@sonninnos

Copy link
Copy Markdown
Collaborator

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

@f4mrfaux

Copy link
Copy Markdown
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
Copy Markdown
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

f4mrfaux commented Aug 26, 2025

Copy link
Copy Markdown
Author

@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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

f4mrfaux commented Aug 26, 2025

Copy link
Copy Markdown
Author

...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
Copy Markdown
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.

Comment thread input/drivers/android_input.c Outdated

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.

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

Comment thread input/drivers/android_input.c Outdated

@zoltanvb zoltanvb Aug 28, 2025

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.

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
Copy Markdown
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

Copy link
Copy Markdown
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
Copy Markdown
Contributor

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

@f4mrfaux

f4mrfaux commented Sep 1, 2025 via email

Copy link
Copy Markdown
Author

@LibretroAdmin

Copy link
Copy Markdown
Contributor

Alright, thanks

@f4mrfaux

f4mrfaux commented Sep 2, 2025

Copy link
Copy Markdown
Author

oof.

@LibretroAdmin

Copy link
Copy Markdown
Contributor

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

@LibretroAdmin

Copy link
Copy Markdown
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

f4mrfaux commented Sep 2, 2025

Copy link
Copy Markdown
Author

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 #15490 and improves upon rejected PR #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>
@xlab

xlab commented Jan 7, 2026

Copy link
Copy Markdown
Contributor

This feature is cursed :)

@f4mrfaux f4mrfaux closed this May 21, 2026
@f4mrfaux

Copy link
Copy Markdown
Author

This feature is cursed :)

indeed. I had to ostep away from it for a while it was really bumming me out lol.

I am proud to say that I fixed it, and I have a fork of the SNES9X core that is actually more accurate than N's implementation of the SNES mouse for the switch 2 :)

re-opening

@f4mrfaux

Copy link
Copy Markdown
Author

Reworked and resubmitted as a focused, S-Pen-only PR (rebased onto current master; the omnibus/unrelated files, the Pokémon-branded files, and the non-portable strcasestr usage have all been removed; builds clean): #19076

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>

5 participants