@@ -51,6 +51,7 @@ class sys_video_c : public sys_IVideo {
5151 sys_main_c* sys = nullptr ;
5252
5353 bool initialised = false ;
54+ bool ignoreDpiScale = false ;
5455 GLFWwindow* wnd = nullptr ;
5556
5657 void RefreshMonitorInfo ();
@@ -278,6 +279,63 @@ struct sys_programIcons_c {
278279 std::deque<std::vector<uint8_t >> imageDatas;
279280};
280281
282+ bool ShouldIgnoreDpiScale () {
283+ #ifdef _WIN32
284+ std::wstring const appChoice = L" HIGHDPIAWARE" , sysChoice = L" DPIUNAWARE" , enhanceFlag = L" GDIDPISCALING" ;
285+ std::wstring const subKey = LR"( Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers)" ;
286+
287+ std::vector<wchar_t > progStr (1 << 16 );
288+ GetModuleFileNameW (NULL , progStr.data (), progStr.size ());
289+ std::filesystem::path progPath (progStr.data ());
290+ progPath = std::filesystem::canonical (progPath);
291+
292+ auto considerKey = [&](HKEY rootKey) -> std::optional<bool > {
293+ std::vector<wchar_t > valData (1 << 16 );
294+ DWORD valType{}, valSize = valData.size () / 2 ;
295+ LRESULT res = RegGetValueW (rootKey, subKey.c_str (), progPath.wstring ().c_str (), RRF_RT_REG_SZ, &valType, valData.data (), &valSize);
296+ if (res == ERROR_SUCCESS) {
297+ std::wstring val = valData.data ();
298+ if (wcsstr (val.c_str (), appChoice.c_str ())) {
299+ return true ;
300+ }
301+ else if (wcsstr (val.c_str (), sysChoice.c_str ())) {
302+ return false ;
303+ }
304+ }
305+ return {};
306+ };
307+
308+ struct ScopedRegKey {
309+ HKEY key{};
310+
311+ ScopedRegKey& operator = (ScopedRegKey const &) = delete ;
312+ ScopedRegKey (ScopedRegKey const &) = delete ;
313+ ~ScopedRegKey () {
314+ if (key) { RegCloseKey (key); }
315+ }
316+
317+ HKEY* operator & () { return &key; }
318+ operator HKEY () const { return key; }
319+ };
320+
321+ // Prioritize the global setting over the user setting to follow Windows' semantics.
322+ ScopedRegKey hklm{};
323+ if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, nullptr , 0 , KEY_READ, &hklm) == ERROR_SUCCESS) {
324+ if (auto ignore = considerKey (hklm)) {
325+ return *ignore;
326+ }
327+ }
328+
329+ ScopedRegKey hkcu{};
330+ if (RegOpenCurrentUser (KEY_READ, &hkcu) == ERROR_SUCCESS) {
331+ if (auto ignore = considerKey (hkcu)) {
332+ return *ignore;
333+ }
334+ }
335+ #endif
336+ return false ;
337+ }
338+
281339// ==================
282340// System Video Class
283341// ==================
@@ -383,6 +441,7 @@ int sys_video_c::Apply(sys_vidSet_s* set)
383441 }
384442 }
385443 else {
444+ ignoreDpiScale = ShouldIgnoreDpiScale ();
386445 glfwWindowHint (GLFW_RESIZABLE, !!(cur.flags & VID_RESIZABLE));
387446 glfwWindowHint (GLFW_VISIBLE, GLFW_FALSE); // Start hidden to not flash the user with a stock window.
388447 glfwWindowHint (GLFW_MAXIMIZED, GLFW_FALSE); // Start restored in order to position the window before maximizing.
@@ -551,7 +610,10 @@ int sys_video_c::Apply(sys_vidSet_s* set)
551610 });
552611 glfwSetWindowContentScaleCallback (wnd, [](GLFWwindow* wnd, float xScale, float yScale) {
553612 auto sys = (sys_main_c*)glfwGetWindowUserPointer (wnd);
554- sys->video ->vid .dpiScale = xScale;
613+ auto video = (sys_video_c*)sys->video ;
614+ if (!video->ignoreDpiScale ) {
615+ video->vid .dpiScale = xScale;
616+ }
555617 });
556618
557619 // Adjust window look and position
@@ -576,7 +638,9 @@ int sys_video_c::Apply(sys_vidSet_s* set)
576638
577639 glfwGetFramebufferSize (wnd, &vid.fbSize [0 ], &vid.fbSize [1 ]);
578640 glfwGetWindowSize (wnd, &vid.size [0 ], &vid.size [1 ]);
579- glfwGetWindowContentScale (wnd, &sys->video ->vid .dpiScale , nullptr );
641+ if (!ignoreDpiScale) {
642+ glfwGetWindowContentScale (wnd, &sys->video ->vid .dpiScale , nullptr );
643+ }
580644
581645 initialised = true ;
582646 return 0 ;
0 commit comments