[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
client/src

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)
{
SDL_Point delta = {
@ -880,18 +894,25 @@ static void handleMouseMoveEvent(int ex, int ey)
if (!state.grabMouse && state.warpState == WARP_STATE_ON)
{
/* check if the movement would exit the window */
const SDL_Point newPos = {
.x = (float)(state.cursor.x + delta.x) / state.scaleX,
.y = (float)(state.cursor.y + delta.y) / state.scaleY
};
if (newPos.x < 0 || newPos.x >= state.dstRect.w ||
newPos.y < 0 || newPos.y >= state.dstRect.h)
const SDL_Point pos = {
.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
* if the aspect ratio is not being forced */
int nx, ny;
int nx = 0, ny = 0;
if (newPos.x < 0)
{
nx = newPos.x;
@ -947,6 +968,13 @@ static void handleResizeEvent(unsigned int w, unsigned int h)
if (state.windowW == w && state.windowH == h)
return;
SDL_GetWindowBordersSize(state.window,
&state.border.y,
&state.border.x,
&state.border.h,
&state.border.w
);
state.windowW = w;
state.windowH = h;
updatePositionInfo();
@ -1047,6 +1075,11 @@ int eventFilter(void * userdata, SDL_Event * event)
handleResizeEvent(event->window.data1, event->window.data2);
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
case SDL_WINDOWEVENT_CLOSE:
state.state = APP_STATE_SHUTDOWN;

View File

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