[Registry Preview] Using TitleBar and AppWindow (#41418)

## Summary of the Pull Request
- Using TitleBar instead of custom XAML
- Using `AppWindow` (as part of WinUIEx)

<img width="1163" height="246" alt="image"
src="https://github.com/user-attachments/assets/65a65c3a-81b7-4afb-b046-57e081709e98"
/>


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] Closes: #41414
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx

<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

---------

Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>
This commit is contained in:
Niels Laute
2025-09-01 15:25:11 +02:00
committed by GitHub
parent 4ced93ce67
commit 566e35af1e
3 changed files with 25 additions and 63 deletions

View File

@@ -15,10 +15,10 @@ namespace RegistryPreview
/// </summary> /// </summary>
private void AppWindow_Closing(Microsoft.UI.Windowing.AppWindow sender, Microsoft.UI.Windowing.AppWindowClosingEventArgs args) private void AppWindow_Closing(Microsoft.UI.Windowing.AppWindow sender, Microsoft.UI.Windowing.AppWindowClosingEventArgs args)
{ {
jsonWindowPlacement.SetNamedValue("appWindow.Position.X", JsonValue.CreateNumberValue(appWindow.Position.X)); jsonWindowPlacement.SetNamedValue("appWindow.Position.X", JsonValue.CreateNumberValue(AppWindow.Position.X));
jsonWindowPlacement.SetNamedValue("appWindow.Position.Y", JsonValue.CreateNumberValue(appWindow.Position.Y)); jsonWindowPlacement.SetNamedValue("appWindow.Position.Y", JsonValue.CreateNumberValue(AppWindow.Position.Y));
jsonWindowPlacement.SetNamedValue("appWindow.Size.Width", JsonValue.CreateNumberValue(appWindow.Size.Width)); jsonWindowPlacement.SetNamedValue("appWindow.Size.Width", JsonValue.CreateNumberValue(AppWindow.Size.Width));
jsonWindowPlacement.SetNamedValue("appWindow.Size.Height", JsonValue.CreateNumberValue(appWindow.Size.Height)); jsonWindowPlacement.SetNamedValue("appWindow.Size.Height", JsonValue.CreateNumberValue(AppWindow.Size.Height));
} }
/// <summary> /// <summary>

View File

@@ -15,38 +15,19 @@
<Window.SystemBackdrop> <Window.SystemBackdrop>
<MicaBackdrop /> <MicaBackdrop />
</Window.SystemBackdrop> </Window.SystemBackdrop>
<Grid x:Name="MainGrid" Loaded="Grid_Loaded"> <Grid x:Name="MainGrid" Loaded="Grid_Loaded">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid <TitleBar x:Name="titleBar">
x:Name="titleBar" <!-- This is a workaround for https://github.com/microsoft/microsoft-ui-xaml/issues/10374, once fixed we should just be using IconSource -->
Grid.Row="0" <TitleBar.LeftHeader>
Height="32" <ImageIcon
Margin="16,0" Height="16"
ColumnSpacing="16" Margin="16,0,0,0"
IsHitTestVisible="True"> Source="/Assets/RegistryPreview/RegistryPreview.ico" />
<Grid.ColumnDefinitions> </TitleBar.LeftHeader>
<!--<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>--> </TitleBar>
<ColumnDefinition x:Name="IconColumn" Width="Auto" />
<ColumnDefinition x:Name="TitleColumn" Width="Auto" />
<!--<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>-->
</Grid.ColumnDefinitions>
<Image
Grid.Column="0"
Width="16"
Height="16"
VerticalAlignment="Center"
Source="../Assets/RegistryPreview/RegistryPreview.ico" />
<TextBlock
x:Name="titleBarText"
Grid.Column="1"
VerticalAlignment="Center"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{Binding ApplicationTitle}" />
</Grid>
</Grid> </Grid>
</winuiex:WindowEx> </winuiex:WindowEx>

View File

