[client] spice: don't disable warp when the future cursor pos is invalid

This commit is contained in:
Geoffrey McRae 2020-12-04 17:32:28 +11:00
parent 265b4544ef
commit c0a3b85580
2 changed files with 39 additions and 4 deletions

View File

@ -793,6 +793,20 @@ static void warpMouse(int x, int y)
} }
} }
static bool isValidCursorLocation(int x, int y)
{
const int displays = SDL_GetNumVideoDisplays();
for(int i = 0; i < displays; ++i)
{
SDL_Rect r;
SDL_GetDisplayBounds(i, &r);
if ((x >= r.x && x < r.x + r.w) &&
(y >= r.y && y < r.y + r.h))
return true;
}
return false;
}
static void handleMouseMoveEvent(int ex, int ey) static void handleMouseMoveEvent(int ex, int ey)
{ {
SDL_Point delta = { SDL_Point delta = {
@ -880,18 +894,25 @@ static void handleMouseMoveEvent(int ex, int ey)
if (!state.grabMouse && state.warpState == WARP_STATE_ON) if (!state.grabMouse && state.warpState == WARP_STATE_ON)
{ {
/* check if the movement would exit the window */
const SDL_Point newPos = { const SDL_Point newPos = {
.x = (float)(state.cursor.x + delta.x) / state.scaleX, .x = (float)(state.cursor.x + delta.x) / state.scaleX,
.y = (float)(state.cursor.y + delta.y) / state.scaleY .y = (float)(state.cursor.y + delta.y) / state.scaleY
}; };
if (newPos.x < 0 || newPos.x >= state.dstRect.w || const SDL_Point pos = {
newPos.y < 0 || newPos.y >= state.dstRect.h) .x = state.windowPos.x + state.border.x + newPos.x,
.y = state.windowPos.y + state.border.y + newPos.y
};
/* check if the movement would exit the window */
if (isValidCursorLocation(pos.x, pos.y) &&
(newPos.x < 0 || newPos.x >= state.dstRect.w ||
newPos.y < 0 || newPos.y >= state.dstRect.h))
{ {
/* determine where to move the cursor to taking into account any borders /* determine where to move the cursor to taking into account any borders
* if the aspect ratio is not being forced */ * if the aspect ratio is not being forced */
int nx, ny; int nx = 0, ny = 0;
if (newPos.x < 0) if (newPos.x < 0)
{ {
nx = newPos.x; nx = newPos.x;
@ -947,6 +968,13 @@ static void handleResizeEvent(unsigned int w, unsigned int h)
if (state.windowW == w && state.windowH == h) if (state.windowW == w && state.windowH == h)
return; return;
SDL_GetWindowBordersSize(state.window,
&state.border.y,
&state.border.x,
&state.border.h,
&state.border.w
);
state.windowW = w; state.windowW = w;
state.windowH = h; state.windowH = h;
updatePositionInfo(); updatePositionInfo();
@ -1047,6 +1075,11 @@ int eventFilter(void * userdata, SDL_Event * event)
handleResizeEvent(event->window.data1, event->window.data2); handleResizeEvent(event->window.data1, event->window.data2);
break; break;
case SDL_WINDOWEVENT_MOVED:
state.windowPos.x = event->window.data1;
state.windowPos.y = event->window.data2;
break;
// allow a window close event to close the application even if ignoreQuit is set // allow a window close event to close the application even if ignoreQuit is set
case SDL_WINDOWEVENT_CLOSE: case SDL_WINDOWEVENT_CLOSE:
state.state = APP_STATE_SHUTDOWN; state.state = APP_STATE_SHUTDOWN;

View File

@ -61,7 +61,9 @@ struct AppState
bool keyDown[SDL_NUM_SCANCODES]; bool keyDown[SDL_NUM_SCANCODES];
bool haveSrcSize; bool haveSrcSize;
SDL_Point windowPos;
int windowW, windowH; int windowW, windowH;
SDL_Rect border;
SDL_Point srcSize; SDL_Point srcSize;
LG_RendererRect dstRect; LG_RendererRect dstRect;
struct CursorInfo cursor; struct CursorInfo cursor;