Skip to content

Commit

Permalink
Fixed bug 4018 - Implement SDL_GetWindowBordersSize() under Windows/W…
Browse files Browse the repository at this point in the history
…in32/WinAPI

Ismael Ferreras Morezuelas (Swyter)

As a new year gift I have implemented the Windows version of SDL_GetWindowBordersSize(). I needed it for auto-selecting a cozy window size for the game I'm currently working on and noticed that it only worked under X11, so I thought it could be a good excuse to contribute back more stuff. The Mercurial patch is attached as a .diff file. Let me know what you think.

Happy 2018 to all the SDL2 devs and users!

--

PS: Keep in mind that Windows 10 includes the 8px invisible grip borders as part of the frame. There's a way of detecting if Aero/DWM is being used and ask only for the visible rect, but I believe that GetWindowRect() is doing that for a reason and working as intended, so I haven't changed it. (See [2])


References:
[1]: http://www.firststeps.ru/mfc/winapi/r.php?72
[2]: https://stackoverflow.com/a/34143777/674685
[3]: https://stackoverflow.com/a/431548/674685
[4]: https://wiki.libsdl.org/SDL_GetWindowBordersSize
  • Loading branch information
slouken committed Jan 3, 2018
1 parent 8111a63 commit 7c60bec
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/video/windows/SDL_windowsvideo.c
Expand Up @@ -143,6 +143,7 @@ WIN_CreateDevice(int devindex)
device->SetWindowIcon = WIN_SetWindowIcon;
device->SetWindowPosition = WIN_SetWindowPosition;
device->SetWindowSize = WIN_SetWindowSize;
device->GetWindowBordersSize = WIN_GetWindowBordersSize;
device->SetWindowOpacity = WIN_SetWindowOpacity;
device->ShowWindow = WIN_ShowWindow;
device->HideWindow = WIN_HideWindow;
Expand Down
43 changes: 43 additions & 0 deletions src/video/windows/SDL_windowswindow.c
Expand Up @@ -479,6 +479,49 @@ WIN_SetWindowSize(_THIS, SDL_Window * window)
WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE);
}

int
WIN_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right)
{
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
RECT rcClient, rcWindow;
POINT ptDiff;

/* rcClient stores the size of the inner window, while rcWindow stores the outer size relative to the top-left
* screen position; so the top/left values of rcClient are always {0,0} and bottom/right are {height,width} */
GetClientRect(hwnd, &rcClient);
GetWindowRect(hwnd, &rcWindow);

/* convert the top/left values to make them relative to
* the window; they will end up being slightly negative */
ptDiff.y = rcWindow.top;
ptDiff.x = rcWindow.left;

ScreenToClient(hwnd, &ptDiff);

rcWindow.top = ptDiff.y;
rcWindow.left = ptDiff.x;

/* convert the bottom/right values to make them relative to the window,
* these will be slightly bigger than the inner width/height */
ptDiff.y = rcWindow.bottom;
ptDiff.x = rcWindow.right;

ScreenToClient(hwnd, &ptDiff);

rcWindow.bottom = ptDiff.y;
rcWindow.right = ptDiff.x;

/* Now that both the inner and outer rects use the same coordinate system we can substract them to get the border size.
* Keep in mind that the top/left coordinates of rcWindow are negative because the border lies slightly before {0,0},
* so switch them around because SDL2 wants them in positive. */
*top = rcClient.top - rcWindow.top;
*left = rcClient.left - rcWindow.left;
*bottom = rcWindow.bottom - rcClient.bottom;
*right = rcWindow.right - rcClient.right;

return 0;
}

void
WIN_ShowWindow(_THIS, SDL_Window * window)
{
Expand Down
1 change: 1 addition & 0 deletions src/video/windows/SDL_windowswindow.h
Expand Up @@ -58,6 +58,7 @@ extern void WIN_SetWindowTitle(_THIS, SDL_Window * window);
extern void WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
extern void WIN_SetWindowPosition(_THIS, SDL_Window * window);
extern void WIN_SetWindowSize(_THIS, SDL_Window * window);
extern int WIN_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right);
extern int WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
extern void WIN_ShowWindow(_THIS, SDL_Window * window);
extern void WIN_HideWindow(_THIS, SDL_Window * window);
Expand Down

0 comments on commit 7c60bec

Please sign in to comment.