From 1476e73a0d00539d6aed9ef4fb4fcaaa903fb9fa Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Wed, 3 Jun 2026 08:00:22 +0000 Subject: [PATCH] Fix text selection brush not applying when text selection changes (#21480) * fix text selection brush not applying when text selection changes * only invalidate text cache on selection change when selection foreground is set --- .../Presenters/TextPresenter.cs | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs index 598ce4905c..6e6ab17853 100644 --- a/src/Avalonia.Controls/Presenters/TextPresenter.cs +++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs @@ -58,7 +58,7 @@ namespace Avalonia.Controls.Presenters /// public static readonly StyledProperty PreeditTextProperty = AvaloniaProperty.Register(nameof(PreeditText)); - + /// /// Defines the property. /// @@ -149,7 +149,7 @@ namespace Avalonia.Controls.Presenters get => GetValue(PreeditTextProperty); set => SetValue(PreeditTextProperty, value); } - + public int? PreeditTextCursorPosition { get => GetValue(PreeditTextCursorPositionProperty); @@ -427,11 +427,11 @@ namespace Avalonia.Controls.Presenters } } - if(VisualRoot is Visual root) + if (VisualRoot is Visual root) { var offset = this.TranslatePoint(Bounds.Position, root); - if(_previousOffset != offset) + if (_previousOffset != offset) { _previousOffset = offset; } @@ -778,7 +778,7 @@ namespace Avalonia.Controls.Presenters CaretChanged(); } - + private void EnsureCaretTimer() { if (_caretTimer == null) @@ -804,7 +804,7 @@ namespace Avalonia.Controls.Presenters _caretTimer = null; } - if (CaretBlinkInterval.TotalMilliseconds > 0) + if (CaretBlinkInterval.TotalMilliseconds > 0) { _caretTimer = new DispatcherTimer { Interval = CaretBlinkInterval }; _caretTimer.Tick += CaretTimerTick; @@ -977,7 +977,7 @@ namespace Avalonia.Controls.Presenters internal void RemoveTextSelectionCanvas() { - if(_layer != null && TextSelectionHandleCanvas is { } canvas) + if (_layer != null && TextSelectionHandleCanvas is { } canvas) { canvas.SetPresenter(null); _layer.Remove(canvas); @@ -998,7 +998,7 @@ namespace Avalonia.Controls.Presenters _caretTimer.Tick -= CaretTimerTick; } } - + private void OnPreeditChanged(string? preeditText, int? cursorPosition) { if (string.IsNullOrEmpty(preeditText)) @@ -1025,17 +1025,17 @@ namespace Avalonia.Controls.Presenters MoveCaretToTextPosition(change.GetNewValue()); } - if(change.Property == PreeditTextProperty) + if (change.Property == PreeditTextProperty) { OnPreeditChanged(change.NewValue as string, PreeditTextCursorPosition); } - - if(change.Property == PreeditTextCursorPositionProperty) + + if (change.Property == PreeditTextCursorPositionProperty) { OnPreeditChanged(PreeditText, PreeditTextCursorPosition); } - if(change.Property == TextProperty || change.Property == CaretIndexProperty) + if (change.Property == TextProperty || change.Property == CaretIndexProperty) { if (!string.IsNullOrEmpty(PreeditText)) { @@ -1063,6 +1063,8 @@ namespace Avalonia.Controls.Presenters case nameof(PasswordChar): case nameof(RevealPassword): case nameof(FlowDirection): + case nameof(SelectionForegroundBrush): + case nameof(ShowSelectionHighlight): { InvalidateTextLayout(); break; @@ -1071,12 +1073,21 @@ namespace Avalonia.Controls.Presenters case nameof(TextAlignment): case nameof(TextWrapping): case nameof(LineHeight): + { + InvalidateTextLayoutKeepCache(); + break; + } case nameof(SelectionStart): case nameof(SelectionEnd): - case nameof(SelectionForegroundBrush): - case nameof(ShowSelectionHighlight): { - InvalidateTextLayoutKeepCache(); + if (SelectionForegroundBrush != null) + { + InvalidateTextLayout(); + } + else + { + InvalidateTextLayoutKeepCache(); + } break; } }