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. 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_window_size Dimension;
SDL_GetWindowSize(Window, &Dimension.Width, &Dimension.Height); SDL_GetWindowSize(Window, &Dimension.Width, &Dimension.Height);
Dimension.Height += Border.Top + Border.Bottom;
// Dimension.Width += Border.Left + Border.Right;
return Dimension; 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. sdl_border_size Border = SDLGetWindowBorderSizes(Window);
S32 top, left;
SDL_GetWindowBordersSize(Window, &top, &left, 0, 0);
sdl_window_position Position; sdl_window_position Position;
SDL_GetWindowPosition(Window, &Position.X, &Position.Y); SDL_GetWindowPosition(Window, &Position.X, &Position.Y);
Position.X -= left; // Position.X -= Border.Left;
Position.Y -= top; Position.Y -= Border.Top;
return Position; 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) static void SDLResizeTexture(offscreen_buffer *Buffer, SDL_Renderer *Renderer, int Width, int Height)
{ {
if(Buffer->Texture) 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. */ /* TODO: We temporarily introduce the target rectangle to avoid stretching the canvas. */
/* SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0); */ /* 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) { if(WinSize.Width >= Buffer->Width*2 && WinSize.Height >= Buffer->Height*2) {
SDL_Rect dest_rect = { OffsetX, OffsetY, Buffer->Width*2, 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)); SDL_RenderCopy(Renderer, Buffer->Texture, 0, (const SDL_Rect *)(&dest_rect));
@@ -315,16 +344,16 @@ static void SDLToggleFullscreen(SDL_Window *Window)
{ {
if(IsFullscreen) { if(IsFullscreen) {
if(SDL_SetWindowFullscreen(Window, 0) == 0) { if(SDL_SetWindowFullscreen(Window, 0) == 0) {
SDL_SetWindowSize(Window, WindowSize.Width, WindowSize.Height); SDLSetBorderedWindowSize(Window, WindowSize.Width, WindowSize.Height);
SDL_SetWindowPosition(Window, WindowPosition.X, WindowPosition.Y); SDLSetBorderedWindowPosition(Window, WindowPosition.X, WindowPosition.Y);
IsFullscreen = FALSE; IsFullscreen = FALSE;
} else { } else {
/* TODO: This didn't work . . . SDL_GetError() */ /* TODO: This didn't work . . . SDL_GetError() */
} }
} else { } else {
WindowSize = SDLGetWindowSize(Window); WindowSize = SDLGetBorderedWindowSize(Window);
WindowPosition = SDLGetWindowPosition(Window); WindowPosition = SDLGetBorderedWindowPosition(Window);
if(SDL_SetWindowFullscreen(Window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) { if(SDL_SetWindowFullscreen(Window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) {
IsFullscreen = TRUE; IsFullscreen = TRUE;
@@ -773,7 +802,7 @@ S32 main(S32 argc, char *argv[])
if(Window) { if(Window) {
SDL_DisplayMode display_mode; 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); SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC);
@@ -789,6 +818,10 @@ S32 main(S32 argc, char *argv[])
thread_context TempContext; // TODO: thread_context TempContext; // TODO:
memset(&TempContext, 0, sizeof(TempContext)); 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"); loaded_bitmap ProgramIcon = DEBUGLoadBMPP(&TempContext, DEBUGPlatformReadEntireFile, "data/program_icon.bmp");
game_offscreen_buffer ProgramIconBuffer; game_offscreen_buffer ProgramIconBuffer;
ProgramIconBuffer.Memory = malloc((ProgramIcon.Width * ProgramIcon.Height) * 4); 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() */ /* TODO: This didn't work . . . SDL_GetError() */
} }
#endif #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; 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. 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 = calloc(SoundOutput.SamplesPerSecond, SoundOutput.BytesPerSample);
/* SoundOutput.Samples = /* SoundOutput.Samples = malloc(SoundOutput.SecondaryBufferSize); */
* malloc(SoundOutput.SecondaryBufferSize); */
/* NOTE: calloc auto clears to zero */ /* NOTE: calloc auto clears to zero */
/* SDLClearSoundBuffer(&SoundOutput); */ /* SDLClearSoundBuffer(&SoundOutput); */
+7
View File
@@ -6,6 +6,13 @@
#include "core.h" #include "core.h"
#include "handmade.h" #include "handmade.h"
typedef struct sdl_border_size {
S32 Top;
S32 Bottom;
S32 Left;
S32 Right;
} sdl_border_size;
typedef struct sdl_window_size { typedef struct sdl_window_size {
S32 Width; S32 Width;
S32 Height; S32 Height;