Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/OpenClaw.SetupEngine.UI/IconFonts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;

namespace OpenClaw.SetupEngine.UI;

internal static class IconFonts
{
public static FontFamily SymbolThemeFontFamily =>
(FontFamily)Application.Current.Resources["SymbolThemeFontFamily"];
}
2 changes: 1 addition & 1 deletion src/OpenClaw.SetupEngine.UI/Pages/CapabilitiesPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private void BuildToggles()
var icon = new TextBlock
{
Text = glyph,
FontFamily = new Microsoft.UI.Xaml.Media.FontFamily("Segoe Fluent Icons"),
FontFamily = IconFonts.SymbolThemeFontFamily,
FontSize = 20,
VerticalAlignment = VerticalAlignment.Center,
Margin = new Thickness(0, 0, 12, 0),
Expand Down
4 changes: 2 additions & 2 deletions src/OpenClaw.SetupEngine.UI/Pages/CompletePage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
CornerRadius="48" HorizontalAlignment="Center"
Margin="0,0,0,20" Visibility="Collapsed"
Background="#3CFF4444">
<TextBlock Text="&#xE783;" FontFamily="Segoe Fluent Icons"
<TextBlock Text="&#xE783;" FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="42" Foreground="#FF6B6B"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
Expand Down Expand Up @@ -58,7 +58,7 @@
Margin="0,20,0,0">
<StackPanel Spacing="6">
<StackPanel Orientation="Horizontal" Spacing="10">
<TextBlock Text="&#xE7BA;" FontFamily="Segoe Fluent Icons" FontSize="16"
<TextBlock Text="&#xE7BA;" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="16"
VerticalAlignment="Center" Foreground="#FFC107" />
<TextBlock Text="Node Mode Active" FontSize="15" FontWeight="SemiBold" />
</StackPanel>
Expand Down
2 changes: 1 addition & 1 deletion src/OpenClaw.SetupEngine.UI/Pages/PermissionsPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<Button x:Name="RefreshButton" HorizontalAlignment="Right"
Padding="12,8,12,8" Click="Refresh_Click">
<StackPanel Orientation="Horizontal" Spacing="8">
<TextBlock Text="&#xE72C;" FontFamily="Segoe Fluent Icons" FontSize="14"
<TextBlock Text="&#xE72C;" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="14"
VerticalAlignment="Center" />
<TextBlock Text="Refresh status" FontSize="13" VerticalAlignment="Center" />
</StackPanel>
Expand Down
4 changes: 2 additions & 2 deletions src/OpenClaw.SetupEngine.UI/Pages/PermissionsPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private static FrameworkElement BuildRow(PermDef perm, string status, bool grant
Child = new TextBlock
{
Text = perm.Glyph,
FontFamily = new FontFamily("Segoe Fluent Icons"),
FontFamily = IconFonts.SymbolThemeFontFamily,
FontSize = 20,
Foreground = new SolidColorBrush(isDark ? Microsoft.UI.Colors.White : Microsoft.UI.Colors.White),
HorizontalAlignment = HorizontalAlignment.Center,
Expand Down Expand Up @@ -97,7 +97,7 @@ private static FrameworkElement BuildRow(PermDef perm, string status, bool grant
var btnContent = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 6 };
btnContent.Children.Add(new TextBlock
{
Text = "\uE8A7", FontFamily = new FontFamily("Segoe Fluent Icons"),
Text = "\uE8A7", FontFamily = IconFonts.SymbolThemeFontFamily,
FontSize = 14, VerticalAlignment = VerticalAlignment.Center
});
btnContent.Children.Add(new TextBlock { Text = "Open Settings", FontSize = 13, VerticalAlignment = VerticalAlignment.Center });
Expand Down
2 changes: 1 addition & 1 deletion src/OpenClaw.SetupEngine.UI/Pages/ProgressPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ private static Border CreateIconBadge(string glyph, Color background, Color fore
{
Glyph = glyph,
FontSize = 12,
FontFamily = new FontFamily("Segoe Fluent Icons"),
FontFamily = IconFonts.SymbolThemeFontFamily,
Foreground = new SolidColorBrush(foreground),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Expand Down
3 changes: 2 additions & 1 deletion src/OpenClaw.Tray.WinUI/A2UI/Hosting/SurfaceHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using OpenClawTray.A2UI.Protocol;
using OpenClawTray.A2UI.Rendering;
using OpenClawTray.A2UI.Theming;
using OpenClawTray.Helpers;

namespace OpenClawTray.A2UI.Hosting;

Expand Down Expand Up @@ -260,7 +261,7 @@ private static FrameworkElement BuildErrorPlaceholder(string componentName, stri
stack.Children.Add(new FontIcon
{
Glyph = "",
FontFamily = new FontFamily("Segoe Fluent Icons"),
FontFamily = FluentIconCatalog.SymbolThemeFontFamily,
});
stack.Children.Add(new TextBlock
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using OpenClawTray.A2UI.Protocol;
using OpenClawTray.Helpers;

namespace OpenClawTray.A2UI.Rendering.Renderers;

Expand Down Expand Up @@ -232,7 +233,7 @@ public FrameworkElement Render(A2UIComponentDef c, RenderContext ctx)
{
var fontIcon = new FontIcon
{
FontFamily = new FontFamily("Segoe Fluent Icons"),
FontFamily = FluentIconCatalog.SymbolThemeFontFamily,
FontSize = 16,
};
var nameVal = ctx.GetValue(c, "name");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using OpenClawTray.A2UI.Protocol;
using OpenClawTray.Helpers;

namespace OpenClawTray.A2UI.Rendering.Renderers;

Expand All @@ -29,7 +30,7 @@ public FrameworkElement Render(A2UIComponentDef component, RenderContext ctx)
stack.Children.Add(new FontIcon
{
Glyph = "", // outlined warning
FontFamily = new FontFamily("Segoe Fluent Icons"),
FontFamily = FluentIconCatalog.SymbolThemeFontFamily,
});
var template = OpenClawTray.Helpers.LocalizationHelper.GetString("A2UI_UnsupportedComponent");
stack.Children.Add(new TextBlock
Expand Down
4 changes: 2 additions & 2 deletions src/OpenClaw.Tray.WinUI/Chat/OpenClawChatTimeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ Element HoverIcon(string entryId, string actionKey, string glyph, string ackGlyp
TextBlock(shownGlyph)
.Set(t =>
{
t.FontFamily = new FontFamily("Segoe Fluent Icons, Segoe MDL2 Assets");
t.FontFamily = FluentIconCatalog.SymbolThemeFontFamily;
t.FontSize = 14;
t.FontWeight = Microsoft.UI.Text.FontWeights.Light;
t.Foreground = shownColor;
Expand Down Expand Up @@ -1062,7 +1062,7 @@ Element RenderUserEntry(ChatTimelineItem entry, bool startsBurst, bool endsBurst
TextBlock(fileGlyph)
.Set(t =>
{
t.FontFamily = new FontFamily("Segoe Fluent Icons");
t.FontFamily = FluentIconCatalog.SymbolThemeFontFamily;
t.FontSize = 16;
t.Foreground = userBubbleFg;
t.VerticalAlignment = VerticalAlignment.Center;
Expand Down
14 changes: 7 additions & 7 deletions src/OpenClaw.Tray.WinUI/Chat/OpenClawComposer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ public override Element Render()
TextBlock("\uE711") // Cancel glyph
.Set(t =>
{
t.FontFamily = new FontFamily("Segoe Fluent Icons");
t.FontFamily = FluentIconCatalog.SymbolThemeFontFamily;
t.FontSize = 10;
}),
() => Props.OnAttachmentRemoved?.Invoke())
Expand Down Expand Up @@ -491,7 +491,7 @@ public override Element Render()
thumb = TextBlock("\uEB9F")
.Set(t =>
{
t.FontFamily = new FontFamily("Segoe Fluent Icons");
t.FontFamily = FluentIconCatalog.SymbolThemeFontFamily;
t.FontSize = 16;
t.VerticalAlignment = VerticalAlignment.Center;
});
Expand All @@ -505,7 +505,7 @@ public override Element Render()
TextBlock("\uE711")
.Set(t =>
{
t.FontFamily = new FontFamily("Segoe Fluent Icons");
t.FontFamily = FluentIconCatalog.SymbolThemeFontFamily;
t.FontSize = 10;
t.HorizontalAlignment = HorizontalAlignment.Center;
t.VerticalAlignment = VerticalAlignment.Center;
Expand Down Expand Up @@ -554,7 +554,7 @@ public override Element Render()
TextBlock("\uE8A5") // Page glyph
.Set(t =>
{
t.FontFamily = new FontFamily("Segoe Fluent Icons");
t.FontFamily = FluentIconCatalog.SymbolThemeFontFamily;
t.FontSize = 12;
t.VerticalAlignment = VerticalAlignment.Center;
})
Expand Down Expand Up @@ -685,7 +685,7 @@ Element IconButton(string glyph, string tip, Action onClick, Brush? foreground =
TextBlock(glyph)
.Set(t =>
{
t.FontFamily = new FontFamily("Segoe Fluent Icons");
t.FontFamily = FluentIconCatalog.SymbolThemeFontFamily;
t.FontSize = composerIconSize;
// Always set foreground explicitly so element diffing resets it.
t.Foreground = foreground
Expand Down Expand Up @@ -773,7 +773,7 @@ Element IconButton(string glyph, string tip, Action onClick, Brush? foreground =
TextBlock(sendGlyph)
.Set(t =>
{
t.FontFamily = new FontFamily("Segoe Fluent Icons");
t.FontFamily = FluentIconCatalog.SymbolThemeFontFamily;
t.FontSize = composerIconSize;
})
.Foreground(glyphBrush),
Expand Down Expand Up @@ -819,7 +819,7 @@ Element IconButton(string glyph, string tip, Action onClick, Brush? foreground =
TextBlock(stopGlyph)
.Set(t =>
{
t.FontFamily = new FontFamily("Segoe Fluent Icons");
t.FontFamily = FluentIconCatalog.SymbolThemeFontFamily;
t.FontSize = composerIconSize;
})
.Foreground(new SolidColorBrush(Colors.White)),
Expand Down
5 changes: 4 additions & 1 deletion src/OpenClaw.Tray.WinUI/Helpers/FluentIconCatalog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ public static class FluentIconCatalog
public const string Workspace = "\uE8DA"; // OpenLocal (alias of Folder)
public const string Cron = "\uE787"; // Calendar — Cron / scheduled jobs (matches HubWindow search mapping)

public static FontFamily SymbolThemeFontFamily =>
(FontFamily)Application.Current.Resources["SymbolThemeFontFamily"];

/// <summary>
/// Builds a <see cref="FontIcon"/> for the given PUA glyph using the
/// system-resolved <c>SymbolThemeFontFamily</c> so the icon honors
Expand All @@ -114,7 +117,7 @@ public static FontIcon Build(string glyph, double size = 16)
return new FontIcon
{
Glyph = glyph,
FontFamily = (FontFamily)Application.Current.Resources["SymbolThemeFontFamily"],
FontFamily = SymbolThemeFontFamily,
FontSize = size,
};
}
Expand Down
39 changes: 39 additions & 0 deletions tests/OpenClaw.Tray.Tests/FluentIconCatalogTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,45 @@ public void Catalog_DefinesBuildHelper()
Assert.Contains("SymbolThemeFontFamily", src);
}

[Fact]
public void NativeWinUiSources_DoNotHardcodeSegoeFluentIcons()
{
var repositoryRoot = TestRepositoryPaths.GetRepositoryRoot();
var sourceRoots = new[]
{
Path.Combine(repositoryRoot, "src", "OpenClaw.Tray.WinUI"),
Path.Combine(repositoryRoot, "src", "OpenClaw.SetupEngine.UI"),
};
var hardcodedIconFont = new Regex(
@"FontFamily\s*\(\s*""Segoe Fluent Icons""\s*\)|FontFamily\s*=\s*""Segoe Fluent Icons""",
RegexOptions.Compiled);

var offenders = sourceRoots
.SelectMany(sourceRoot => Directory
.EnumerateFiles(sourceRoot, "*", SearchOption.AllDirectories)
.Where(path => path.EndsWith(".cs", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".xaml", StringComparison.OrdinalIgnoreCase))
.Where(path => !IsBuildArtifact(sourceRoot, path)))
.SelectMany(path => File.ReadLines(path)
.Select((line, index) => (path, line, lineNumber: index + 1)))
.Where(item => hardcodedIconFont.IsMatch(item.line))
.Select(item => $"{Path.GetRelativePath(repositoryRoot, item.path)}:{item.lineNumber}")
.ToArray();

Assert.True(
offenders.Length == 0,
"Use the SymbolThemeFontFamily theme resource/property so icon glyphs fall back to Segoe MDL2 Assets on Windows 10:"
+ Environment.NewLine
+ string.Join(Environment.NewLine, offenders));

static bool IsBuildArtifact(string sourceRoot, string path)
{
var relative = Path.GetRelativePath(sourceRoot, path);
return relative.StartsWith($"bin{Path.DirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase)
|| relative.StartsWith($"obj{Path.DirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase);
}
}

}

/// <summary>
Expand Down
5 changes: 3 additions & 2 deletions tests/OpenClaw.Tray.UITests/A2UIControlMatrixTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ await _ui.RunOnUIAsync(() =>
}

[Fact]
public Task Icon_RendersFontIcon_WithSegoeFluentGlyph() => RunAsync(
public Task Icon_RendersFontIcon_WithSymbolThemeFontFamily() => RunAsync(
"Icon → FontIcon",
Surface("s", "i", new[]
{
Expand All @@ -252,7 +252,8 @@ public Task Icon_RendersFontIcon_WithSegoeFluentGlyph() => RunAsync(
root =>
{
var fi = FindLogical<FontIcon>(root).Single();
Assert.Equal("Segoe Fluent Icons", fi.FontFamily.Source);
var expectedFont = (Microsoft.UI.Xaml.Media.FontFamily)Application.Current.Resources["SymbolThemeFontFamily"];
Assert.Equal(expectedFont.Source, fi.FontFamily.Source);
// "search" maps to the Segoe MDL2 Search glyph (U+E721).
Assert.Equal("", fi.Glyph);
});
Expand Down
Loading