Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
From 2ea4ce664afefbcad1a767a1b21e6836fafc8368 Mon Sep 17 00:00:00 2001
From: Edouard Durand <edouard.durand@gmail.com>
Date: Sat, 1 Aug 2026 10:10:59 +0800
Subject: [PATCH] sdl: fix touchscreen input on hosts without native touch
support

---
src/input/sdl.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/src/input/sdl.c b/src/input/sdl.c
index 72a2a3e..9ef8b18 100644
--- a/src/input/sdl.c
+++ b/src/input/sdl.c
@@ -432,6 +432,12 @@ static void remove_gamepad(SDL_JoystickID sdl_id) {
void sdlinput_init(char* mappings) {
memset(gamepads, 0, sizeof(gamepads));

+ // Touch is handled above, either natively or by emulating the mouse there.
+ // Letting SDL also synthesise mouse events from touch moves its internal
+ // cursor, and the compositor then re-reports the real pointer once the touch
+ // ends, which arrives as a large spurious motion.
+ SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
+
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
#if !SDL_VERSION_ATLEAST(2, 0, 9)
SDL_InitSubSystem(SDL_INIT_HAPTIC);
@@ -542,8 +548,28 @@ int sdlinput_handle_event(SDL_Window* window, SDL_Event* event) {
event->tfinger.x = SDL_max(SDL_min(1.0f, event->tfinger.x), 0.0f);
event->tfinger.y = SDL_max(SDL_min(1.0f, event->tfinger.y), 0.0f);

- LiSendTouchEvent(touchEventType, event->tfinger.fingerId, event->tfinger.x, event->tfinger.y,
- event->tfinger.pressure, 0.0f, 0.0f, LI_ROT_UNKNOWN);
+ if (LiSendTouchEvent(touchEventType, event->tfinger.fingerId, event->tfinger.x, event->tfinger.y,
+ event->tfinger.pressure, 0.0f, 0.0f, LI_ROT_UNKNOWN) == LI_ERR_UNSUPPORTED) {
+ // The host has no native touch support, so drive the mouse instead.
+ int w, h;
+ SDL_GetWindowSize(window, &w, &h);
+
+ // A touchscreen is absolute, so position the pointer where the finger is
+ // rather than following the mouse capture mode.
+ switch (event->type) {
+ case SDL_FINGERDOWN:
+ LiSendMousePositionEvent(event->tfinger.x * w, event->tfinger.y * h, w, h);
+ LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
+ break;
+ case SDL_FINGERMOTION:
+ LiSendMousePositionEvent(event->tfinger.x * w, event->tfinger.y * h, w, h);
+ break;
+ case SDL_FINGERUP:
+ // Deliberately no movement here: a release carries no new position.
+ LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
+ break;
+ }
+ }
break;
case SDL_CONTROLLERAXISMOTION:
gamepad = get_gamepad(event->caxis.which, false);