mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge branch 'v5' of github.com:noctalia-dev/noctalia-shell into v5
This commit is contained in:
@@ -330,6 +330,22 @@ void Application::initServices() {
|
||||
m_themeService.apply();
|
||||
m_configService.addReloadCallback([this]() { m_themeService.onConfigReload(); });
|
||||
|
||||
// Watch the dconf user database so Auto mode reacts immediately to system
|
||||
// color-scheme changes (org.gnome.desktop.interface color-scheme).
|
||||
{
|
||||
const char* xdg = std::getenv("XDG_CONFIG_HOME");
|
||||
const char* home = std::getenv("HOME");
|
||||
std::filesystem::path dconfDb;
|
||||
if (xdg != nullptr && xdg[0] != '\0') {
|
||||
dconfDb = std::filesystem::path(xdg) / "dconf" / "user";
|
||||
} else if (home != nullptr && home[0] != '\0') {
|
||||
dconfDb = std::filesystem::path(home) / ".config" / "dconf" / "user";
|
||||
}
|
||||
if (!dconfDb.empty()) {
|
||||
m_fileWatcher.watch(dconfDb, [this]() { m_themeService.onAutoSchemeChanged(); });
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_wayland.connect()) {
|
||||
throw std::runtime_error("failed to connect to Wayland display");
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <exception>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <gio/gio.h>
|
||||
#include <json.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
@@ -38,7 +39,37 @@ namespace noctalia::theme {
|
||||
std::string mode;
|
||||
};
|
||||
|
||||
std::string resolvedModeName(const ThemeConfig& cfg) { return cfg.mode == ThemeMode::Light ? "light" : "dark"; }
|
||||
// Returns "light" or "dark" from org.gnome.desktop.interface color-scheme.
|
||||
std::string_view readSystemColorScheme() {
|
||||
static GSettings* settings = []() -> GSettings* {
|
||||
GSettingsSchemaSource* source = g_settings_schema_source_get_default();
|
||||
if (source == nullptr)
|
||||
return nullptr;
|
||||
GSettingsSchema* schema = g_settings_schema_source_lookup(source, "org.gnome.desktop.interface", TRUE);
|
||||
if (schema == nullptr)
|
||||
return nullptr;
|
||||
const bool hasKey = g_settings_schema_has_key(schema, "color-scheme") != FALSE;
|
||||
g_settings_schema_unref(schema);
|
||||
if (!hasKey)
|
||||
return nullptr;
|
||||
return g_settings_new("org.gnome.desktop.interface");
|
||||
}();
|
||||
|
||||
if (settings == nullptr)
|
||||
return "dark";
|
||||
gchar* raw = g_settings_get_string(settings, "color-scheme");
|
||||
if (raw == nullptr)
|
||||
return "dark";
|
||||
const bool isLight = (std::string_view(raw) == "prefer-light");
|
||||
g_free(raw);
|
||||
return isLight ? "light" : "dark";
|
||||
}
|
||||
|
||||
std::string resolvedModeName(const ThemeConfig& cfg) {
|
||||
if (cfg.mode == ThemeMode::Auto)
|
||||
return std::string(readSystemColorScheme());
|
||||
return cfg.mode == ThemeMode::Light ? "light" : "dark";
|
||||
}
|
||||
|
||||
ResolvedTheme resolveBuiltin(const ThemeConfig& cfg) {
|
||||
const auto* palette = findBuiltinPalette(cfg.builtinPalette);
|
||||
@@ -240,6 +271,12 @@ namespace noctalia::theme {
|
||||
}
|
||||
}
|
||||
|
||||
void ThemeService::onAutoSchemeChanged() {
|
||||
if (m_config.config().theme.mode == ThemeMode::Auto) {
|
||||
resolveAndSet(/*animate=*/true);
|
||||
}
|
||||
}
|
||||
|
||||
void ThemeService::toggleLightDark() {
|
||||
const auto next = m_isLightMode ? ThemeMode::Dark : ThemeMode::Light;
|
||||
// Persist via ConfigService → StateService. The resulting overrides-change
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace noctalia::theme {
|
||||
// Resolves the target theme and cross-fades to it.
|
||||
void onConfigReload();
|
||||
void onWallpaperChange();
|
||||
void onAutoSchemeChanged();
|
||||
void toggleLightDark();
|
||||
void cycleMode();
|
||||
[[nodiscard]] ThemeMode configuredMode() const noexcept;
|
||||
|
||||
Reference in New Issue
Block a user