Mercurial > minori
changeset 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 | 6b0768158dcd |
children | c844f8bb87ce |
files | src/sys/glib/dark_theme.cc |
diffstat | 1 files changed, 60 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/src/sys/glib/dark_theme.cc Tue Jun 25 11:19:54 2024 -0400 +++ b/src/sys/glib/dark_theme.cc Sun Jul 14 19:12:40 2024 -0400 @@ -1,74 +1,91 @@ +#include "sys/glib/dark_theme.h" + #include <cstring> #include <gio/gio.h> #include <string_view> - -/* this file uses the regular gio C interface because I don't - * see any real benefit to using the C++ bindings. */ +#include <memory> +#include <array> namespace glib { +/* deleters */ +template<typename T> +struct g_object_del { + void operator()(T* p) const { ::g_object_unref(p); }; +}; + +template<typename T> +struct g_variant_del { + void operator()(T* p) const { ::g_variant_unref(p); }; +}; + +template<typename T> +struct g_malloc_del { + void operator()(T* p) const { ::g_free(p); }; +}; + +template<typename T> +using GObjectPtr = std::unique_ptr<T, g_object_del<T>>; + +template<typename T> +using GVariantPtr = std::unique_ptr<T, g_variant_del<T>>; + +template<typename T> +using GMallocPtr = std::unique_ptr<T, g_malloc_del<T>>; + bool IsInDarkTheme() { - GSettings* settings = ::g_settings_new("org.gnome.desktop.interface"); + GObjectPtr<GSettings> settings(::g_settings_new("org.gnome.desktop.interface")); if (!settings) return false; { - GVariant* val = ::g_settings_get_value(settings, "color-scheme"); - if (!val) { - ::g_object_unref(settings); + /* first attempt to get the colorscheme */ + GVariantPtr<GVariant> val(::g_settings_get_value(settings.get(), "color-scheme")); + if (!val) return false; - } - const gchar* str = nullptr; - ::g_variant_get(val, "&s", &str); /* should not be freed */ - if (!str) { /* how */ - ::g_variant_unref(val); - ::g_object_unref(settings); + /* this is free'd upon deconstruction of the GVariantPtr */ + gsize size; + const gchar* str = ::g_variant_get_string(val.get(), &size); + if (!str) return false; - } - bool success = !std::strcmp(str, "prefer-dark"); - - ::g_variant_unref(val); + bool success = !std::strncmp(str, size, "prefer-dark"); if (success) return true; } { - GVariant* gtk_theme = ::g_settings_get_value(settings, "gtk-theme"); - if (!gtk_theme) { - ::g_object_unref(settings); - return false; - } - - const gchar* gtk_theme_str = nullptr; - ::g_variant_get(gtk_theme, "&s", gtk_theme_str); - if (!gtk_theme_str) { - ::g_variant_unref(gtk_theme); - ::g_object_unref(settings); - return false; - } - - static constexpr std::string_view suffix = "-dark"; + /* if that doesn't exist, use the GTK theme and check for some known + * suffixes. if one is found, return + * + * XXX probably better to use case folding here */ + static constexpr std::array<std::string_view, 3> suffixes = { + "-dark", /* Adwaita-dark */ + "-Dark", /* Arc-Dark */ + "-Darker", /* Arc-Darker */ + }; - size_t gtk_theme_len = strlen(gtk_theme_str); - - if (gtk_theme_len < suffix.length()) { - ::g_variant_unref(gtk_theme); - ::g_object_unref(settings); + GVariantPtr<GVariant> gtk_theme(::g_settings_get_value(settings.get(), "gtk-theme")); + if (!gtk_theme) return false; - } - bool success = !std::strncmp(gtk_theme_str + gtk_theme_len - suffix.length(), suffix.data(), suffix.length()); + gsize size; + const gchar* str = ::g_variant_get_string(gtk_theme.get(), &size); + if (!str) + return false; - ::g_variant_unref(gtk_theme); - ::g_object_unref(settings); + for (const auto& suffix : suffixes) { + if (size < suffix.size()) + continue; - if (success) - return true; + if (std::equal(str + size - suffix.length(), str + size, suffix.begin(), suffix.end())) + return true; + } } + /* welp, we tried */ return false; }