Skip to content

SDL3 migration, Phase 3: pen/pressure input and native window handle - #271

Merged
Nidrax merged 6 commits into
trunkfrom
nidrax/sdl3-phase3-tablet-wm
Oct 6, 2026
Merged

Nidrax merged 6 commits into
trunkfrom
nidrax/sdl3-phase3-tablet-wm

Conversation

@Nidrax

@Nidrax Nidrax commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

Summary

Part of #73. Closes #263.

This phase's issue flagged an architectural decision (R4) that needed to be made before implementing anything: whether to keep the vendored EasyTab library (patching its WM plumbing for SDL3), drop it entirely for SDL3's native pen API, or run a hybrid. Per discussion, we went with dropping EasyTab and using SDL3's native SDL_EVENT_PEN_* events, matching the issue's own recommendation — broader native pen coverage (Windows Ink, XInput2, Wayland tablet-v2, Cocoa) than EasyTab has today, and it sidesteps the X11 XInput1-vs-XInput2 conflict the issue raised as a high-risk open question (R1).

Changes

  • Pen pressure: SDL_EVENT_PEN_AXIS (when axis == SDL_PEN_AXIS_PRESSURE) feeds the existing penPressure global that mouse events already read from — same pattern as the existing finger-pressure-as-pen-proxy hack, just fed by a real pen axis instead of a touch digitizer's pressure field.
  • Fixes the stuck-pressure bug the issue called out: SDL_EVENT_PEN_PROXIMITY_OUT now resets penPressure to 0 and pointerType back to Mouse — EasyTab never reset this, so a plain mouse click after the pen last touched the tablet would get misreported as pen input with stale pressure.
  • R5 (mouse/touch/pen event conflict): SDL_HINT_PEN_TOUCH_EVENTS is disabled so pen input doesn't also synthesize touch events that would fight the pressure tracking above with a second, less precise value. SDL_HINT_PEN_MOUSE_EVENTS is left at its SDL3 default (enabled), so position/clicks keep arriving as ordinary SDL_EVENT_MOUSE_* events exactly as before — no change needed to the mouse-event handling added in Phase 2.
  • Raw SDL_EVENT_PEN_PROXIMITY_IN/DOWN/UP/MOTION/BUTTON_DOWN/BUTTON_UP are consumed silently — position/clicks are already covered by the synthesized mouse events, so there's nothing left to do with them beyond the pressure tracking above.
  • SDL3Display::nativeHandle(): ported via SDL_GetWindowProperties() + SDL_PROP_WINDOW_WIN32_HWND_POINTER / _COCOA_WINDOW_POINTER / _ANDROID_WINDOW_POINTER / _X11_WINDOW_NUMBER, replacing the removed SDL_GetWindowWMInfo(). This is independent of the pen-input decision above and is used by native file dialogs, the clip library (clipboard), and Explorer/Finder shell integration.
  • Removed the SDL3Display constructor's "Tablet support: FAILED" placeholder from Phase 0/1 scaffolding, since there's no more per-window tablet loading step to report on.

What's explicitly not changed

The SDL2 backend's EasyTab path is untouched — this only affects she/sdl3/.

Test plan

  • Builds clean with -DUSE_SDL2_BACKEND=off -DUSE_SDL3_BACKEND=on.
  • bin/besprited launches and exits cleanly under a bounded timeout, no new "Unknown event" spam from the added pen cases.
  • Verified nativeHandle()'s SDL_GetWindowProperties/SDL_PROP_WINDOW_X11_WINDOW_NUMBER path directly with a standalone SDL3 program in this (X11) session — it returns a real, plausible, nonzero X11 window ID rather than a stub nullptr.
  • Not verified — needs real hardware, per the issue's R1–R3 (this sandbox has no tablet/pen device):
    • Wacom/Huion/etc. pressure curve feels correct on Linux X11.
    • Same on Linux Wayland (native, not XWayland) — this is where SDL3's own pen backend has the best chance of working where EasyTab never could (no Wayland support at all).
    • Windows: Wintab-mode drivers (no longer supported — Windows Ink only) vs. Windows Ink-mode drivers.
    • macOS: SDL3's Cocoa pen events vs. the untouched she/osx/tablet.mm tap (the issue notes the macOS path doesn't use EasyTab/WM-info at all, so it should be unaffected either way — worth confirming).
    • Alt-Tabbing away and back doesn't leave pressure "stuck" from a pen that was in contact before losing focus.

🤖 Generated with Claude Code

@Nidrax

Nidrax commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

macOS: tested and working, but found a bug:
Picking a colour from the palette: right after changing the foreground colour the brush size is set to the actual numeric value and stays that way until a full stroke is made with the pen and only then the brush size starts reacting to the pressure.

Nidrax and others added 3 commits October 5, 2026 15:13
Drops EasyTab (SDL_GetWindowWMInfo/SDL_SYSWMEVENT have no SDL3
equivalent reachable without per-platform native message hooks) in
favor of SDL3's native SDL_EVENT_PEN_* events, per #263's R4
recommendation: broader native coverage (Windows Ink, XInput2, Wayland
tablet-v2, Cocoa) than EasyTab has today, with no Wintab/XInput1 vs.
SDL3-XInput2 conflict to work around (R1).

