From bc4d180cf53cb6a71d4001a63f05d593d01829c9 Mon Sep 17 00:00:00 2001 From: Trigg Date: Sun, 8 Nov 2026 00:57:55 +0000 Subject: [PATCH 1/2] panel: fix order of css rules --- src/panel/panel.cpp | 4 ++-- src/panel/widgets/menu/menu.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/panel/panel.cpp b/src/panel/panel.cpp index f85d09cab..aaa80b336 100644 --- a/src/panel/panel.cpp +++ b/src/panel/panel.cpp @@ -624,6 +624,8 @@ void WayfirePanelApp::on_activate() priv->panel_outputs->value() << std::endl; } + new CssFromConfigEdge("panel/position", "panel/minimal_height", "panel/minimal_width"); + const static std::vector> icon_sizes_args = { {"panel/default_icon_size", ".default-icon"}, @@ -646,8 +648,6 @@ void WayfirePanelApp::on_activate() new CssFromConfigIconSize(pair.first, pair.second); } - new CssFromConfigEdge("panel/position", "panel/minimal_height", "panel/minimal_width"); - new CssFromConfigInt("panel/launchers_spacing", ".launcher{padding: 0px ", "px;}"); new CssFromConfigString("panel/background_color", ".wf-panel{background-color:", ";}"); new CssFromConfigBool("panel/battery_icon_invert", ".battery image{filter:invert(100%);}", ""); diff --git a/src/panel/widgets/menu/menu.cpp b/src/panel/widgets/menu/menu.cpp index 3c66e6024..f5a810d41 100644 --- a/src/panel/widgets/menu/menu.cpp +++ b/src/panel/widgets/menu/menu.cpp @@ -467,7 +467,7 @@ void WayfireMenu::init(Gtk::Box *container) category_list["Hidden"] = std::make_unique("Other Desktops", "user-desktop"); - main_image.add_css_class("default-icon"); + main_image.add_css_class("widget-icon"); main_image.add_css_class("menu-icon"); signals.push_back(output->toggle_menu_signal().connect(sigc::mem_fun(*this, &WayfireMenu::toggle_menu))); From 1892f0f3691e42d2eedc7cefac3b3ccba6700082 Mon Sep 17 00:00:00 2001 From: Trigg Date: Sun, 8 Nov 2026 02:16:22 +0000 Subject: [PATCH 2/2] util: css-config now makes one unified stylesheet to avoid a gtk quirk --- src/locker/locker.hpp | 3 - src/panel/panel.cpp | 35 ++++---- src/panel/panel.hpp | 1 - src/panel/widgets/menu/logout.cpp | 4 - src/util/css-config.cpp | 139 +++++++++++++++++------------- src/util/css-config.hpp | 20 ++++- 6 files changed, 115 insertions(+), 87 deletions(-) diff --git a/src/locker/locker.hpp b/src/locker/locker.hpp index a69738f95..6a43ca6e2 100644 --- a/src/locker/locker.hpp +++ b/src/locker/locker.hpp @@ -1,7 +1,6 @@ #pragma once #include #include -#include #include #include @@ -47,8 +46,6 @@ class WayfireLockerApp : public WayfireShellApp int inotify_bg_file; Glib::RefPtr background_file; - - std::vector> css_rules; sigc::connection lockout_signal, prewake_signal; std::vector windows_signals; diff --git a/src/panel/panel.cpp b/src/panel/panel.cpp index aaa80b336..d01254b90 100644 --- a/src/panel/panel.cpp +++ b/src/panel/panel.cpp @@ -624,30 +624,31 @@ void WayfirePanelApp::on_activate() priv->panel_outputs->value() << std::endl; } - new CssFromConfigEdge("panel/position", "panel/minimal_height", "panel/minimal_width"); - const static std::vector> icon_sizes_args = { - {"panel/default_icon_size", ".default-icon"}, - {"panel/menu_icon_size", ".menu-icon.widget-icon"}, - {"panel/menu_item_icon_size", ".app-button .default-icon"}, - {"panel/menu_category_icon_size", ".app-category .default-icon"}, - {"panel/launchers_size", ".launcher.widget-icon"}, - {"panel/battery_icon_size", ".battery image.widget-icon"}, - {"panel/network_icon_size", ".network .widget-icon"}, - {"panel/volume_icon_size", ".volume .widget-icon"}, - {"panel/mixer_icon_size", ".mixer .widget-icon"}, - {"panel/mixer_popup_icon_size", ".mute-toggle .default-icon, .default-button .default-icon"}, - {"panel/notifications_icon_size", ".notification-center .widget-icon"}, - {"panel/tray_icon_size", ".tray-button .widget-icon"}, - {"panel/brightness_icon_size", ".brightness .widget-icon"}, - {"panel/window_list_icon_size", ".toplevel-icon.widget-icon"}, + {"panel/default_icon_size", ".wf-panel .default-icon"}, + {"panel/menu_icon_size", ".wf-panel image.menu-icon.widget-icon"}, + {"panel/menu_item_icon_size", ".wf-panel .app-button image.default-icon"}, + {"panel/menu_category_icon_size", ".wf-panel .app-category image.default-icon"}, + {"panel/launchers_size", ".wf-panel image.launcher.widget-icon"}, + {"panel/battery_icon_size", ".wf-panel .battery image.widget-icon"}, + {"panel/network_icon_size", ".wf-panel .network image.widget-icon"}, + {"panel/volume_icon_size", ".wf-panel .volume image.widget-icon"}, + {"panel/mixer_icon_size", ".wf-panel .mixer image.widget-icon"}, + {"panel/mixer_popup_icon_size", + ".wf-panel .mute-toggle image.default-icon, .wf-panel .default-button image.default-icon"}, + {"panel/notifications_icon_size", ".wf-panel .notification-center image.widget-icon"}, + {"panel/tray_icon_size", ".wf-panel .tray-button image.widget-icon"}, + {"panel/brightness_icon_size", ".wf-panel .brightness image.widget-icon"}, + {"panel/window_list_icon_size", ".wf-panel image.toplevel-icon.widget-icon"}, }; for (auto pair : icon_sizes_args) { new CssFromConfigIconSize(pair.first, pair.second); } + new CssFromConfigEdge("panel/position", "panel/minimal_height", "panel/minimal_width"); + new CssFromConfigInt("panel/launchers_spacing", ".launcher{padding: 0px ", "px;}"); new CssFromConfigString("panel/background_color", ".wf-panel{background-color:", ";}"); new CssFromConfigBool("panel/battery_icon_invert", ".battery image{filter:invert(100%);}", ""); @@ -656,6 +657,8 @@ void WayfirePanelApp::on_activate() new CssFromConfigFont("panel/battery_font", ".battery {", "}"); new CssFromConfigFont("panel/clock_font", ".clock {", "}"); new CssFromConfigFont("panel/weather_font", ".weather {", "}"); + + new CssStatic("logout background", "window.logout { background-color: rgba(0, 0, 0, 0.5); }"); } std::shared_ptr WayfirePanelApp::get_ipc_server_instance() diff --git a/src/panel/panel.hpp b/src/panel/panel.hpp index a74fd3bfa..30a61917b 100644 --- a/src/panel/panel.hpp +++ b/src/panel/panel.hpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "giomm/application.h" #include "css-config.hpp" diff --git a/src/panel/widgets/menu/logout.cpp b/src/panel/widgets/menu/logout.cpp index 2a22aee99..2cb2e3397 100644 --- a/src/panel/widgets/menu/logout.cpp +++ b/src/panel/widgets/menu/logout.cpp @@ -117,10 +117,6 @@ WayfireLogoutUI::WayfireLogoutUI() ui.set_child(box); ui.add_css_class("logout"); auto display = ui.get_display(); - auto css_provider = Gtk::CssProvider::create(); - css_provider->load_from_data("window.logout { background-color: rgba(0, 0, 0, 0.5); }"); - Gtk::StyleContext::add_provider_for_display(display, - css_provider, GTK_STYLE_PROVIDER_PRIORITY_USER); } WayfireLogoutUI::~WayfireLogoutUI() diff --git a/src/util/css-config.cpp b/src/util/css-config.cpp index ae23d3749..0d8fbb9db 100644 --- a/src/util/css-config.cpp +++ b/src/util/css-config.cpp @@ -5,129 +5,144 @@ #include #include -void CssFromConfig::add_provider() +Glib::RefPtr CssFromConfig::main_provider = nullptr; +std::map CssFromConfig::css_registry; + +CssFromConfig::CssFromConfig(std::string instance_id) : instance_id(instance_id) +{} + +CssFromConfig::~CssFromConfig() { - Gtk::StyleContext::add_provider_for_display( - Gdk::Display::get_default(), provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + if (!instance_id.empty()) + { + css_registry.erase(instance_id); + rebuild_stylesheet(); + } +} + +void CssFromConfig::update_css(const std::string& css_string) +{ + if (!main_provider) + { + main_provider = Gtk::CssProvider::create(); + Gtk::StyleContext::add_provider_for_display( + Gdk::Display::get_default(), main_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + } + + css_registry[instance_id] = css_string; + rebuild_stylesheet(); } -void CssFromConfig::remove_provider() +void CssFromConfig::rebuild_stylesheet() { - Gtk::StyleContext::remove_provider_for_display(Gdk::Display::get_default(), provider); + if (!main_provider) + { + return; + } + + std::stringstream stream; + for (const auto& [id, css_slice] : css_registry) + { + stream << "/* " << id << " */\n" << css_slice << "\n"; + } + + main_provider->load_from_string(stream.str()); } -CssFromConfigDouble::CssFromConfigDouble(std::string option_name, std::string before, std::string after) : +CssFromConfigDouble::CssFromConfigDouble(std::string option_name, std::string before, + std::string after) : CssFromConfig(option_name), option_value{option_name} { - provider = Gtk::CssProvider::create(); auto cb = [=] { std::stringstream ss; ss.imbue(std::locale::classic()); ss << before << std::to_string(option_value.value()) << after; std::cout << ss.str() << std::endl; - provider->load_from_string(ss.str()); + update_css(ss.str()); }; option_value.set_callback(cb); cb(); - add_provider(); } -CssFromConfigBool::CssFromConfigBool(std::string option_name, std::string css_true, std::string css_false) : +CssFromConfigBool::CssFromConfigBool(std::string option_name, std::string css_true, + std::string css_false) : CssFromConfig(option_name), option_value{option_name} { - provider = Gtk::CssProvider::create(); auto cb = [=] { - provider->load_from_string(option_value ? css_true : css_false); + update_css(option_value ? css_true : css_false); }; option_value.set_callback(cb); cb(); - - add_provider(); } -CssFromConfigInt::CssFromConfigInt(std::string option_name, std::string css_before, std::string css_after) : +CssFromConfigInt::CssFromConfigInt(std::string option_name, std::string css_before, + std::string css_after) : CssFromConfig(option_name), option_value{option_name} { - provider = Gtk::CssProvider::create(); - option_value.set_callback([=] + auto cb = [=] { int value = option_value; // TODO When we go up to c++20 use std::format std::stringstream ss; ss.imbue(std::locale::classic()); ss << css_before << std::to_string(value) << css_after; - provider->load_from_string(ss.str()); - }); - int value = option_value; - std::stringstream ss; - ss.imbue(std::locale::classic()); - ss << css_before << std::to_string(value) << css_after; - provider->load_from_string(ss.str()); - - add_provider(); + update_css(ss.str()); + }; + option_value.set_callback(cb); + cb(); } CssFromConfigIconSize::CssFromConfigIconSize(std::string option_name, - std::string css_class) : option_value{option_name} + std::string css_class) : CssFromConfig(option_name), option_value{option_name} { - provider = Gtk::CssProvider::create(); - auto reload_css = [=] () { if (option_value.value() == 0) { - provider->load_from_string(""); + update_css(""); return; } std::stringstream ss; ss.imbue(std::locale::classic()); - ss << ".wf-panel " << css_class << " {-gtk-icon-size:" << option_value.value() << "px;}"; - provider->load_from_string(ss.str()); + ss << css_class << " {-gtk-icon-size:" << option_value.value() << "px;}"; + std::cout << ss.str() << std::endl; + update_css(ss.str()); }; - option_value.set_callback(reload_css); - reload_css(); - add_provider(); } CssFromConfigString::CssFromConfigString(std::string option_name, std::string css_before, - std::string css_after) : + std::string css_after) : CssFromConfig(option_name), option_value{option_name} { - provider = Gtk::CssProvider::create(); - option_value.set_callback([=] () + auto cb = [=] () { // TODO When we go up to c++20 use std::format std::stringstream ss; ss.imbue(std::locale::classic()); ss << css_before << (std::string)option_value << css_after; - provider->load_from_string(ss.str()); - }); - std::stringstream ss; - ss.imbue(std::locale::classic()); - ss << css_before << (std::string)option_value << css_after; - provider->load_from_string(ss.str()); - - add_provider(); + update_css(ss.str()); + }; + option_value.set_callback(cb); + cb(); } -CssFromConfigFont::CssFromConfigFont(std::string option_name, std::string css_before, std::string css_after) : +CssFromConfigFont::CssFromConfigFont(std::string option_name, std::string css_before, + std::string css_after) : CssFromConfig(option_name), option_value{option_name} { this->css_before = css_before; this->css_after = css_after; - provider = Gtk::CssProvider::create(); - option_value.set_callback([=] () + auto cb = [=] () { set_from_string(); - }); - - set_from_string(); - add_provider(); + }; + option_value.set_callback(cb); + cb(); } void CssFromConfigFont::set_from_string() @@ -156,7 +171,7 @@ void CssFromConfigFont::set_from_string() ss << css_before << "font: " << size << unit << " " << before.str() << " " << after.str() << ";" << css_after; auto css = ss.str(); - provider->load_from_string(css); + update_css(css); std::cout << "Font " << css << std::endl; } else @@ -165,18 +180,18 @@ void CssFromConfigFont::set_from_string() ss.imbue(std::locale::classic()); ss << css_before << "font: 1rem " << font_name << ";" << css_after; auto css = ss.str(); - provider->load_from_string(css); + update_css(css); std::cout << "Font fallback " << css << std::endl; } } -CssFromConfigEdge::CssFromConfigEdge(std::string config_opt, std::string height_opt, std::string width_opt) : +CssFromConfigEdge::CssFromConfigEdge(std::string config_opt, std::string height_opt, + std::string width_opt) : CssFromConfig(config_opt), option_value{config_opt}, height_value{height_opt}, width_value(width_opt) { - provider = Gtk::CssProvider::create(); - + instance_id = config_opt; auto callback = [=] () { std::stringstream ss; @@ -190,11 +205,15 @@ CssFromConfigEdge::CssFromConfigEdge(std::string config_opt, std::string height_ ss << ".wf-panel .widget-icon {-gtk-icon-size:" << width_value.value() << "px;}"; } - provider->load_from_string(ss.str()); + update_css(ss.str()); }; option_value.set_callback(callback); height_value.set_callback(callback); width_value.set_callback(callback); callback(); - add_provider(); +} + +CssStatic::CssStatic(std::string id, std::string rule) : CssFromConfig(id) +{ + update_css(rule); } diff --git a/src/util/css-config.hpp b/src/util/css-config.hpp index 90aae8676..5c51bcdf4 100644 --- a/src/util/css-config.hpp +++ b/src/util/css-config.hpp @@ -7,11 +7,19 @@ class CssFromConfig { + protected: + std::string instance_id; + void update_css(const std::string& css_string); + public: - Glib::RefPtr provider; + CssFromConfig(std::string instance_id); + virtual ~CssFromConfig(); + + private: + static Glib::RefPtr main_provider; + static std::map css_registry; - void add_provider(); - void remove_provider(); + static void rebuild_stylesheet(); }; class CssFromConfigDouble : public CssFromConfig @@ -72,3 +80,9 @@ class CssFromConfigEdge : public CssFromConfig public: CssFromConfigEdge(std::string config_opt, std::string height_opt, std::string width_opt); }; + +class CssStatic : public CssFromConfig +{ + public: + CssStatic(std::string id, std::string rule); +};