@@ -51,6 +51,7 @@ class sys_video_c : public sys_IVideo {
51
51
sys_main_c* sys = nullptr ;
52
52
53
53
bool initialised = false ;
54
+ bool ignoreDpiScale = false ;
54
55
GLFWwindow* wnd = nullptr ;
55
56
56
57
void RefreshMonitorInfo ();
@@ -278,6 +279,63 @@ struct sys_programIcons_c {
278
279
std::deque<std::vector<uint8_t >> imageDatas;
279
280
};
280
281
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
+
281
339
// ==================
282
340
// System Video Class
283
341
// ==================
@@ -383,6 +441,7 @@ int sys_video_c::Apply(sys_vidSet_s* set)
383
441
}
384
442
}
385
443
else {
444
+ ignoreDpiScale = ShouldIgnoreDpiScale ();
386
445
glfwWindowHint (GLFW_RESIZABLE, !!(cur.flags & VID_RESIZABLE));
387
446
glfwWindowHint (GLFW_VISIBLE, GLFW_FALSE); // Start hidden to not flash the user with a stock window.
388
447
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)
551
610
});
552
611
glfwSetWindowContentScaleCallback (wnd, [](GLFWwindow* wnd, float xScale, float yScale) {
553
612
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
+ }
555
617
});
556
618
557
619
// Adjust window look and position
@@ -576,7 +638,9 @@ int sys_video_c::Apply(sys_vidSet_s* set)
576
638
577
639
glfwGetFramebufferSize (wnd, &vid.fbSize [0 ], &vid.fbSize [1 ]);
578
640
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
+ }
580
644
581
645
initialised = true ;
582
646
return 0 ;
0 commit comments