Fixed unclipping the mouse when a monitor is placed left of the primary one on Windows.

There is now a desktop bounds variable that could potentially be exposed in the API if we wanted.
This commit is contained in:
Sam Lantinga 2024-04-24 12:03:50 -07:00
parent 5fbc038375
commit e56f05bac1
4 changed files with 40 additions and 1 deletions

View File

@ -57,6 +57,9 @@ int SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent,
case SDL_EVENT_DISPLAY_ADDED: case SDL_EVENT_DISPLAY_ADDED:
SDL_OnDisplayAdded(display); SDL_OnDisplayAdded(display);
break; break;
case SDL_EVENT_DISPLAY_MOVED:
SDL_OnDisplayMoved(display);
break;
default: default:
break; break;
} }

View File

@ -352,6 +352,7 @@ struct SDL_VideoDevice
SDL_Mutex *wakeup_lock; /* Initialized only if WaitEventTimeout/SendWakeupEvent are supported */ SDL_Mutex *wakeup_lock; /* Initialized only if WaitEventTimeout/SendWakeupEvent are supported */
int num_displays; int num_displays;
SDL_VideoDisplay **displays; SDL_VideoDisplay **displays;
SDL_Rect desktop_bounds;
SDL_Window *windows; SDL_Window *windows;
SDL_Window *grabbed_window; SDL_Window *grabbed_window;
Uint8 window_magic; Uint8 window_magic;
@ -515,6 +516,7 @@ extern void SDL_RelativeToGlobalForWindow(SDL_Window *window, int rel_x, int rel
extern void SDL_GlobalToRelativeForWindow(SDL_Window *window, int abs_x, int abs_y, int *rel_x, int *rel_y); extern void SDL_GlobalToRelativeForWindow(SDL_Window *window, int abs_x, int abs_y, int *rel_x, int *rel_y);
extern void SDL_OnDisplayAdded(SDL_VideoDisplay *display); extern void SDL_OnDisplayAdded(SDL_VideoDisplay *display);
extern void SDL_OnDisplayMoved(SDL_VideoDisplay *display);
extern void SDL_OnWindowShown(SDL_Window *window); extern void SDL_OnWindowShown(SDL_Window *window);
extern void SDL_OnWindowHidden(SDL_Window *window); extern void SDL_OnWindowHidden(SDL_Window *window);
extern void SDL_OnWindowMoved(SDL_Window *window); extern void SDL_OnWindowMoved(SDL_Window *window);

View File

@ -624,6 +624,28 @@ SDL_SystemTheme SDL_GetSystemTheme(void)
} }
} }
static void SDL_UpdateDesktopBounds()
{
SDL_Rect rect;
SDL_zero(rect);
SDL_DisplayID *displays = SDL_GetDisplays(NULL);
if (displays) {
for (int i = 0; displays[i]; ++i) {
SDL_Rect bounds;
if (SDL_GetDisplayBounds(displays[i], &bounds) == 0) {
if (i == 0) {
SDL_copyp(&rect, &bounds);
} else {
SDL_GetRectUnion(&rect, &bounds, &rect);
}
}
}
SDL_free(displays);
}
SDL_copyp(&_this->desktop_bounds, &rect);
}
static void SDL_FinalizeDisplayMode(SDL_DisplayMode *mode) static void SDL_FinalizeDisplayMode(SDL_DisplayMode *mode)
{ {
/* Make sure all the fields are set up correctly */ /* Make sure all the fields are set up correctly */
@ -705,6 +727,8 @@ SDL_DisplayID SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send
SDL_SetFloatProperty(props, SDL_PROP_DISPLAY_HDR_HEADROOM_FLOAT, display->HDR.HDR_headroom); SDL_SetFloatProperty(props, SDL_PROP_DISPLAY_HDR_HEADROOM_FLOAT, display->HDR.HDR_headroom);
} }
SDL_UpdateDesktopBounds();
return id; return id;
} }
@ -718,6 +742,11 @@ void SDL_OnDisplayAdded(SDL_VideoDisplay *display)
} }
} }
void SDL_OnDisplayMoved(SDL_VideoDisplay *display)
{
SDL_UpdateDesktopBounds();
}
void SDL_DelVideoDisplay(SDL_DisplayID displayID, SDL_bool send_event) void SDL_DelVideoDisplay(SDL_DisplayID displayID, SDL_bool send_event)
{ {
SDL_VideoDisplay *display; SDL_VideoDisplay *display;
@ -745,6 +774,8 @@ void SDL_DelVideoDisplay(SDL_DisplayID displayID, SDL_bool send_event)
SDL_memmove(&_this->displays[display_index], &_this->displays[display_index + 1], (_this->num_displays - display_index - 1) * sizeof(_this->displays[display_index])); SDL_memmove(&_this->displays[display_index], &_this->displays[display_index + 1], (_this->num_displays - display_index - 1) * sizeof(_this->displays[display_index]));
} }
--_this->num_displays; --_this->num_displays;
SDL_UpdateDesktopBounds();
} }
SDL_DisplayID *SDL_GetDisplays(int *count) SDL_DisplayID *SDL_GetDisplays(int *count)

View File

@ -1492,6 +1492,7 @@ static BOOL GetClientScreenRect(HWND hwnd, RECT *rect)
void WIN_UpdateClipCursor(SDL_Window *window) void WIN_UpdateClipCursor(SDL_Window *window)
{ {
SDL_VideoDevice *videodevice = SDL_GetVideoDevice();
SDL_WindowData *data = window->driverdata; SDL_WindowData *data = window->driverdata;
SDL_Mouse *mouse = SDL_GetMouse(); SDL_Mouse *mouse = SDL_GetMouse();
RECT rect, clipped_rect; RECT rect, clipped_rect;
@ -1568,7 +1569,9 @@ void WIN_UpdateClipCursor(SDL_Window *window)
SDL_bool unclip_cursor = SDL_FALSE; SDL_bool unclip_cursor = SDL_FALSE;
/* If the cursor is clipped to the screen, clear the clip state */ /* If the cursor is clipped to the screen, clear the clip state */
if (clipped_rect.left == 0 && clipped_rect.top == 0) { if (!videodevice ||
(clipped_rect.left == videodevice->desktop_bounds.x &&
clipped_rect.top == videodevice->desktop_bounds.y)) {
unclip_cursor = SDL_TRUE; unclip_cursor = SDL_TRUE;
} else { } else {
POINT first, second; POINT first, second;