From 0a57812968539176bbeaa76c61532d0d6dec4881 Mon Sep 17 00:00:00 2001 From: Spodi Date: Sun, 6 Aug 2023 19:40:21 +0200 Subject: [PATCH] Window positon tweaks and fullscreen in OpenGL (#333) * Fixed window pos not restored with OpenGL * Fixed fullscreen in OpenGL (again) Fixes going full screen on the next monitor when the game was on the second half of the screen. * Set Fullscreen state only when call succeeds Also some logging so we hopefully know why it failed. * Consistent behavior for getting monitor SDL always gets the monitor at the middle of the window. Now DXGI does too. Also only resets the position if there is no pixel of the window on any screen. * also get current monitor on resize (DirectX) * Correct typo Co-authored-by: Kenix3 --------- Co-authored-by: Kenix3 --- src/graphic/Fast3D/gfx_dxgi.cpp | 39 ++++++++++++++++++++++++++++----- src/graphic/Fast3D/gfx_sdl2.cpp | 36 +++++++++++++++++------------- 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/src/graphic/Fast3D/gfx_dxgi.cpp b/src/graphic/Fast3D/gfx_dxgi.cpp index 887fe4c53..441a2d33b 100644 --- a/src/graphic/Fast3D/gfx_dxgi.cpp +++ b/src/graphic/Fast3D/gfx_dxgi.cpp @@ -197,11 +197,12 @@ std::vector> GetMonitorList() { } // Uses coordinates to get a Monitor handle from a list -bool GetMonitorAtCoords(std::vector> MonitorList, int x, int y, +bool GetMonitorAtCoords(std::vector> MonitorList, int x, int y, UINT cx, UINT cy, std::tuple& MonitorInfo) { + RECT wr = { x, y, (x + cx), (y + cy) }; std::tuple primary; for (std::tuple i : MonitorList) { - if (PtInRect(&get<1>(i), POINT(x, y))) { + if (PtInRect(&get<1>(i), POINT((x + (cx / 2)), (y + (cy / 2))))) { MonitorInfo = i; return true; } @@ -209,6 +210,23 @@ bool GetMonitorAtCoords(std::vector> MonitorLis primary = i; } } + RECT intersection; + LONG area; + LONG lastArea = 0; + std::tuple biggest; + for (std::tuple i : MonitorList) { + if (IntersectRect(&intersection, &get<1>(i), &wr)) { + area = (intersection.right - intersection.left) * (intersection.bottom - intersection.top); + if (area > lastArea) { + lastArea = area; + biggest = i; + } + } + } + if (lastArea > 0) { + MonitorInfo = biggest; + return true; + } MonitorInfo = primary; // Fallback to primary, when out of bounds. return false; } @@ -237,7 +255,7 @@ static void toggle_borderless_window_full_screen(bool enable, bool call_callback dxgi.current_height = conf->GetInt("Window.Height", 480); dxgi.posX = conf->GetInt("Window.PositionX", 100); dxgi.posY = conf->GetInt("Window.PositionY", 100); - if (!GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, + if (!GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.current_width, dxgi.current_height, Monitor)) { // Fallback to default when out of bounds. dxgi.posX = 100; dxgi.posY = 100; @@ -340,11 +358,18 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par case WM_SIZE: dxgi.current_width = LOWORD(l_param); dxgi.current_height = HIWORD(l_param); + GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.current_width, dxgi.current_height, + newMonitor); + if (get<0>(newMonitor) != get<0>(dxgi.h_Monitor)) { + dxgi.h_Monitor = newMonitor; + GetMonitorHzPeriod(dxgi.h_Monitor, dxgi.detected_hz, dxgi.display_period); + } break; case WM_MOVE: dxgi.posX = GET_X_LPARAM(l_param); dxgi.posY = GET_Y_LPARAM(l_param); - GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, newMonitor); + GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.current_width, dxgi.current_height, + newMonitor); if (get<0>(newMonitor) != get<0>(dxgi.h_Monitor)) { dxgi.h_Monitor = newMonitor; GetMonitorHzPeriod(dxgi.h_Monitor, dxgi.detected_hz, dxgi.display_period); @@ -389,7 +414,8 @@ static LRESULT CALLBACK gfx_dxgi_wnd_proc(HWND h_wnd, UINT message, WPARAM w_par break; case WM_DISPLAYCHANGE: dxgi.monitor_list = GetMonitorList(); - GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.h_Monitor); + GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.current_width, dxgi.current_height, + dxgi.h_Monitor); GetMonitorHzPeriod(dxgi.h_Monitor, dxgi.detected_hz, dxgi.display_period); break; default: @@ -452,7 +478,8 @@ void gfx_dxgi_init(const char* game_name, const char* gfx_api_name, bool start_i dxgi.monitor_list = GetMonitorList(); dxgi.posX = posX; dxgi.posY = posY; - if (!GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.h_Monitor)) { + if (!GetMonitorAtCoords(dxgi.monitor_list, dxgi.posX, dxgi.posY, dxgi.current_width, dxgi.current_height, + dxgi.h_Monitor)) { dxgi.posX = 100; dxgi.posY = 100; } diff --git a/src/graphic/Fast3D/gfx_sdl2.cpp b/src/graphic/Fast3D/gfx_sdl2.cpp index e308447f5..efe220050 100644 --- a/src/graphic/Fast3D/gfx_sdl2.cpp +++ b/src/graphic/Fast3D/gfx_sdl2.cpp @@ -223,20 +223,21 @@ static void set_fullscreen(bool on, bool call_callback) { if (fullscreen_state == on) { return; } - fullscreen_state = on; int display_in_use = SDL_GetWindowDisplayIndex(wnd); - SDL_DisplayMode mode; if (display_in_use < 0) { - SDL_GetDesktopDisplayMode(0, &mode); - } else { - SDL_GetDesktopDisplayMode(display_in_use, &mode); + SPDLOG_WARN("Can't detect on which monitor we are. Probably out of display area?"); + SPDLOG_WARN(SDL_GetError()); } if (on) { // OTRTODO: Get mode from config. - window_width = mode.w; - window_height = mode.h; - SDL_ShowCursor(false); + SDL_DisplayMode mode; + if (SDL_GetDesktopDisplayMode(display_in_use, &mode) >= 0) { + SDL_SetWindowDisplayMode(wnd, &mode); + SDL_ShowCursor(false); + } else { + SPDLOG_ERROR(SDL_GetError()); + } } else { auto conf = LUS::Context::GetInstance()->GetConfig(); window_width = conf->GetInt("Window.Width", 640); @@ -248,11 +249,16 @@ static void set_fullscreen(bool on, bool call_callback) { posY = 100; } SDL_SetWindowPosition(wnd, posX, posY); + SDL_SetWindowSize(wnd, window_width, window_height); + } + if (SDL_SetWindowFullscreen(wnd, on ? (CVarGetInteger("gSdlWindowedFullscreen", 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP + : SDL_WINDOW_FULLSCREEN) + : 0) >= 0) { + fullscreen_state = on; + } else { + SPDLOG_ERROR("Failed to switch from or to fullscreen mode."); + SPDLOG_ERROR(SDL_GetError()); } - SDL_SetWindowSize(wnd, window_width, window_height); - SDL_SetWindowFullscreen( - wnd, - on ? (CVarGetInteger("gSdlWindowedFullscreen", 0) ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN) : 0); SDL_SetCursor(SDL_DISABLE); if (on_fullscreen_changed_callback != NULL && call_callback) { @@ -333,15 +339,15 @@ static void gfx_sdl_init(const char* game_name, const char* gfx_api_name, bool s flags = flags | SDL_WINDOW_METAL; } + wnd = SDL_CreateWindow(title, posX, posY, window_width, window_height, flags); + LUS::GuiWindowInitData window_impl; + int display_in_use = SDL_GetWindowDisplayIndex(wnd); if (display_in_use < 0) { // Fallback to default if out of bounds posX = 100; posY = 100; } - wnd = SDL_CreateWindow(title, posX, posY, window_width, window_height, flags); - LUS::GuiWindowInitData window_impl; - if (use_opengl) { #ifndef __SWITCH__ SDL_GL_GetDrawableSize(wnd, &window_width, &window_height);