Mercurial > minori
annotate src/sys/osx/dark_theme.cc @ 273:f31305b9f60a
*: various code safety changes
this also makes the code build on Qt 5.7. I can't test it though
because I don't have it working... FAIL!
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Thu, 18 Apr 2024 16:53:17 -0400 |
parents | 862d0d8619f6 |
children | 22f9aacf6ac1 |
rev | line source |
---|---|
194
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
1 #include "sys/osx/dark_theme.h" |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
2 |
258 | 3 #include <objc/message.h> |
194
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
4 #include <objc/runtime.h> |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
5 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
6 #include <CoreFoundation/CoreFoundation.h> |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
7 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
8 namespace osx { |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
9 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
10 typedef id (*object_message_send)(id, SEL, ...); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
11 typedef id (*class_message_send)(Class, SEL, ...); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
12 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
13 static const object_message_send obj_send = reinterpret_cast<object_message_send>(objc_msgSend); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
14 static const class_message_send cls_send = reinterpret_cast<class_message_send>(objc_msgSend); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
15 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
16 static CFStringRef NSAppearanceNameAqua = nullptr; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
17 static CFStringRef NSAppearanceNameDarkAqua = nullptr; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
18 |
195
975a3f0965e2
locale: only attempt loading locales after QApplication is init'd
Paper <mrpapersonic@gmail.com>
parents:
194
diff
changeset
|
19 static const CFStringRef kAppKitBundleID = CFSTR("com.apple.AppKit"); |
194
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
20 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
21 bool RetrieveAppearanceNames() { |
195
975a3f0965e2
locale: only attempt loading locales after QApplication is init'd
Paper <mrpapersonic@gmail.com>
parents:
194
diff
changeset
|
22 CFBundleRef appkit_bundle = CFBundleGetBundleWithIdentifier(kAppKitBundleID); |
194
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
23 if (!appkit_bundle) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
24 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
25 |
258 | 26 NSAppearanceNameAqua = |
27 *reinterpret_cast<CFStringRef*>(CFBundleGetDataPointerForName(appkit_bundle, CFSTR("NSAppearanceNameAqua"))); | |
194
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
28 if (!NSAppearanceNameAqua) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
29 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
30 |
258 | 31 NSAppearanceNameDarkAqua = *reinterpret_cast<CFStringRef*>( |
32 CFBundleGetDataPointerForName(appkit_bundle, CFSTR("NSAppearanceNameDarkAqua"))); | |
194
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
33 if (!NSAppearanceNameDarkAqua) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
34 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
35 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
36 return true; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
37 } |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
38 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
39 bool DarkThemeAvailable() { |
273
f31305b9f60a
*: various code safety changes
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
40 return (__builtin_available(macOS 10.14, *)); |
194
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
41 } |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
42 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
43 bool IsInDarkTheme() { |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
44 if (!DarkThemeAvailable()) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
45 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
46 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
47 if (!NSAppearanceNameAqua || !NSAppearanceNameDarkAqua) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
48 if (!RetrieveAppearanceNames()) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
49 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
50 |
196
f0ff06a45c42
date: use std::optional for values
Paper <mrpapersonic@gmail.com>
parents:
195
diff
changeset
|
51 // NSArray* array = @[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]; |
194
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
52 CFArrayRef array = []() -> CFArrayRef { |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
53 CFStringRef refs[] = {NSAppearanceNameAqua, NSAppearanceNameDarkAqua}; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
54 return CFArrayCreate(NULL, reinterpret_cast<const void**>(refs), 2, &kCFTypeArrayCallBacks); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
55 }(); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
56 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
57 // NSApplication* app = [NSApplication sharedApplication]; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
58 const id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication")); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
59 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
60 // NSAppearance* effectiveAppearance = [app effectiveAppearance]; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
61 const id effectiveAppearance = obj_send(app, sel_getUid("effectiveAppearance")); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
62 if (!effectiveAppearance) { |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
63 CFRelease(array); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
64 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
65 } |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
66 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
67 // NSAppearance* appearance = [effectiveAppearance bestMatchFromAppearancesWithNames: array]; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
68 const id appearance = obj_send(effectiveAppearance, sel_getUid("bestMatchFromAppearancesWithNames:"), array); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
69 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
70 CFRelease(array); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
71 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
72 if (!appearance) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
73 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
74 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
75 return CFEqual(appearance, NSAppearanceNameDarkAqua); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
76 } |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
77 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
78 bool SetToDarkTheme() { |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
79 // https://stackoverflow.com/questions/55925862/how-can-i-set-my-os-x-application-theme-in-code |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
80 if (!DarkThemeAvailable()) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
81 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
82 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
83 if (!NSAppearanceNameAqua || !NSAppearanceNameDarkAqua) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
84 if (!RetrieveAppearanceNames()) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
85 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
86 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
87 // NSApplication* app = [NSApplication sharedApplication]; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
88 const id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication")); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
89 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
90 // NSAppearance* appearance = [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua]; |
258 | 91 const id appearance = |
92 cls_send(objc_getClass("NSAppearance"), sel_getUid("appearanceNamed:"), NSAppearanceNameDarkAqua); | |
194
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
93 if (!appearance) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
94 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
95 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
96 // [app setAppearance: appearance]; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
97 obj_send(app, sel_getUid("setAppearance:"), appearance); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
98 return true; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
99 } |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
100 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
101 bool SetToLightTheme() { |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
102 // https://stackoverflow.com/questions/55925862/how-can-i-set-my-os-x-application-theme-in-code |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
103 if (!DarkThemeAvailable()) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
104 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
105 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
106 if (!NSAppearanceNameAqua || !NSAppearanceNameDarkAqua) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
107 if (!RetrieveAppearanceNames()) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
108 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
109 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
110 // NSApplication* app = [NSApplication sharedApplication]; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
111 const id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication")); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
112 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
113 // NSAppearance* appearance = [NSAppearance appearanceNamed: NSAppearanceNameDarkAqua]; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
114 const id appearance = cls_send(objc_getClass("NSAppearance"), sel_getUid("appearanceNamed:"), NSAppearanceNameAqua); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
115 if (!appearance) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
116 return false; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
117 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
118 // [app setAppearance: appearance]; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
119 obj_send(app, sel_getUid("setAppearance:"), appearance); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
120 return true; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
121 } |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
122 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
123 void SetToAutoTheme() { |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
124 if (!DarkThemeAvailable()) |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
125 return; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
126 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
127 // NSApplication* app = [NSApplication sharedApplication]; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
128 const id app = cls_send(objc_getClass("NSApplication"), sel_getUid("sharedApplication")); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
129 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
130 // [app setAppearance: null]; |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
131 obj_send(app, sel_getUid("setAppearance:"), nullptr); |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
132 } |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
133 |
8548dc425697
sys/osx: remove all objective-c++ stuff
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
134 } // namespace osx |