mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
CmdPal: Add configuration option for Escape key behavior (#43354)
## Summary of the Pull Request This PR adds a new option to the **General** page in **Settings**: Escape key behavior — a dropdown with the following choices: - Clear search first, then go back - Current behavior. - If the search box contains text, it is cleared; otherwise goes back. - On the home page, CmdPal is dismissed. - Go back - Leaves the search text intact. - If the page is not transient, the search text reappears when returning. - On the home page, CmdPal is dismissed. - Hide window and go home (Always dismiss) - Immediately dismisses CmdPal and navigates to the home page. - Ignores the **Go home when activated** setting. - Search text is cleared. - Hide window - Just hides the window. - Intended to be used with #43355. This implementation preserves existing behavior, except for **Always dismiss**, which always forces navigation to the home page. ## Pictures? Pictures! <img width="1305" height="892" alt="image" src="https://github.com/user-attachments/assets/562e5604-1da6-4fc6-8358-5053df9c573d" /> <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #38311 - [ ] **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
This commit is contained in:
@@ -4,6 +4,4 @@
|
|||||||
|
|
||||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||||
|
|
||||||
public record DismissMessage()
|
public record DismissMessage(bool ForceGoHome = false);
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,6 +4,4 @@
|
|||||||
|
|
||||||
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
namespace Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||||
|
|
||||||
public record NavigateBackMessage(bool FromBackspace = false)
|
public record NavigateBackMessage(bool FromBackspace = false);
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ public partial class ShellViewModel : ObservableObject,
|
|||||||
{
|
{
|
||||||
// Reset the palette to the main page and dismiss
|
// Reset the palette to the main page and dismiss
|
||||||
GoHome(withAnimation: false, focusSearch: false);
|
GoHome(withAnimation: false, focusSearch: false);
|
||||||
WeakReferenceMessenger.Default.Send<DismissMessage>();
|
WeakReferenceMessenger.Default.Send(new DismissMessage());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +398,7 @@ public partial class ShellViewModel : ObservableObject,
|
|||||||
case CommandResultKind.Hide:
|
case CommandResultKind.Hide:
|
||||||
{
|
{
|
||||||
// Keep this page open, but hide the palette.
|
// Keep this page open, but hide the palette.
|
||||||
WeakReferenceMessenger.Default.Send<DismissMessage>();
|
WeakReferenceMessenger.Default.Send(new DismissMessage());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ public partial class SettingsModel : ObservableObject
|
|||||||
|
|
||||||
public TimeSpan AutoGoHomeInterval { get; set; } = Timeout.InfiniteTimeSpan;
|
public TimeSpan AutoGoHomeInterval { get; set; } = Timeout.InfiniteTimeSpan;
|
||||||
|
|
||||||
|
public EscapeKeyBehavior EscapeKeyBehaviorSetting { get; set; } = EscapeKeyBehavior.ClearSearchFirstThenGoBack;
|
||||||
|
|
||||||
// END SETTINGS
|
// END SETTINGS
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -282,3 +284,11 @@ public enum MonitorBehavior
|
|||||||
InPlace = 3,
|
InPlace = 3,
|
||||||
ToLast = 4,
|
ToLast = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum EscapeKeyBehavior
|
||||||
|
{
|
||||||
|
ClearSearchFirstThenGoBack = 0,
|
||||||
|
AlwaysGoBack = 1,
|
||||||
|
AlwaysDismiss = 2,
|
||||||
|
AlwaysHide = 3,
|
||||||
|
}
|
||||||
|
|||||||
@@ -160,6 +160,16 @@ public partial class SettingsViewModel : INotifyPropertyChanged
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int EscapeKeyBehaviorIndex
|
||||||
|
{
|
||||||
|
get => (int)_settings.EscapeKeyBehaviorSetting;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_settings.EscapeKeyBehaviorSetting = (EscapeKeyBehavior)value;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public ObservableCollection<ProviderSettingsViewModel> CommandProviders { get; } = [];
|
public ObservableCollection<ProviderSettingsViewModel> CommandProviders { get; } = [];
|
||||||
|
|
||||||
public SettingsExtensionsViewModel Extensions { get; }
|
public SettingsExtensionsViewModel Extensions { get; }
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ using CommunityToolkit.WinUI;
|
|||||||
using Microsoft.CmdPal.Core.ViewModels;
|
using Microsoft.CmdPal.Core.ViewModels;
|
||||||
using Microsoft.CmdPal.Core.ViewModels.Commands;
|
using Microsoft.CmdPal.Core.ViewModels.Commands;
|
||||||
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
using Microsoft.CmdPal.Core.ViewModels.Messages;
|
||||||
using Microsoft.CmdPal.UI.Messages;
|
using Microsoft.CmdPal.Ext.ClipboardHistory.Messages;
|
||||||
|
using Microsoft.CmdPal.UI.ViewModels;
|
||||||
using Microsoft.CmdPal.UI.Views;
|
using Microsoft.CmdPal.UI.Views;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.UI.Dispatching;
|
using Microsoft.UI.Dispatching;
|
||||||
using Microsoft.UI.Input;
|
using Microsoft.UI.Input;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
@@ -49,6 +51,8 @@ public sealed partial class SearchBar : UserControl,
|
|||||||
// 0.6+ suggestions
|
// 0.6+ suggestions
|
||||||
private string? _textToSuggest;
|
private string? _textToSuggest;
|
||||||
|
|
||||||
|
private SettingsModel Settings => App.Current.Services.GetRequiredService<SettingsModel>();
|
||||||
|
|
||||||
public PageViewModel? CurrentPageViewModel
|
public PageViewModel? CurrentPageViewModel
|
||||||
{
|
{
|
||||||
get => (PageViewModel?)GetValue(CurrentPageViewModelProperty);
|
get => (PageViewModel?)GetValue(CurrentPageViewModelProperty);
|
||||||
@@ -131,6 +135,22 @@ public sealed partial class SearchBar : UserControl,
|
|||||||
}
|
}
|
||||||
else if (e.Key == VirtualKey.Escape)
|
else if (e.Key == VirtualKey.Escape)
|
||||||
{
|
{
|
||||||
|
switch (Settings.EscapeKeyBehaviorSetting)
|
||||||
|
{
|
||||||
|
case EscapeKeyBehavior.AlwaysGoBack:
|
||||||
|
WeakReferenceMessenger.Default.Send<NavigateBackMessage>(new());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EscapeKeyBehavior.AlwaysDismiss:
|
||||||
|
WeakReferenceMessenger.Default.Send<DismissMessage>(new(ForceGoHome: true));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EscapeKeyBehavior.AlwaysHide:
|
||||||
|
WeakReferenceMessenger.Default.Send<HideWindowMessage>(new());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EscapeKeyBehavior.ClearSearchFirstThenGoBack:
|
||||||
|
default:
|
||||||
if (string.IsNullOrEmpty(FilterBox.Text))
|
if (string.IsNullOrEmpty(FilterBox.Text))
|
||||||
{
|
{
|
||||||
WeakReferenceMessenger.Default.Send<NavigateBackMessage>(new());
|
WeakReferenceMessenger.Default.Send<NavigateBackMessage>(new());
|
||||||
@@ -147,6 +167,9 @@ public sealed partial class SearchBar : UserControl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
else if (e.Key == VirtualKey.Back)
|
else if (e.Key == VirtualKey.Back)
|
||||||
|
|||||||
@@ -530,6 +530,11 @@ public sealed partial class MainWindow : WindowEx,
|
|||||||
|
|
||||||
public void Receive(DismissMessage message)
|
public void Receive(DismissMessage message)
|
||||||
{
|
{
|
||||||
|
if (message.ForceGoHome)
|
||||||
|
{
|
||||||
|
WeakReferenceMessenger.Default.Send(new GoHomeMessage(false, false));
|
||||||
|
}
|
||||||
|
|
||||||
// This might come in off the UI thread. Make sure to hop back.
|
// This might come in off the UI thread. Make sure to hop back.
|
||||||
DispatcherQueue.TryEnqueue(() =>
|
DispatcherQueue.TryEnqueue(() =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
|
|||||||
if (!message.FromBackspace)
|
if (!message.FromBackspace)
|
||||||
{
|
{
|
||||||
// If we can't go back then we must be at the top and thus escape again should quit.
|
// If we can't go back then we must be at the top and thus escape again should quit.
|
||||||
WeakReferenceMessenger.Default.Send<DismissMessage>();
|
WeakReferenceMessenger.Default.Send(new DismissMessage());
|
||||||
|
|
||||||
PowerToysTelemetry.Log.WriteEvent(new CmdPalDismissedOnEsc());
|
PowerToysTelemetry.Log.WriteEvent(new CmdPalDismissedOnEsc());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,15 @@
|
|||||||
<ToggleSwitch IsOn="{x:Bind viewModel.BackspaceGoesBack, Mode=TwoWay}" />
|
<ToggleSwitch IsOn="{x:Bind viewModel.BackspaceGoesBack, Mode=TwoWay}" />
|
||||||
</controls:SettingsCard>
|
</controls:SettingsCard>
|
||||||
|
|
||||||
|
<controls:SettingsCard x:Uid="Settings_GeneralPage_EscapeKeyBehavior_SettingsCard" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||||
|
<ComboBox MinWidth="{StaticResource SettingActionControlMinWidth}" SelectedIndex="{x:Bind viewModel.EscapeKeyBehaviorIndex, Mode=TwoWay}">
|
||||||
|
<ComboBoxItem x:Uid="Settings_GeneralPage_EscapeKeyBehavior_Option_DismissEmptySearchOrGoBack" />
|
||||||
|
<ComboBoxItem x:Uid="Settings_GeneralPage_EscapeKeyBehavior_Option_AlwaysGoBack" />
|
||||||
|
<ComboBoxItem x:Uid="Settings_GeneralPage_EscapeKeyBehavior_Option_AlwaysDismiss" />
|
||||||
|
<ComboBoxItem x:Uid="Settings_GeneralPage_EscapeKeyBehavior_Option_AlwaysHide" />
|
||||||
|
</ComboBox>
|
||||||
|
</controls:SettingsCard>
|
||||||
|
|
||||||
<controls:SettingsCard x:Uid="Settings_GeneralPage_SingleClickActivation_SettingsCard" HeaderIcon="{ui:FontIcon Glyph=}">
|
<controls:SettingsCard x:Uid="Settings_GeneralPage_SingleClickActivation_SettingsCard" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||||
<ToggleSwitch IsOn="{x:Bind viewModel.SingleClickActivates, Mode=TwoWay}" />
|
<ToggleSwitch IsOn="{x:Bind viewModel.SingleClickActivates, Mode=TwoWay}" />
|
||||||
</controls:SettingsCard>
|
</controls:SettingsCard>
|
||||||
|
|||||||
@@ -556,4 +556,22 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
|
|||||||
<data name="Settings_PageTitles_ExtensionsPage" xml:space="preserve">
|
<data name="Settings_PageTitles_ExtensionsPage" xml:space="preserve">
|
||||||
<value>Extensions</value>
|
<value>Extensions</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Settings_GeneralPage_EscapeKeyBehavior_Option_DismissEmptySearchOrGoBack.Content" xml:space="preserve">
|
||||||
|
<value>Clear search first, then go back</value>
|
||||||
|
</data>
|
||||||
|
<data name="Settings_GeneralPage_EscapeKeyBehavior_Option_AlwaysGoBack.Content" xml:space="preserve">
|
||||||
|
<value>Go back</value>
|
||||||
|
</data>
|
||||||
|
<data name="Settings_GeneralPage_EscapeKeyBehavior_Option_AlwaysDismiss.Content" xml:space="preserve">
|
||||||
|
<value>Hide window and go home</value>
|
||||||
|
</data>
|
||||||
|
<data name="Settings_GeneralPage_EscapeKeyBehavior_Option_AlwaysHide.Content" xml:space="preserve">
|
||||||
|
<value>Hide window</value>
|
||||||
|
</data>
|
||||||
|
<data name="Settings_GeneralPage_EscapeKeyBehavior_SettingsCard.Header" xml:space="preserve">
|
||||||
|
<value>Escape key behavior</value>
|
||||||
|
</data>
|
||||||
|
<data name="Settings_GeneralPage_EscapeKeyBehavior_SettingsCard.Description" xml:space="preserve">
|
||||||
|
<value>Choose how Escape key behaves</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
Reference in New Issue
Block a user