From 665e957cde25c2dd8e2d8e1901f2e6c0a720d5a9 Mon Sep 17 00:00:00 2001 From: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com> Date: Thu, 20 Mar 2025 16:20:19 +0100 Subject: [PATCH] [settings] Show uneditable shortcut in CmdPal page (#38060) * [settings] Show CmdPal shortcut * show in dashboard as well ![image](https://github.com/user-attachments/assets/395d112d-162c-412c-99c2-2625b23cc451) ![image](https://github.com/user-attachments/assets/a0362e2b-e647-4a19-b4ff-fdb501e236d7) As noted in #37908 --- .../Settings.UI.Library/CmdPalProperties.cs | 62 +++++++++++++++++++ .../Settings.UI.Library/Utilities/Helper.cs | 21 +++++++ .../SettingsXAML/Views/CmdPalPage.xaml | 10 +++ .../SettingsXAML/Views/CmdPalPage.xaml.cs | 3 +- .../Settings.UI/Strings/en-us/Resources.resw | 9 +++ .../Settings.UI/ViewModels/CmdPalViewModel.cs | 43 ++++++++++++- .../ViewModels/DashboardViewModel.cs | 4 +- 7 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 src/settings-ui/Settings.UI.Library/CmdPalProperties.cs diff --git a/src/settings-ui/Settings.UI.Library/CmdPalProperties.cs b/src/settings-ui/Settings.UI.Library/CmdPalProperties.cs new file mode 100644 index 0000000000..406f67c2a4 --- /dev/null +++ b/src/settings-ui/Settings.UI.Library/CmdPalProperties.cs @@ -0,0 +1,62 @@ +// 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. + +using System; +using System.IO; +using System.IO.Abstractions; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Microsoft.PowerToys.Settings.UI.Library +{ + public class CmdPalProperties + { + // Default shortcut - Win + Alt + Space + public static readonly HotkeySettings DefaultHotkeyValue = new HotkeySettings(true, false, true, false, 32); + +#pragma warning disable SA1401 // Fields should be private +#pragma warning disable CA1051 // Do not declare visible instance fields + public HotkeySettings Hotkey; +#pragma warning restore CA1051 // Do not declare visible instance fields +#pragma warning restore SA1401 // Fields should be private + + private string _settingsFilePath; + + public CmdPalProperties() + { + var localAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + +#if DEBUG + _settingsFilePath = Path.Combine(localAppDataDir, "Packages", "Microsoft.CommandPalette.Dev_8wekyb3d8bbwe", "LocalState", "settings.json"); +#else + _settingsFilePath = Path.Combine(localAppDataDir, "Packages", "Microsoft.CommandPalette_8wekyb3d8bbwe", "LocalState", "settings.json"); +#endif + + InitializeHotkey(); + } + + public void InitializeHotkey() + { + try + { + string json = File.ReadAllText(_settingsFilePath); // Read JSON file + using JsonDocument doc = JsonDocument.Parse(json); + + if (doc.RootElement.TryGetProperty(nameof(Hotkey), out JsonElement hotkeyElement)) + { + Hotkey = JsonSerializer.Deserialize(hotkeyElement.GetRawText()); + + if (Hotkey == null) + { + Hotkey = DefaultHotkeyValue; + } + } + } + catch (Exception) + { + Hotkey = DefaultHotkeyValue; + } + } + } +} diff --git a/src/settings-ui/Settings.UI.Library/Utilities/Helper.cs b/src/settings-ui/Settings.UI.Library/Utilities/Helper.cs index 862377f2d5..3fa4479b79 100644 --- a/src/settings-ui/Settings.UI.Library/Utilities/Helper.cs +++ b/src/settings-ui/Settings.UI.Library/Utilities/Helper.cs @@ -53,6 +53,27 @@ namespace Microsoft.PowerToys.Settings.UI.Library.Utilities return sendCustomAction.ToJsonString(); } + public static IFileSystemWatcher GetFileWatcher(string path, Action onChangedCallback, IFileSystem fileSystem = null) + { + fileSystem ??= FileSystem; + + var dirPath = Path.GetDirectoryName(path); + if (!fileSystem.Directory.Exists(dirPath)) + { + return null; + } + + var watcher = fileSystem.FileSystemWatcher.New(); + watcher.Path = dirPath; + watcher.Filter = Path.GetFileName(path); + watcher.NotifyFilter = NotifyFilters.LastWrite; + watcher.EnableRaisingEvents = true; + + watcher.Changed += (o, e) => onChangedCallback(); + + return watcher; + } + public static IFileSystemWatcher GetFileWatcher(string moduleName, string fileName, Action onChangedCallback, IFileSystem fileSystem = null) { fileSystem ??= FileSystem; diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/CmdPalPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/CmdPalPage.xaml index 52859352f6..df8d9995ec 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/CmdPalPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/CmdPalPage.xaml @@ -25,6 +25,16 @@ IsOpen="{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}" IsTabStop="{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}" Severity="Informational" /> + + + + + + + diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/CmdPalPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/CmdPalPage.xaml.cs index 30dcbcf11f..f00acdc750 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/CmdPalPage.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/CmdPalPage.xaml.cs @@ -19,7 +19,8 @@ namespace Microsoft.PowerToys.Settings.UI.Views ViewModel = new CmdPalViewModel( settingsUtils, SettingsRepository.GetInstance(settingsUtils), - ShellPage.SendDefaultIPCMessage); + ShellPage.SendDefaultIPCMessage, + DispatcherQueue); DataContext = ViewModel; InitializeComponent(); } diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index d4b23ba82f..9e209f89a7 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -4990,4 +4990,13 @@ To record a specific window, enter the hotkey with the Alt key in the opposite m Retry + + Activation + + + Activation shortcut + + + Go to Command Palette settings to customize the activation shortcut. + \ No newline at end of file diff --git a/src/settings-ui/Settings.UI/ViewModels/CmdPalViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/CmdPalViewModel.cs index 1236ec55bf..07806bf31a 100644 --- a/src/settings-ui/Settings.UI/ViewModels/CmdPalViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/CmdPalViewModel.cs @@ -4,15 +4,19 @@ using System; using System.IO; +using System.IO.Abstractions; using System.Linq; using System.Reflection; +using System.Text.Json; using System.Text.RegularExpressions; using global::PowerToys.GPOWrapper; using ManagedCommon; using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; +using Microsoft.PowerToys.Settings.UI.Library.Utilities; using Microsoft.PowerToys.Settings.UI.ViewModels.Commands; +using Microsoft.UI.Dispatching; using Windows.Management.Deployment; namespace Microsoft.PowerToys.Settings.UI.ViewModels @@ -21,12 +25,16 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels { private GpoRuleConfigured _enabledGpoRuleConfiguration; private bool _isEnabled; + private HotkeySettings _hotkey; + private IFileSystemWatcher _watcher; + private DispatcherQueue _uiDispatcherQueue; + private CmdPalProperties _cmdPalProperties; private GeneralSettings GeneralSettingsConfig { get; set; } private Func SendConfigMSG { get; } - public CmdPalViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, Func ipcMSGCallBackFunc) + public CmdPalViewModel(ISettingsUtils settingsUtils, ISettingsRepository settingsRepository, Func ipcMSGCallBackFunc, DispatcherQueue uiDispatcherQueue) { ArgumentNullException.ThrowIfNull(settingsUtils); @@ -35,8 +43,32 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels GeneralSettingsConfig = settingsRepository.SettingsConfig; + _uiDispatcherQueue = uiDispatcherQueue; + _cmdPalProperties = new CmdPalProperties(); + InitializeEnabledValue(); + var localAppDataDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + +#if DEBUG + var settingsPath = Path.Combine(localAppDataDir, "Packages", "Microsoft.CommandPalette.Dev_8wekyb3d8bbwe", "LocalState", "settings.json"); +#else + var settingsPath = Path.Combine(localAppDataDir, "Packages", "Microsoft.CommandPalette_8wekyb3d8bbwe", "LocalState", "settings.json"); +#endif + + _hotkey = _cmdPalProperties.Hotkey; + + _watcher = Helper.GetFileWatcher(settingsPath, () => + { + _cmdPalProperties.InitializeHotkey(); + _hotkey = _cmdPalProperties.Hotkey; + + _uiDispatcherQueue.TryEnqueue(() => + { + OnPropertyChanged(nameof(Hotkey)); + }); + }); + // set the callback functions value to handle outgoing IPC message. SendConfigMSG = ipcMSGCallBackFunc; } @@ -82,6 +114,15 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels } } + public HotkeySettings Hotkey + { + get => _hotkey; + + private set + { + } + } + public bool IsEnabledGpoConfigured { get; private set; } public void RefreshEnabledState() diff --git a/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs index e12cda222e..bc40b5b1cb 100644 --- a/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs @@ -223,9 +223,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels private ObservableCollection GetModuleItemsCmdPal() { + var hotkey = new CmdPalProperties().Hotkey; + var list = new List { - new DashboardModuleTextItem() { Label = resourceLoader.GetString("CmdPal_ShortDescription") }, + new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("CmdPal_ShortDescription"), Shortcut = hotkey.GetKeysList() }, }; return new ObservableCollection(list); }