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;
 }