Mercurial > minori
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 |
rev | line source |
---|---|
9 | 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 | 4 #include <QOperatingSystemVersion> |
9 | 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 | 42 |
43 namespace win32 { | |
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 | 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 | 76 } |
77 | |
9 | 78 bool IsInDarkTheme() { |
15 | 79 QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", |
80 QSettings::NativeFormat); | |
9 | 81 return settings.value("AppsUseLightTheme", 1).toInt() == 0; |
2 | 82 } |
9 | 83 |
84 } // namespace win32 |