annotate src/sys/win32/dark_theme.cc @ 198:bc1ae1810855

dep/animia: switch from using classes to global functions the old idea was ok, but sort of hackish; this method doesn't use classes at all, and this way (especially important!) we can do wayland stuff AND x11 at the same time, which wasn't really possible without stupid workarounds in the other method
author Paper <mrpapersonic@gmail.com>
date Sun, 24 Dec 2023 02:59:42 -0500
parents f0ff06a45c42
children 862d0d8619f6
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
196
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
28 // GCC throws a fit here because C/C++ lacks a "generic" function pointer type.
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
29 // Ignore.
178
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
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
45 bool SetTitleBarToBlack(QWidget* win, bool enabled) {
196
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
46 /* 19 and 20 are *both* DWMWA_USE_IMMERSIVE_DARK_MODE.
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
47 *
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
48 * It's 20 on newer versions of windows (i.e. win11 and late win10),
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
49 * but it's 19 on very old versions of win10 nobody ought to be using anymore.
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
50 */
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
51 static constexpr DWORD DWMWA_USE_IMMERSIVE_DARK_MODE_OLD = 19;
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
52 static constexpr DWORD DWMWA_USE_IMMERSIVE_DARK_MODE = 20;
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
53
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
54 BOOL b = enabled;
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
55
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
56 {
196
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
57 HRESULT result = dwmapi.SetWindowAttribute(reinterpret_cast<HWND>(win->winId()), DWMWA_USE_IMMERSIVE_DARK_MODE, &b, sizeof(b));
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
58 if (result == S_OK)
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
59 return b;
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
60 }
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
61
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
62 {
196
f0ff06a45c42 date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents: 178
diff changeset
63 HRESULT result = dwmapi.SetWindowAttribute(reinterpret_cast<HWND>(win->winId()), DWMWA_USE_IMMERSIVE_DARK_MODE_OLD, &b, sizeof(b));
105
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
64 if (result == S_OK)
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
65 return b;
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
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
68 return b;
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
69 }
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 void SetTitleBarsToBlack(bool enabled) {
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
72 for (QWidget* widget : qApp->topLevelWidgets()) {
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
73 SetTitleBarToBlack(widget, enabled);
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
74 }
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
75 }
6d8da6e64d61 theme: add dark stylesheet, make it actually usable
Paper <mrpapersonic@gmail.com>
parents: 81
diff changeset
76
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
77 bool DarkThemeAvailable() {
66
6481c5aed3e1 posters: add poster widget...
Paper <mrpapersonic@gmail.com>
parents: 15
diff changeset
78 const auto& ver = QOperatingSystemVersion::current();
6481c5aed3e1 posters: add poster widget...
Paper <mrpapersonic@gmail.com>
parents: 15
diff changeset
79 return (ver.majorVersion() > 10) ? true : (ver.majorVersion() == 10 && ver.microVersion() >= 17763);
2
Paper <mrpapersonic@gmail.com>
parents: 1
diff changeset
80 }
Paper <mrpapersonic@gmail.com>
parents: 1
diff changeset
81
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
82 bool IsInDarkTheme() {
15
cde8f67a7c7d *: update, megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 9
diff changeset
83 QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
cde8f67a7c7d *: update, megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 9
diff changeset
84 QSettings::NativeFormat);
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
85 return settings.value("AppsUseLightTheme", 1).toInt() == 0;
2
Paper <mrpapersonic@gmail.com>
parents: 1
diff changeset
86 }
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
87
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 2
diff changeset
88 } // namespace win32