From 7a4a633d04ecfb3aad95fd3aa3de246d72676d7e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 25 May 2026 21:22:50 +0200 Subject: [PATCH] UI/Qt+WebContent: Refresh theme colors live Refresh Qt chrome palettes from the current color scheme when the application palette changes. Recompute autocomplete and location field colors and repaint WebContent immediately so theme changes do not require another interaction or restart. --- Services/WebContent/PageClient.cpp | 5 +- UI/Qt/Autocomplete.cpp | 68 +++++++++++++++---- UI/Qt/Autocomplete.h | 4 ++ UI/Qt/ChromeStyle.cpp | 102 +++++++++++++++++++++++++---- UI/Qt/ChromeStyle.h | 4 ++ UI/Qt/Icon.cpp | 22 ++++--- UI/Qt/LocationEdit.cpp | 44 +++++++++++-- UI/Qt/LocationEdit.h | 3 + UI/Qt/Tab.cpp | 4 ++ UI/Qt/WebContentView.cpp | 19 +++++- 10 files changed, 234 insertions(+), 41 deletions(-) diff --git a/Services/WebContent/PageClient.cpp b/Services/WebContent/PageClient.cpp index 6e96904514..c513637d7b 100644 --- a/Services/WebContent/PageClient.cpp +++ b/Services/WebContent/PageClient.cpp @@ -150,8 +150,11 @@ Gfx::Palette PageClient::palette() const void PageClient::set_palette_impl(Gfx::PaletteImpl& impl) { m_palette_impl = impl; - if (auto* document = page().top_level_browsing_context().active_document()) + if (auto* document = page().top_level_browsing_context().active_document()) { document->invalidate_style(Web::DOM::StyleInvalidationReason::SettingsChange); + document->set_needs_media_query_evaluation(); + } + request_frame(); } void PageClient::set_preferred_color_scheme(Web::CSS::PreferredColorScheme color_scheme) diff --git a/UI/Qt/Autocomplete.cpp b/UI/Qt/Autocomplete.cpp index d8e1fed770..4ccdd5cd8c 100644 --- a/UI/Qt/Autocomplete.cpp +++ b/UI/Qt/Autocomplete.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace Ladybird { @@ -87,6 +88,21 @@ static QFont autocomplete_section_header_font() return font; } +static QColor autocomplete_selection_fill(QPalette const& palette) +{ + auto surface = ChromeStyle::chrome_surface(palette); + return ChromeStyle::is_dark(palette) + ? ChromeStyle::mix(surface, QColor(92, 112, 140), 0.54) + : ChromeStyle::mix(surface, palette.color(QPalette::Highlight), 0.10); +} + +static QColor autocomplete_selection_border(QPalette const& palette) +{ + return ChromeStyle::is_dark(palette) + ? ChromeStyle::mix(autocomplete_selection_fill(palette), QColor(160, 176, 198), 0.32) + : ChromeStyle::mix(ChromeStyle::chrome_border(palette), palette.color(QPalette::Highlight), 0.12); +} + class AutocompleteModel final : public QAbstractListModel { public: explicit AutocompleteModel(QObject* parent) @@ -257,7 +273,7 @@ public: if (kind == RowKind::SectionHeader) { auto text = index.data(HeaderTextRole).toString(); painter->setFont(autocomplete_section_header_font()); - auto header_color = option.palette.color(QPalette::PlaceholderText); + auto header_color = ChromeStyle::chrome_muted_text(option.palette); header_color.setAlpha(170); painter->setPen(header_color); auto rect = option.rect.adjusted( @@ -270,14 +286,10 @@ public: bool selected = option.state & QStyle::State_Selected; if (selected) { - auto fill = ChromeStyle::chrome_surface_hover(option.palette); - fill.setAlpha(190); - auto border = ChromeStyle::chrome_border(option.palette); - border.setAlpha(76); auto rect = option.rect.adjusted(3, 2, -3, -2); painter->setRenderHint(QPainter::Antialiasing, true); - painter->setPen(QPen(border, 1)); - painter->setBrush(fill); + painter->setPen(QPen(autocomplete_selection_border(option.palette), 1)); + painter->setBrush(autocomplete_selection_fill(option.palette)); painter->drawRoundedRect(rect, 7, 7); } @@ -314,13 +326,13 @@ public: int block_y = option.rect.top() + (option.rect.height() - block_height) / 2; painter->setFont(autocomplete_primary_font()); - painter->setPen(option.palette.color(QPalette::Text)); + painter->setPen(ChromeStyle::chrome_text(option.palette)); auto elided_title = primary_fm.elidedText(title_text, Qt::ElideRight, text_width); painter->drawText(QRect(text_x, block_y, text_width, primary_fm.height()), Qt::AlignLeft | Qt::AlignVCenter, elided_title); painter->setFont(autocomplete_secondary_font()); - auto secondary_color = option.palette.color(QPalette::PlaceholderText); + auto secondary_color = ChromeStyle::chrome_muted_text(option.palette); secondary_color.setAlpha(180); painter->setPen(secondary_color); auto elided_secondary = secondary_fm.elidedText(secondary_text, Qt::ElideRight, text_width); @@ -330,7 +342,7 @@ public: Qt::AlignLeft | Qt::AlignVCenter, elided_secondary); } else { painter->setFont(QApplication::font()); - painter->setPen(option.palette.color(QPalette::Text)); + painter->setPen(ChromeStyle::chrome_text(option.palette)); QFontMetrics fm(QApplication::font()); auto elided_url = fm.elidedText(url_text, Qt::ElideRight, text_width); painter->drawText( @@ -356,7 +368,6 @@ Autocomplete::Autocomplete(QLineEdit* anchor) m_popup->setFrameShape(QFrame::StyledPanel); m_popup->setFrameShadow(QFrame::Raised); m_popup->setAutoFillBackground(true); - m_popup->setStyleSheet(ChromeStyle::autocomplete_popup_style_sheet(m_anchor->palette())); m_popup->hide(); m_list_view = new QListView(m_popup); @@ -372,6 +383,7 @@ Autocomplete::Autocomplete(QLineEdit* anchor) m_delegate = new AutocompleteDelegate(this); m_list_view->setModel(m_model); m_list_view->setItemDelegate(m_delegate); + update_chrome_style(); auto* layout = new QVBoxLayout(m_popup); layout->setContentsMargins(0, POPUP_PADDING, 0, POPUP_PADDING); @@ -416,6 +428,33 @@ void Autocomplete::cancel_pending_query() m_autocomplete->cancel_pending_query(); } +void Autocomplete::update_chrome_style() +{ + if (m_is_updating_chrome_style) + return; + + m_is_updating_chrome_style = true; + auto palette = m_anchor->palette(); + m_popup->setPalette(palette); + m_list_view->setPalette(palette); + m_popup->setStyleSheet(ChromeStyle::autocomplete_popup_style_sheet(palette)); + m_popup->update(); + m_list_view->viewport()->update(); + m_is_updating_chrome_style = false; +} + +void Autocomplete::schedule_chrome_style_update() +{ + if (m_has_pending_chrome_style_update) + return; + + m_has_pending_chrome_style_update = true; + QTimer::singleShot(0, this, [this] { + m_has_pending_chrome_style_update = false; + update_chrome_style(); + }); +} + void Autocomplete::show_with_suggestions(Vector suggestions, int selected_suggestion_index) { m_model->set_suggestions(move(suggestions)); @@ -424,7 +463,7 @@ void Autocomplete::show_with_suggestions(Vector return; } - m_popup->setStyleSheet(ChromeStyle::autocomplete_popup_style_sheet(m_anchor->palette())); + update_chrome_style(); position_popup(); if (!m_popup->isVisible()) m_popup->show(); @@ -514,6 +553,11 @@ bool Autocomplete::select_previous_suggestion() bool Autocomplete::eventFilter(QObject* watched, QEvent* event) { + auto type = event->type(); + if (type == QEvent::ApplicationPaletteChange || type == QEvent::ThemeChange + || (type == QEvent::PaletteChange && (watched == m_anchor || watched == m_popup || watched == m_list_view))) + schedule_chrome_style_update(); + if (event->type() == QEvent::MouseButtonPress && is_visible()) { auto* mouse_event = static_cast(event); auto global = mouse_event->globalPosition().toPoint(); diff --git a/UI/Qt/Autocomplete.h b/UI/Qt/Autocomplete.h index 548195b9e6..f66ce15ddf 100644 --- a/UI/Qt/Autocomplete.h +++ b/UI/Qt/Autocomplete.h @@ -37,6 +37,8 @@ public: void query_autocomplete_engine(String); void cancel_pending_query(); + void update_chrome_style(); + void schedule_chrome_style_update(); void show_with_suggestions(Vector, int selected_suggestion_index); bool close(); @@ -66,6 +68,8 @@ private: QListView* m_list_view { nullptr }; AutocompleteModel* m_model { nullptr }; AutocompleteDelegate* m_delegate { nullptr }; + bool m_is_updating_chrome_style { false }; + bool m_has_pending_chrome_style_update { false }; NonnullOwnPtr m_autocomplete; }; diff --git a/UI/Qt/ChromeStyle.cpp b/UI/Qt/ChromeStyle.cpp index 3363f16cf4..e53f414faa 100644 --- a/UI/Qt/ChromeStyle.cpp +++ b/UI/Qt/ChromeStyle.cpp @@ -6,14 +6,75 @@ #include +#include +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) +# include +#endif + namespace Ladybird::ChromeStyle { -static bool is_dark(QPalette const& palette) +static bool color_is_dark(QColor const& color) { - return palette.color(QPalette::Window).lightness() < 128; + return color.lightness() < 128; } -static QColor mix(QColor const& from, QColor const& to, double amount) +static bool palette_is_dark(QPalette const& palette) +{ + return color_is_dark(palette.color(QPalette::Window)); +} + +bool is_dark(QPalette const& palette) +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) + auto color_scheme = QGuiApplication::styleHints()->colorScheme(); + if (color_scheme != Qt::ColorScheme::Unknown) + return color_scheme == Qt::ColorScheme::Dark; +#endif + + return palette_is_dark(palette); +} + +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) +static bool palette_roles_match_color_scheme(QPalette const& palette, bool dark) +{ + return color_is_dark(palette.color(QPalette::Window)) == dark + && color_is_dark(palette.color(QPalette::Base)) == dark + && color_is_dark(palette.color(QPalette::Text)) != dark + && color_is_dark(palette.color(QPalette::ButtonText)) != dark; +} +#endif + +static bool palette_matches_current_color_scheme(QPalette const& palette) +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) + auto color_scheme = QGuiApplication::styleHints()->colorScheme(); + if (color_scheme == Qt::ColorScheme::Dark) + return palette_roles_match_color_scheme(palette, true); + if (color_scheme == Qt::ColorScheme::Light) + return palette_roles_match_color_scheme(palette, false); +#endif + + Q_UNUSED(palette); + return true; +} + +static QColor chrome_window(QPalette const& palette) +{ + if (palette_matches_current_color_scheme(palette)) + return palette.color(QPalette::Window); + + return is_dark(palette) ? QColor(26, 29, 36) : QColor(244, 246, 248); +} + +static QColor chrome_base(QPalette const& palette) +{ + if (palette_matches_current_color_scheme(palette)) + return palette.color(QPalette::Base); + + return is_dark(palette) ? QColor(24, 29, 38) : QColor(255, 255, 255); +} + +QColor mix(QColor const& from, QColor const& to, double amount) { auto channel = [&](int from_channel, int to_channel) { return static_cast(from_channel + (to_channel - from_channel) * amount); @@ -28,7 +89,7 @@ static QColor mix(QColor const& from, QColor const& to, double amount) QColor chrome_background(QPalette const& palette) { - auto window = palette.color(QPalette::Window); + auto window = chrome_window(palette); return is_dark(palette) ? mix(window, QColor(10, 16, 24), 0.72) : mix(window, QColor(241, 245, 249), 0.62); @@ -36,7 +97,7 @@ QColor chrome_background(QPalette const& palette) QColor chrome_surface(QPalette const& palette) { - auto base = palette.color(QPalette::Base); + auto base = chrome_base(palette); return is_dark(palette) ? mix(base, QColor(31, 39, 52), 0.64) : mix(base, QColor(255, 255, 255), 0.72); @@ -70,8 +131,27 @@ QColor chrome_accent(QPalette const& palette) return palette.color(QPalette::Highlight); } +QColor chrome_text(QPalette const& palette) +{ + if (palette_matches_current_color_scheme(palette)) + return palette.color(QPalette::Text); + + return is_dark(palette) ? QColor(238, 241, 246) : QColor(24, 29, 36); +} + +QColor chrome_button_text(QPalette const& palette) +{ + if (palette_matches_current_color_scheme(palette)) + return palette.color(QPalette::ButtonText); + + return chrome_text(palette); +} + QColor chrome_muted_text(QPalette const& palette) { + if (!palette_matches_current_color_scheme(palette)) + return is_dark(palette) ? QColor(154, 163, 176) : QColor(98, 108, 122); + return palette.color(QPalette::PlaceholderText); } @@ -88,7 +168,7 @@ QString navigation_toolbar_style_sheet(QPalette const& palette) auto surface_pressed = style_sheet_color(chrome_surface_pressed(palette)); auto border = style_sheet_color(chrome_border(palette)); auto separator = style_sheet_color(mix(chrome_background(palette), chrome_border(palette), is_dark(palette) ? 0.28 : 0.56)); - auto text = style_sheet_color(palette.color(QPalette::ButtonText)); + auto text = style_sheet_color(chrome_button_text(palette)); auto disabled_text = style_sheet_color(chrome_muted_text(palette)); return QStringLiteral(R"( @@ -143,7 +223,7 @@ QString location_edit_style_sheet(QPalette const& palette) auto hover = style_sheet_color(hover_color); auto border = style_sheet_color(chrome_border(palette)); auto focus_border = style_sheet_color(mix(chrome_border(palette), chrome_accent(palette), is_dark(palette) ? 0.46 : 0.58)); - auto text = style_sheet_color(palette.color(QPalette::Text)); + auto text = style_sheet_color(chrome_text(palette)); auto placeholder = style_sheet_color(chrome_muted_text(palette)); auto selection = style_sheet_color(chrome_accent(palette)); auto selection_text = style_sheet_color(palette.color(QPalette::HighlightedText)); @@ -199,7 +279,7 @@ QString bookmarks_bar_style_sheet(QPalette const& palette) auto hover = style_sheet_color(chrome_surface_hover(palette)); auto pressed = style_sheet_color(chrome_surface_pressed(palette)); auto border = style_sheet_color(chrome_border(palette)); - auto text = style_sheet_color(palette.color(QPalette::ButtonText)); + auto text = style_sheet_color(chrome_button_text(palette)); return QStringLiteral(R"( QToolBar#LadybirdBookmarksBar { @@ -241,7 +321,7 @@ QString find_in_page_style_sheet(QPalette const& palette) auto pressed = style_sheet_color(chrome_surface_pressed(palette)); auto border = style_sheet_color(chrome_border(palette)); auto accent = style_sheet_color(chrome_accent(palette)); - auto text = style_sheet_color(palette.color(QPalette::Text)); + auto text = style_sheet_color(chrome_text(palette)); auto muted = style_sheet_color(chrome_muted_text(palette)); return QStringLiteral(R"( @@ -297,7 +377,7 @@ QString tab_widget_style_sheet(QPalette const& palette) auto hover = style_sheet_color(chrome_surface_hover(palette)); auto pressed = style_sheet_color(chrome_surface_pressed(palette)); auto border = style_sheet_color(chrome_border(palette)); - auto text = style_sheet_color(palette.color(QPalette::ButtonText)); + auto text = style_sheet_color(chrome_button_text(palette)); auto close_hover = style_sheet_color(QColor(196, 43, 28)); auto close_text = style_sheet_color(QColor(255, 255, 255)); @@ -379,7 +459,7 @@ QString autocomplete_popup_style_sheet(QPalette const& palette) { auto surface = style_sheet_color(chrome_surface(palette)); auto border = style_sheet_color(chrome_border(palette)); - auto text = style_sheet_color(palette.color(QPalette::Text)); + auto text = style_sheet_color(chrome_text(palette)); return QStringLiteral(R"( QFrame#LadybirdAutocompletePopup { diff --git a/UI/Qt/ChromeStyle.h b/UI/Qt/ChromeStyle.h index da0ec7f339..41b97804d9 100644 --- a/UI/Qt/ChromeStyle.h +++ b/UI/Qt/ChromeStyle.h @@ -12,6 +12,10 @@ namespace Ladybird::ChromeStyle { +bool is_dark(QPalette const&); +QColor mix(QColor const& from, QColor const& to, double amount); +QColor chrome_text(QPalette const&); +QColor chrome_button_text(QPalette const&); QColor chrome_background(QPalette const&); QColor chrome_surface(QPalette const&); QColor chrome_surface_hover(QPalette const&); diff --git a/UI/Qt/Icon.cpp b/UI/Qt/Icon.cpp index cab40231e0..51d0354f0b 100644 --- a/UI/Qt/Icon.cpp +++ b/UI/Qt/Icon.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -198,12 +199,17 @@ static QIcon create_y_offset_icon(QIcon const& source, int y_offset) QIcon create_chrome_icon(ChromeIcon icon, QPalette const& palette) { - if (icon == ChromeIcon::Reload) - return create_y_offset_icon(create_tvg_icon_with_theme_colors("reload", palette), 1); - if (icon == ChromeIcon::Globe) - return create_y_offset_icon(create_tvg_icon_with_theme_colors("globe", palette, 202, 96, 236, 236), 1); + auto chrome_palette = palette; + chrome_palette.setColor(QPalette::Normal, QPalette::ButtonText, ChromeStyle::chrome_button_text(palette)); + chrome_palette.setColor(QPalette::Active, QPalette::ButtonText, ChromeStyle::chrome_button_text(palette)); + chrome_palette.setColor(QPalette::Disabled, QPalette::ButtonText, ChromeStyle::chrome_muted_text(palette)); - auto normal = palette.color(QPalette::ColorGroup::Normal, QPalette::ColorRole::ButtonText); + if (icon == ChromeIcon::Reload) + return create_y_offset_icon(create_tvg_icon_with_theme_colors("reload", chrome_palette), 1); + if (icon == ChromeIcon::Globe) + return create_y_offset_icon(create_tvg_icon_with_theme_colors("globe", chrome_palette, 202, 96, 236, 236), 1); + + auto normal = ChromeStyle::chrome_button_text(palette); auto normal_alpha = 216; if (icon == ChromeIcon::Close) normal_alpha = 172; @@ -211,10 +217,10 @@ QIcon create_chrome_icon(ChromeIcon icon, QPalette const& palette) normal_alpha = 204; normal.setAlpha(normal_alpha); - auto active = palette.color(QPalette::ColorGroup::Active, QPalette::ColorRole::ButtonText); + auto active = ChromeStyle::chrome_button_text(palette); active.setAlpha(icon == ChromeIcon::Close ? 220 : 236); - auto disabled = palette.color(QPalette::ColorGroup::Disabled, QPalette::ColorRole::ButtonText); + auto disabled = ChromeStyle::chrome_muted_text(palette); disabled.setAlpha(icon == ChromeIcon::Close ? 78 : 96); QIcon qicon; @@ -237,7 +243,7 @@ QIcon loading_spinner_icon(QPalette const& palette, int frame) painter.setRenderHint(QPainter::Antialiasing); painter.translate(icon_size / 2.0, icon_size / 2.0); - auto color = palette.color(QPalette::Text); + auto color = ChromeStyle::chrome_text(palette); for (int segment = 0; segment < segment_count; ++segment) { auto segment_color = color; segment_color.setAlpha(((segment - frame + segment_count) % segment_count + 1) * 255 / segment_count); diff --git a/UI/Qt/LocationEdit.cpp b/UI/Qt/LocationEdit.cpp index cc6066c038..80c21f8433 100644 --- a/UI/Qt/LocationEdit.cpp +++ b/UI/Qt/LocationEdit.cpp @@ -20,10 +20,14 @@ #include #include #include +#include #include #include #include #include +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) +# include +#endif #include #include #include @@ -33,7 +37,7 @@ namespace Ladybird { static QColor location_focus_glow_color(QPalette const& palette, int alpha) { - auto color = palette.color(QPalette::Highlight); + auto color = ChromeStyle::chrome_accent(palette); color.setAlpha(alpha); return color; } @@ -270,6 +274,12 @@ LocationEdit::LocationEdit(QWidget* parent) highlight_location(); update_location_icon(); }); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) + connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, [this] { + schedule_chrome_style_update(); + }); +#endif } void LocationEdit::set_trailing_action(QAction* action) @@ -278,13 +288,16 @@ void LocationEdit::set_trailing_action(QAction* action) m_trailing_action_button->setVisible(action != nullptr); } +QAction* LocationEdit::trailing_action() const +{ + return m_trailing_action_button->defaultAction(); +} + void LocationEdit::changeEvent(QEvent* event) { QLineEdit::changeEvent(event); - if (event->type() == QEvent::PaletteChange) { - update_chrome_style(); - update_focus_glow(m_focus_glow_alpha); - update_location_icon(); + if (event->type() == QEvent::PaletteChange || event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::ThemeChange) { + schedule_chrome_style_update(); } } @@ -402,6 +415,23 @@ void LocationEdit::update_chrome_style() m_is_updating_chrome_style = false; } +void LocationEdit::schedule_chrome_style_update() +{ + if (m_has_pending_chrome_style_update) + return; + + m_has_pending_chrome_style_update = true; + QTimer::singleShot(0, this, [this] { + m_has_pending_chrome_style_update = false; + update_chrome_style(); + m_autocomplete->schedule_chrome_style_update(); + update_focus_glow(m_focus_glow_alpha); + update_location_icon(); + highlight_location(); + update(); + }); +} + void LocationEdit::update_placeholder() { if (auto const& search_engine = WebView::Application::settings().search_engine(); search_engine.has_value()) { @@ -447,14 +477,14 @@ void LocationEdit::highlight_location() QList attributes; if (auto url_parts = WebView::break_url_into_parts(url); url_parts.has_value()) { - auto darkened_text_color = QPalette().color(QPalette::Text); + auto darkened_text_color = ChromeStyle::chrome_text(palette()); darkened_text_color.setAlpha(127); QTextCharFormat dark_attributes; dark_attributes.setForeground(darkened_text_color); QTextCharFormat highlight_attributes; - highlight_attributes.setForeground(QPalette().color(QPalette::Text)); + highlight_attributes.setForeground(ChromeStyle::chrome_text(palette())); attributes.append({ QInputMethodEvent::TextFormat, diff --git a/UI/Qt/LocationEdit.h b/UI/Qt/LocationEdit.h index c1241361c2..b022a370bc 100644 --- a/UI/Qt/LocationEdit.h +++ b/UI/Qt/LocationEdit.h @@ -37,6 +37,7 @@ public: explicit LocationEdit(QWidget*); void set_trailing_action(QAction*); + QAction* trailing_action() const; Optional url() const { return m_url; } void set_url(Optional); @@ -60,6 +61,7 @@ private: void update_location_icon(); void update_loading_icon(); void update_focus_glow(int alpha); + void schedule_chrome_style_update(); void animate_focus_glow(int target_alpha); void highlight_location(); bool text_matches_current_url() const; @@ -83,6 +85,7 @@ private: bool m_url_is_hidden { false }; bool m_is_loading { false }; bool m_is_updating_chrome_style { false }; + bool m_has_pending_chrome_style_update { false }; int m_focus_glow_alpha { 0 }; int m_loading_animation_frame { 0 }; diff --git a/UI/Qt/Tab.cpp b/UI/Qt/Tab.cpp index 2845f5908f..1a075c8287 100644 --- a/UI/Qt/Tab.cpp +++ b/UI/Qt/Tab.cpp @@ -674,6 +674,10 @@ void Tab::recreate_toolbar_icons() m_reload_action->setIcon(create_chrome_icon(ChromeIcon::Reload, palette())); m_window->new_tab_action().setIcon(create_chrome_icon(ChromeIcon::NewTab, palette())); m_hamburger_button->setIcon(create_chrome_icon(ChromeIcon::Menu, palette())); + if (auto* action = m_location_edit->trailing_action()) { + auto icon = view().toggle_bookmark_action().engaged() ? ChromeIcon::StarFilled : ChromeIcon::Star; + action->setIcon(create_chrome_icon(icon, palette())); + } } void Tab::show_find_in_page() diff --git a/UI/Qt/WebContentView.cpp b/UI/Qt/WebContentView.cpp index 2b614c83cb..bc142cfcff 100644 --- a/UI/Qt/WebContentView.cpp +++ b/UI/Qt/WebContentView.cpp @@ -40,6 +40,9 @@ #include #include #include +#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) +# include +#endif #include #include #include @@ -71,6 +74,15 @@ WebContentView::WebContentView(QWidget* window, RefPtr= QT_VERSION_CHECK(6, 5, 0) + QObject::connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged, this, [this] { + QTimer::singleShot(0, this, [this] { + update_palette(); + update(); + }); + }); +#endif + m_tooltip_hover_timer.setSingleShot(true); QObject::connect(&m_tooltip_hover_timer, &QTimer::timeout, [this] { @@ -784,8 +796,11 @@ bool WebContentView::event(QEvent* event) return true; } - if (event->type() == QEvent::PaletteChange) { - update_palette(); + if (event->type() == QEvent::PaletteChange || event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::ThemeChange) { + QTimer::singleShot(0, this, [this] { + update_palette(); + update(); + }); return QWidget::event(event); }