From a882d7bcf23cbc6d9b4761d8b658915b7de980ad Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 31 Aug 2023 01:24:06 -0500 Subject: [PATCH] GUI: detect UI scale factor when moving window --- src/gui/gui.cpp | 36 ++++++++++++++++++++++++++++++++++-- src/gui/macstuff.h | 2 +- src/gui/macstuff.m | 25 +++++++++++++++++++++++-- src/gui/scaling.cpp | 41 ++++++++++++++++++++++++++++++++++------- src/gui/scaling.h | 2 +- src/gui/settings.cpp | 26 ++++++++++++++------------ 6 files changed, 107 insertions(+), 25 deletions(-) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 37efe4c7..5e774d21 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -3491,6 +3491,7 @@ bool FurnaceGUI::loop() { scrX=ev.window.data1; scrY=ev.window.data2; updateWindow=true; + shallDetectScale=2; logV("window moved to %dx%d",scrX,scrY); break; case SDL_WINDOWEVENT_SIZE_CHANGED: @@ -6140,7 +6141,38 @@ bool FurnaceGUI::loop() { if (shallDetectScale) { if (--shallDetectScale<1) { if (settings.dpiScale<0.5f) { - applyUISettings(); + const char* videoBackend=SDL_GetCurrentVideoDriver(); + double newScale=getScaleFactor(videoBackend,sdlWin); + if (newScale<0.1f) { + logW("scale what?"); + newScale=1.0f; + } + + if (newScale!=dpiScale) { + logD("auto UI scale changed (%f != %f) - applying settings...",newScale,dpiScale); + ImGui::GetIO().Fonts->Clear(); + + applyUISettings(); + + if (rend) rend->destroyFontsTexture(); + if (!ImGui::GetIO().Fonts->Build()) { + logE("error while building font atlas!"); + showError("error while loading fonts! please check your settings."); + ImGui::GetIO().Fonts->Clear(); + mainFont=ImGui::GetIO().Fonts->AddFontDefault(); + patFont=mainFont; + bigFont=mainFont; + headFont=mainFont; + if (rend) rend->destroyFontsTexture(); + if (!ImGui::GetIO().Fonts->Build()) { + logE("error again while building font atlas!"); + } else { + rend->createFontsTexture(); + } + } else { + rend->createFontsTexture(); + } + } } } } @@ -6368,7 +6400,7 @@ bool FurnaceGUI::init() { dpiScale=settings.dpiScale; } else { logD("auto-detecting UI scale factor."); - dpiScale=getScaleFactor(videoBackend); + dpiScale=getScaleFactor(videoBackend,sdlWin); logD("scale factor: %f",dpiScale); if (dpiScale<0.1f) { logW("scale what?"); diff --git a/src/gui/macstuff.h b/src/gui/macstuff.h index 76afff16..242abd17 100644 --- a/src/gui/macstuff.h +++ b/src/gui/macstuff.h @@ -17,4 +17,4 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -double getMacDPIScale(); +double getMacDPIScale(void* sysWin, unsigned char isUIKit); diff --git a/src/gui/macstuff.m b/src/gui/macstuff.m index 7d20c433..fe6d641a 100644 --- a/src/gui/macstuff.m +++ b/src/gui/macstuff.m @@ -20,7 +20,28 @@ #include #include "macstuff.h" -double getMacDPIScale() { - CGFloat val=[[NSScreen mainScreen] backingScaleFactor]; +double getMacDPIScale(void* sysWin, unsigned char isUIKit) { + NSScreen* screen=nil; + if (sysWin!=NULL) { + if (isUIKit) { + UIWindow* win=(UIWindow*)sysWin; + UIWindowScene* winScene=[win windowScene]; + if (winScene!=nil) { + UIScreen* winScreen=[winScene screen]; + CGFloat ret=[winScreen scale]; + return (double)ret; + } + } else { + NSWindow* win=(NSWindow*)sysWin; + screen=[win screen]; + } + } + if (screen==nil) { + screen=[NSScreen mainScreen]; + } + if (screen==nil) { + return 1.0; + } + CGFloat val=[screen backingScaleFactor]; return (double)val; } diff --git a/src/gui/scaling.cpp b/src/gui/scaling.cpp index e3d8d6f8..f122aac8 100644 --- a/src/gui/scaling.cpp +++ b/src/gui/scaling.cpp @@ -42,14 +42,23 @@ typedef int (*XDS)(void*); typedef int (*XDW)(void*,int); #endif -double getScaleFactor(const char* driverHint) { +double getScaleFactor(const char* driverHint, void* windowHint) { double ret=1.0; // Windows #ifdef _WIN32 POINT nullPoint; - nullPoint.x=-1; - nullPoint.y=-1; + if (windowHint!=NULL) { + int px=0; + int py=0; + + SDL_GetWindowPosition((SDL_Window*)windowHint,&px,&py); + nullPoint.x=px; + nullPoint.y=py; + } else { + nullPoint.x=-1; + nullPoint.y=-1; + } HMONITOR disp=MonitorFromPoint(nullPoint,MONITOR_DEFAULTTOPRIMARY); if (disp==NULL) { @@ -93,12 +102,30 @@ double getScaleFactor(const char* driverHint) { return ret; #endif - // macOS - backingScaleFactor + // macOS #ifdef __APPLE__ if (driverHint==NULL) { - return getMacDPIScale(); - } else if (strcmp(driverHint,"cocoa")==0 || strcmp(driverHint,"uikit")==0) { - return getMacDPIScale(); + return getMacDPIScale(NULL,false); + } else if (strcmp(driverHint,"cocoa")==0) { + void* nsWindow=NULL; + SDL_SysWMinfo wmInfo; + if (windowHint!=NULL) { + SDL_VERSION(&info.version) + if (SDL_GetWindowWMInfo((SDL_Window*)windowHint,&wmInfo)==SDL_TRUE) { + nsWindow=wmInfo.cocoa.window; + } + } + return getMacDPIScale(nsWindow,false); + } else if (strcmp(driverHint,"uikit")==0) { + void* uiWindow=NULL; + SDL_SysWMinfo wmInfo; + if (windowHint!=NULL) { + SDL_VERSION(&info.version) + if (SDL_GetWindowWMInfo((SDL_Window*)windowHint,&wmInfo)==SDL_TRUE) { + uiWindow=wmInfo.cocoa.window; + } + } + return getMacDPIScale(uiWindow,true); } #endif diff --git a/src/gui/scaling.h b/src/gui/scaling.h index 60710a34..be2c9f03 100644 --- a/src/gui/scaling.h +++ b/src/gui/scaling.h @@ -17,4 +17,4 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -double getScaleFactor(const char* driverHint); \ No newline at end of file +double getScaleFactor(const char* driverHint, void* windowHint); \ No newline at end of file diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 1c219d01..52d0008f 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -4153,18 +4153,20 @@ void FurnaceGUI::applyUISettings(bool updateFonts) { setupLabel(settings.emptyLabel.c_str(),emptyLabel,3); setupLabel(settings.emptyLabel2.c_str(),emptyLabel2,2); - // get scale factor - const char* videoBackend=SDL_GetCurrentVideoDriver(); - if (settings.dpiScale>=0.5f) { - logD("setting UI scale factor from config (%f).",settings.dpiScale); - dpiScale=settings.dpiScale; - } else { - logD("auto-detecting UI scale factor."); - dpiScale=getScaleFactor(videoBackend); - logD("scale factor: %f",dpiScale); - if (dpiScale<0.1f) { - logW("scale what?"); - dpiScale=1.0f; + if (updateFonts) { + // get scale factor + const char* videoBackend=SDL_GetCurrentVideoDriver(); + if (settings.dpiScale>=0.5f) { + logD("setting UI scale factor from config (%f).",settings.dpiScale); + dpiScale=settings.dpiScale; + } else { + logD("auto-detecting UI scale factor."); + dpiScale=getScaleFactor(videoBackend,sdlWin); + logD("scale factor: %f",dpiScale); + if (dpiScale<0.1f) { + logW("scale what?"); + dpiScale=1.0f; + } } }