Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
176c869
Migrate legacy dialogs to WinUI-style immersive overlays
Meteony Jul 25, 2026
616102a
WinUI-style sliding pill
Meteony Jul 26, 2026
53665e5
Match immersive dialog background to WinUI
Meteony Jul 26, 2026
0cf24cc
revert branding change
Meteony Jul 28, 2026
5d1cc11
Hard-capped pill stretch to 5x height
Meteony Jul 28, 2026
409dbd7
Test WinUI pill animation duration
Meteony Jul 28, 2026
f50bb34
test dual-line branding layout for tray
Meteony Jul 28, 2026
efffeaf
tweak up ignored update window listview border and color to be consis…
Meteony Jul 28, 2026
e642568
adjust SettingsCardBorderBrush to be consistent with previous UI
Meteony Jul 28, 2026
b14fac4
step back pill animation slowdown
Meteony Jul 28, 2026
1f2c0aa
tweak active / inactive searchbox styles to match previous UI
Meteony Jul 28, 2026
3f38fb0
tweak selected view-mode indicator geometry to look like previous UI
Meteony Jul 28, 2026
b16ac0a
emapped Avalonia’s raw-accent control resources to the WinUI-adjusted…
Meteony Jul 28, 2026
0ece76f
revert tray dual-line experiment
Meteony Jul 28, 2026
7ff836e
switch close glyph to path-rendering for thickness consistency
Meteony Jul 28, 2026
62a525b
update package-manager status indicators to add icons for parity with…
Meteony Jul 28, 2026
5d8786d
combobox styling update
Meteony Jul 28, 2026
903bb4e
Revert "emapped Avalonia’s raw-accent control resources to the WinUI-…
Meteony Jul 28, 2026
d8d203e
restore focus outine for search boxes
Meteony Jul 28, 2026
776b875
indicator tweaks
Meteony Jul 28, 2026
cd38af4
restore dark active backdrop for search boxes
Meteony Jul 28, 2026
d3c8f2b
adjust tick / cross stying
Meteony Jul 28, 2026
cc90555
tweak disabled glyph
Meteony Jul 28, 2026
2264a92
Fix manager page import ordering
Meteony Jul 28, 2026
b8d0056
format
Meteony Jul 28, 2026
be5421b
Fine-tune status badge glyph positioning
Meteony Jul 28, 2026
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
129 changes: 94 additions & 35 deletions src/UniGetUI.Avalonia/Assets/Styles/Styles.Common.axaml

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions src/UniGetUI.Avalonia/Assets/Styles/Styles.WindowsMica.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<!-- Window/page surface goes transparent so Mica shows behind chrome + page -->
<SolidColorBrush x:Key="MicaPageBackground" Color="Transparent"/>
<!-- Cards / panels: translucent white layers over the (light) Mica -->
<SolidColorBrush x:Key="SettingsCardBackground" Color="#80FFFFFF"/>
<SolidColorBrush x:Key="SettingsCardBackground" Color="#B3FFFFFF"/>
<SolidColorBrush x:Key="SettingsCardBorderBrush" Color="#14000000"/>
<!-- Package list: near-transparent so Mica shows through, matching WinUI's SystemFillColorNeutralBackground -->
<SolidColorBrush x:Key="PackageListBackground" Color="#06000000"/>
Expand All @@ -30,7 +30,7 @@
<SolidColorBrush x:Key="AppDialogDarkBackground" Color="#80FFFFFF"/>
<!-- Flyouts / menus / dropdowns / tooltips: DWM acrylic backdrop with the card tint over it -->
<SolidColorBrush x:Key="FlyoutPresenterBackground" Color="#80FFFFFF"/>
<SolidColorBrush x:Key="MenuFlyoutPresenterBackground" Color="#80FFFFFF"/>
<SolidColorBrush x:Key="MenuFlyoutPresenterBackground" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBoxDropDownBackground" Color="#80FFFFFF"/>
<SolidColorBrush x:Key="ToolTipBackground" Color="#80FFFFFF"/>
<!-- Expander chrome -->
Expand All @@ -53,8 +53,8 @@

