comparison src/sys/glib/dark_theme.cc @ 350:daa03aa2262d

sys/glib: general cleanup, use C++ principles, add more suffixes
author Paper <paper@paper.us.eu.org>
date Sun, 14 Jul 2024 19:12:40 -0400
parents ac1451035c85
children c844f8bb87ce
comparison
equal deleted inserted replaced
348:6b0768158dcd 350:daa03aa2262d
1 #include "sys/glib/dark_theme.h"
2
1 #include <cstring> 3 #include <cstring>
2 #include <gio/gio.h> 4 #include <gio/gio.h>
3 #include <string_view> 5 #include <string_view>
4 6 #include <memory>
5 /* this file uses the regular gio C interface because I don't 7 #include <array>
6 * see any real benefit to using the C++ bindings. */
7 8
8 namespace glib { 9 namespace glib {
9 10
11 /* deleters */
12 template<typename T>
13 struct g_object_del {
14 void operator()(T* p) const { ::g_object_unref(p); };
15 };
16
17 template<typename T>
18 struct g_variant_del {
19 void operator()(T* p) const { ::g_variant_unref(p); };
20 };
21
22 template<typename T>
23 struct g_malloc_del {
24 void operator()(T* p) const { ::g_free(p); };
25 };
26
27 template<typename T>
28 using GObjectPtr = std::unique_ptr<T, g_object_del<T>>;
29
30 template<typename T>
31 using GVariantPtr = std::unique_ptr<T, g_variant_del<T>>;
32
33 template<typename T>
34 using GMallocPtr = std::unique_ptr<T, g_malloc_del<T>>;
35
10 bool IsInDarkTheme() { 36 bool IsInDarkTheme() {
11 GSettings* settings = ::g_settings_new("org.gnome.desktop.interface"); 37 GObjectPtr<GSettings> settings(::g_settings_new("org.gnome.desktop.interface"));
12 if (!settings) 38 if (!settings)
13 return false; 39 return false;
14 40
15 { 41 {
16 GVariant* val = ::g_settings_get_value(settings, "color-scheme"); 42 /* first attempt to get the colorscheme */
17 if (!val) { 43 GVariantPtr<GVariant> val(::g_settings_get_value(settings.get(), "color-scheme"));
18 ::g_object_unref(settings); 44 if (!val)
19 return false; 45 return false;
20 }
21 46
22 const gchar* str = nullptr; 47 /* this is free'd upon deconstruction of the GVariantPtr */
23 ::g_variant_get(val, "&s", &str); /* should not be freed */ 48 gsize size;
24 if (!str) { /* how */ 49 const gchar* str = ::g_variant_get_string(val.get(), &size);
25 ::g_variant_unref(val); 50 if (!str)
26 ::g_object_unref(settings);
27 return false; 51 return false;
28 }
29 52
30 bool success = !std::strcmp(str, "prefer-dark"); 53 bool success = !std::strncmp(str, size, "prefer-dark");
31
32 ::g_variant_unref(val);
33 54
34 if (success) 55 if (success)
35 return true; 56 return true;
36 } 57 }
37 58
38 { 59 {
39 GVariant* gtk_theme = ::g_settings_get_value(settings, "gtk-theme"); 60 /* if that doesn't exist, use the GTK theme and check for some known
40 if (!gtk_theme) { 61 * suffixes. if one is found, return
41 ::g_object_unref(settings); 62 *
63 * XXX probably better to use case folding here */
64 static constexpr std::array<std::string_view, 3> suffixes = {
65 "-dark", /* Adwaita-dark */
66 "-Dark", /* Arc-Dark */
67 "-Darker", /* Arc-Darker */
68 };
69
70 GVariantPtr<GVariant> gtk_theme(::g_settings_get_value(settings.get(), "gtk-theme"));
71 if (!gtk_theme)
42 return false; 72 return false;
73
74 gsize size;
75 const gchar* str = ::g_variant_get_string(gtk_theme.get(), &size);
76 if (!str)
77 return false;
78
79 for (const auto& suffix : suffixes) {
80 if (size < suffix.size())
81 continue;
82
83 if (std::equal(str + size - suffix.length(), str + size, suffix.begin(), suffix.end()))
84 return true;
43 } 85 }
44
45 const gchar* gtk_theme_str = nullptr;
46 ::g_variant_get(gtk_theme, "&s", gtk_theme_str);
47 if (!gtk_theme_str) {
48 ::g_variant_unref(gtk_theme);
49 ::g_object_unref(settings);
50 return false;
51 }
52
53 static constexpr std::string_view suffix = "-dark";
54
55 size_t gtk_theme_len = strlen(gtk_theme_str);
56
57 if (gtk_theme_len < suffix.length()) {
58 ::g_variant_unref(gtk_theme);
59 ::g_object_unref(settings);
60 return false;
61 }
62
63 bool success = !std::strncmp(gtk_theme_str + gtk_theme_len - suffix.length(), suffix.data(), suffix.length());
64
65 ::g_variant_unref(gtk_theme);
66 ::g_object_unref(settings);
67
68 if (success)
69 return true;
70 } 86 }
71 87
88 /* welp, we tried */
72 return false; 89 return false;
73 } 90 }
74 91
75 } // namespace glib 92 } // namespace glib