[client] spice: improve mouse syncronization with the host

This commit is contained in:
Geoffrey McRae 2020-08-20 14:52:24 +10:00
parent 7e362050f7
commit 5c912e3c27
3 changed files with 60 additions and 37 deletions

View File

@ -1 +1 @@
B2-rc4-3-gc66a339bbc+1
B2-rc4-6-g7e362050f7+1

View File

@ -302,19 +302,6 @@ static int cursorThread(void * unused)
state.cursorVisible =
msg.udata & CURSOR_FLAG_VISIBLE;
if (msg.udata & CURSOR_FLAG_POSITION)
{
state.cursor.x = cursor->x;
state.cursor.y = cursor->y;
state.haveCursorPos = true;
if (!state.haveAligned && state.haveSrcSize && state.haveCurLocal)
{
alignMouseWithHost();
state.haveAligned = true;
}
}
if (msg.udata & CURSOR_FLAG_SHAPE)
{
switch(cursor->type)
@ -347,6 +334,16 @@ static int cursorThread(void * unused)
}
}
if (msg.udata & CURSOR_FLAG_POSITION)
{
state.cursor.x = cursor->x;
state.cursor.y = cursor->y;
state.haveCursorPos = true;
if (state.haveSrcSize && state.haveCurLocal && !state.serverMode)
alignMouseWithGuest();
}
lgmpClientMessageDone(queue);
state.updateCursor = false;
@ -671,10 +668,22 @@ void spiceClipboardRequest(const SpiceDataType type)
state.lgc->request(spice_type_to_clipboard_type(type));
}
static void warpMouse(int x, int y)
{
if (state.warpState != WARP_STATE_ON)
return;
state.warpFromX = state.curLastX;
state.warpFromY = state.curLastY;
state.warpToX = x;
state.warpToY = y;
state.warpState = WARP_STATE_ACTIVE;
SDL_WarpMouseInWindow(state.window, x, y);
}
static void handleMouseMoveEvent(int ex, int ey)
{
static bool wrapping = false;
static int wrapX, wrapY;
state.curLocalX = ex;
state.curLocalY = ey;
@ -683,28 +692,23 @@ static void handleMouseMoveEvent(int ex, int ey)
if (state.ignoreInput || !params.useSpiceInput)
return;
if (state.warpState == WARP_STATE_ACTIVE)
{
if (ex == state.warpToX && ey == state.warpToY)
{
state.curLastX += state.warpToX - state.warpFromX;
state.curLastY += state.warpToY - state.warpFromY;
state.warpState = WARP_STATE_ON;
}
}
if (state.serverMode)
{
if (wrapping)
if (
ex < 100 || ex > state.windowW - 100 ||
ey < 100 || ey > state.windowH - 100)
{
if (ex == state.windowW / 2 && ey == state.windowH / 2)
{
state.curLastX += (state.windowW / 2) - wrapX;
state.curLastY += (state.windowH / 2) - wrapY;
wrapping = false;
}
}
else
{
if (
ex < 100 || ex > state.windowW - 100 ||
ey < 100 || ey > state.windowH - 100)
{
wrapping = true;
wrapX = ex;
wrapY = ey;
SDL_WarpMouseInWindow(state.window, state.windowW / 2, state.windowH / 2);
}
warpMouse(state.windowW / 2, state.windowH / 2);
}
}
else
@ -716,6 +720,7 @@ static void handleMouseMoveEvent(int ex, int ey)
{
state.cursorInView = false;
state.updateCursor = true;
state.warpState = WARP_STATE_OFF;
return;
}
}
@ -724,6 +729,8 @@ static void handleMouseMoveEvent(int ex, int ey)
{
state.cursorInView = true;
state.updateCursor = true;
if (state.warpState == WARP_STATE_ARMED)
state.warpState = WARP_STATE_ON;
}
int rx = ex - state.curLastX;
@ -765,7 +772,7 @@ static void alignMouseWithGuest()
state.curLastX = (int)round((float)(state.cursor.x + state.cursor.hx) / state.scaleX) + state.dstRect.x;
state.curLastY = (int)round((float)(state.cursor.y + state.cursor.hy) / state.scaleY) + state.dstRect.y;
SDL_WarpMouseInWindow(state.window, state.curLastX, state.curLastY);
warpMouse(state.curLastX, state.curLastY);
}
static void alignMouseWithHost()
@ -799,6 +806,7 @@ static void handleWindowLeave()
state.drawCursor = false;
state.cursorInView = false;
state.updateCursor = true;
state.warpState = WARP_STATE_OFF;
}
static void handleWindowEnter()
@ -809,6 +817,7 @@ static void handleWindowEnter()
alignMouseWithHost();
state.drawCursor = true;
state.updateCursor = true;
state.warpState = WARP_STATE_ARMED;
}
int eventFilter(void * userdata, SDL_Event * event)
@ -951,7 +960,9 @@ int eventFilter(void * userdata, SDL_Event * event)
state.serverMode ? "Capture Enabled" : "Capture Disabled"
);
if (!state.serverMode)
if (state.serverMode)
state.warpState = WARP_STATE_ON;
else
alignMouseWithGuest();
}
}

View File

@ -42,6 +42,14 @@ struct CursorInfo
int hx, hy;
};
enum WarpState
{
WARP_STATE_ARMED,
WARP_STATE_ON,
WARP_STATE_ACTIVE,
WARP_STATE_OFF
};
struct AppState
{
enum RunState state;
@ -73,6 +81,10 @@ struct AppState
int curLocalY;
bool haveAligned;
enum WarpState warpState;
int warpFromX, warpFromY;
int warpToX , warpToY;
const LG_Renderer * lgr;
void * lgrData;
bool lgrResize;