<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="MicaPageBackground" Color="Transparent"/>
<!-- Cards / panels: translucent dark layers; ~40% so the wallpaper-tinted Mica bleeds through -->
<SolidColorBrush x:Key="SettingsCardBackground" Color="#662D2D2D"/>
<!-- Cards / panels: WinUI's translucent card layer over the Mica backdrop -->
<SolidColorBrush x:Key="SettingsCardBackground" Color="#0DFFFFFF"/>
<SolidColorBrush x:Key="SettingsCardBorderBrush" Color="#26FFFFFF"/>
<!-- Package list: near-transparent so Mica shows through, matching WinUI's SystemFillColorNeutralBackground -->
<SolidColorBrush x:Key="PackageListBackground" Color="#08FFFFFF"/>
Expand All @@ -71,7 +71,7 @@
stays readably dark even when the popup floats over bright content (e.g. the release-notes
WebView) — a lighter tint let the white page wash the menu out (#5007) -->
<SolidColorBrush x:Key="FlyoutPresenterBackground" Color="#BF2D2D2D"/>
<SolidColorBrush x:Key="MenuFlyoutPresenterBackground" Color="#BF2D2D2D"/>
<SolidColorBrush x:Key="MenuFlyoutPresenterBackground" Color="#FF2C2C2C"/>
<SolidColorBrush x:Key="ComboBoxDropDownBackground" Color="#BF2D2D2D"/>
<SolidColorBrush x:Key="ToolTipBackground" Color="#BF2D2D2D"/>
<!-- Expander chrome -->
Expand Down
44 changes: 36 additions & 8 deletions src/UniGetUI.Avalonia/Infrastructure/MicaWindowHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Avalonia.Controls.Primitives;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.VisualTree;
using UniGetUI.Avalonia.Assets.Styles;

namespace UniGetUI.Avalonia.Infrastructure;
Expand Down Expand Up @@ -48,22 +49,22 @@ public static void Apply(Window window)
};
}

