diff --git a/runtime/include/window_fullscreen.h b/runtime/include/window_fullscreen.h index 2a74dd5c..741187c7 100644 --- a/runtime/include/window_fullscreen.h +++ b/runtime/include/window_fullscreen.h @@ -65,7 +65,13 @@ static inline int psx_window_fullscreen_set(SDL_Window* window, SDL_SetWindowBordered(window, SDL_FALSE); SDL_SetWindowResizable(window, SDL_FALSE); SDL_SetWindowPosition(window, desktop.x, desktop.y); - SDL_SetWindowSize(window, desktop.w, desktop.h); + /* One row taller than the display: a window exactly covering it is + * promoted by Windows to a direct/independent flip, and OpenGL swaps + * from the render thread then stop reaching the screen (NVIDIA: the + * image freezes while the game runs; any overlay -- taskbar, another + * window -- forces composition and the frames reappear). The extra + * row is off-screen; the window stays composed. */ + SDL_SetWindowSize(window, desktop.w, desktop.h + 1); SDL_SyncWindow(window); #elif defined(PSX_SDL3) if (!SDL_SetWindowFullscreen(window, true)) return -1; diff --git a/runtime/tests/test_window_fullscreen.cpp b/runtime/tests/test_window_fullscreen.cpp index a8229c5b..21af1d42 100644 --- a/runtime/tests/test_window_fullscreen.cpp +++ b/runtime/tests/test_window_fullscreen.cpp @@ -35,7 +35,8 @@ int main() { SDL_Rect bounds{}; SDL_GetDisplayBounds(SDL_GetDisplayForWindow(window), &bounds); int full_w, full_h; SDL_GetWindowSize(window, &full_w, &full_h); - check(full_w == bounds.w && full_h == bounds.h, "borderless covers the current display"); + check(full_w == bounds.w && full_h == bounds.h + 1, + "borderless covers the current display (one row over: stays composed)"); check(!SDL_CursorVisible(), "fullscreen cursor hidden"); SDL_DisplayMode current{}; check(SDL_GetCurrentDisplayMode(original_display, ¤t) == 0 &&