Fixed window positioning on Windows. TODO: Test again on Linux and MacOS.

This commit is contained in:
2026-05-28 20:09:50 -07:00
parent d2c6c337b7
commit 94e20cdff5
2 changed files with 59 additions and 16 deletions
+52 -16
View File
@@ -138,27 +138,56 @@ void DEBUGPlatformFreeFileMemory(thread_context *Thread, void *Memory)
free(Memory); // TODO: Should we accept debug_read_file_result instead of just memory.
}
static sdl_window_size SDLGetWindowSize(SDL_Window *Window)
static sdl_border_size SDLGetWindowBorderSizes(SDL_Window *Window)
{
sdl_border_size Result;
SDL_GetWindowBordersSize(Window, &Result.Top, &Result.Left, &Result.Bottom, &Result.Right);
return Result;
}
// NOTE: All SDL window functions (SDL_GetWindowSize, SDL_GetWindowPosition, SDL_SetWindowPosition, SDL_SetWindowSize)
// work ONLY with client area. This has some weird behavior with SDL_SetWindowPosition where SDLGetWindowBorderSizes
// reports left border (of 8 in our case), however it does not have that border in reality, so we ignore left and right borders.
// As a result, we ignore left and right borders, for now.
static sdl_window_size SDLGetBorderedWindowSize(SDL_Window *Window)
{
sdl_border_size Border = SDLGetWindowBorderSizes(Window);
sdl_window_size Dimension;
SDL_GetWindowSize(Window, &Dimension.Width, &Dimension.Height);
Dimension.Height += Border.Top + Border.Bottom;
// Dimension.Width += Border.Left + Border.Right;
return Dimension;
}
static sdl_window_position SDLGetWindowPosition(SDL_Window *Window)
static sdl_window_position SDLGetBorderedWindowPosition(SDL_Window *Window)
{
// NOTE: SDL_GetWindowPosition returns the client area position.
S32 top, left;
SDL_GetWindowBordersSize(Window, &top, &left, 0, 0);
sdl_border_size Border = SDLGetWindowBorderSizes(Window);
sdl_window_position Position;
SDL_GetWindowPosition(Window, &Position.X, &Position.Y);
Position.X -= left;
Position.Y -= top;
// Position.X -= Border.Left;
Position.Y -= Border.Top;
return Position;
}
static void SDLSetBorderedWindowPosition(SDL_Window *Window, S32 X, S32 Y)
{
sdl_border_size Border = SDLGetWindowBorderSizes(Window);
SDL_SetWindowPosition(Window, X, Y + Border.Top);
}
static void SDLSetBorderedWindowSize(SDL_Window *Window, S32 Width, S32 Height)
{
sdl_border_size Border = SDLGetWindowBorderSizes(Window);
// SDL_SetWindowSize(Window, Width - (Border.Left + Border.Right), Height - (Border.Top + Border.Bottom));
SDL_SetWindowSize(Window, Width, Height - (Border.Top + Border.Bottom));
}
static void SDLResizeTexture(offscreen_buffer *Buffer, SDL_Renderer *Renderer, int Width, int Height)
{
if(Buffer->Texture)
@@ -191,7 +220,7 @@ static void SDLDisplayBufferInWindow(offscreen_buffer *Buffer, SDL_Window *Windo
/* TODO: We temporarily introduce the target rectangle to avoid stretching the canvas. */
/* SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0); */
sdl_window_size WinSize = SDLGetWindowSize(Window);
sdl_window_size WinSize = SDLGetBorderedWindowSize(Window);
if(WinSize.Width >= Buffer->Width*2 && WinSize.Height >= Buffer->Height*2) {
SDL_Rect dest_rect = { OffsetX, OffsetY, Buffer->Width*2, Buffer->Height*2 };
SDL_RenderCopy(Renderer, Buffer->Texture, 0, (const SDL_Rect *)(&dest_rect));
@@ -315,16 +344,16 @@ static void SDLToggleFullscreen(SDL_Window *Window)
{
if(IsFullscreen) {
if(SDL_SetWindowFullscreen(Window, 0) == 0) {
SDL_SetWindowSize(Window, WindowSize.Width, WindowSize.Height);
SDL_SetWindowPosition(Window, WindowPosition.X, WindowPosition.Y);
SDLSetBorderedWindowSize(Window, WindowSize.Width, WindowSize.Height);
SDLSetBorderedWindowPosition(Window, WindowPosition.X, WindowPosition.Y);
IsFullscreen = FALSE;
} else {
/* TODO: This didn't work . . . SDL_GetError() */
}
} else {
WindowSize = SDLGetWindowSize(Window);
WindowPosition = SDLGetWindowPosition(Window);
WindowSize = SDLGetBorderedWindowSize(Window);
WindowPosition = SDLGetBorderedWindowPosition(Window);
if(SDL_SetWindowFullscreen(Window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) {
IsFullscreen = TRUE;
@@ -773,7 +802,7 @@ S32 main(S32 argc, char *argv[])
if(Window) {
SDL_DisplayMode display_mode;
SDL_GetCurrentDisplayMode(0, &display_mode);
SDL_GetCurrentDisplayMode(0, &display_mode); // Various display information.
SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC);
@@ -789,6 +818,10 @@ S32 main(S32 argc, char *argv[])
thread_context TempContext; // TODO:
memset(&TempContext, 0, sizeof(TempContext));
// TODO: It should be in the handmade layer. Expose the SDLSetProgramIcon to handmade layer the same way we expose file writing.
// This way, we can use all the drawing functions of handmade.
// https://learn.microsoft.com/en-us/windows/apps/design/iconography/app-icon-construction
// Probably, the icon size should be 256x256, so windows scales it properly. This buffer should be allocated into the arena.
loaded_bitmap ProgramIcon = DEBUGLoadBMPP(&TempContext, DEBUGPlatformReadEntireFile, "data/program_icon.bmp");
game_offscreen_buffer ProgramIconBuffer;
ProgramIconBuffer.Memory = malloc((ProgramIcon.Width * ProgramIcon.Height) * 4);
@@ -809,7 +842,11 @@ S32 main(S32 argc, char *argv[])
/* TODO: This didn't work . . . SDL_GetError() */
}
#endif
SDL_SetWindowPosition(Window, (display_mode.w - RESOLUTION_WIDTH-20), (display_mode.h - RESOLUTION_HEIGHT-20));
SDL_Rect UsableDisplayRect;
SDL_GetDisplayUsableBounds(0, &UsableDisplayRect);
sdl_window_size CurrentWindowSize = SDLGetBorderedWindowSize(Window);
SDLSetBorderedWindowPosition(Window, (UsableDisplayRect.x + UsableDisplayRect.w - CurrentWindowSize.Width), (UsableDisplayRect.y + UsableDisplayRect.h - CurrentWindowSize.Height));
GlobalRunning = TRUE;
@@ -828,8 +865,7 @@ S32 main(S32 argc, char *argv[])
SDL_PauseAudio(0); // TODO: This should be paused until we have some actual sound to play.
SoundOutput.Samples = calloc(SoundOutput.SamplesPerSecond, SoundOutput.BytesPerSample);
/* SoundOutput.Samples =
* malloc(SoundOutput.SecondaryBufferSize); */
/* SoundOutput.Samples = malloc(SoundOutput.SecondaryBufferSize); */
/* NOTE: calloc auto clears to zero */
/* SDLClearSoundBuffer(&SoundOutput); */