// Gives flyouts / menus / combo dropdowns / tooltips a native Win11 acrylic backdrop:
// the popup window is made transparent and DWM paints the (blurred, theme-adaptive)
// acrylic material behind it. Registered once at startup when Mica is enabled.
// Applies the Windows 11 transient-surface treatment to popup hosts. Menus use an
// opaque WinUI surface; combo dropdowns, tooltips, and ordinary flyouts use acrylic.
// Registered once at startup when Mica is enabled.
public static void EnableAcrylicPopups()
{
if (!IsMicaEnabled() || _acrylicPopupsHooked)
return;
_acrylicPopupsHooked = true;

// In-app flyouts/menus/tooltips/combo popups are hosted in a PopupRoot; style each as it loads.
// In-app menus, flyouts, tooltips, and combo popups are hosted in a PopupRoot.
Control.LoadedEvent.AddClassHandler<PopupRoot>((root, _) => ApplyAcrylicToPopup(root));

// The system-tray context menu is NOT a PopupRoot — Avalonia hosts it in its own Window
// (Avalonia.Win32.TrayIconImpl.TrayPopupRoot), so it misses the handler above and would
// render with no backdrop (transparent over the desktop). Catch it by type name and apply
// the same acrylic treatment. The other Windows (MainWindow/dialogs) are handled via Apply().
// render with no surface over the desktop. Catch it by type name and apply the opaque
// menu treatment. The other Windows (MainWindow/dialogs) are handled via Apply().
Control.LoadedEvent.AddClassHandler<Window>((win, _) =>
{
if (win.GetType().Name == "TrayPopupRoot")
Expand All @@ -76,10 +77,28 @@ private static void ApplyAcrylicToPopup(TopLevel root)
if (!IsMicaEnabled())
return;

// Menus use WinUI's opaque flyout surface. Other transient controls (combo boxes,
// tooltips and ordinary flyouts) retain acrylic.
bool isMenu = root.GetType().Name == "TrayPopupRoot"
|| root.GetVisualDescendants()
.Any(control => control is MenuFlyoutPresenter or ContextMenu);
if (isMenu)
{
root.TransparencyLevelHint = new[] { WindowTransparencyLevel.None };
if (root.TryFindResource("MenuSurfaceBrush", root.ActualThemeVariant, out object? resource)
&& resource is IBrush brush)
{
root.Background = brush;
}

ApplyRoundedCorners(root);
return;
}

// Request acrylic (not Transparent): the Transparent level makes a layered window, and DWM
// system backdrops never paint on those — so the popup ended up fully see-through with only
// the presenter tint, unreadable when shown over the desktop (e.g. the tray menu). AcrylicBlur
// gives a composited window DWM can actually fill. This path only runs when Mica is enabled
// the presenter tint and make its contents unreadable. AcrylicBlur gives a composited window
// DWM can actually fill. This path only runs when Mica is enabled
// (Win11 + transparency effects), so acrylic is always available here.
root.TransparencyLevelHint = new[] { WindowTransparencyLevel.AcrylicBlur, WindowTransparencyLevel.Blur };
root.Background = Brushes.Transparent;
Expand All @@ -93,6 +112,15 @@ private static void ApplyAcrylicToPopup(TopLevel root)
NativeMethods.DwmSetWindowAttribute(handle, DWMWA_SYSTEMBACKDROP_TYPE, ref backdrop, sizeof(int));
}

private static void ApplyRoundedCorners(TopLevel root)
{
if (root.TryGetPlatformHandle()?.Handle is not { } handle || handle == 0)
return;

int corner = DWMWCP_ROUND;
NativeMethods.DwmSetWindowAttribute(handle, DWMWA_WINDOW_CORNER_PREFERENCE, ref corner, sizeof(int));
}

/// <summary>
/// True when the native Mica look should be used: Windows 11+, "Transparency effects" on,
/// GPU-accelerated (software rendering can't be transparent, so Mica shows as black — #5111),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,10 @@ public static async Task<bool> ConfirmAsync(Window owner, IReadOnlyList<IPackage
}

bool isConfirmed = false;
var dialog = new Window
var dialog = new UniGetUI.Avalonia.Views.DialogPages.ImmersiveDialog
{
Width = packages.Count == 1 ? 520 : 560,
Height = packages.Count == 1 ? 220 : 380,
MinWidth = 420,
MinHeight = packages.Count == 1 ? 220 : 300,
CanResize = packages.Count > 1,
ShowInTaskbar = false,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
MaxWidth = packages.Count == 1 ? 520 : 560,
MaxHeight = packages.Count == 1 ? 220 : 380,
Title = CoreTools.Translate("Are you sure?"),
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ namespace UniGetUI.Avalonia.ViewModels;

public partial class ManageIgnoredUpdatesViewModel : ObservableObject
{
public event EventHandler? CloseRequested;

public string Title { get; } = CoreTools.Translate("Manage ignored updates");
public string Description { get; } = CoreTools.Translate("The packages listed here won't be taken in account when checking for updates. Double-click them or click the button on their right to stop ignoring their updates.");
public string ResetLabel { get; } = CoreTools.Translate("Reset list");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,11 @@ private static async Task RestoreFromCloud()
Width = 360,
};

var dialog = new Window
var dialog = new UniGetUI.Avalonia.Views.DialogPages.ImmersiveDialog
{
Title = CoreTools.Translate("Select backup"),
Width = 440,
Height = 160,
CanResize = false,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
MaxWidth = 440,
MaxHeight = 160,
Content = new StackPanel
{
Margin = new Thickness(20),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,13 +366,10 @@ public async Task ShowInfoDialog(Window owner, string title, string message)
{
object? bgResource = null;
Application.Current?.Resources.TryGetResource("AppWindowBackground", Application.Current.ActualThemeVariant, out bgResource);
var dialog = new Window
var dialog = new UniGetUI.Avalonia.Views.DialogPages.ImmersiveDialog
{
Width = 460,
Height = 180,
CanResize = false,
ShowInTaskbar = false,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
MaxWidth = 460,
MaxHeight = 180,
Title = title,
Background = bgResource as IBrush,
};
Expand Down
33 changes: 27 additions & 6 deletions src/UniGetUI.Avalonia/Views/Controls/InfoBar.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public InfoBar()
}

private InfoBarViewModel? _vm;
private IDisposable? _severityStripBinding;
private IDisposable? _severityIconBinding;

private void OnDataContextChanged(object? sender, EventArgs e)
{
Expand Down Expand Up @@ -53,24 +55,43 @@ private void ApplySeverity(InfoBarSeverity severity)
BodyBorder.Classes.Set("severity-warning", severity == InfoBarSeverity.Warning);
BodyBorder.Classes.Set("severity-info", severity == InfoBarSeverity.Informational);

// Strip colour (solid, not theme-sensitive)
var stripColor = severity switch
_severityStripBinding?.Dispose();
_severityIconBinding?.Dispose();
_severityStripBinding = null;
_severityIconBinding = null;

Color? stripColor = severity switch
{
InfoBarSeverity.Warning => Color.Parse("#F7A800"),
InfoBarSeverity.Error => Color.Parse("#C42B1C"),
InfoBarSeverity.Success => Color.Parse("#107C10"),
_ => Color.Parse("#0078D4"),
_ => null,
};
SeverityStrip.Background = new SolidColorBrush(stripColor);

// Icon (shared SVG asset, tinted with the severity colour)
SeverityIcon.Path = severity switch
{
InfoBarSeverity.Warning => WarningIcon,
InfoBarSeverity.Error => ErrorIcon,
InfoBarSeverity.Success => SuccessIcon,
_ => InfoIcon,
};
SeverityIcon.Foreground = new SolidColorBrush(stripColor);

if (stripColor is { } color)
{
var brush = new SolidColorBrush(color);
SeverityStrip.Background = brush;
SeverityIcon.Foreground = brush;
}
else
{
SeverityStrip.ClearValue(Border.BackgroundProperty);
SeverityIcon.ClearValue(ForegroundProperty);
_severityStripBinding = SeverityStrip.Bind(
Border.BackgroundProperty,
this.GetResourceObservable("SystemAccentColor"));
_severityIconBinding = SeverityIcon.Bind(
ForegroundProperty,
this.GetResourceObservable("SystemAccentColor"));
}
}
}
16 changes: 8 additions & 8 deletions src/UniGetUI.Avalonia/Views/DialogPages/AboutWindow.axaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<Window xmlns="https://github.com/avaloniaui"
<dialogs:ImmersiveDialog xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dialogs="using:UniGetUI.Avalonia.Views.DialogPages"
xmlns:t="using:UniGetUI.Avalonia.MarkupExtensions"
xmlns:about="using:UniGetUI.Avalonia.Views.Pages.AboutPages"
x:Class="UniGetUI.Avalonia.Views.DialogPages.AboutWindow"
Title="{t:Translate About UniGetUI}"
Width="700" MinWidth="500"
Height="600" MinHeight="400"
CanResize="True"
ShowInTaskbar="False"
Background="{DynamicResource AppDialogBackground}"
WindowStartupLocation="CenterOwner">
MaxWidth="700"
MinWidth="500"
MaxHeight="600"
MinHeight="400"
Background="{DynamicResource AppDialogBackground}">

<TabControl x:Name="MainTabControl" Margin="8">

Expand All @@ -31,4 +31,4 @@

</TabControl>

</Window>
</dialogs:ImmersiveDialog>
3 changes: 1 addition & 2 deletions src/UniGetUI.Avalonia/Views/DialogPages/AboutWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@

namespace UniGetUI.Avalonia.Views.DialogPages;

public partial class AboutWindow : Window
public partial class AboutWindow : UniGetUI.Avalonia.Views.DialogPages.ImmersiveDialog
{
public AboutWindow()
{
InitializeComponent();
UniGetUI.Avalonia.Infrastructure.MicaWindowHelper.Apply(this);
}

protected override void OnOpened(EventArgs e)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
<Window xmlns="https://github.com/avaloniaui"
<dialogs:ImmersiveDialog xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dialogs="using:UniGetUI.Avalonia.Views.DialogPages"
xmlns:automation="clr-namespace:Avalonia.Automation;assembly=Avalonia.Controls"
xmlns:t="using:UniGetUI.Avalonia.MarkupExtensions"
x:Class="UniGetUI.Avalonia.Views.DialogPages.BundleSecurityReportDialog"
Title="{t:Translate Bundle security report}"
Width="580"
Height="420"
MaxWidth="580"
MinWidth="400"
MaxHeight="420"
MinHeight="300"
CanResize="True"
ShowInTaskbar="False"
Background="{DynamicResource AppDialogBackground}"
WindowStartupLocation="CenterOwner">
Background="{DynamicResource AppDialogBackground}">

<Grid Margin="20"
RowDefinitions="Auto,*,Auto"
Expand Down Expand Up @@ -42,4 +40,4 @@

</Grid>

</Window>
</dialogs:ImmersiveDialog>
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

namespace UniGetUI.Avalonia.Views.DialogPages;

public partial class BundleSecurityReportDialog : Window
public partial class BundleSecurityReportDialog : UniGetUI.Avalonia.Views.DialogPages.ImmersiveDialog
{
public BundleSecurityReportDialog(BundleReport report)
{
InitializeComponent();
UniGetUI.Avalonia.Infrastructure.MicaWindowHelper.Apply(this);

var sb = new System.Text.StringBuilder();
foreach (var (pkgId, entries) in report.Contents)
Expand Down
16 changes: 8 additions & 8 deletions src/UniGetUI.Avalonia/Views/DialogPages/CrashReportWindow.axaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<Window xmlns="https://github.com/avaloniaui"
<dialogs:ImmersiveDialog xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dialogs="using:UniGetUI.Avalonia.Views.DialogPages"
xmlns:t="using:UniGetUI.Avalonia.MarkupExtensions"
x:Class="UniGetUI.Avalonia.Views.DialogPages.CrashReportWindow"
Title="{t:Translate UniGetUI – Crash Report}"
Width="800" MinWidth="500"
Height="580" MinHeight="380"
CanResize="True"
ShowInTaskbar="False"
Background="{DynamicResource AppDialogBackground}"
WindowStartupLocation="CenterOwner">
MaxWidth="800"
MinWidth="500"
MaxHeight="580"
MinHeight="380"
Background="{DynamicResource AppDialogBackground}">

<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Margin="24,20,24,24" Spacing="16">
Expand Down Expand Up @@ -66,4 +66,4 @@
</StackPanel>
</ScrollViewer>

</Window>
</dialogs:ImmersiveDialog>
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@

namespace UniGetUI.Avalonia.Views.DialogPages;

internal sealed partial class CrashReportWindow : Window
internal sealed partial class CrashReportWindow : UniGetUI.Avalonia.Views.DialogPages.ImmersiveDialog
{
private readonly string _crashReport;

public CrashReportWindow(string crashReport)
{
_crashReport = crashReport;
InitializeComponent();
UniGetUI.Avalonia.Infrastructure.MicaWindowHelper.Apply(this);
CrashReportText.Text = crashReport;
DontSendButton.Content = CoreTools.Translate("Don't Send");
SendButton.Content = CoreTools.Translate("Send Report");
Expand Down
Loading
Loading