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_DESKTOP_MODE_CHANGED, /**< Display has changed desktop mode */
|
||||||
SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED, /**< Display has changed current 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_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_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 */
|
/* Window events */
|
||||||
/* 0x200 was SDL_WINDOWEVENT, reserve the number for sdl2-compat */
|
/* 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_DESKTOP_MODE_CHANGED);
|
||||||
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_CURRENT_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_CONTENT_SCALE_CHANGED);
|
||||||
|
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED);
|
||||||
#undef SDL_DISPLAYEVENT_CASE
|
#undef SDL_DISPLAYEVENT_CASE
|
||||||
|
|
||||||
#define SDL_WINDOWEVENT_CASE(x) \
|
#define SDL_WINDOWEVENT_CASE(x) \
|
||||||
|
|||||||
@@ -1626,6 +1626,14 @@ void SDLTest_PrintEvent(const SDL_Event *event)
|
|||||||
event->display.displayID, (int)(scale * 100.0f));
|
event->display.displayID, (int)(scale * 100.0f));
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
|
||||||
SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " desktop mode changed to %" SDL_PRIs32 "x%" SDL_PRIs32,
|
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);
|
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) {
|
if (_this->GetDisplayBounds) {
|
||||||
|
SDL_zerop(rect);
|
||||||
if (_this->GetDisplayBounds(_this, display, rect)) {
|
if (_this->GetDisplayBounds(_this, display, rect)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1103,6 +1104,7 @@ bool SDL_GetDisplayUsableBounds(SDL_DisplayID displayID, SDL_Rect *rect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_this->GetDisplayUsableBounds) {
|
if (_this->GetDisplayUsableBounds) {
|
||||||
|
SDL_zerop(rect);
|
||||||
if (_this->GetDisplayUsableBounds(_this, display, rect)) {
|
if (_this->GetDisplayUsableBounds(_this, display, rect)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
struct SDL_DisplayData
|
struct SDL_DisplayData
|
||||||
{
|
{
|
||||||
CGDirectDisplayID display;
|
CGDirectDisplayID display;
|
||||||
|
SDL_Rect usable_bounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SDL_DisplayModeData
|
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)
|
bool Cocoa_AddDisplay(CGDirectDisplayID display, bool send_event)
|
||||||
{
|
{
|
||||||
@@ -331,7 +346,7 @@ bool Cocoa_AddDisplay(CGDirectDisplayID display, bool send_event)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_DisplayData *displaydata = (SDL_DisplayData *)SDL_malloc(sizeof(*displaydata));
|
SDL_DisplayData *displaydata = (SDL_DisplayData *)SDL_calloc(1, sizeof(*displaydata));
|
||||||
if (!displaydata) {
|
if (!displaydata) {
|
||||||
CGDisplayModeRelease(moderef);
|
CGDisplayModeRelease(moderef);
|
||||||
return false;
|
return false;
|
||||||
@@ -359,6 +374,8 @@ bool Cocoa_AddDisplay(CGDirectDisplayID display, bool send_event)
|
|||||||
|
|
||||||
Cocoa_GetHDRProperties(displaydata->display, &viddisplay.HDR);
|
Cocoa_GetHDRProperties(displaydata->display, &viddisplay.HDR);
|
||||||
|
|
||||||
|
Cocoa_GetUsableBounds(displaydata->display, &displaydata->usable_bounds);
|
||||||
|
|
||||||
viddisplay.desktop_mode = mode;
|
viddisplay.desktop_mode = mode;
|
||||||
viddisplay.internal = displaydata;
|
viddisplay.internal = displaydata;
|
||||||
const bool retval = SDL_AddVideoDisplay(&viddisplay, send_event);
|
const bool retval = SDL_AddVideoDisplay(&viddisplay, send_event);
|
||||||
@@ -538,6 +555,13 @@ void Cocoa_UpdateDisplays(SDL_VideoDevice *_this)
|
|||||||
|
|
||||||
Cocoa_GetHDRProperties(displaydata->display, &HDR);
|
Cocoa_GetHDRProperties(displaydata->display, &HDR);
|
||||||
SDL_SetDisplayHDRProperties(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)
|
bool Cocoa_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
SDL_DisplayData *displaydata = (SDL_DisplayData *)display->internal;
|
||||||
SDL_DisplayData *displaydata = (SDL_DisplayData *)display->internal;
|
|
||||||
NSScreen *screen = GetNSScreenForDisplayID(displaydata->display);
|
|
||||||
|
|
||||||
if (screen == nil) {
|
SDL_memcpy(rect, &displaydata->usable_bounds, sizeof(*rect));
|
||||||
return SDL_SetError("Couldn't get NSScreen for display");
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
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_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
|
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) {
|
if (wParam == SPI_SETMOUSE || wParam == SPI_SETMOUSESPEED) {
|
||||||
WIN_UpdateMouseSystemScale();
|
WIN_UpdateMouseSystemScale();
|
||||||
}
|
}
|
||||||
|
if (wParam == SPI_SETWORKAREA) {
|
||||||
|
WIN_UpdateDisplayUsableBounds(SDL_GetVideoDevice());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#endif // !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
#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)
|
void WIN_QuitModes(SDL_VideoDevice *_this)
|
||||||
{
|
{
|
||||||
// All fullscreen windows should have restored modes by now
|
// 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_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
|
||||||
extern bool WIN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
|
extern bool WIN_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
|
||||||
extern void WIN_RefreshDisplays(SDL_VideoDevice *_this);
|
extern void WIN_RefreshDisplays(SDL_VideoDevice *_this);
|
||||||
|
extern void WIN_UpdateDisplayUsableBounds(SDL_VideoDevice *_this);
|
||||||
extern void WIN_QuitModes(SDL_VideoDevice *_this);
|
extern void WIN_QuitModes(SDL_VideoDevice *_this);
|
||||||
|
|
||||||
#endif // SDL_windowsmodes_h_
|
#endif // SDL_windowsmodes_h_
|
||||||
|
|||||||
@@ -1418,31 +1418,33 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
|||||||
|
|
||||||
X11_UpdateKeymap(_this, true);
|
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);
|
char *name_of_atom = X11_XGetAtomName(display, xevent->xproperty.atom);
|
||||||
|
if (name_of_atom) {
|
||||||
if (SDL_strncmp(name_of_atom, "_ICC_PROFILE", sizeof("_ICC_PROFILE") - 1) == 0) {
|
if (SDL_startswith(name_of_atom, "_ICC_PROFILE")) {
|
||||||
XWindowAttributes attrib;
|
XWindowAttributes attrib;
|
||||||
int screennum;
|
int screennum;
|
||||||
for (i = 0; i < videodata->numwindows; ++i) {
|
for (i = 0; i < videodata->numwindows; ++i) {
|
||||||
if (videodata->windowlist[i] != NULL) {
|
if (videodata->windowlist[i] != NULL) {
|
||||||
data = videodata->windowlist[i];
|
data = videodata->windowlist[i];
|
||||||
X11_XGetWindowAttributes(display, data->xwindow, &attrib);
|
X11_XGetWindowAttributes(display, data->xwindow, &attrib);
|
||||||
screennum = X11_XScreenNumberOfScreen(attrib.screen);
|
screennum = X11_XScreenNumberOfScreen(attrib.screen);
|
||||||
if (screennum == 0 && SDL_strcmp(name_of_atom, "_ICC_PROFILE") == 0) {
|
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);
|
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);
|
X11_XFree(name_of_atom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user