diff options
author | implicitfield <114500360+implicitfield@users.noreply.github.com> | 2023-02-12 15:48:23 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-03-10 22:03:49 +0100 |
commit | e9e4baee777c82db2191af0a016411f46aa4b71c (patch) | |
tree | 36f9abb50b3759c4aab98260b4aa515dfcf076e8 /Userland | |
parent | fba0cee622701638b6853c33464f7c36b64b90e6 (diff) | |
download | serenity-e9e4baee777c82db2191af0a016411f46aa4b71c.zip |
Everywhere: Support overriding the system color scheme
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Applications/DisplaySettings/ThemesSettings.gml | 18 | ||||
-rw-r--r-- | Userland/Applications/DisplaySettings/ThemesSettingsWidget.cpp | 64 | ||||
-rw-r--r-- | Userland/Applications/DisplaySettings/ThemesSettingsWidget.h | 3 | ||||
-rw-r--r-- | Userland/Applications/ThemeEditor/MainWidget.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/Palette.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/SystemTheme.cpp | 48 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/SystemTheme.h | 4 | ||||
-rw-r--r-- | Userland/Services/Taskbar/main.cpp | 9 | ||||
-rw-r--r-- | Userland/Services/WindowServer/ConnectionFromClient.cpp | 9 | ||||
-rw-r--r-- | Userland/Services/WindowServer/ConnectionFromClient.h | 3 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowManager.cpp | 15 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowManager.h | 4 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowServer.ipc | 4 | ||||
-rw-r--r-- | Userland/Services/WindowServer/main.cpp | 6 |
14 files changed, 160 insertions, 30 deletions
diff --git a/Userland/Applications/DisplaySettings/ThemesSettings.gml b/Userland/Applications/DisplaySettings/ThemesSettings.gml index 56ed183fc4..a701c96ef6 100644 --- a/Userland/Applications/DisplaySettings/ThemesSettings.gml +++ b/Userland/Applications/DisplaySettings/ThemesSettings.gml @@ -39,6 +39,24 @@ } @GUI::GroupBox { + title: "Color Scheme" + preferred_height: "fit" + layout: @GUI::VerticalBoxLayout { + margins: [14, 14, 14] + } + + @GUI::CheckBox { + name: "custom_color_scheme_checkbox" + text: "Use a custom color scheme" + } + + @GUI::ComboBox { + name: "color_scheme_combo" + enabled: "false" + } + } + + @GUI::GroupBox { layout: @GUI::VerticalBoxLayout { margins: [14, 14, 4] } diff --git a/Userland/Applications/DisplaySettings/ThemesSettingsWidget.cpp b/Userland/Applications/DisplaySettings/ThemesSettingsWidget.cpp index 3f66e7f301..24f46e47ac 100644 --- a/Userland/Applications/DisplaySettings/ThemesSettingsWidget.cpp +++ b/Userland/Applications/DisplaySettings/ThemesSettingsWidget.cpp @@ -11,6 +11,7 @@ #include <Applications/DisplaySettings/ThemesSettingsGML.h> #include <LibCore/DirIterator.h> #include <LibGUI/Application.h> +#include <LibGUI/CheckBox.h> #include <LibGUI/ConnectionToWindowServer.h> #include <LibGUI/ItemListModel.h> #include <LibGUI/MessageBox.h> @@ -18,6 +19,11 @@ namespace DisplaySettings { +static DeprecatedString get_color_scheme_name_from_pathname(DeprecatedString const& color_scheme_path) +{ + return color_scheme_path.replace("/res/color-schemes/"sv, ""sv, ReplaceMode::FirstOnly).replace(".ini"sv, ""sv, ReplaceMode::FirstOnly); +}; + ThemesSettingsWidget::ThemesSettingsWidget(bool& background_settings_changed) : m_background_settings_changed { background_settings_changed } { @@ -49,6 +55,47 @@ ThemesSettingsWidget::ThemesSettingsWidget(bool& background_settings_changed) m_themes_combo->set_selected_index(current_theme_index, GUI::AllowCallback::No); auto mouse_settings_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/app-mouse.png"sv).release_value_but_fixme_should_propagate_errors(); + + m_color_scheme_names.clear(); + Core::DirIterator iterator("/res/color-schemes", Core::DirIterator::SkipParentAndBaseDir); + while (iterator.has_next()) { + auto path = iterator.next_path(); + m_color_scheme_names.append(path.replace(".ini"sv, ""sv, ReplaceMode::FirstOnly)); + } + quick_sort(m_color_scheme_names); + auto& color_scheme_combo = *find_descendant_of_type_named<GUI::ComboBox>("color_scheme_combo"); + color_scheme_combo.set_only_allow_values_from_model(true); + color_scheme_combo.set_model(*GUI::ItemListModel<DeprecatedString>::create(m_color_scheme_names)); + m_selected_color_scheme_name = get_color_scheme_name_from_pathname(GUI::Widget::palette().color_scheme_path()); + auto selected_color_scheme_index = m_color_scheme_names.find_first_index(m_selected_color_scheme_name); + if (selected_color_scheme_index.has_value()) + color_scheme_combo.set_selected_index(selected_color_scheme_index.value()); + else { + color_scheme_combo.set_text("Custom"); + m_color_scheme_is_file_based = false; + if (m_color_scheme_names.size() > 1) { + color_scheme_combo.set_enabled(true); + find_descendant_of_type_named<GUI::CheckBox>("custom_color_scheme_checkbox")->set_checked(true); + } + } + color_scheme_combo.on_change = [this](auto&, const GUI::ModelIndex& index) { + m_selected_color_scheme_name = index.data().as_string(); + m_color_scheme_is_file_based = true; + set_modified(true); + }; + + find_descendant_of_type_named<GUI::CheckBox>("custom_color_scheme_checkbox")->on_checked = [this](bool) { + if (m_color_scheme_names.size() <= 1) + return; + + if (find_descendant_of_type_named<GUI::CheckBox>("custom_color_scheme_checkbox")->is_checked()) + find_descendant_of_type_named<GUI::ComboBox>("color_scheme_combo")->set_enabled(true); + else { + find_descendant_of_type_named<GUI::ComboBox>("color_scheme_combo")->set_enabled(false); + set_modified(true); + } + }; + m_cursor_themes_button = *find_descendant_of_type_named<GUI::Button>("cursor_themes_button"); m_cursor_themes_button->set_icon(mouse_settings_icon); m_cursor_themes_button->on_click = [&](auto) { @@ -82,8 +129,21 @@ ThemesSettingsWidget::ThemesSettingsWidget(bool& background_settings_changed) void ThemesSettingsWidget::apply_settings() { - if (m_selected_theme && m_selected_theme->name != GUI::ConnectionToWindowServer::the().get_system_theme()) - VERIFY(GUI::ConnectionToWindowServer::the().set_system_theme(m_selected_theme->path, m_selected_theme->name, m_background_settings_changed)); + Optional<DeprecatedString> color_scheme_path = DeprecatedString::formatted("/res/color-schemes/{}.ini", m_selected_color_scheme_name); + + if (!m_color_scheme_is_file_based && find_descendant_of_type_named<GUI::CheckBox>("custom_color_scheme_checkbox")->is_checked()) + VERIFY(GUI::ConnectionToWindowServer::the().set_system_theme(m_selected_theme->path, m_selected_theme->name, m_background_settings_changed, "Custom"sv)); + else if (find_descendant_of_type_named<GUI::CheckBox>("custom_color_scheme_checkbox")->is_checked()) + VERIFY(GUI::ConnectionToWindowServer::the().set_system_theme(m_selected_theme->path, m_selected_theme->name, m_background_settings_changed, color_scheme_path)); + else { + VERIFY(GUI::ConnectionToWindowServer::the().set_system_theme(m_selected_theme->path, m_selected_theme->name, m_background_settings_changed, OptionalNone())); + // Update the color scheme combobox to match the new theme. + auto const theme_config = Core::ConfigFile::open(m_selected_theme->path).release_value_but_fixme_should_propagate_errors(); + auto const color_scheme_index = m_color_scheme_names.find_first_index(get_color_scheme_name_from_pathname(theme_config->read_entry("Paths", "ColorScheme"))); + if (color_scheme_index.has_value()) + find_descendant_of_type_named<GUI::ComboBox>("color_scheme_combo")->set_selected_index(color_scheme_index.value()); + } + m_background_settings_changed = false; } diff --git a/Userland/Applications/DisplaySettings/ThemesSettingsWidget.h b/Userland/Applications/DisplaySettings/ThemesSettingsWidget.h index 3ec7a9fb28..b0778537db 100644 --- a/Userland/Applications/DisplaySettings/ThemesSettingsWidget.h +++ b/Userland/Applications/DisplaySettings/ThemesSettingsWidget.h @@ -25,14 +25,17 @@ public: private: Vector<Gfx::SystemThemeMetaData> m_themes; Vector<DeprecatedString> m_theme_names; + Vector<DeprecatedString> m_color_scheme_names; RefPtr<GUI::ComboBox> m_themes_combo; RefPtr<ThemePreviewWidget> m_theme_preview; Gfx::SystemThemeMetaData const* m_selected_theme { nullptr }; + DeprecatedString m_selected_color_scheme_name = ""; RefPtr<GUI::Button> m_cursor_themes_button; bool& m_background_settings_changed; + bool m_color_scheme_is_file_based = true; ThemesSettingsWidget(bool& background_settings_changed); }; diff --git a/Userland/Applications/ThemeEditor/MainWidget.cpp b/Userland/Applications/ThemeEditor/MainWidget.cpp index adeeca6ad7..17ef0bdc07 100644 --- a/Userland/Applications/ThemeEditor/MainWidget.cpp +++ b/Userland/Applications/ThemeEditor/MainWidget.cpp @@ -414,6 +414,8 @@ void MainWidget::build_override_controls() auto encoded = encode(); if (encoded.is_error()) return; + // Empty the color scheme path to signal that it exists only in memory. + m_current_palette.path(Gfx::PathRole::ColorScheme) = ""; GUI::ConnectionToWindowServer::the().async_set_system_theme_override(encoded.value()); }; diff --git a/Userland/Libraries/LibGfx/Palette.h b/Userland/Libraries/LibGfx/Palette.h index b2e20efbfd..8cbb443609 100644 --- a/Userland/Libraries/LibGfx/Palette.h +++ b/Userland/Libraries/LibGfx/Palette.h @@ -181,6 +181,7 @@ public: DeprecatedString menu_shadow_path() const { return path(PathRole::MenuShadow); } DeprecatedString taskbar_shadow_path() const { return path(PathRole::TaskbarShadow); } DeprecatedString tooltip_shadow_path() const { return path(PathRole::TooltipShadow); } + DeprecatedString color_scheme_path() const { return path(PathRole::ColorScheme); } Color color(ColorRole role) const { return m_impl->color(role); } Gfx::TextAlignment alignment(AlignmentRole role) const { return m_impl->alignment(role); } diff --git a/Userland/Libraries/LibGfx/SystemTheme.cpp b/Userland/Libraries/LibGfx/SystemTheme.cpp index 23b4014477..f67d50c99d 100644 --- a/Userland/Libraries/LibGfx/SystemTheme.cpp +++ b/Userland/Libraries/LibGfx/SystemTheme.cpp @@ -31,15 +31,26 @@ void set_system_theme(Core::AnonymousBuffer buffer) theme_page = theme_buffer.data<SystemTheme>(); } -ErrorOr<Core::AnonymousBuffer> load_system_theme(Core::ConfigFile const& file) +ErrorOr<Core::AnonymousBuffer> load_system_theme(Core::ConfigFile const& file, Optional<DeprecatedString> const& color_scheme) { auto buffer = TRY(Core::AnonymousBuffer::create_with_size(sizeof(SystemTheme))); auto* data = buffer.data<SystemTheme>(); - auto get_color = [&](auto& name) { + if (color_scheme.has_value()) { + if (color_scheme.value().length() > 255) + return Error::from_string_literal("Passed an excessively long color scheme pathname"); + if (color_scheme.value() != "Custom"sv) + memcpy(data->path[(int)PathRole::ColorScheme], color_scheme.value().characters(), color_scheme.value().length()); + else + memcpy(buffer.data<SystemTheme>(), theme_buffer.data<SystemTheme>(), sizeof(SystemTheme)); + } + + auto get_color = [&](auto& name) -> Optional<Color> { auto color_string = file.read_entry("Colors", name); auto color = Color::from_string(color_string); + if (color_scheme.has_value() && color_scheme.value() == "Custom"sv) + return color; if (!color.has_value()) { auto maybe_color_config = Core::ConfigFile::open(data->path[(int)PathRole::ColorScheme]); if (maybe_color_config.is_error()) @@ -135,11 +146,16 @@ ErrorOr<Core::AnonymousBuffer> load_system_theme(Core::ConfigFile const& file) ENCODE_PATH(TaskbarShadow, true); ENCODE_PATH(MenuShadow, true); ENCODE_PATH(TooltipShadow, true); - ENCODE_PATH(ColorScheme, true); + if (!color_scheme.has_value()) + ENCODE_PATH(ColorScheme, true); #undef __ENUMERATE_COLOR_ROLE -#define __ENUMERATE_COLOR_ROLE(role) \ - data->color[(int)ColorRole::role] = get_color(#role).value(); +#define __ENUMERATE_COLOR_ROLE(role) \ + { \ + Optional<Color> result = get_color(#role); \ + if (result.has_value()) \ + data->color[(int)ColorRole::role] = result.value().value(); \ + } ENUMERATE_COLOR_ROLES(__ENUMERATE_COLOR_ROLE) #undef __ENUMERATE_COLOR_ROLE @@ -150,8 +166,11 @@ ErrorOr<Core::AnonymousBuffer> load_system_theme(Core::ConfigFile const& file) #undef __ENUMERATE_ALIGNMENT_ROLE #undef __ENUMERATE_FLAG_ROLE -#define __ENUMERATE_FLAG_ROLE(role) \ - data->flag[(int)FlagRole::role] = get_flag(#role); +#define __ENUMERATE_FLAG_ROLE(role) \ + { \ + if (#role != "BoldTextAsBright"sv) \ + data->flag[(int)FlagRole::role] = get_flag(#role); \ + } ENUMERATE_FLAG_ROLES(__ENUMERATE_FLAG_ROLE) #undef __ENUMERATE_FLAG_ROLE @@ -161,20 +180,21 @@ ErrorOr<Core::AnonymousBuffer> load_system_theme(Core::ConfigFile const& file) ENUMERATE_METRIC_ROLES(__ENUMERATE_METRIC_ROLE) #undef __ENUMERATE_METRIC_ROLE - data->flag[(int)FlagRole::BoldTextAsBright] = true; - auto maybe_color_config = Core::ConfigFile::open(data->path[(int)PathRole::ColorScheme]); - if (!maybe_color_config.is_error()) { - auto color_config = maybe_color_config.release_value(); - data->flag[(int)FlagRole::BoldTextAsBright] = color_config->read_bool_entry("Options", "ShowBoldTextAsBright", true); + if (!color_scheme.has_value() || color_scheme.value() != "Custom"sv) { + auto maybe_color_config = Core::ConfigFile::open(data->path[(int)PathRole::ColorScheme]); + if (!maybe_color_config.is_error()) { + auto color_config = maybe_color_config.release_value(); + data->flag[(int)FlagRole::BoldTextAsBright] = color_config->read_bool_entry("Options", "ShowBoldTextAsBright", true); + } } return buffer; } -ErrorOr<Core::AnonymousBuffer> load_system_theme(DeprecatedString const& path) +ErrorOr<Core::AnonymousBuffer> load_system_theme(DeprecatedString const& path, Optional<DeprecatedString> const& color_scheme) { auto config_file = TRY(Core::ConfigFile::open(path)); - return TRY(load_system_theme(config_file)); + return TRY(load_system_theme(config_file, color_scheme)); } ErrorOr<Vector<SystemThemeMetaData>> list_installed_system_themes() diff --git a/Userland/Libraries/LibGfx/SystemTheme.h b/Userland/Libraries/LibGfx/SystemTheme.h index 698a1e5435..1f056a6265 100644 --- a/Userland/Libraries/LibGfx/SystemTheme.h +++ b/Userland/Libraries/LibGfx/SystemTheme.h @@ -291,8 +291,8 @@ struct SystemTheme { Core::AnonymousBuffer& current_system_theme_buffer(); void set_system_theme(Core::AnonymousBuffer); -ErrorOr<Core::AnonymousBuffer> load_system_theme(Core::ConfigFile const&); -ErrorOr<Core::AnonymousBuffer> load_system_theme(DeprecatedString const& path); +ErrorOr<Core::AnonymousBuffer> load_system_theme(Core::ConfigFile const&, Optional<DeprecatedString> const& color_scheme = OptionalNone()); +ErrorOr<Core::AnonymousBuffer> load_system_theme(DeprecatedString const& path, Optional<DeprecatedString> const& color_scheme = OptionalNone()); struct SystemThemeMetaData { DeprecatedString name; diff --git a/Userland/Services/Taskbar/main.cpp b/Userland/Services/Taskbar/main.cpp index 533bc5e548..f3b996a25f 100644 --- a/Userland/Services/Taskbar/main.cpp +++ b/Userland/Services/Taskbar/main.cpp @@ -25,6 +25,7 @@ #include <LibGUI/MenuItem.h> #include <LibGUI/Process.h> #include <LibGUI/Window.h> +#include <LibGfx/Palette.h> #include <LibGfx/SystemTheme.h> #include <LibMain/Main.h> #include <WindowServer/Window.h> @@ -229,11 +230,13 @@ ErrorOr<NonnullRefPtr<GUI::Menu>> build_system_menu(GUI::Window& window) { int theme_identifier = 0; for (auto& theme : g_themes) { - auto action = GUI::Action::create_checkable(theme.name, [theme_identifier](auto&) { + auto action = GUI::Action::create_checkable(theme.name, [theme_identifier, &window](auto&) { auto& theme = g_themes[theme_identifier]; dbgln("Theme switched to {} at path {}", theme.name, theme.path); - auto success = GUI::ConnectionToWindowServer::the().set_system_theme(theme.path, theme.name, false); - VERIFY(success); + if (window.main_widget()->palette().color_scheme_path() != ""sv) + VERIFY(GUI::ConnectionToWindowServer::the().set_system_theme(theme.path, theme.name, false, GUI::ConnectionToWindowServer::the().get_preferred_color_scheme())); + else + VERIFY(GUI::ConnectionToWindowServer::the().set_system_theme(theme.path, theme.name, false, "Custom"sv)); }); if (theme.name == current_theme_name) action->set_checked(true); diff --git a/Userland/Services/WindowServer/ConnectionFromClient.cpp b/Userland/Services/WindowServer/ConnectionFromClient.cpp index dab03a3c81..34bf167b78 100644 --- a/Userland/Services/WindowServer/ConnectionFromClient.cpp +++ b/Userland/Services/WindowServer/ConnectionFromClient.cpp @@ -865,9 +865,9 @@ void ConnectionFromClient::set_accepts_drag(bool accepts) wm.set_accepts_drag(accepts); } -Messages::WindowServer::SetSystemThemeResponse ConnectionFromClient::set_system_theme(DeprecatedString const& theme_path, DeprecatedString const& theme_name, bool keep_desktop_background) +Messages::WindowServer::SetSystemThemeResponse ConnectionFromClient::set_system_theme(DeprecatedString const& theme_path, DeprecatedString const& theme_name, bool keep_desktop_background, Optional<DeprecatedString> const& color_scheme_path) { - bool success = WindowManager::the().update_theme(theme_path, theme_name, keep_desktop_background); + bool success = WindowManager::the().update_theme(theme_path, theme_name, keep_desktop_background, color_scheme_path); return success; } @@ -897,6 +897,11 @@ Messages::WindowServer::IsSystemThemeOverriddenResponse ConnectionFromClient::is return WindowManager::the().is_theme_overridden(); } +Messages::WindowServer::GetPreferredColorSchemeResponse ConnectionFromClient::get_preferred_color_scheme() +{ + return WindowManager::the().get_preferred_color_scheme(); +} + void ConnectionFromClient::apply_cursor_theme(DeprecatedString const& name) { WindowManager::the().apply_cursor_theme(name); diff --git a/Userland/Services/WindowServer/ConnectionFromClient.h b/Userland/Services/WindowServer/ConnectionFromClient.h index 627b647a5f..c511716478 100644 --- a/Userland/Services/WindowServer/ConnectionFromClient.h +++ b/Userland/Services/WindowServer/ConnectionFromClient.h @@ -145,12 +145,13 @@ private: virtual void set_window_icon_bitmap(i32, Gfx::ShareableBitmap const&) override; virtual Messages::WindowServer::StartDragResponse start_drag(DeprecatedString const&, HashMap<DeprecatedString, ByteBuffer> const&, Gfx::ShareableBitmap const&) override; virtual void set_accepts_drag(bool) override; - virtual Messages::WindowServer::SetSystemThemeResponse set_system_theme(DeprecatedString const&, DeprecatedString const&, bool keep_desktop_background) override; + virtual Messages::WindowServer::SetSystemThemeResponse set_system_theme(DeprecatedString const&, DeprecatedString const&, bool keep_desktop_background, Optional<DeprecatedString> const& color_scheme_path) override; virtual Messages::WindowServer::GetSystemThemeResponse get_system_theme() override; virtual Messages::WindowServer::SetSystemThemeOverrideResponse set_system_theme_override(Core::AnonymousBuffer const&) override; virtual Messages::WindowServer::GetSystemThemeOverrideResponse get_system_theme_override() override; virtual void clear_system_theme_override() override; virtual Messages::WindowServer::IsSystemThemeOverriddenResponse is_system_theme_overridden() override; + virtual Messages::WindowServer::GetPreferredColorSchemeResponse get_preferred_color_scheme() override; virtual void apply_cursor_theme(DeprecatedString const&) override; virtual void set_cursor_highlight_radius(int radius) override; virtual Messages::WindowServer::GetCursorHighlightRadiusResponse get_cursor_highlight_radius() override; diff --git a/Userland/Services/WindowServer/WindowManager.cpp b/Userland/Services/WindowServer/WindowManager.cpp index dee3f2680d..ae44b26b74 100644 --- a/Userland/Services/WindowServer/WindowManager.cpp +++ b/Userland/Services/WindowServer/WindowManager.cpp @@ -2077,9 +2077,9 @@ void WindowManager::invalidate_after_theme_or_font_change() Compositor::the().invalidate_after_theme_or_font_change(); } -bool WindowManager::update_theme(DeprecatedString theme_path, DeprecatedString theme_name, bool keep_desktop_background) +bool WindowManager::update_theme(DeprecatedString theme_path, DeprecatedString theme_name, bool keep_desktop_background, Optional<DeprecatedString> const& color_scheme_path) { - auto error_or_new_theme = Gfx::load_system_theme(theme_path); + auto error_or_new_theme = Gfx::load_system_theme(theme_path, color_scheme_path); if (error_or_new_theme.is_error()) { dbgln("WindowManager: Updating theme failed, error {}", error_or_new_theme.error()); return false; @@ -2089,6 +2089,15 @@ bool WindowManager::update_theme(DeprecatedString theme_path, DeprecatedString t Gfx::set_system_theme(new_theme); m_palette = Gfx::PaletteImpl::create_with_anonymous_buffer(new_theme); g_config->write_entry("Theme", "Name", theme_name); + if (color_scheme_path.has_value() && color_scheme_path.value() != "Custom"sv) { + g_config->write_bool_entry("Theme", "LoadCustomColorScheme", true); + g_config->write_entry("Theme", "CustomColorSchemePath", color_scheme_path.value()); + m_preferred_color_scheme = color_scheme_path.value(); + } else if (!color_scheme_path.has_value()) { + g_config->write_bool_entry("Theme", "LoadCustomColorScheme", false); + g_config->remove_entry("Theme", "CustomColorSchemePath"); + m_preferred_color_scheme = OptionalNone(); + } if (!keep_desktop_background) g_config->remove_entry("Background", "Color"); if (!sync_config_to_disk()) @@ -2119,7 +2128,7 @@ void WindowManager::clear_theme_override() { m_theme_overridden = false; auto previous_theme_name = g_config->read_entry("Theme", "Name"); - auto previous_theme = MUST(Gfx::load_system_theme(DeprecatedString::formatted("/res/themes/{}.ini", previous_theme_name))); + auto previous_theme = MUST(Gfx::load_system_theme(DeprecatedString::formatted("/res/themes/{}.ini", previous_theme_name), m_preferred_color_scheme)); Gfx::set_system_theme(previous_theme); m_palette = Gfx::PaletteImpl::create_with_anonymous_buffer(previous_theme); invalidate_after_theme_or_font_change(); diff --git a/Userland/Services/WindowServer/WindowManager.h b/Userland/Services/WindowServer/WindowManager.h index 1dd9fc686e..fd375e4423 100644 --- a/Userland/Services/WindowServer/WindowManager.h +++ b/Userland/Services/WindowServer/WindowManager.h @@ -201,13 +201,14 @@ public: return nullptr; } - bool update_theme(DeprecatedString theme_path, DeprecatedString theme_name, bool keep_desktop_background); + bool update_theme(DeprecatedString theme_path, DeprecatedString theme_name, bool keep_desktop_background, Optional<DeprecatedString> const& color_scheme_path); void invalidate_after_theme_or_font_change(); bool set_theme_override(Core::AnonymousBuffer const& theme_override); Optional<Core::AnonymousBuffer> get_theme_override() const; void clear_theme_override(); bool is_theme_overridden() { return m_theme_overridden; } + Optional<DeprecatedString> get_preferred_color_scheme() { return m_preferred_color_scheme; } bool set_hovered_window(Window*); void deliver_mouse_event(Window&, MouseEvent const&); @@ -439,6 +440,7 @@ private: bool m_mouse_buttons_switched { false }; bool m_natural_scroll { false }; bool m_theme_overridden { false }; + Optional<DeprecatedString> m_preferred_color_scheme { OptionalNone() }; WeakPtr<Window> m_hovered_window; WeakPtr<Window> m_highlight_window; diff --git a/Userland/Services/WindowServer/WindowServer.ipc b/Userland/Services/WindowServer/WindowServer.ipc index f40e4e1394..e8e8b7b4bc 100644 --- a/Userland/Services/WindowServer/WindowServer.ipc +++ b/Userland/Services/WindowServer/WindowServer.ipc @@ -130,7 +130,7 @@ endpoint WindowServer start_drag([UTF8] DeprecatedString text, HashMap<DeprecatedString,ByteBuffer> mime_data, Gfx::ShareableBitmap drag_bitmap) => (bool started) set_accepts_drag(bool accepts) =| - set_system_theme(DeprecatedString theme_path, [UTF8] DeprecatedString theme_name, bool keep_desktop_background) => (bool success) + set_system_theme(DeprecatedString theme_path, [UTF8] DeprecatedString theme_name, bool keep_desktop_background, Optional<DeprecatedString> color_scheme_path) => (bool success) get_system_theme() => ([UTF8] DeprecatedString theme_name) refresh_system_theme() =| @@ -139,6 +139,8 @@ endpoint WindowServer clear_system_theme_override() =| is_system_theme_overridden() => (bool overridden) + get_preferred_color_scheme() => (Optional<DeprecatedString> path) + apply_cursor_theme(DeprecatedString name) =| get_cursor_theme() => (DeprecatedString name) diff --git a/Userland/Services/WindowServer/main.cpp b/Userland/Services/WindowServer/main.cpp index 5fc766a26c..da17e92616 100644 --- a/Userland/Services/WindowServer/main.cpp +++ b/Userland/Services/WindowServer/main.cpp @@ -47,7 +47,11 @@ ErrorOr<int> serenity_main(Main::Arguments) WindowServer::g_config = TRY(Core::ConfigFile::open("/etc/WindowServer.ini", Core::ConfigFile::AllowWriting::Yes)); auto theme_name = WindowServer::g_config->read_entry("Theme", "Name", "Default"); - auto theme = TRY(Gfx::load_system_theme(DeprecatedString::formatted("/res/themes/{}.ini", theme_name))); + Optional<DeprecatedString> custom_color_scheme_path = OptionalNone(); + if (WindowServer::g_config->read_bool_entry("Theme", "LoadCustomColorScheme", false)) + custom_color_scheme_path = WindowServer::g_config->read_entry("Theme", "CustomColorSchemePath"); + + auto theme = TRY(Gfx::load_system_theme(DeprecatedString::formatted("/res/themes/{}.ini", theme_name), custom_color_scheme_path)); Gfx::set_system_theme(theme); auto palette = Gfx::PaletteImpl::create_with_anonymous_buffer(theme); |