From 680d0f043a8a3defec3ad7a2c8f64e0c6d6c636c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 10 Oct 2022 09:26:49 -0700 Subject: [PATCH] Added support for undefined or centered position for shaped windows Fixes https://github.com/libsdl-org/SDL/issues/6359 --- src/video/SDL_shape.c | 46 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/video/SDL_shape.c b/src/video/SDL_shape.c index 919ae9598..c099ae179 100644 --- a/src/video/SDL_shape.c +++ b/src/video/SDL_shape.c @@ -257,20 +257,54 @@ SDL_FreeShapeTree(SDL_ShapeTree** shape_tree) int SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { + SDL_VideoDevice *_this = SDL_GetVideoDevice(); int result; - if(window == NULL || !SDL_IsShapedWindow(window)) + + if (window == NULL || !SDL_IsShapedWindow(window)) { /* The window given was not a shapeable window. */ return SDL_NONSHAPEABLE_WINDOW; - if(shape == NULL) + } + if (shape == NULL) { /* Invalid shape argument. */ return SDL_INVALID_SHAPE_ARGUMENT; + } - if(shape_mode != NULL) + if (shape_mode != NULL) { window->shaper->mode = *shape_mode; - result = SDL_GetVideoDevice()->shape_driver.SetWindowShape(window->shaper,shape,shape_mode); + } + result = _this->shape_driver.SetWindowShape(window->shaper, shape, shape_mode); window->shaper->hasshape = SDL_TRUE; - if(window->shaper->userx != 0 && window->shaper->usery != 0) { - SDL_SetWindowPosition(window,window->shaper->userx,window->shaper->usery); + if (window->shaper->userx != 0 && window->shaper->usery != 0) { + int x = window->shaper->userx; + int y = window->shaper->usery; + + if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) || + SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) { + int displayIndex; + SDL_Rect bounds; + + if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) { + displayIndex = (x & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + } else if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) { + displayIndex = (y & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + return displayIndex; + } + + SDL_GetDisplayBounds(displayIndex, &bounds); + if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) { + window->x = bounds.x + (bounds.w - window->w) / 2; + } + if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) { + window->y = bounds.y + (bounds.h - window->h) / 2; + } + } + SDL_SetWindowPosition(window, x, y); window->shaper->userx = 0; window->shaper->usery = 0; }