@@ -6,6 +6,7 @@ using System;
using ManagedCommon; using ManagedCommon;
using Microsoft.PowerToys.Telemetry; using Microsoft.PowerToys.Telemetry;
using Microsoft.UI; using Microsoft.UI;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Media;
@@ -23,7 +24,6 @@ namespace RegistryPreview
private const string APPNAME = "RegistryPreview"; private const string APPNAME = "RegistryPreview";
// private members // private members
private Microsoft.UI.Windowing.AppWindow appWindow;
private JsonObject jsonWindowPlacement; private JsonObject jsonWindowPlacement;
private string settingsFolder = string.Empty; private string settingsFolder = string.Empty;
private string windowPlacementFile = "app-placement.json"; private string windowPlacementFile = "app-placement.json";
@@ -38,20 +38,15 @@ namespace RegistryPreview
settingsFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Microsoft\PowerToys\" + APPNAME; settingsFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Microsoft\PowerToys\" + APPNAME;
OpenWindowPlacementFile(settingsFolder, windowPlacementFile); OpenWindowPlacementFile(settingsFolder, windowPlacementFile);
// Update the Win32 looking window with the correct icon (and grab the appWindow handle for later)
IntPtr windowHandle = this.GetWindowHandle();
WindowId windowId = Win32Interop.GetWindowIdFromWindow(windowHandle);
appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
appWindow.SetIcon("Assets\\RegistryPreview\\RegistryPreview.ico");
// TODO(stefan) // TODO(stefan)
appWindow.Closing += AppWindow_Closing; AppWindow.Closing += AppWindow_Closing;
Activated += MainWindow_Activated;
// Extend the canvas to include the title bar so the app can support theming // Extend the canvas to include the title bar so the app can support theming
ExtendsContentIntoTitleBar = true; ExtendsContentIntoTitleBar = true;
IntPtr windowHandle = this.GetWindowHandle();
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(windowHandle); WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(windowHandle);
SetTitleBar(titleBar); SetTitleBar(titleBar);
AppWindow.SetIcon("Assets\\RegistryPreview\\RegistryPreview.ico");
// if have settings, update the location of the window // if have settings, update the location of the window
if (jsonWindowPlacement != null) if (jsonWindowPlacement != null)
@@ -66,7 +61,7 @@ namespace RegistryPreview
// check to make sure the size values are reasonable before attempting to restore the last saved size // check to make sure the size values are reasonable before attempting to restore the last saved size
if (size.Width >= 320 && size.Height >= 240) if (size.Width >= 320 && size.Height >= 240)
{ {
appWindow.Resize(size); AppWindow.Resize(size);
} }
} }
@@ -80,7 +75,7 @@ namespace RegistryPreview
// check to make sure the move values are reasonable before attempting to restore the last saved location // check to make sure the move values are reasonable before attempting to restore the last saved location
if (point.X >= 0 && point.Y >= 0) if (point.X >= 0 && point.Y >= 0)
{ {
appWindow.Move(point); AppWindow.Move(point);
} }
} }
} }
@@ -92,20 +87,6 @@ namespace RegistryPreview
PowerToysTelemetry.Log.WriteEvent(new RegistryPreviewEditorStartFinishEvent() { TimeStamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }); PowerToysTelemetry.Log.WriteEvent(new RegistryPreviewEditorStartFinishEvent() { TimeStamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() });
} }
private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
{
if (args.WindowActivationState == WindowActivationState.Deactivated)
{
titleBarText.Foreground =
(SolidColorBrush)Application.Current.Resources["WindowCaptionForegroundDisabled"];
}
else
{
titleBarText.Foreground =
(SolidColorBrush)Application.Current.Resources["WindowCaptionForeground"];
}
}
private void Grid_Loaded(object sender, RoutedEventArgs e) private void Grid_Loaded(object sender, RoutedEventArgs e)
{ {
MainGrid.Children.Add(MainPage); MainGrid.Children.Add(MainPage);
@@ -118,23 +99,23 @@ namespace RegistryPreview
if (string.IsNullOrEmpty(filename)) if (string.IsNullOrEmpty(filename))
{ {
titleBarText.Text = APPNAME; titleBar.Title = APPNAME;
appWindow.Title = APPNAME; AppWindow.Title = APPNAME;
} }
else else
{ {
string[] file = filename.Split('\\'); string[] file = filename.Split('\\');
if (file.Length > 0) if (file.Length > 0)
{ {
titleBarText.Text = file[file.Length - 1] + " - " + APPNAME; titleBar.Title = file[file.Length - 1] + " - " + APPNAME;
} }
else else
{ {
titleBarText.Text = filename + " - " + APPNAME; titleBar.Title = filename + " - " + APPNAME;
} }
// Continue to update the window's title, after updating the custom title bar // Continue to update the window's title, after updating the custom title bar
appWindow.Title = titleBarText.Text; AppWindow.Title = titleBar.Title;
} }
} }
} }