view src/sys/glib/dark_theme.cc @ 403:df4a027623d0 default tip

x11: fix build fail when glib is not detected this can happen if glib is just not installed, or if dev headers are not installed either.
author Paper <paper@tflc.us>
date Mon, 10 Nov 2025 15:51:45 -0500
parents 5eaafed6c10b
children
line wrap: on
line source

#include "sys/glib/dark_theme.h"
#include "core/strings.h"

#include <array>
#include <cstring>
#include <gio/gio.h>
#include <memory>
#include <string_view>

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()
{
	GObjectPtr<GSettings> settings(::g_settings_new("org.gnome.desktop.interface"));
	if (!settings)
		return false;

	{
		/* first attempt to get the colorscheme */
		GVariantPtr<GVariant> val(::g_settings_get_value(settings.get(), "color-scheme"));
		if (!val)
			return false;

		/* 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::strncmp(str, "prefer-dark", size);

		if (success)
			return true;
	}

	{

		GVariantPtr<GVariant> gtk_theme(::g_settings_get_value(settings.get(), "gtk-theme"));
		if (!gtk_theme)
			return false;

		gsize size;
		const gchar *str = ::g_variant_get_string(gtk_theme.get(), &size);
		if (!str)
			return false;

		if (Strings::IsGTKThemeDark({str, size}))
			return true;
	}

	/* welp, we tried */
	return false;
}

} // namespace glib