From d819152b4ee0d3cfdb00c94e727e3e9258c786ac Mon Sep 17 00:00:00 2001 From: Jelle Raaijmakers Date: Thu, 18 Jun 2026 13:09:01 +0200 Subject: [PATCH] LibGfx+LibWeb: Preserve text color for selections Selecting text without custom ::selection styling changed the foreground color of the selected content. This was especially visible for links, where the text changed color but the underline did not. The default selection style supplied both a selection background and a foreground color from the palette or HighlightText system color. That made ordinary selections behave as if the page had explicitly styled ::selection color. Only provide a default selection background, so selected content keeps its own foreground color unless CSS overrides it. Remove the now-unused SelectionText palette role. --- Base/res/themes/Dark.ini | 1 - Base/res/themes/Default.ini | 1 - Libraries/LibGfx/Palette.h | 1 - Libraries/LibGfx/SystemTheme.h | 1 - Libraries/LibWeb/Painting/Paintable.cpp | 15 +++------------ Libraries/LibWeb/Painting/Paintable.h | 6 +++--- .../selection-default-color-scheme-ref.html | 4 ++-- ...-default-forced-dark-color-scheme-ref.html | 2 +- .../expected/selection-default-link-ref.html | 3 ++- ...on-default-meta-dark-color-scheme-ref.html | 2 +- ...t-normal-forced-dark-color-scheme-ref.html | 2 +- .../expected/selection-with-image-ref.html | 2 +- .../expected-macos/selection-text-color.png | Bin 5894 -> 5974 bytes .../expected/selection-text-color.png | Bin 5891 -> 6005 bytes .../input/selection-text-color.html | 1 - ...decoration-underline-partial-selection.txt | 2 +- UI/AppKit/Interface/Palette.mm | 1 - UI/Qt/WebContentView.cpp | 1 - 18 files changed, 15 insertions(+), 30 deletions(-) diff --git a/Base/res/themes/Dark.ini b/Base/res/themes/Dark.ini index 3d9e4fe53d..aea1d17b3f 100644 --- a/Base/res/themes/Dark.ini +++ b/Base/res/themes/Dark.ini @@ -35,7 +35,6 @@ ThreedShadow1=#3d3e40 ThreedShadow2=#2e2f30 HoverHighlight=#696969 Selection=#14141a -SelectionText=white InactiveSelection=#606060 InactiveSelectionText=white RubberBandFill=#8080803c diff --git a/Base/res/themes/Default.ini b/Base/res/themes/Default.ini index 5706efa5fb..5d127986c4 100644 --- a/Base/res/themes/Default.ini +++ b/Base/res/themes/Default.ini @@ -43,7 +43,6 @@ ThreedShadow1=#808080 ThreedShadow2=#404040 HoverHighlight=#e3dfdb Selection=#84351a -SelectionText=white InactiveSelection=#606060 InactiveSelectionText=white PlaceholderText=#808080 diff --git a/Libraries/LibGfx/Palette.h b/Libraries/LibGfx/Palette.h index 5c80b9e993..b583d0bba0 100644 --- a/Libraries/LibGfx/Palette.h +++ b/Libraries/LibGfx/Palette.h @@ -65,7 +65,6 @@ public: Color window() const { return color(ColorRole::Window); } Color window_text() const { return color(ColorRole::WindowText); } Color selection() const { return color(ColorRole::Selection); } - Color selection_text() const { return color(ColorRole::SelectionText); } Color inactive_selection() const { return color(ColorRole::InactiveSelection); } Color inactive_selection_text() const { return color(ColorRole::InactiveSelectionText); } Color desktop_background() const { return color(ColorRole::DesktopBackground); } diff --git a/Libraries/LibGfx/SystemTheme.h b/Libraries/LibGfx/SystemTheme.h index 11f1f61990..825704d242 100644 --- a/Libraries/LibGfx/SystemTheme.h +++ b/Libraries/LibGfx/SystemTheme.h @@ -86,7 +86,6 @@ namespace Gfx { C(RulerBorder) \ C(RulerInactiveText) \ C(Selection) \ - C(SelectionText) \ C(SyntaxComment) \ C(SyntaxControlKeyword) \ C(SyntaxIdentifier) \ diff --git a/Libraries/LibWeb/Painting/Paintable.cpp b/Libraries/LibWeb/Painting/Paintable.cpp index 60a798f8b1..956d3e11c3 100644 --- a/Libraries/LibWeb/Painting/Paintable.cpp +++ b/Libraries/LibWeb/Painting/Paintable.cpp @@ -302,20 +302,11 @@ Paintable::SelectionStyle Paintable::selection_style() const auto default_style_for_color_scheme = [&](CSS::PreferredColorScheme color_scheme, bool use_palette_for_normal_color_scheme = true) { auto palette = document().page().palette(); auto palette_color_scheme = palette.is_dark() ? CSS::PreferredColorScheme::Dark : CSS::PreferredColorScheme::Light; - if (color_scheme == palette_color_scheme || use_palette_for_normal_color_scheme) { - return SelectionStyle { - CSS::SystemColor::transform_selection_background_color(palette.selection()), - palette.selection_text(), - {}, - {}, - }; - } + if (color_scheme == palette_color_scheme || use_palette_for_normal_color_scheme) + return SelectionStyle { CSS::SystemColor::transform_selection_background_color(palette.selection()) }; return SelectionStyle { - CSS::SystemColor::transform_selection_background_color(CSS::SystemColor::highlight(color_scheme)), - CSS::SystemColor::highlight_text(color_scheme), - {}, - {}, + CSS::SystemColor::transform_selection_background_color(CSS::SystemColor::highlight(color_scheme)) }; }; diff --git a/Libraries/LibWeb/Painting/Paintable.h b/Libraries/LibWeb/Painting/Paintable.h index 3175d95044..661e1230bd 100644 --- a/Libraries/LibWeb/Painting/Paintable.h +++ b/Libraries/LibWeb/Painting/Paintable.h @@ -128,9 +128,9 @@ public: }; struct SelectionStyle { Color background_color; - Optional text_color; - Optional> text_shadow; - Optional text_decoration; + Optional text_color {}; + Optional> text_shadow {}; + Optional text_decoration {}; bool has_styling() const { diff --git a/Tests/LibWeb/Ref/expected/selection-default-color-scheme-ref.html b/Tests/LibWeb/Ref/expected/selection-default-color-scheme-ref.html index 32604abb05..1b8c1990f9 100644 --- a/Tests/LibWeb/Ref/expected/selection-default-color-scheme-ref.html +++ b/Tests/LibWeb/Ref/expected/selection-default-color-scheme-ref.html @@ -7,11 +7,11 @@ p { } .selected-light { background: rgba(101, 2, 0, 0.8); - color: white; + color: black; } .selected-dark { background: rgba(61, 174, 233, 0.5); - color: rgb(20, 20, 20); + color: black; } diff --git a/Tests/LibWeb/Ref/expected/selection-default-forced-dark-color-scheme-ref.html b/Tests/LibWeb/Ref/expected/selection-default-forced-dark-color-scheme-ref.html index fe42bfb64c..d9f7bb4ae7 100644 --- a/Tests/LibWeb/Ref/expected/selection-default-forced-dark-color-scheme-ref.html +++ b/Tests/LibWeb/Ref/expected/selection-default-forced-dark-color-scheme-ref.html @@ -7,7 +7,7 @@ p { } .selected { background: rgba(61, 174, 233, 0.5); - color: rgb(20, 20, 20); + color: black; } diff --git a/Tests/LibWeb/Ref/expected/selection-default-link-ref.html b/Tests/LibWeb/Ref/expected/selection-default-link-ref.html index 6440be9833..6b34ad4075 100644 --- a/Tests/LibWeb/Ref/expected/selection-default-link-ref.html +++ b/Tests/LibWeb/Ref/expected/selection-default-link-ref.html @@ -6,7 +6,8 @@ td { } .selected { background: rgba(101, 2, 0, 0.8); - color: white; + color: #000000; + text-decoration: none; } diff --git a/Tests/LibWeb/Ref/expected/selection-default-meta-dark-color-scheme-ref.html b/Tests/LibWeb/Ref/expected/selection-default-meta-dark-color-scheme-ref.html index 30f97395d7..de7234e1ed 100644 --- a/Tests/LibWeb/Ref/expected/selection-default-meta-dark-color-scheme-ref.html +++ b/Tests/LibWeb/Ref/expected/selection-default-meta-dark-color-scheme-ref.html @@ -8,7 +8,7 @@ p { } .selected { background: rgba(61, 174, 233, 0.5); - color: rgb(20, 20, 20); + color: rgb(235, 235, 235); } diff --git a/Tests/LibWeb/Ref/expected/selection-default-normal-forced-dark-color-scheme-ref.html b/Tests/LibWeb/Ref/expected/selection-default-normal-forced-dark-color-scheme-ref.html index 306b3669ba..beb18f68d5 100644 --- a/Tests/LibWeb/Ref/expected/selection-default-normal-forced-dark-color-scheme-ref.html +++ b/Tests/LibWeb/Ref/expected/selection-default-normal-forced-dark-color-scheme-ref.html @@ -7,7 +7,7 @@ p { } .selected { background: rgba(101, 2, 0, 0.8); - color: white; + color: black; } diff --git a/Tests/LibWeb/Ref/expected/selection-with-image-ref.html b/Tests/LibWeb/Ref/expected/selection-with-image-ref.html index 28e97742d4..3b6d2a3432 100644 --- a/Tests/LibWeb/Ref/expected/selection-with-image-ref.html +++ b/Tests/LibWeb/Ref/expected/selection-with-image-ref.html @@ -1,7 +1,7 @@