# HG changeset patch # User Paper # Date 1720998760 14400 # Node ID daa03aa2262d2572451a848cf977e589ffaed2ce # Parent 6b0768158dcda0081425c3e97dd42a599f1c923c sys/glib: general cleanup, use C++ principles, add more suffixes diff -r 6b0768158dcd -r daa03aa2262d src/sys/glib/dark_theme.cc --- 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 #include #include - -/* this file uses the regular gio C interface because I don't - * see any real benefit to using the C++ bindings. */ +#include +#include namespace glib { +/* deleters */ +template +struct g_object_del { + void operator()(T* p) const { ::g_object_unref(p); }; +}; + +template +struct g_variant_del { + void operator()(T* p) const { ::g_variant_unref(p); }; +}; + +template +struct g_malloc_del { + void operator()(T* p) const { ::g_free(p); }; +}; + +template +using GObjectPtr = std::unique_ptr>; + +template +using GVariantPtr = std::unique_ptr>; + +template +using GMallocPtr = std::unique_ptr>; + bool IsInDarkTheme() { - GSettings* settings = ::g_settings_new("org.gnome.desktop.interface"); + GObjectPtr 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 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 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 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; }