We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3226 - SDL_SetRelativeMouseMode doesn't work for Android platform
Summary: SDL_SetRelativeMouseMode doesn't work for Android platform
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: events (show other bugs)
Version: 2.0.8
Hardware: ARM Android (All)
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-01-09 02:00 UTC by Anthony @ POW Games
Modified: 2019-01-17 14:36 UTC (History)
3 users (show)

See Also:


Attachments
patch (11.29 KB, patch)
2017-11-12 20:11 UTC, Sylvain
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Anthony @ POW Games 2016-01-09 02:00:34 UTC
SDL_SetRelativeMouseMode(1) doesn't work on the Android platform.

SDL_MOUSEMOTION produces event.motion.xrel & event.motion.yrel values that are relative to the center of the screen, rather than movement of the mouse compared to the last mouse position (it's as if it believes the last mouse position is the center of the screen, permanantly). Also, once the mouse pointer has moved to the edge of the screen, events stop.

SDL_SetRelativeMouseMode(0) produces correct xrel & yrel values.

This bug can be reproduced without a physical mouse by touching the screen and generating fake mouse events. Normally you receive finger movement values as expected, but SDL_SetRelativeMouseMode(1) produces values relating to pixel distance from the center of the screen.

(Ryan, if you're reading this, I'm sure this time :)
Comment 1 Anthony @ POW Games 2016-01-09 02:17:49 UTC
Correction: when the mouse hits the edge of the screen, events continue, but the erroneous values don't go beyond the edge of the screen.
Comment 2 Philipp Wiesemann 2016-01-09 19:50:50 UTC
The required functionality is not implemented (e.g. centering the cursor).
Comment 3 Anthony @ POW Games 2016-01-11 03:03:32 UTC
SDL_SetRelativeMouseMode(SDL_TRUE) returns 0 though, shouldn't it return -1?

I read somewhere Ryan mentioning that after 2.0.4, the minimum API level will rise to 14, so that SDL_ShowCursor() can work. Would this be true for warping the mouse position? Can we return -1 and set errors & mention this in the wiki until it's fixed?
Comment 4 Philipp Wiesemann 2016-01-11 18:28:36 UTC
This was in bug 2930. But I hope the target API will be changed and not the minimum API.

The wiki seems to be correct. SDL_SetRelativeMouseMode() is wrong. It checks for support of relative mode but there is none. It then seems to fall back to warping without checking if it is actually implemented and returns SDL_TRUE.
Comment 5 Anthony @ POW Games 2016-01-11 18:37:42 UTC
Thanks for clarifying Philipp. I've made a work-around for now.

I wouldn't mind the minimum APK rising to 14 if required.
Comment 6 Sam Lantinga 2017-08-12 15:07:50 UTC
At this point we can raise the minimum API level.
Does anyone have a tested patch for this issue?
Comment 7 Sylvain 2017-11-10 13:42:27 UTC
I think there is no API to position mouse cursor on android, for this reason there is no WarpMouse function available in the android port.

Android doesn't provide relative mouse event, so SDL has to use the internal "relative_mode_warp".

Using relative_mode_warp without WarpMouse provide the behavior described in the first comment.

But this is still possible to have some consistent relative mode by not considering that the last point is always the screen center.

By doing: 

diff -r 2ce56475ad57 src/events/SDL_mouse.c
--- a/src/events/SDL_mouse.c	Tue Nov 07 09:10:32 2017 -0800
+++ b/src/events/SDL_mouse.c	Fri Nov 10 14:35:57 2017 +0100
@@ -274,6 +274,7 @@
     }
 
     if (mouseID != SDL_TOUCH_MOUSEID && mouse->relative_mode_warp) {
+        if (mouse->WarpMouse) {
         int center_x = 0, center_y = 0;
         SDL_GetWindowSize(window, &center_x, &center_y);
         center_x /= 2;
@@ -284,6 +285,7 @@
             return 0;
         }
         SDL_WarpMouseInWindow(window, center_x, center_y);
+        }
     }
Comment 8 Sylvain 2017-11-10 13:58:22 UTC
But it should maybe just be reported as un-available : 
relative_mode_warp cannot be done without WarpMouse



diff -r 2ce56475ad57 src/events/SDL_mouse.c
--- a/src/events/SDL_mouse.c	Tue Nov 07 09:10:32 2017 -0800
+++ b/src/events/SDL_mouse.c	Fri Nov 10 14:56:37 2017 +0100
@@ -700,6 +700,11 @@
     SDL_Mouse *mouse = SDL_GetMouse();
     SDL_Window *focusWindow = SDL_GetKeyboardFocus();
 
+    /* No relative mouse mode possible */
+    if (ShouldUseRelativeModeWarp(mouse) && !mouse->WarpMouse) {
+        return -1;
+    }
+
Comment 9 Anthony @ POW Games 2017-11-10 19:00:16 UTC
That's all reasonable. Can the wiki be updated to explain this will return error on Android?
Comment 10 Eric Wasylishen 2017-11-10 20:04:09 UTC
Looks like relative mouse events were added in API 24 (Android 7.0)
https://developer.android.com/reference/android/view/MotionEvent.html#AXIS_RELATIVE_X

> For a mouse, reports a difference of x position between the previous position. This is useful when pointer is captured, in that case the mouse pointer doesn't change the location but this axis reports the difference which allows the app to see how the mouse is moved.
Comment 11 Sylvain 2017-11-10 20:35:51 UTC
Getting relative position can be done inside SDL, this relative_mode_warp.

But in your link, they talk also about the ability of hide the mouse pointer, this is :

https://developer.android.com/reference/android/view/View.html#requestPointerCapture()

But that's API 26 .. Android 8.0
Comment 12 Sylvain 2017-11-12 20:11:50 UTC
Created attachment 3085 [details]
patch

Here's a patch to use SDL_SetRelativeMode() on Android.
to compile, you need a recent SDK and use compileSdkVersion 26.

It will work on platforms where SDK_INT >= 26. For older platforms SDL_SetRelativeMode will return -1 as not supported.
Comment 13 Anthony @ POW Games 2018-04-20 23:31:09 UTC
I've just tested this on 4.2.2 (Api 17) and SDL_SetRelativeMouseMode is still returning no error and proceeds to generate seemingly random xrel & yrel values...
Comment 14 Anthony @ POW Games 2018-04-20 23:33:50 UTC
I was testing 2.0.8 without the patch, so I guess the patch hasn't been applied yet?
Comment 15 Sylvain 2018-04-26 09:30:48 UTC
It hasn't been merged.
Apply the patch locally to see whether it works and fits your needs.
Comment 16 Sylvain 2019-01-17 14:36:15 UTC
Someone a re-done the patch, so closed:

https://hg.libsdl.org/SDL/rev/5b41aa10b12f
https://hg.libsdl.org/SDL/rev/d7cb1131aada