mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 17:56:44 +02:00
[Keyboard Manager] Updated WinUI3 KBM and toggles (#45649)
## Running the Project **Option 1: Test via runner** 1. Check out branch `niels9001/kbm-ux-consolidation` 2. Build PowerToys project 3. Manually build `Modules/KeyboardManagerEditorUI` project separately 4. Run `runner` project 5. Ensure experimental features are enabled in general settings (should be on by default) 6. Launch keyboard manager via settings app **Option 2: Test via installer** 1. Install PowerToys via installer on azure pipeline 1. Launch keyboard manager ## Validation For each page (Text, Remappings, Programs, URLs): * Create shortcuts with variable options and ensure they run as expected * Delete shortcuts and ensure they no longer execute * Try to create invalid shortcuts to check for proper validation * Ensure created shortcuts appear in Power Toys Settings Keyboard manager page * Try toggling shortcuts * Try deleting shortcuts while toggled off ### UI * Any feedback on UI design appreciated as well <img width="1071" height="671" alt="image" src="https://github.com/user-attachments/assets/d2e81de0-6d92-4189-9a33-32e94cce74f7" /> <img width="2142" height="1341" alt="image" src="https://github.com/user-attachments/assets/0e4e5685-fdf1-4dfd-ba52-a2e5bc9a66db" /> Closes: #15870 Closes: #31902 Closes: #45302 Closes: #36227 Closes: #16093 Closes: #13409 Closes: #9919 Closes: #9482 Closes: #8798 Closes: #7054 Closes: #2733 Closes: #2027 Closes: #30167 --------- Co-authored-by: Hao Liu <liuhao3418@gmail.com> Co-authored-by: chenmy77 <162882040+chenmy77@users.noreply.github.com> Co-authored-by: Niels Laute <niels.laute@live.nl> Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com> Co-authored-by: Jaylyn Barbee <51131738+Jaylyn-Barbee@users.noreply.github.com> Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
This commit is contained in:
@@ -12,16 +12,16 @@ using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
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.Telemetry.Events;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.ViewModels.Commands;
|
||||
using Microsoft.PowerToys.Settings.UI.SerializationContext;
|
||||
using Microsoft.PowerToys.Settings.Utilities;
|
||||
using Microsoft.Win32;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
@@ -38,8 +38,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
// Default editor path. Can be removed once the new WinUI3 editor is released.
|
||||
private const string KeyboardManagerEditorPath = "KeyboardManagerEditor\\PowerToys.KeyboardManagerEditor.exe";
|
||||
|
||||
// New WinUI3 editor path. Still in development and do NOT use it in production.
|
||||
private const string KeyboardManagerEditorUIPath = "KeyboardManagerEditorUI\\PowerToys.KeyboardManagerEditorUI.exe";
|
||||
private const string KeyboardManagerEditorUIPath = "WinUI3Apps\\PowerToys.KeyboardManagerEditorUI.exe";
|
||||
|
||||
private Process editor;
|
||||
|
||||
@@ -57,6 +56,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
private ICommand _remapKeyboardCommand;
|
||||
private ICommand _editShortcutCommand;
|
||||
private ICommand _openNewEditorCommand;
|
||||
private KeyboardManagerProfile _profile;
|
||||
|
||||
private Func<string, int> SendConfigMSG { get; }
|
||||
@@ -181,7 +181,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
{
|
||||
var hotkeysDict = new Dictionary<string, HotkeySettings[]>
|
||||
{
|
||||
[ModuleName] = [ToggleShortcut],
|
||||
[ModuleName] = [ToggleShortcut, EditorShortcut],
|
||||
};
|
||||
|
||||
return hotkeysDict;
|
||||
@@ -192,11 +192,55 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
get => Settings.Properties.ToggleShortcut;
|
||||
set
|
||||
{
|
||||
if (Settings.Properties.ToggleShortcut != value)
|
||||
if (value != Settings.Properties.ToggleShortcut)
|
||||
{
|
||||
Settings.Properties.ToggleShortcut = value ?? Settings.Properties.DefaultToggleShortcut;
|
||||
Settings.Properties.ToggleShortcut = value == null ? Settings.Properties.DefaultToggleShortcut : value;
|
||||
|
||||
OnPropertyChanged(nameof(ToggleShortcut));
|
||||
NotifySettingsChanged();
|
||||
|
||||
SendConfigMSG(
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
|
||||
KeyboardManagerSettings.ModuleName,
|
||||
JsonSerializer.Serialize(Settings, SourceGenerationContextContext.Default.KeyboardManagerSettings)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool UseNewEditor
|
||||
{
|
||||
get => Settings.Properties.UseNewEditor;
|
||||
set
|
||||
{
|
||||
if (Settings.Properties.UseNewEditor != value)
|
||||
{
|
||||
Settings.Properties.UseNewEditor = value;
|
||||
OnPropertyChanged(nameof(UseNewEditor));
|
||||
NotifySettingsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HotkeySettings EditorShortcut
|
||||
{
|
||||
get => Settings.Properties.EditorShortcut;
|
||||
set
|
||||
{
|
||||
if (value != Settings.Properties.EditorShortcut)
|
||||
{
|
||||
Settings.Properties.EditorShortcut = value == null ? Settings.Properties.DefaultEditorShortcut : value;
|
||||
|
||||
OnPropertyChanged(nameof(EditorShortcut));
|
||||
NotifySettingsChanged();
|
||||
|
||||
SendConfigMSG(
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
|
||||
KeyboardManagerSettings.ModuleName,
|
||||
JsonSerializer.Serialize(Settings, SourceGenerationContextContext.Default.KeyboardManagerSettings)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -262,6 +306,8 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
public ICommand EditShortcutCommand => _editShortcutCommand ?? (_editShortcutCommand = new RelayCommand(OnEditShortcut));
|
||||
|
||||
public ICommand OpenNewEditorCommand => _openNewEditorCommand ?? (_openNewEditorCommand = new RelayCommand(OnOpenNewEditor));
|
||||
|
||||
public void OnRemapKeyboard()
|
||||
{
|
||||
OpenEditor((int)KeyboardManagerEditorType.KeyEditor);
|
||||
@@ -272,6 +318,11 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
OpenEditor((int)KeyboardManagerEditorType.ShortcutEditor);
|
||||
}
|
||||
|
||||
public void OnOpenNewEditor()
|
||||
{
|
||||
OpenNewEditor();
|
||||
}
|
||||
|
||||
private static void BringProcessToFront(Process process)
|
||||
{
|
||||
if (process == null)
|
||||
@@ -305,41 +356,16 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
// Launch the new editor if:
|
||||
// 1. the experimentation toggle is enabled in the settings
|
||||
// 2. the new WinUI3 editor is enabled in the registry. The registry value does not exist by default and is only used for development purposes
|
||||
string editorPath = KeyboardManagerEditorPath;
|
||||
try
|
||||
{
|
||||
// Check if the experimentation toggle is enabled in the settings
|
||||
var settingsUtils = SettingsUtils.Default;
|
||||
bool isExperimentationEnabled = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.EnableExperimentation;
|
||||
|
||||
// Only read the registry value if the experimentation toggle is enabled
|
||||
if (isExperimentationEnabled)
|
||||
{
|
||||
// Read the registry value to determine which editor to launch
|
||||
var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\PowerToys\Keyboard Manager");
|
||||
if (key != null && (int?)key.GetValue("UseNewEditor") == 1)
|
||||
{
|
||||
editorPath = KeyboardManagerEditorUIPath;
|
||||
}
|
||||
|
||||
// Close the registry key
|
||||
key?.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Fall back to the default editor path if any exception occurs
|
||||
Logger.LogError("Failed to launch the new WinUI3 Editor", e);
|
||||
}
|
||||
|
||||
string path = Path.Combine(Environment.CurrentDirectory, editorPath);
|
||||
string path = Path.Combine(Environment.CurrentDirectory, KeyboardManagerEditorPath);
|
||||
Logger.LogInfo($"Starting {ModuleName} editor from {path}");
|
||||
|
||||
// InvariantCulture: type represents the KeyboardManagerEditorType enum value
|
||||
editor = Process.Start(path, $"{type.ToString(CultureInfo.InvariantCulture)} {Environment.ProcessId}");
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo(path);
|
||||
startInfo.UseShellExecute = true; // LOAD BEARING
|
||||
startInfo.Arguments = $"{type.ToString(CultureInfo.InvariantCulture)} {Environment.ProcessId}";
|
||||
System.Environment.SetEnvironmentVariable("MICROSOFT_WINDOWSAPPRUNTIME_BASE_DIRECTORY", null);
|
||||
editor = Process.Start(startInfo);
|
||||
PowerToysTelemetry.Log.WriteEvent(new ModuleLaunchedFromSettingsEvent("KeyboardManagerClassic"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -347,6 +373,39 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenNewEditor()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (editor != null && editor.HasExited)
|
||||
{
|
||||
Logger.LogInfo($"Previous instance of {ModuleName} editor exited");
|
||||
editor = null;
|
||||
}
|
||||
|
||||
if (editor != null)
|
||||
{
|
||||
Logger.LogInfo($"The {ModuleName} editor instance {editor.Id} exists. Bringing the process to the front");
|
||||
BringProcessToFront(editor);
|
||||
return;
|
||||
}
|
||||
|
||||
string path = Path.Combine(Environment.CurrentDirectory, KeyboardManagerEditorUIPath);
|
||||
Logger.LogInfo($"Starting {ModuleName} new editor from {path}");
|
||||
|
||||
System.Environment.SetEnvironmentVariable("MICROSOFT_WINDOWSAPPRUNTIME_BASE_DIRECTORY", null);
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo(path);
|
||||
startInfo.UseShellExecute = true; // LOAD BEARING
|
||||
startInfo.Arguments = $"{Environment.ProcessId}";
|
||||
editor = Process.Start(startInfo);
|
||||
PowerToysTelemetry.Log.WriteEvent(new ModuleLaunchedFromSettingsEvent("KeyboardManagerWinUI"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError($"Exception encountered when opening the new {ModuleName} editor", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void NotifyFileChanged()
|
||||
{
|
||||
OnPropertyChanged(nameof(RemapKeys));
|
||||
|
||||
Reference in New Issue
Block a user