[client] wayland: move wayland specific mouse code out of main.c

This commit is contained in:
Geoffrey McRae 2021-01-16 20:17:19 +11:00
parent a4a042e90d
commit ef678bab1d
4 changed files with 66 additions and 62 deletions

View File

@ -63,6 +63,12 @@ static bool sdlEventFilter(SDL_Event * event)
// stop motion events during the warp out of the window // stop motion events during the warp out of the window
if (sdl.exiting) if (sdl.exiting)
return true; return true;
app_updateCursorPos(event->motion.x, event->motion.y);
if (app_cursorIsGrabbed())
app_handleMouseGrabbed(event->motion.xrel, event->motion.yrel);
else
app_handleMouseNormal(event->motion.xrel, event->motion.yrel);
break; break;
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:

View File

@ -356,6 +356,19 @@ static void waylandFree(void)
static bool waylandEventFilter(SDL_Event * event) static bool waylandEventFilter(SDL_Event * event)
{ {
/* prevent the default processing for the following events */
switch(event->type)
{
case SDL_MOUSEMOTION:
{
app_updateCursorPos(event->motion.x, event->motion.y);
// we must use the basic handler as Wayland has no warp support
app_handleMouseBasic(event->motion.x, event->motion.y);
return true;
}
}
return false; return false;
} }

View File

@ -34,6 +34,7 @@ void app_updateWindowPos(int x, int y);
void app_handleResizeEvent(int w, int h); void app_handleResizeEvent(int w, int h);
void app_handleMouseGrabbed(double ex, double ey); void app_handleMouseGrabbed(double ex, double ey);
void app_handleMouseNormal(double ex, double ey); void app_handleMouseNormal(double ex, double ey);
void app_handleMouseBasic(double ex, double ey);
void app_handleWindowEnter(); void app_handleWindowEnter();
void app_handleWindowLeave(); void app_handleWindowLeave();

View File

@ -950,43 +950,6 @@ static void guestCurToLocal(struct DoublePoint *local)
local->y = (g_cursor.guest.y + g_cursor.guest.hy) / g_cursor.scale.y; local->y = (g_cursor.guest.y + g_cursor.guest.hy) / g_cursor.scale.y;
} }
// On Wayland, our normal cursor logic does not work due to the lack of cursor
// warp support. Instead, we attempt a best-effort emulation which works with a
// 1:1 mouse movement patch applied in the guest. For anything fancy, use
// capture mode.
static void app_handleMouseWayland(void)
{
const bool inView =
g_cursor.pos.x >= g_state.dstRect.x &&
g_cursor.pos.x < g_state.dstRect.x + g_state.dstRect.w &&
g_cursor.pos.y >= g_state.dstRect.y &&
g_cursor.pos.y < g_state.dstRect.y + g_state.dstRect.h;
if (params.hideMouse && inView != g_cursor.inView)
SDL_ShowCursor(inView ? SDL_DISABLE : SDL_ENABLE);
g_cursor.inView = inView;
if (g_cursor.guest.dpiScale == 0)
return;
/* translate the guests position to our coordinate space */
struct DoublePoint local;
guestCurToLocal(&local);
double ex = (g_cursor.pos.x - local.x) / g_cursor.dpiScale;
double ey = (g_cursor.pos.y - local.y) / g_cursor.dpiScale;
int x, y;
cursorToInt(ex, ey, &x, &y);
g_cursor.guest.x += x;
g_cursor.guest.y += y;
if (!spice_mouse_motion(x, y))
DEBUG_ERROR("failed to send mouse motion message");
}
void app_handleMouseNormal(double ex, double ey) void app_handleMouseNormal(double ex, double ey)
{ {
/* if we don't have the current cursor pos just send cursor movements */ /* if we don't have the current cursor pos just send cursor movements */
@ -997,12 +960,6 @@ void app_handleMouseNormal(double ex, double ey)
return; return;
} }
if (g_state.wminfo.subsystem == SDL_SYSWM_WAYLAND)
{
app_handleMouseWayland();
return;
}
/* scale the movement to the guest */ /* scale the movement to the guest */
if (g_cursor.useScale && params.scaleMouseInput) if (g_cursor.useScale && params.scaleMouseInput)
{ {
@ -1135,6 +1092,52 @@ void app_handleMouseNormal(double ex, double ey)
DEBUG_ERROR("failed to send mouse motion message"); DEBUG_ERROR("failed to send mouse motion message");
} }
// On some display servers normal cursor logic does not work due to the lack of
// cursor warp support. Instead, we attempt a best-effort emulation which works
// with a 1:1 mouse movement patch applied in the guest. For anything fancy, use
// capture mode.
void app_handleMouseBasic(double ex, double ey)
{
/* if we don't have the current cursor pos just send cursor movements */
if (!g_cursor.guest.valid)
{
if (g_cursor.grab)
app_handleMouseGrabbed(ex, ey);
return;
}
const bool inView =
g_cursor.pos.x >= g_state.dstRect.x &&
g_cursor.pos.x < g_state.dstRect.x + g_state.dstRect.w &&
g_cursor.pos.y >= g_state.dstRect.y &&
g_cursor.pos.y < g_state.dstRect.y + g_state.dstRect.h;
if (params.hideMouse && inView != g_cursor.inView)
SDL_ShowCursor(inView ? SDL_DISABLE : SDL_ENABLE);
g_cursor.inView = inView;
if (g_cursor.guest.dpiScale == 0)
return;
/* translate the guests position to our coordinate space */
struct DoublePoint local;
guestCurToLocal(&local);
double lx = (g_cursor.pos.x - local.x) / g_cursor.dpiScale;
double ly = (g_cursor.pos.y - local.y) / g_cursor.dpiScale;
int x, y;
cursorToInt(lx, ly, &x, &y);
g_cursor.guest.x += x;
g_cursor.guest.y += y;
if (!spice_mouse_motion(x, y))
DEBUG_ERROR("failed to send mouse motion message");
}
void app_updateWindowPos(int x, int y) void app_updateWindowPos(int x, int y)
{ {
g_state.windowPos.x = x; g_state.windowPos.x = x;
@ -1320,25 +1323,6 @@ int eventFilter(void * userdata, SDL_Event * event)
return 0; return 0;
} }
case SDL_MOUSEMOTION:
{
g_cursor.pos.x = event->motion.x;
g_cursor.pos.y = event->motion.y;
if (g_state.wminfo.subsystem != SDL_SYSWM_WAYLAND)
{
// On Wayland, wm.c calls these functions, bypassing the SDL event loop.
if (g_cursor.grab)
{
if (g_state.wminfo.subsystem != SDL_SYSWM_WAYLAND)
app_handleMouseGrabbed(event->motion.xrel, event->motion.yrel);
}
else
app_handleMouseNormal(event->motion.xrel, event->motion.yrel);
}
break;
}
case SDL_KEYDOWN: case SDL_KEYDOWN:
{ {
SDL_Scancode sc = event->key.keysym.scancode; SDL_Scancode sc = event->key.keysym.scancode;