mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 09:46:54 +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:
@@ -6,6 +6,8 @@ using System.Threading;
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Controls;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using PowerToys.Interop;
|
||||
|
||||
namespace Microsoft.PowerToys.QuickAccess.Services
|
||||
@@ -27,6 +29,12 @@ namespace Microsoft.PowerToys.QuickAccess.Services
|
||||
if (moduleRun)
|
||||
{
|
||||
_coordinator?.OnModuleLaunched(moduleType);
|
||||
|
||||
// Send telemetry event for module launch from Quick Access
|
||||
if (moduleType == ModuleType.KeyboardManager)
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new ModuleLaunchedFromSettingsEvent("KeyboardManagerWinUI"));
|
||||
}
|
||||
}
|
||||
|
||||
_coordinator?.HideFlyout();
|
||||
|
||||
@@ -126,6 +126,13 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
eventHandle.Set();
|
||||
}
|
||||
|
||||
return true;
|
||||
case ModuleType.KeyboardManager:
|
||||
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.OpenNewKeyboardManagerEvent()))
|
||||
{
|
||||
eventHandle.Set();
|
||||
}
|
||||
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -17,6 +17,10 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
public partial class QuickAccessViewModel : Observable
|
||||
{
|
||||
private readonly ISettingsRepository<GeneralSettings> _settingsRepository;
|
||||
|
||||
// Pulling in KBMSettingsRepository separately as we need to listen to changes in the
|
||||
// UseNewEditor property to determine the visibility of the KeyboardManager quick access item.
|
||||
private readonly SettingsRepository<KeyboardManagerSettings> _kbmSettingsRepository;
|
||||
private readonly IQuickAccessLauncher _launcher;
|
||||
private readonly Func<ModuleType, bool> _isModuleGpoDisabled;
|
||||
private readonly Func<ModuleType, bool> _isModuleGpoEnabled;
|
||||
@@ -44,6 +48,9 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
_generalSettings.AddEnabledModuleChangeNotification(ModuleEnabledChanged);
|
||||
_settingsRepository.SettingsChanged += OnSettingsChanged;
|
||||
|
||||
_kbmSettingsRepository = SettingsRepository<KeyboardManagerSettings>.GetInstance(SettingsUtils.Default);
|
||||
_kbmSettingsRepository.SettingsChanged += OnKbmSettingsChanged;
|
||||
|
||||
InitializeItems();
|
||||
}
|
||||
|
||||
@@ -67,6 +74,7 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
AddFlyoutMenuItem(ModuleType.EnvironmentVariables);
|
||||
AddFlyoutMenuItem(ModuleType.FancyZones);
|
||||
AddFlyoutMenuItem(ModuleType.Hosts);
|
||||
AddFlyoutMenuItem(ModuleType.KeyboardManager);
|
||||
AddFlyoutMenuItem(ModuleType.LightSwitch);
|
||||
|
||||
// AddFlyoutMenuItem(ModuleType.PowerDisplay); // TEMPORARILY_DISABLED: PowerDisplay
|
||||
@@ -89,7 +97,7 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
{
|
||||
Title = _resourceLoader.GetString(Microsoft.PowerToys.Settings.UI.Library.Helpers.ModuleHelper.GetModuleLabelResourceName(moduleType)),
|
||||
Tag = moduleType,
|
||||
Visible = _isModuleGpoEnabled(moduleType) || Microsoft.PowerToys.Settings.UI.Library.Helpers.ModuleHelper.GetIsModuleEnabled(_generalSettings, moduleType),
|
||||
Visible = GetItemVisibility(moduleType),
|
||||
Description = GetModuleToolTip(moduleType),
|
||||
Icon = Microsoft.PowerToys.Settings.UI.Library.Helpers.ModuleHelper.GetModuleTypeFluentIconName(moduleType),
|
||||
Command = new RelayCommand(() => _launcher.Launch(moduleType)),
|
||||
@@ -115,11 +123,38 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
{
|
||||
if (item.Tag is ModuleType moduleType)
|
||||
{
|
||||
item.Visible = _isModuleGpoEnabled(moduleType) || Microsoft.PowerToys.Settings.UI.Library.Helpers.ModuleHelper.GetIsModuleEnabled(_generalSettings, moduleType);
|
||||
bool visible = GetItemVisibility(moduleType);
|
||||
|
||||
item.Visible = visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnKbmSettingsChanged(KeyboardManagerSettings newSettings)
|
||||
{
|
||||
if (_dispatcherQueue != null)
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
RefreshItemsVisibility();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private bool GetItemVisibility(ModuleType moduleType)
|
||||
{
|
||||
// Generally, if gpo is enabled or if module enabled, then quick access item is visible.
|
||||
bool visible = _isModuleGpoEnabled(moduleType) || Microsoft.PowerToys.Settings.UI.Library.Helpers.ModuleHelper.GetIsModuleEnabled(_generalSettings, moduleType);
|
||||
|
||||
// For KeyboardManager Quick Access item is only shown when using the new editor
|
||||
if (moduleType == ModuleType.KeyboardManager)
|
||||
{
|
||||
visible = visible && _kbmSettingsRepository.SettingsConfig.Properties.UseNewEditor;
|
||||
}
|
||||
|
||||
return visible;
|
||||
}
|
||||
|
||||
private string GetModuleToolTip(ModuleType moduleType)
|
||||
{
|
||||
return moduleType switch
|
||||
@@ -127,6 +162,7 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
|
||||
ModuleType.ColorPicker => SettingsRepository<ColorPickerSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.ActivationShortcut.ToString(),
|
||||
ModuleType.FancyZones => SettingsRepository<FancyZonesSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.FancyzonesEditorHotkey.Value.ToString(),
|
||||
ModuleType.PowerDisplay => SettingsRepository<PowerDisplaySettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.ActivationShortcut.ToString(),
|
||||
ModuleType.KeyboardManager => SettingsRepository<KeyboardManagerSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.DefaultEditorShortcut.ToString(),
|
||||
ModuleType.LightSwitch => SettingsRepository<LightSwitchSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.ToggleThemeHotkey.Value.ToString(),
|
||||
ModuleType.PowerLauncher => SettingsRepository<PowerLauncherSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.OpenPowerLauncher.ToString(),
|
||||
ModuleType.PowerOCR => SettingsRepository<PowerOcrSettings>.GetInstance(SettingsUtils.Default).SettingsConfig.Properties.ActivationShortcut.ToString(),
|
||||
|
||||
@@ -23,15 +23,23 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
|
||||
public HotkeySettings DefaultToggleShortcut => new HotkeySettings(true, false, false, true, 0x4B);
|
||||
|
||||
public HotkeySettings DefaultEditorShortcut => new HotkeySettings(true, false, false, true, 0x51);
|
||||
|
||||
public KeyboardManagerProperties()
|
||||
{
|
||||
ToggleShortcut = DefaultToggleShortcut;
|
||||
EditorShortcut = DefaultEditorShortcut;
|
||||
KeyboardConfigurations = new GenericProperty<List<string>>(new List<string> { "default", });
|
||||
ActiveConfiguration = new GenericProperty<string>("default");
|
||||
}
|
||||
|
||||
public HotkeySettings ToggleShortcut { get; set; }
|
||||
|
||||
public HotkeySettings EditorShortcut { get; set; }
|
||||
|
||||
[JsonPropertyName("useNewEditor")]
|
||||
public bool UseNewEditor { get; set; }
|
||||
|
||||
public string ToJsonString()
|
||||
{
|
||||
return JsonSerializer.Serialize(this);
|
||||
|
||||
@@ -42,6 +42,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
() => Properties.ToggleShortcut,
|
||||
value => Properties.ToggleShortcut = value ?? Properties.DefaultToggleShortcut,
|
||||
"Toggle_Shortcut"),
|
||||
new HotkeyAccessor(
|
||||
() => Properties.EditorShortcut,
|
||||
value => Properties.EditorShortcut = value ?? Properties.DefaultEditorShortcut,
|
||||
"Editor_Shortcut"),
|
||||
};
|
||||
|
||||
return hotkeyAccessors.ToArray();
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// 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.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Tracing;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
using Microsoft.PowerToys.Telemetry.Events;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events
|
||||
{
|
||||
[EventData]
|
||||
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
|
||||
public class ModuleLaunchedFromSettingsEvent : EventBase, IEvent
|
||||
{
|
||||
public string ModuleName { get; set; }
|
||||
|
||||
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
|
||||
|
||||
public ModuleLaunchedFromSettingsEvent(string moduleName)
|
||||
{
|
||||
EventName = "PowerToys_ModuleLaunchedFromSettings";
|
||||
ModuleName = moduleName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ namespace ViewModelTests
|
||||
var expectedEntry = new AppSpecificKeysDataModel();
|
||||
expectedEntry.OriginalKeys = entry.OriginalKeys;
|
||||
expectedEntry.NewRemapKeys = entry.NewRemapKeys;
|
||||
expectedEntry.TargetApp = "All Apps";
|
||||
expectedEntry.TargetApp = "All apps";
|
||||
expectedResult.Add(expectedEntry);
|
||||
|
||||
Assert.AreEqual(expectedResult.Count, result.Count);
|
||||
@@ -123,7 +123,7 @@ namespace ViewModelTests
|
||||
var expectedEntry = new AppSpecificKeysDataModel();
|
||||
expectedEntry.OriginalKeys = entry.OriginalKeys;
|
||||
expectedEntry.NewRemapKeys = entry.NewRemapKeys;
|
||||
expectedEntry.TargetApp = "All Apps";
|
||||
expectedEntry.TargetApp = "All apps";
|
||||
expectedResult.Add(expectedEntry);
|
||||
var x = expectedResult[0].Equals(result[0]);
|
||||
Assert.AreEqual(expectedResult.Count, result.Count);
|
||||
@@ -181,7 +181,7 @@ namespace ViewModelTests
|
||||
var expectedFirstEntry = new AppSpecificKeysDataModel();
|
||||
expectedFirstEntry.OriginalKeys = firstListEntry.OriginalKeys;
|
||||
expectedFirstEntry.NewRemapKeys = firstListEntry.NewRemapKeys;
|
||||
expectedFirstEntry.TargetApp = "All Apps";
|
||||
expectedFirstEntry.TargetApp = "All apps";
|
||||
expectedResult.Add(expectedFirstEntry);
|
||||
var expectedSecondEntry = new AppSpecificKeysDataModel();
|
||||
expectedSecondEntry.OriginalKeys = secondListEntry.OriginalKeys;
|
||||
|
||||
@@ -15,219 +15,276 @@
|
||||
mc:Ignorable="d">
|
||||
|
||||
<local:NavigablePage.Resources>
|
||||
<tkconverters:CollectionVisibilityConverter x:Key="CollectionVisibilityConverter" />
|
||||
<Style x:Name="KeysListViewContainerStyle" TargetType="ListViewItem">
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
</Style>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Default">
|
||||
<LinearGradientBrush x:Key="CardGradient2Brush" StartPoint="0,0" EndPoint="0.5, 1">
|
||||
<GradientStop Offset="0" Color="#38C8AEC4" />
|
||||
<GradientStop Offset="1" Color="#383286EE" />
|
||||
</LinearGradientBrush>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
<LinearGradientBrush x:Key="CardGradient2Brush" StartPoint="0,0" EndPoint="1, 1">
|
||||
<GradientStop Offset="0.0" Color="#FFF6F9FF" />
|
||||
<GradientStop Offset="0.4" Color="#FFEFF5FF" />
|
||||
<GradientStop Offset="0.7" Color="#FFF7FAFD" />
|
||||
<GradientStop Offset="1.0" Color="#FFF5F8FA" />
|
||||
</LinearGradientBrush>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
<SolidColorBrush x:Key="CardGradient2Brush" Color="Transparent" />
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
|
||||
<DataTemplate x:Key="OriginalKeyTemplate" x:DataType="x:String">
|
||||
<ptcontrols:KeyVisual
|
||||
Padding="8"
|
||||
Content="{Binding}"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}" />
|
||||
</DataTemplate>
|
||||
<tkconverters:CollectionVisibilityConverter x:Key="CollectionVisibilityConverter" />
|
||||
<Style x:Name="KeysListViewContainerStyle" TargetType="ListViewItem">
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
</Style>
|
||||
|
||||
<DataTemplate x:Key="RemappedKeyTemplate" x:DataType="x:String">
|
||||
<ptcontrols:KeyVisual
|
||||
Padding="8"
|
||||
Content="{Binding}"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}"
|
||||
Style="{StaticResource AccentKeyVisualStyle}" />
|
||||
</DataTemplate>
|
||||
<DataTemplate x:Key="OriginalKeyTemplate" x:DataType="x:String">
|
||||
<ptcontrols:KeyVisual
|
||||
Padding="8"
|
||||
Content="{Binding}"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}" />
|
||||
</DataTemplate>
|
||||
|
||||
<!--<DataTemplate x:Name="KeysListViewTemplate" x:DataType="Lib:KeysDataModel">
|
||||
<StackPanel
|
||||
Name="KeyboardManager_RemappedKeysListItem"
|
||||
x:Uid="KeyboardManager_RemappedKeysListItem"
|
||||
Orientation="Horizontal"
|
||||
Height="56">
|
||||
|
||||
</StackPanel>
|
||||
</DataTemplate>-->
|
||||
<!--<DataTemplate x:Name="ShortcutKeysListViewTemplate" x:DataType="Lib:AppSpecificKeysDataModel">
|
||||
<StackPanel
|
||||
Name="KeyboardManager_RemappedShortcutsListItem"
|
||||
x:Uid="KeyboardManager_RemappedShortcutsListItem"
|
||||
Orientation="Horizontal"
|
||||
Height="56">
|
||||
|
||||
</DataTemplate>-->
|
||||
<DataTemplate x:Key="RemappedKeyTemplate" x:DataType="x:String">
|
||||
<ptcontrols:KeyVisual
|
||||
Padding="8"
|
||||
Content="{Binding}"
|
||||
CornerRadius="{StaticResource ControlCornerRadius}"
|
||||
Style="{StaticResource AccentKeyVisualStyle}" />
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
||||
</local:NavigablePage.Resources>
|
||||
|
||||
<controls:SettingsPageControl x:Uid="KeyboardManager" ModuleImageSource="ms-appx:///Assets/Settings/Modules/KBM.png">
|
||||
<controls:SettingsPageControl.ModuleContent>
|
||||
<StackPanel ChildrenTransitions="{StaticResource SettingsCardsAnimations}" Orientation="Vertical">
|
||||
<controls:GPOInfoControl ShowWarning="{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
<tkcontrols:SettingsExpander
|
||||
Name="KeyboardManagerEnableToggle"
|
||||
x:Uid="KeyboardManager_EnableToggle"
|
||||
HeaderIcon="{ui:BitmapIcon Source=/Assets/Settings/Icons/KeyboardManager.png}">
|
||||
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.Enabled, Mode=TwoWay}" />
|
||||
<tkcontrols:SettingsCard.Description>
|
||||
<tkcontrols:SettingsExpander.Description>
|
||||
<HyperlinkButton NavigateUri="https://aka.ms/powerToysCannotRemapKeys">
|
||||
<TextBlock x:Uid="KBM_KeysCannotBeRemapped" FontWeight="SemiBold" />
|
||||
</HyperlinkButton>
|
||||
</tkcontrols:SettingsCard.Description>
|
||||
</tkcontrols:SettingsCard>
|
||||
</tkcontrols:SettingsExpander.Description>
|
||||
<tkcontrols:SettingsExpander.Items>
|
||||
<tkcontrols:SettingsCard
|
||||
Name="ToggleShortcut"
|
||||
x:Uid="KeyboardManager_Toggle_Shortcut"
|
||||
IsEnabled="{x:Bind ViewModel.Enabled, Mode=OneWay}">
|
||||
<controls:ShortcutControl
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
AllowDisable="True"
|
||||
HotkeySettings="{x:Bind Path=ViewModel.ToggleShortcut, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</tkcontrols:SettingsExpander.Items>
|
||||
</tkcontrols:SettingsExpander>
|
||||
</controls:GPOInfoControl>
|
||||
|
||||
<tkcontrols:SettingsCard
|
||||
Name="ToggleShortcut"
|
||||
x:Uid="KeyboardManager_Toggle_Shortcut"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<controls:ShortcutControl MinWidth="{StaticResource SettingActionControlMinWidth}" HotkeySettings="{x:Bind Path=ViewModel.ToggleShortcut, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SwitchPresenter TargetType="x:Boolean" Value="{x:Bind ViewModel.UseNewEditor, Mode=OneWay}">
|
||||
<tkcontrols:Case Value="False">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<tkcontrols:SettingsCard
|
||||
x:Uid="KeyboardManager_TryNewExperience"
|
||||
MinHeight="64"
|
||||
Margin="0,0,0,24"
|
||||
Background="{ThemeResource CardGradient2Brush}"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind ViewModel.Enabled, Mode=OneWay}">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.UseNewEditor, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<controls:SettingsGroup x:Uid="KeyboardManager_Keys" IsEnabled="{x:Bind ViewModel.Enabled, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="KeyboardManagerRemapKeyboardButton"
|
||||
x:Uid="KeyboardManager_RemapKeyboardButton"
|
||||
ActionIcon="{ui:FontIcon Glyph=}"
|
||||
Command="{Binding Path=RemapKeyboardCommand}"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsClickEnabled="True" />
|
||||
|
||||
<controls:SettingsGroup x:Uid="KeyboardManager_Keys" IsEnabled="{x:Bind ViewModel.Enabled, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="KeyboardManagerRemapKeyboardButton"
|
||||
x:Uid="KeyboardManager_RemapKeyboardButton"
|
||||
ActionIcon="{ui:FontIcon Glyph=}"
|
||||
Command="{Binding Path=RemapKeyboardCommand}"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsClickEnabled="True" />
|
||||
<ListView
|
||||
x:Name="RemapKeysList"
|
||||
x:Uid="RemapKeysList"
|
||||
IsSwipeEnabled="False"
|
||||
ItemsSource="{x:Bind Path=ViewModel.RemapKeys, Mode=OneWay}"
|
||||
SelectionMode="None"
|
||||
Visibility="{x:Bind Path=ViewModel.RemapKeys, Mode=OneWay, Converter={StaticResource CollectionVisibilityConverter}}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="Lib:KeysDataModel">
|
||||
<tkcontrols:SettingsCard ContentAlignment="Left">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ItemsControl
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource OriginalKeyTemplate}"
|
||||
ItemsSource="{x:Bind GetMappedOriginalKeys()}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
<ptcontrols:IsEnabledTextBlock
|
||||
x:Uid="To"
|
||||
Margin="8,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SecondaryIsEnabledTextBlockStyle}" />
|
||||
<ItemsControl
|
||||
Name="KeyboardManager_RemappedTo"
|
||||
x:Uid="KeyboardManager_RemappedTo"
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource RemappedKeyTemplate}"
|
||||
ItemsSource="{x:Bind GetMappedNewRemapKeys(50)}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</tkcontrols:SettingsCard>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</controls:SettingsGroup>
|
||||
|
||||
<ListView
|
||||
x:Name="RemapKeysList"
|
||||
x:Uid="RemapKeysList"
|
||||
IsSwipeEnabled="False"
|
||||
ItemsSource="{x:Bind Path=ViewModel.RemapKeys, Mode=OneWay}"
|
||||
SelectionMode="None"
|
||||
Visibility="{x:Bind Path=ViewModel.RemapKeys, Mode=OneWay, Converter={StaticResource CollectionVisibilityConverter}}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="Lib:KeysDataModel">
|
||||
<tkcontrols:SettingsCard ContentAlignment="Left">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ItemsControl
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource OriginalKeyTemplate}"
|
||||
ItemsSource="{x:Bind GetMappedOriginalKeys()}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
<ptcontrols:IsEnabledTextBlock
|
||||
x:Uid="To"
|
||||
Margin="8,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SecondaryIsEnabledTextBlockStyle}" />
|
||||
<ItemsControl
|
||||
Name="KeyboardManager_RemappedTo"
|
||||
x:Uid="KeyboardManager_RemappedTo"
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource RemappedKeyTemplate}"
|
||||
ItemsSource="{x:Bind GetMappedNewRemapKeys(50)}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</tkcontrols:SettingsCard>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup x:Uid="KeyboardManager_Shortcuts" IsEnabled="{x:Bind ViewModel.Enabled, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="KeyboardManagerRemapShortcutsButton"
|
||||
x:Uid="KeyboardManager_RemapShortcutsButton"
|
||||
ActionIcon="{ui:FontIcon Glyph=}"
|
||||
Command="{Binding Path=EditShortcutCommand}"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsClickEnabled="True" />
|
||||
|
||||
<controls:SettingsGroup x:Uid="KeyboardManager_Shortcuts" IsEnabled="{x:Bind ViewModel.Enabled, Mode=OneWay}">
|
||||
<tkcontrols:SettingsCard
|
||||
Name="KeyboardManagerRemapShortcutsButton"
|
||||
x:Uid="KeyboardManager_RemapShortcutsButton"
|
||||
ActionIcon="{ui:FontIcon Glyph=}"
|
||||
Command="{Binding Path=EditShortcutCommand}"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsClickEnabled="True" />
|
||||
<ListView
|
||||
x:Name="RemapShortcutsList"
|
||||
x:Uid="RemapShortcutsList"
|
||||
IsSwipeEnabled="False"
|
||||
ItemsSource="{x:Bind Path=ViewModel.RemapShortcuts, Mode=OneWay}"
|
||||
SelectionMode="None"
|
||||
Visibility="{x:Bind Path=ViewModel.RemapShortcuts, Mode=OneWay, Converter={StaticResource CollectionVisibilityConverter}}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="Lib:AppSpecificKeysDataModel">
|
||||
|
||||
<ListView
|
||||
x:Name="RemapShortcutsList"
|
||||
x:Uid="RemapShortcutsList"
|
||||
IsSwipeEnabled="False"
|
||||
ItemsSource="{x:Bind Path=ViewModel.RemapShortcuts, Mode=OneWay}"
|
||||
SelectionMode="None"
|
||||
Visibility="{x:Bind Path=ViewModel.RemapShortcuts, Mode=OneWay, Converter={StaticResource CollectionVisibilityConverter}}">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:DataType="Lib:AppSpecificKeysDataModel">
|
||||
<tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard.Description>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ItemsControl
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource OriginalKeyTemplate}"
|
||||
ItemsSource="{x:Bind GetMappedOriginalKeysWithoutChord()}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
|
||||
<tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard.Description>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ItemsControl
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource OriginalKeyTemplate}"
|
||||
ItemsSource="{x:Bind GetMappedOriginalKeysWithoutChord()}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
<TextBlock
|
||||
Padding="6,0,6,6"
|
||||
VerticalAlignment="Bottom"
|
||||
Text=","
|
||||
Visibility="{x:Bind Path=HasChord, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
|
||||
<TextBlock
|
||||
Padding="6,0,6,6"
|
||||
VerticalAlignment="Bottom"
|
||||
Text=","
|
||||
Visibility="{x:Bind Path=HasChord, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<ItemsControl
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource OriginalKeyTemplate}"
|
||||
ItemsSource="{x:Bind GetMappedOriginalKeysOnlyChord()}"
|
||||
Visibility="{x:Bind Path=HasChord, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
|
||||
<ItemsControl
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource OriginalKeyTemplate}"
|
||||
ItemsSource="{x:Bind GetMappedOriginalKeysOnlyChord()}"
|
||||
Visibility="{x:Bind Path=HasChord, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
<ptcontrols:IsEnabledTextBlock
|
||||
x:Uid="To"
|
||||
Margin="8,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SecondaryIsEnabledTextBlockStyle}"
|
||||
Visibility="{x:Bind Path=IsOpenUriOrIsRunProgram, Mode=OneWay, Converter={StaticResource ReverseBoolToVisibilityConverter}}" />
|
||||
|
||||
<ptcontrols:IsEnabledTextBlock
|
||||
x:Uid="To"
|
||||
Margin="8,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SecondaryIsEnabledTextBlockStyle}"
|
||||
Visibility="{x:Bind Path=IsOpenUriOrIsRunProgram, Mode=OneWay, Converter={StaticResource ReverseBoolToVisibilityConverter}}" />
|
||||
|
||||
<ptcontrols:IsEnabledTextBlock
|
||||
x:Uid="Starts"
|
||||
Margin="8,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SecondaryIsEnabledTextBlockStyle}"
|
||||
Visibility="{x:Bind Path=IsOpenUriOrIsRunProgram, Mode=OneWay}" />
|
||||
<ptcontrols:IsEnabledTextBlock
|
||||
x:Uid="Starts"
|
||||
Margin="8,0,8,0"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource SecondaryIsEnabledTextBlockStyle}"
|
||||
Visibility="{x:Bind Path=IsOpenUriOrIsRunProgram, Mode=OneWay}" />
|
||||
|
||||
|
||||
<ItemsControl
|
||||
Name="KeyboardManager_RemappedTo"
|
||||
x:Uid="KeyboardManager_RemappedTo"
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource RemappedKeyTemplate}"
|
||||
ItemsSource="{x:Bind GetMappedNewRemapKeys(50)}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
<Border
|
||||
Margin="16,0,0,0"
|
||||
Padding="12,4,12,6"
|
||||
VerticalAlignment="Center"
|
||||
CornerRadius="12">
|
||||
<Border.Background>
|
||||
<SolidColorBrush Opacity="0.3" Color="{ThemeResource SystemAccentColor}" />
|
||||
</Border.Background>
|
||||
<TextBlock Text="{x:Bind TargetApp}" />
|
||||
</Border>
|
||||
<ItemsControl
|
||||
Name="KeyboardManager_RemappedTo"
|
||||
x:Uid="KeyboardManager_RemappedTo"
|
||||
IsTabStop="False"
|
||||
ItemTemplate="{StaticResource RemappedKeyTemplate}"
|
||||
ItemsSource="{x:Bind GetMappedNewRemapKeys(50)}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" Spacing="4" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
<Border
|
||||
Margin="16,0,0,0"
|
||||
Padding="12,4,12,6"
|
||||
VerticalAlignment="Center"
|
||||
CornerRadius="12">
|
||||
<Border.Background>
|
||||
<SolidColorBrush Opacity="0.3" Color="{ThemeResource SystemAccentColor}" />
|
||||
</Border.Background>
|
||||
<TextBlock Text="{x:Bind TargetApp}" />
|
||||
</Border>
|
||||
|
||||
</StackPanel>
|
||||
</tkcontrols:SettingsCard.Description>
|
||||
</tkcontrols:SettingsCard>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</controls:SettingsGroup>
|
||||
</StackPanel>
|
||||
</tkcontrols:SettingsCard.Description>
|
||||
</tkcontrols:SettingsCard>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</controls:SettingsGroup>
|
||||
</StackPanel>
|
||||
</tkcontrols:Case>
|
||||
|
||||
<tkcontrols:Case Value="True">
|
||||
<controls:SettingsGroup x:Uid="KeyboardManager_Editor" IsEnabled="{x:Bind ViewModel.Enabled, Mode=OneWay}">
|
||||
<StackPanel Orientation="Vertical" Spacing="16">
|
||||
<tkcontrols:SettingsExpander
|
||||
x:Uid="KeyboardManager_OpenNewEditor"
|
||||
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="{x:Bind ViewModel.Enabled, Mode=OneWay}"
|
||||
IsExpanded="True">
|
||||
<Button
|
||||
x:Uid="KeyboardManager_LaunchEditor_Button"
|
||||
Command="{Binding Path=OpenNewEditorCommand}"
|
||||
Style="{StaticResource AccentButtonStyle}" />
|
||||
<tkcontrols:SettingsExpander.Items>
|
||||
<!-- HACK: ShortcutControl does not work correctly if it's the first or last item in the expander, so we add invisible cards. -->
|
||||
<tkcontrols:SettingsCard Visibility="Collapsed" />
|
||||
<tkcontrols:SettingsCard Name="KBMEditorOpenShortcut" x:Uid="KeyboardManager_Editor_Open_Shortcut">
|
||||
<controls:ShortcutControl
|
||||
MinWidth="{StaticResource SettingActionControlMinWidth}"
|
||||
AllowDisable="True"
|
||||
HotkeySettings="{x:Bind Path=ViewModel.EditorShortcut, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<tkcontrols:SettingsCard Visibility="Collapsed" />
|
||||
</tkcontrols:SettingsExpander.Items>
|
||||
</tkcontrols:SettingsExpander>
|
||||
<HyperlinkButton
|
||||
x:Uid="KeyboardManager_GoBackClassic"
|
||||
Padding="0"
|
||||
Click="GoBackClassic_Click"
|
||||
FontSize="12"
|
||||
FontWeight="SemiBold" />
|
||||
</StackPanel>
|
||||
</controls:SettingsGroup>
|
||||
</tkcontrols:Case>
|
||||
</tkcontrols:SwitchPresenter>
|
||||
</StackPanel>
|
||||
</controls:SettingsPageControl.ModuleContent>
|
||||
<controls:SettingsPageControl.PrimaryLinks>
|
||||
|
||||
@@ -91,5 +91,10 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
{
|
||||
ViewModel.RefreshEnabledState();
|
||||
}
|
||||
|
||||
private void GoBackClassic_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.UseNewEditor = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,6 +557,10 @@ opera.exe</value>
|
||||
<data name="KeyboardManager_RemapKeyboardButton.Header" xml:space="preserve">
|
||||
<value>Remap a key</value>
|
||||
<comment>Keyboard Manager remap keyboard button content</comment>
|
||||
</data>
|
||||
<data name="KeyboardManager_Editor.Header" xml:space="preserve">
|
||||
<value>Editor</value>
|
||||
<comment>Keyboard Manager new editor header</comment>
|
||||
</data>
|
||||
<data name="KeyboardManager_Keys.Header" xml:space="preserve">
|
||||
<value>Keys</value>
|
||||
@@ -571,9 +575,29 @@ opera.exe</value>
|
||||
<comment>Keyboard Manager remap keyboard header</comment>
|
||||
</data>
|
||||
<data name="KeyboardManager_All_Apps_Description" xml:space="preserve">
|
||||
<value>All Apps</value>
|
||||
<value>All apps</value>
|
||||
<comment>Should be the same as EditShortcuts_AllApps from keyboard manager editor</comment>
|
||||
</data>
|
||||
<data name="KeyboardManager_TryNewExperience.Header" xml:space="preserve">
|
||||
<value>Try the new editor</value>
|
||||
<comment>Keyboard Manager toggle to switch to the new unified editor</comment>
|
||||
</data>
|
||||
<data name="KeyboardManager_TryNewExperience.Description" xml:space="preserve">
|
||||
<value>Switch to the new editor. You can switch back at any time.</value>
|
||||
<comment>Description for the new experience toggle</comment>
|
||||
</data>
|
||||
<data name="KeyboardManager_OpenNewEditor.Header" xml:space="preserve">
|
||||
<value>Editor</value>
|
||||
<comment>Keyboard Manager button to open the new unified editor</comment>
|
||||
</data>
|
||||
<data name="KeyboardManager_OpenNewEditor.Description" xml:space="preserve">
|
||||
<value>Set and manage your remappings</value>
|
||||
<comment>Description for the new editor button</comment>
|
||||
</data>
|
||||
<data name="KeyboardManager_GoBackClassic.Content" xml:space="preserve">
|
||||
<value>Switch back to the classic editor</value>
|
||||
<comment>Keyboard Manager link to switch back to the classic editor UI</comment>
|
||||
</data>
|
||||
<data name="Shortcut.Header" xml:space="preserve">
|
||||
<value>Shortcut</value>
|
||||
</data>
|
||||
@@ -1883,12 +1907,24 @@ Made with 💗 by Microsoft and the PowerToys community.</value>
|
||||
<value>Customize the shortcut to activate this module</value>
|
||||
</data>
|
||||
<data name="KeyboardManager_Toggle_Shortcut.Header" xml:space="preserve">
|
||||
<value>Toggle shortcut</value>
|
||||
<value>Shortcut</value>
|
||||
</data>
|
||||
<data name="KeyboardManager_Toggle_Shortcut.Description" xml:space="preserve">
|
||||
<value>Use a shortcut to toggle this module on or off (note that the Settings UI will not update)</value>
|
||||
<value>Enable or disable this module (Note: the Settings UI will not update)</value>
|
||||
</data>
|
||||
<data name="PasteAsPlainText_Shortcut.Header" xml:space="preserve">
|
||||
<data name="KeyboardManager_Editor_Shortcut.Header" xml:space="preserve">
|
||||
<value>Editor shortcut</value>
|
||||
</data>
|
||||
<data name="KeyboardManager_Editor_Open_Shortcut.Header" xml:space="preserve">
|
||||
<value>Open editor shortcut</value>
|
||||
</data>
|
||||
<data name="KeyboardManager_Editor_Open_Shortcut.Description" xml:space="preserve">
|
||||
<value>Customize the shortcut to open the Keyboard Manager editor</value>
|
||||
</data>
|
||||
<data name="KeyboardManager_LaunchEditor_Button.Content" xml:space="preserve">
|
||||
<value>Open editor</value>
|
||||
</data>
|
||||
<data name="PasteAsPlainText_Shortcut.Header" xml:space="preserve">
|
||||
<value>Paste as plain text directly</value>
|
||||
</data>
|
||||
<data name="AdvancedPasteUI_Actions.Header" xml:space="preserve">
|
||||
|
||||
@@ -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