Fix: [SDL] unify the way X11 and Wayland handle mouse events

Basically, we drop RelativeMode completely, and use the same trick
as used by the Windows driver: read all motion events till the last
one, and use that as value.
This commit is contained in:
Patric Stout 2023-06-03 23:08:37 +02:00 committed by Patric Stout
parent 220b08b868
commit 2ce9f640ef
2 changed files with 30 additions and 9 deletions

View File

@ -371,12 +371,25 @@ bool VideoDriver_SDL_Base::PollEvent()
if (!SDL_PollEvent(&ev)) return false;
switch (ev.type) {
case SDL_MOUSEMOTION:
if (_cursor.UpdateCursorPosition(ev.motion.x, ev.motion.y, true)) {
case SDL_MOUSEMOTION: {
int32_t x = ev.motion.x;
int32_t y = ev.motion.y;
if (_cursor.fix_at) {
/* Get all queued mouse events now in case we have to warp the cursor. In the
* end, we only care about the current mouse position and not bygone events. */
while (SDL_PeepEvents(&ev, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION)) {
x = ev.motion.x;
y = ev.motion.y;
}
}
if (_cursor.UpdateCursorPosition(x, y, false)) {
SDL_WarpMouseInWindow(this->sdl_window, _cursor.pos.x, _cursor.pos.y);
}
HandleMouseEvents();
break;
}
case SDL_MOUSEWHEEL:
if (ev.wheel.y > 0) {
@ -478,10 +491,8 @@ bool VideoDriver_SDL_Base::PollEvent()
} else if (ev.window.event == SDL_WINDOWEVENT_ENTER) {
// mouse entered the window, enable cursor
_cursor.in_window = true;
#ifdef __EMSCRIPTEN__
/* Ensure pointer lock will not occur. */
SDL_SetRelativeMouseMode(SDL_FALSE);
#endif
} else if (ev.window.event == SDL_WINDOWEVENT_LEAVE) {
// mouse left the window, undraw cursor
UndrawMouseCursor();
@ -500,9 +511,6 @@ static const char *InitializeSDL()
* UpdateWindowSurface() to update the window's texture instead of
* its surface. */
SDL_SetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION, "0");
#ifndef __EMSCRIPTEN__
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1");
#endif
/* Check if the video-driver is already initialized. */
if (SDL_WasInit(SDL_INIT_VIDEO) != 0) return nullptr;

View File

@ -477,12 +477,25 @@ bool VideoDriver_SDL::PollEvent()
if (!SDL_PollEvent(&ev)) return false;
switch (ev.type) {
case SDL_MOUSEMOTION:
if (_cursor.UpdateCursorPosition(ev.motion.x, ev.motion.y, true)) {
case SDL_MOUSEMOTION: {
int32_t x = ev.motion.x;
int32_t y = ev.motion.y;
if (_cursor.fix_at) {
/* Get all queued mouse events now in case we have to warp the cursor. In the
* end, we only care about the current mouse position and not bygone events. */
while (SDL_PeepEvents(&ev, 1, SDL_GETEVENT, SDL_MOUSEMOTION)) {
x = ev.motion.x;
y = ev.motion.y;
}
}
if (_cursor.UpdateCursorPosition(x, y, false)) {
SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y);
}
HandleMouseEvents();
break;
}
case SDL_MOUSEBUTTONDOWN:
if (_rightclick_emulate && SDL_GetModState() & KMOD_CTRL) {