Skip to content

Commit 87dc3dc

Browse files
shanselmanCopilot
andauthored
Fix user chat bubble text rendering
Fixes #880 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d08a3e7 commit 87dc3dc

2 files changed

Lines changed: 54 additions & 0 deletions

File tree

src/OpenClaw.Tray.WinUI/Chat/OpenClawChatTimeline.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ private static readonly System.Runtime.CompilerServices.ConditionalWeakTable<Tex
141141
private const string MonoFontFamilySource = "Cascadia Code, Cascadia Mono, Consolas";
142142
private static readonly System.Runtime.CompilerServices.ConditionalWeakTable<
143143
Microsoft.UI.Dispatching.DispatcherQueue, FontFamily> s_monoFontByDispatcher = new();
144+
private const string ChatTextFontFamilySource = "Segoe UI Variable Text, Segoe UI";
145+
private static readonly System.Runtime.CompilerServices.ConditionalWeakTable<
146+
Microsoft.UI.Dispatching.DispatcherQueue, FontFamily> s_chatTextFontByDispatcher = new();
144147
private static FontFamily s_monoFontFamily
145148
{
146149
get
@@ -158,6 +161,23 @@ private static FontFamily s_monoFontFamily
158161
return family;
159162
}
160163
}
164+
private static FontFamily s_chatTextFontFamily
165+
{
166+
get
167+
{
168+
var dispatcher = Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread();
169+
if (dispatcher is null)
170+
{
171+
return new FontFamily(ChatTextFontFamilySource);
172+
}
173+
if (!s_chatTextFontByDispatcher.TryGetValue(dispatcher, out var family))
174+
{
175+
family = new FontFamily(ChatTextFontFamilySource);
176+
s_chatTextFontByDispatcher.Add(dispatcher, family);
177+
}
178+
return family;
179+
}
180+
}
161181

162182
// Per-DispatcherQueue selection-highlight brushes for the user
163183
// bubble. The bubble background is the user's chosen system accent
@@ -1117,6 +1137,14 @@ Element RenderUserEntry(ChatTimelineItem entry, bool startsBurst, bool endsBurst
11171137
t.FontSize = 14;
11181138
t.Foreground = userBubbleFg;
11191139
t.IsTextSelectionEnabled = true;
1140+
t.FontFamily = s_chatTextFontFamily;
1141+
t.TextTrimming = TextTrimming.None;
1142+
t.MaxLines = 0;
1143+
t.LineHeight = 0;
1144+
t.CharacterSpacing = 0;
1145+
t.Width = double.NaN;
1146+
t.MinWidth = 0;
1147+
t.MaxWidth = double.PositiveInfinity;
11201148
// The default SelectionHighlightColor is the
11211149
// system accent — which equals the user bubble's
11221150
// background — so the highlight band is invisible
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Text.RegularExpressions;
2+
3+
namespace OpenClaw.Tray.Tests;
4+
5+
public sealed class ChatUserBubbleTextContractTests
6+
{
7+
[Fact]
8+
public void UserPromptText_ResetsStaleTextBlockVisualStateBeforeApplyingInlines()
9+
{
10+
var timeline = Read("src", "OpenClaw.Tray.WinUI", "Chat", "OpenClawChatTimeline.cs");
11+
12+
Assert.Contains("private const string ChatTextFontFamilySource", timeline);
13+
Assert.Contains("TextBlock(string.Empty)", timeline);
14+
Assert.Contains("t.FontFamily = s_chatTextFontFamily;", timeline);
15+
Assert.Contains("t.TextTrimming = TextTrimming.None;", timeline);
16+
Assert.Contains("t.MaxLines = 0;", timeline);
17+
Assert.Contains("t.Width = double.NaN;", timeline);
18+
Assert.Contains("t.MaxWidth = double.PositiveInfinity;", timeline);
19+
Assert.Matches(
20+
new Regex(@"t\.TextTrimming\s*=\s*TextTrimming\.None;[\s\S]*ApplyPlainSelectableInlines\(t,\s*messageText\);"),
21+
timeline);
22+
}
23+
24+
private static string Read(params string[] parts)
25+
=> File.ReadAllText(Path.Combine(new[] { TestRepositoryPaths.GetRepositoryRoot() }.Concat(parts).ToArray()));
26+
}

0 commit comments

Comments
 (0)