mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-02-13 23:33:13 +00:00
Added SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED
Fixes https://github.com/libsdl-org/SDL/issues/12785
This commit is contained in:
@@ -127,8 +127,9 @@ typedef enum SDL_EventType
|
||||
SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED, /**< Display has changed desktop mode */
|
||||
SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED, /**< Display has changed current mode */
|
||||
SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED, /**< Display has changed content scale */
|
||||
SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED, /**< Display has changed usable bounds */
|
||||
SDL_EVENT_DISPLAY_FIRST = SDL_EVENT_DISPLAY_ORIENTATION,
|
||||
SDL_EVENT_DISPLAY_LAST = SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED,
|
||||
SDL_EVENT_DISPLAY_LAST = SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED,
|
||||
|
||||
/* Window events */
|
||||
/* 0x200 was SDL_WINDOWEVENT, reserve the number for sdl2-compat */
|
||||
|
||||
@@ -525,6 +525,7 @@ int SDL_GetEventDescription(const SDL_Event *event, char *buf, int buflen)
|
||||
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED);
|
||||
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED);
|
||||
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED);
|
||||
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED);
|
||||
#undef SDL_DISPLAYEVENT_CASE
|
||||
|
||||
#define SDL_WINDOWEVENT_CASE(x) \
|
||||
|
||||
@@ -1626,6 +1626,14 @@ void SDLTest_PrintEvent(const SDL_Event *event)
|
||||
event->display.displayID, (int)(scale * 100.0f));
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED:
|
||||
{
|
||||
SDL_Rect bounds;
|
||||
SDL_GetDisplayUsableBounds(event->display.displayID, &bounds);
|
||||
SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed usable bounds to %dx%d at %d,%d",
|
||||
event->display.displayID, bounds.w, bounds.h, bounds.x, bounds.y);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
|
||||
SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " desktop mode changed to %" SDL_PRIs32 "x%" SDL_PRIs32,
|
||||
event->display.displayID, event->display.data1, event->display.data2);
|
||||
|
||||
@@ -1064,6 +1064,7 @@ bool SDL_GetDisplayBounds(SDL_DisplayID displayID, SDL_Rect *rect)
|
||||
}
|
||||
|
||||
if (_this->GetDisplayBounds) {
|
||||
SDL_zerop(rect);
|
||||
if (_this->GetDisplayBounds(_this, display, rect)) {
|
||||
return true;
|
||||
}
|
||||
@@ -1103,6 +1104,7 @@ bool SDL_GetDisplayUsableBounds(SDL_DisplayID displayID, SDL_Rect *rect)
|
||||
}
|
||||
|
||||
if (_this->GetDisplayUsableBounds) {
|
||||
SDL_zerop(rect);
|
||||
if (_this->GetDisplayUsableBounds(_this, display, rect)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
struct SDL_DisplayData
|
||||
{
|
||||
CGDirectDisplayID display;
|
||||
SDL_Rect usable_bounds;
|
||||
};
|
||||
|
||||
struct SDL_DisplayModeData
|
||||
|
||||
@@ -323,6 +323,21 @@ static void Cocoa_GetHDRProperties(CGDirectDisplayID displayID, SDL_HDROutputPro
|
||||
}
|
||||
}
|
||||
|
||||
static bool Cocoa_GetUsableBounds(CGDirectDisplayID displayID, SDL_Rect *rect)
|
||||
{
|
||||
NSScreen *screen = GetNSScreenForDisplayID(displayID);
|
||||
|
||||
if (screen == nil) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const NSRect frame = [screen visibleFrame];
|
||||
rect->x = (int)frame.origin.x;
|
||||
rect->y = (int)(CGDisplayPixelsHigh(kCGDirectMainDisplay) - frame.origin.y - frame.size.height);
|
||||
rect->w = (int)frame.size.width;
|
||||
rect->h = (int)frame.size.height;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cocoa_AddDisplay(CGDirectDisplayID display, bool send_event)
|
||||
{
|
||||
@@ -331,7 +346,7 @@ bool Cocoa_AddDisplay(CGDirectDisplayID display, bool send_event)
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *)SDL_malloc(sizeof(*displaydata));
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *)SDL_calloc(1, sizeof(*displaydata));
|
||||
if (!displaydata) {
|
||||
CGDisplayModeRelease(moderef);
|
||||
return false;
|
||||
@@ -359,6 +374,8 @@ bool Cocoa_AddDisplay(CGDirectDisplayID display, bool send_event)
|
||||
|
||||
Cocoa_GetHDRProperties(displaydata->display, &viddisplay.HDR);
|
||||
|
||||
Cocoa_GetUsableBounds(displaydata->display, &displaydata->usable_bounds);
|
||||
|
||||
viddisplay.desktop_mode = mode;
|
||||
viddisplay.internal = displaydata;
|
||||
const bool retval = SDL_AddVideoDisplay(&viddisplay, send_event);
|
||||
@@ -538,6 +555,13 @@ void Cocoa_UpdateDisplays(SDL_VideoDevice *_this)
|
||||
|
||||
Cocoa_GetHDRProperties(displaydata->display, &HDR);
|
||||
SDL_SetDisplayHDRProperties(display, &HDR);
|
||||
|
||||
SDL_Rect rect;
|
||||
if (Cocoa_GetUsableBounds(displaydata->display, &rect) &&
|
||||
SDL_memcmp(&displaydata->usable_bounds, &rect, sizeof(rect)) != 0) {
|
||||
SDL_memcpy(&displaydata->usable_bounds, &rect, sizeof(rect));
|
||||
SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,24 +580,10 @@ bool Cocoa_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, S
|
||||
|
||||
bool Cocoa_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
|
||||
{
|
||||
@autoreleasepool {
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *)display->internal;
|
||||
NSScreen *screen = GetNSScreenForDisplayID(displaydata->display);
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *)display->internal;
|
||||
|
||||
if (screen == nil) {
|
||||
return SDL_SetError("Couldn't get NSScreen for display");
|
||||
}
|
||||
|
||||
{
|
||||
const NSRect frame = [screen visibleFrame];
|
||||
rect->x = (int)frame.origin.x;
|
||||
rect->y = (int)(CGDisplayPixelsHigh(kCGDirectMainDisplay) - frame.origin.y - frame.size.height);
|
||||
rect->w = (int)frame.size.width;
|
||||
rect->h = (int)frame.size.height;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
SDL_memcpy(rect, &displaydata->usable_bounds, sizeof(*rect));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cocoa_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
|
||||
|
||||
@@ -2422,6 +2422,9 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
|
||||
if (wParam == SPI_SETMOUSE || wParam == SPI_SETMOUSESPEED) {
|
||||
WIN_UpdateMouseSystemScale();
|
||||
}
|
||||
if (wParam == SPI_SETWORKAREA) {
|
||||
WIN_UpdateDisplayUsableBounds(SDL_GetVideoDevice());
|
||||
}
|
||||
break;
|
||||
|
||||
#endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
||||
|
||||
@@ -933,6 +933,14 @@ void WIN_RefreshDisplays(SDL_VideoDevice *_this)
|
||||
}
|
||||
}
|
||||
|
||||
void WIN_UpdateDisplayUsableBounds(SDL_VideoDevice *_this)
|
||||
{
|
||||
// This almost never happens, so just go ahead and send update events for all displays
|
||||
for (int i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_SendDisplayEvent(_this->displays[i], SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void WIN_QuitModes(SDL_VideoDevice *_this)
|
||||
{
|
||||
// All fullscreen windows should have restored modes by now
|
||||
|
||||
@@ -50,6 +50,7 @@ extern bool WIN_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay
|
||||
extern bool WIN_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
|
||||
extern bool WIN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
|
||||
extern void WIN_RefreshDisplays(SDL_VideoDevice *_this);
|
||||
extern void WIN_UpdateDisplayUsableBounds(SDL_VideoDevice *_this);
|
||||
extern void WIN_QuitModes(SDL_VideoDevice *_this);
|
||||
|
||||
#endif // SDL_windowsmodes_h_
|
||||
|
||||
@@ -1418,31 +1418,33 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
||||
|
||||
X11_UpdateKeymap(_this, true);
|
||||
}
|
||||
} else if (xevent->type == PropertyNotify && videodata && videodata->windowlist) {
|
||||
} else if (xevent->type == PropertyNotify && videodata) {
|
||||
char *name_of_atom = X11_XGetAtomName(display, xevent->xproperty.atom);
|
||||
|
||||
if (SDL_strncmp(name_of_atom, "_ICC_PROFILE", sizeof("_ICC_PROFILE") - 1) == 0) {
|
||||
XWindowAttributes attrib;
|
||||
int screennum;
|
||||
for (i = 0; i < videodata->numwindows; ++i) {
|
||||
if (videodata->windowlist[i] != NULL) {
|
||||
data = videodata->windowlist[i];
|
||||
X11_XGetWindowAttributes(display, data->xwindow, &attrib);
|
||||
screennum = X11_XScreenNumberOfScreen(attrib.screen);
|
||||
if (screennum == 0 && SDL_strcmp(name_of_atom, "_ICC_PROFILE") == 0) {
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_ICCPROF_CHANGED, 0, 0);
|
||||
} else if (SDL_strncmp(name_of_atom, "_ICC_PROFILE_", sizeof("_ICC_PROFILE_") - 1) == 0 && SDL_strlen(name_of_atom) > sizeof("_ICC_PROFILE_") - 1) {
|
||||
int iccscreennum = SDL_atoi(&name_of_atom[sizeof("_ICC_PROFILE_") - 1]);
|
||||
|
||||
if (screennum == iccscreennum) {
|
||||
if (name_of_atom) {
|
||||
if (SDL_startswith(name_of_atom, "_ICC_PROFILE")) {
|
||||
XWindowAttributes attrib;
|
||||
int screennum;
|
||||
for (i = 0; i < videodata->numwindows; ++i) {
|
||||
if (videodata->windowlist[i] != NULL) {
|
||||
data = videodata->windowlist[i];
|
||||
X11_XGetWindowAttributes(display, data->xwindow, &attrib);
|
||||
screennum = X11_XScreenNumberOfScreen(attrib.screen);
|
||||
if (screennum == 0 && SDL_strcmp(name_of_atom, "_ICC_PROFILE") == 0) {
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_ICCPROF_CHANGED, 0, 0);
|
||||
} else if (SDL_strncmp(name_of_atom, "_ICC_PROFILE_", sizeof("_ICC_PROFILE_") - 1) == 0 && SDL_strlen(name_of_atom) > sizeof("_ICC_PROFILE_") - 1) {
|
||||
int iccscreennum = SDL_atoi(&name_of_atom[sizeof("_ICC_PROFILE_") - 1]);
|
||||
|
||||
if (screennum == iccscreennum) {
|
||||
SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_ICCPROF_CHANGED, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (SDL_strcmp(name_of_atom, "_NET_WORKAREA") == 0) {
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_SendDisplayEvent(_this->displays[i], SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (name_of_atom) {
|
||||
X11_XFree(name_of_atom);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user