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); }