annotate src/sys/win32/dark_theme.cc @ 187:9613d72b097e

*: multiple performance improvements like marking `static const` when it makes sense... date: change old stupid heap-based method to a structure which should make copying the thing actually make a copy. also many performance-based changes, like removing the std::tie dependency and forward-declaring nlohmann json *: replace every instance of QString::fromUtf8 to Strings::ToQString. the main difference is that our function will always convert exactly what is in the string, while some other times it would only convert up to the nearest NUL byte
author Paper <mrpapersonic@gmail.com>
date Wed, 06 Dec 2023 13:43:54 -0500
parents bc8d2ccff09c
children f0ff06a45c42
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
1 #include "sys/win32/dark_theme.h"
178
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
2
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
3 #include <QApplication>
2
Paper <mrpapersonic@gmail.com>
parents: 1
diff changeset
4 #include <QOperatingSystemVersion>
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
5 #include <QSettings>
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
6 #include <QWidget>
178
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
7
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
8 #include <iostream>
178
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
9 #include <memory>
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
10
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
11 #include <dwmapi.h>
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
12
178
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
13 struct LibraryDeconstructor {
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
14 using pointer = HINSTANCE;
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
15 void operator()(pointer t) const { ::FreeLibrary(t); };
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
16 };
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
17
178
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
18 using Library = std::unique_ptr<HINSTANCE, LibraryDeconstructor>;
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
19
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
20 class Dwmapi {
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
21 public:
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
22 Dwmapi() { library.reset( ::LoadLibraryW(L"dwmapi.dll")); }
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
23
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
24 HRESULT SetWindowAttribute(HWND hWnd, DWORD key, LPCVOID data, DWORD sz_data) {
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
25 if (!library.get())
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
26 return E_POINTER;
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
27
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
28 /* GCC throws a fit here because C/C++ lacks a "generic" function pointer type.
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
29 Ignore. */
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
30 auto set_wind_attrib = reinterpret_cast<decltype(::DwmSetWindowAttribute)*>(GetProcAddress(library.get(), "DwmSetWindowAttribute"));
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
31 if (!set_wind_attrib)
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
32 return E_POINTER;
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
33
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
34 return set_wind_attrib(hWnd, key, data, sz_data);
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
35 }
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
36
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
37 protected:
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
38 Library library = nullptr;
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
39 };
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
40
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
41 Dwmapi dwmapi;
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
42
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
43 namespace win32 {
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
44
178
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
45 /* NOTE: explicit conversion from builtin `bool` and win32 `BOOL` IS allowed. */
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
46 bool SetTitleBarToBlack(QWidget* win, bool enabled) {
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
47 BOOL b = enabled;
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
48
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
49 /* MAGIC NUMBERS: 19 and 20 are both DWMWA_USE_IMMERSIVE_DARK_MODE.
178
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
50 For clarification: it's 20 on newer versions of windows (i.e. win11 and late win10),
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
51 but it's 19 on very old versions of win10 nobody ought to be using anymore. */
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
52 {
178
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
53 HRESULT result = dwmapi.SetWindowAttribute(reinterpret_cast<HWND>(win->winId()), 20, &b, sizeof(b));
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
54 if (result == S_OK)
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
55 return b;
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
56 }
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
57
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
58 {
178
bc8d2ccff09c win32/dark: use existing STL classes for dwmapi
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
59 HRESULT result = dwmapi.SetWindowAttribute(reinterpret_cast<HWND>(win->winId()), 19, &b, sizeof(b));
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
60 if (result == S_OK)
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
61 return b;
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
62 }
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
63
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
64 return b;
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
65 }
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
66
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
67 void SetTitleBarsToBlack(bool enabled) {
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
68 for (QWidget* widget : qApp->topLevelWidgets()) {
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
69 SetTitleBarToBlack(widget, enabled);
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
70 }
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
71 }
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
72
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
73 bool DarkThemeAvailable() {
66
6481c5aed3e1 posters: add poster widget...
Paper <mrpapersonic@gmail.com>
parents: 15
diff changeset
74 const auto& ver = QOperatingSystemVersion::current();
6481c5aed3e1 posters: add poster widget...
Paper <mrpapersonic@gmail.com>
parents: 15
diff changeset
75 return (ver.majorVersion() > 10) ? true : (ver.majorVersion() == 10 && ver.microVersion() >= 17763);
2
Paper <mrpapersonic@gmail.com>
parents: 1
diff changeset
76 }
Paper <mrpapersonic@gmail.com>
parents: 1
diff changeset
77
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
78 bool IsInDarkTheme() {
15
cde8f67a7c7d *: update, megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 9
diff changeset
79 QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
cde8f67a7c7d *: update, megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 9
diff changeset
80 QSettings::NativeFormat);
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
81 return settings.value("AppsUseLightTheme", 1).toInt() == 0;
2
Paper <mrpapersonic@gmail.com>
parents: 1
diff changeset
82 }
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
83
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
84 } // namespace win32