[Settings] Move title bar shutdown button to navigation view (#40714)

<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

Based on
https://github.com/microsoft/PowerToys/pull/40260#issuecomment-3085099815
feedback, this PR remove the title bar shutdown button in favor of a
menu item in the navigation view footer.

- Menu item is visible only when tray icon is hidden
- A confirm dialog has been added

<img width="848" height="448" alt="image"
src="https://github.com/user-attachments/assets/529bcfa9-94ed-48b1-b2bb-ca6993d12e0f"
/>

<img width="848" height="448" alt="image"
src="https://github.com/user-attachments/assets/febafbb4-3a5b-4b04-8065-28f0d269ab6c"
/>

- Close is used in tray icon menu for closing app

<img alt="image"
src="https://github.com/user-attachments/assets/3ac79a8c-961f-4f95-8967-adef00aba77b"
/>

<img alt="image"
src="https://github.com/user-attachments/assets/c2800a77-c733-41a9-aa4f-fa4c2afd30a3"
/>

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

- [x] **Closes:** #40346 #40577
- [x] **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
- [x] **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

- Open settings with tray icon visible: close menu is hidden
- Open settings with tray icon hidden: close menu is visible
- Tested close menu visibility change when tray icon option is changed
- Tested cancel button of close dialog
- Tested close button of dialog

---------

Co-authored-by: Niels Laute <niels.laute@live.nl>
This commit is contained in:
Davide Giacometti
2025-08-21 10:40:37 +02:00
committed by GitHub
parent 75d85f80b9
commit db953bb325
12 changed files with 90 additions and 67 deletions

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Services;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.UI.Windowing;
@@ -113,7 +114,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
/// <summary>
/// Gets view model.
/// </summary>
public ShellViewModel ViewModel { get; } = new ShellViewModel();
public ShellViewModel ViewModel { get; }
/// <summary>
/// Gets a collection of functions that handle IPC responses.
@@ -134,6 +135,8 @@ namespace Microsoft.PowerToys.Settings.UI.Views
{
InitializeComponent();
var settingsUtils = new SettingsUtils();
ViewModel = new ShellViewModel(SettingsRepository<GeneralSettings>.GetInstance(settingsUtils));
DataContext = ViewModel;
ShellHandler = this;
ViewModel.Initialize(shellFrame, navigationView, KeyboardAccelerators);
@@ -461,17 +464,22 @@ namespace Microsoft.PowerToys.Settings.UI.Views
navigationView.IsPaneOpen = !navigationView.IsPaneOpen;
}
private void ExitPTItem_Tapped(object sender, RoutedEventArgs e)
private async void Close_Tapped(object sender, Microsoft.UI.Xaml.Input.TappedRoutedEventArgs e)
{
await CloseDialog.ShowAsync();
}
private void CloseDialog_Click(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
const string ptTrayIconWindowClass = "PToyTrayIconWindow"; // Defined in runner/tray_icon.h
const nuint ID_EXIT_MENU_COMMAND = 40001; // Generated resource from runner/runner.base.rc
const nuint ID_CLOSE_MENU_COMMAND = 40001; // Generated resource from runner/runner.base.rc
// Exit the XAML application
Application.Current.Exit();
// Invoke the exit command from the tray icon
IntPtr hWnd = NativeMethods.FindWindow(ptTrayIconWindowClass, ptTrayIconWindowClass);
NativeMethods.SendMessage(hWnd, NativeMethods.WM_COMMAND, ID_EXIT_MENU_COMMAND, 0);
NativeMethods.SendMessage(hWnd, NativeMethods.WM_COMMAND, ID_CLOSE_MENU_COMMAND, 0);
}
}
}