- SDL_EVENT_PEN_AXIS (SDL_PEN_AXIS_PRESSURE) feeds the existing
  penPressure global that mouse events already read from, mirroring
  the current finger-pressure-as-pen-proxy pattern.
- SDL_EVENT_PEN_PROXIMITY_OUT resets pressure/pointer type, fixing the
  "stale pressure after the pen last touched the tablet" bug the issue
  flagged in the existing pointerType handling.
- SDL_HINT_PEN_TOUCH_EVENTS is disabled so pen input doesn't also
  synthesize touch events that would fight the pressure tracking above
  with a second, less precise value (R5); SDL_HINT_PEN_MOUSE_EVENTS is
  left at its default so position/clicks keep arriving as ordinary
  mouse events, unchanged.
- SDL3Display::nativeHandle() is ported via SDL_GetWindowProperties()
  (SDL_PROP_WINDOW_WIN32_HWND_POINTER / _COCOA_WINDOW_POINTER /
  _ANDROID_WINDOW_POINTER / _X11_WINDOW_NUMBER), replacing the removed
  SDL_GetWindowWMInfo(); verified against a real X11 window in this
  session.

This direction and the SDL_EVENT_PEN_* handling above have not been
validated against real tablet hardware (R1-R3 in the issue all require
it); the SDL2 backend's EasyTab path is untouched and unaffected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Set the SDL video driver hint to "wayland,x11" on Linux when
WAYLAND_DISPLAY is set, so Wayland sessions get a native window
(with X11 as fallback) instead of XWayland. An explicit
SDL_VIDEO_DRIVER/SDL_VIDEODRIVER env var still takes precedence.

Refs #145. Pixel-perfect DPI handling is tracked in #315.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Treat mouse events tagged SDL_PEN_MOUSEID as pen input instead of
relying on the last pressure value, which is 0 after the pen leaves
proximity. The first stroke was reported as a mouse (pressure 1.0)
and drew at the fixed brush size.

Assisted-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Nidrax
Nidrax force-pushed the nidrax/sdl3-phase3-tablet-wm branch from 05f62ee to b0eec56 Compare October 5, 2026 13:13
Nidrax and others added 2 commits October 5, 2026 16:05
A hovering pen sends no pressure axis events, so the stored pressure
stayed 0 after proximity-out and the full-size brush preview was shown
until the first touch. Mark the pen as present on proximity-in and
pen motion.

Assisted-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The synthesized double click was emitted after the second release, and
ui::Widget turns it into a mouse down with no matching release, so a
freehand stroke kept running at 1px. Emit it in place of the second
press instead, mark the button pressed in the manager, and keep the
pen pressure through the conversion.

Assisted-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Nidrax

Nidrax commented Oct 5, 2026

Copy link
Copy Markdown
Member Author

Tested on macOS -- latest patchset OK

@Nidrax

Nidrax commented Oct 5, 2026 •

Copy link
Copy Markdown
Member Author

Alt-Tabbing away and back doesn't leave pressure "stuck" from a pen that was in contact before losing focus.

Hard to even test, because the still active pressure makes the app regain focus immediately, but looks to be working properly (no weird pressure spikes noticed)

@Nidrax
Nidrax force-pushed the nidrax/sdl3-phase3-tablet-wm branch from 256d177 to c0eeb63 Compare October 5, 2026 15:05
@Nidrax

Nidrax commented Oct 6, 2026 •

Copy link
Copy Markdown
Member Author

Windows: application reports Tablet support: OK but no pressure changes are registered in-app. Disabling Windows ink and defaulting to WinTab API also doesn't seem to change anything
Scrap that. I downloaded the PR artifact which was a SDL2 with WinTab build

@Nidrax
Nidrax force-pushed the nidrax/sdl3-phase3-tablet-wm branch from 93faa9e to b2cabc6 Compare October 6, 2026 08:49
@Nidrax

Nidrax commented Oct 6, 2026 •

Copy link
Copy Markdown
Member Author

SDL3 backend tablet support works ✅, it's EasyTab that doesn't

I am not sure about EasyTab, but clippy for sure does not support
Wayland natively, so running in a XWayland session to at least have
some partial KWayland/xwayland-sattelite wrapping over X11 clipboard
looks like a safer choice.
@Nidrax
Nidrax force-pushed the nidrax/sdl3-phase3-tablet-wm branch from b2cabc6 to b62da0e Compare October 6, 2026 09:14
@Nidrax

Nidrax commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

Xfce X11 session: OK

@Nidrax
Nidrax merged commit 15ccc51 into trunk Oct 6, 2026
18 checks passed
@Nidrax
Nidrax deleted the nidrax/sdl3-phase3-tablet-wm branch October 6, 2026 10:25
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.

SDL3 migration, Phase 3: tablet/pen input (EasyTab, WM properties)

1 participant