Compare commits

...

3 Commits

Author SHA1 Message Date
Niels Laute
e64ccdf677 Merge branch 'main' into niels9001/run-kbm-directly 2026-04-03 11:25:58 +02:00
Niels Laute
55f77280be Merge branch 'main' into niels9001/run-kbm-directly 2026-04-01 10:31:22 +02:00
Niels Laute
91a03fdd55 Push 2026-03-21 17:28:37 +01:00
3 changed files with 81 additions and 26 deletions

View File

@@ -8,6 +8,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using KeyboardManagerEditorUI.Interop;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library;
using Windows.System;
@@ -19,7 +20,7 @@ namespace KeyboardManagerEditorUI.Helpers
public static KeyboardHookHelper Instance => _instance ??= new KeyboardHookHelper();
private KeyboardMappingService _mappingService;
private KeyboardMappingService? _mappingService;
private HotkeySettingsControlHook? _keyboardHook;
@@ -34,7 +35,14 @@ namespace KeyboardManagerEditorUI.Helpers
// Singleton to make sure only one instance of the hook is active
private KeyboardHookHelper()
{
_mappingService = new KeyboardMappingService();
try
{
_mappingService = new KeyboardMappingService();
}
catch (Exception ex) when (ex is DllNotFoundException or InvalidOperationException)
{
Logger.LogWarning($"Native KBM library unavailable for keyboard hook: {ex.Message}");
}
}
public void ActivateHook(IKeyboardHookTarget target)
@@ -46,11 +54,18 @@ namespace KeyboardManagerEditorUI.Helpers
_currentlyPressedKeys.Clear();
_keyPressOrder.Clear();
_keyboardHook = new HotkeySettingsControlHook(
KeyDown,
KeyUp,
() => true,
(key, extraInfo) => true);
try
{
_keyboardHook = new HotkeySettingsControlHook(
KeyDown,
KeyUp,
() => true,
(key, extraInfo) => true);
}
catch (Exception ex)
{
Logger.LogWarning($"Keyboard hook unavailable: {ex.Message}");
}
}
public void CleanupHook()
@@ -140,6 +155,11 @@ namespace KeyboardManagerEditorUI.Helpers
return new List<string>();
}
if (_mappingService is null)
{
return new List<string>();
}
List<string> keyList = new List<string>();
List<VirtualKey> modifierKeys = new List<VirtualKey>();
VirtualKey? actionKey = null;
@@ -189,6 +209,11 @@ namespace KeyboardManagerEditorUI.Helpers
private void RemoveExistingModifierVariant(VirtualKey key)
{
if (_mappingService is null)
{
return;
}
KeyType keyType = (KeyType)KeyboardManagerInterop.GetKeyType((int)key);
// No need to remove if the key is an action key

View File

@@ -87,13 +87,13 @@ namespace KeyboardManagerEditorUI.Pages
try
{
_mappingService = new KeyboardMappingService();
LoadAllMappings();
}
catch (Exception ex)
{
Logger.LogError("Failed to initialize KeyboardMappingService in MainPage page: " + ex.Message);
}
LoadAllMappings();
Unloaded += All_Unloaded;
}
@@ -739,7 +739,7 @@ namespace KeyboardManagerEditorUI.Pages
{
SettingsManager.EditorSettings.ShortcutsByOperationType.TryGetValue(ShortcutOperationType.RemapShortcut, out var remapShortcutIds);
if (_mappingService == null || remapShortcutIds == null)
if (remapShortcutIds == null)
{
return;
}
@@ -769,7 +769,7 @@ namespace KeyboardManagerEditorUI.Pages
{
SettingsManager.EditorSettings.ShortcutsByOperationType.TryGetValue(ShortcutOperationType.RemapText, out var remapShortcutIds);
if (_mappingService == null || remapShortcutIds == null)
if (remapShortcutIds == null)
{
return;
}
@@ -798,7 +798,7 @@ namespace KeyboardManagerEditorUI.Pages
{
SettingsManager.EditorSettings.ShortcutsByOperationType.TryGetValue(ShortcutOperationType.RunProgram, out var remapShortcutIds);
if (_mappingService == null || remapShortcutIds == null)
if (remapShortcutIds == null)
{
return;
}
@@ -832,7 +832,7 @@ namespace KeyboardManagerEditorUI.Pages
{
SettingsManager.EditorSettings.ShortcutsByOperationType.TryGetValue(ShortcutOperationType.OpenUri, out var remapShortcutIds);
if (_mappingService == null || remapShortcutIds == null)
if (remapShortcutIds == null)
{
return;
}
@@ -860,8 +860,12 @@ namespace KeyboardManagerEditorUI.Pages
private List<string> ParseKeyCodes(string keyCodesString)
{
return keyCodesString.Split(';')
.Where(keyCode => int.TryParse(keyCode, out int code))
.Select(keyCode => _mappingService!.GetKeyDisplayName(int.Parse(keyCode, CultureInfo.InvariantCulture)))
.Where(keyCode => int.TryParse(keyCode, out _))
.Select(keyCode =>
{
int code = int.Parse(keyCode, CultureInfo.InvariantCulture);
return _mappingService?.GetKeyDisplayName(code) ?? $"VK {code}";
})
.ToList();
}

View File

@@ -24,12 +24,28 @@ namespace KeyboardManagerEditorUI.Settings
private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions { WriteIndented = true };
private static readonly KeyboardMappingService _mappingService = new KeyboardMappingService();
private static readonly KeyboardMappingService? _mappingService;
/// <summary>
/// Gets a value indicating whether the native C++ wrapper DLL is available.
/// When false the editor runs in read-only / XAML-preview mode using JSON settings only.
/// </summary>
internal static bool IsNativeServiceAvailable => _mappingService is not null;
public static EditorSettings EditorSettings { get; set; }
static SettingsManager()
{
try
{
_mappingService = new KeyboardMappingService();
}
catch (Exception ex) when (ex is DllNotFoundException or InvalidOperationException)
{
ManagedCommon.Logger.LogWarning($"Native KBM library unavailable, running in standalone mode: {ex.Message}");
_mappingService = null;
}
EditorSettings = LoadSettings();
}
@@ -39,9 +55,14 @@ namespace KeyboardManagerEditorUI.Settings
{
if (!File.Exists(_settingsFilePath))
{
EditorSettings createdSettings = CreateSettingsFromKeyboardManagerService();
WriteSettings(createdSettings);
return createdSettings;
if (_mappingService is not null)
{
EditorSettings createdSettings = CreateSettingsFromKeyboardManagerService();
WriteSettings(createdSettings);
return createdSettings;
}
return new EditorSettings();
}
string json = File.ReadAllText(_settingsFilePath);
@@ -75,13 +96,13 @@ namespace KeyboardManagerEditorUI.Settings
EditorSettings settings = new EditorSettings();
// Process all shortcut mappings (RunProgram, OpenUri, RemapShortcut, RemapText)
foreach (ShortcutKeyMapping mapping in _mappingService.GetShortcutMappings())
foreach (ShortcutKeyMapping mapping in _mappingService!.GetShortcutMappings())
{
AddShortcutMapping(settings, mapping);
}
// Process single key to key mappings
foreach (var mapping in _mappingService.GetSingleKeyMappings())
foreach (var mapping in _mappingService!.GetSingleKeyMappings())
{
var shortcutMapping = new ShortcutKeyMapping
{
@@ -110,10 +131,15 @@ namespace KeyboardManagerEditorUI.Settings
public static void CorrelateServiceAndEditorMappings()
{
if (_mappingService is not { } service)
{
return;
}
bool shortcutSettingsChanged = false;
// Process all shortcut mappings
foreach (ShortcutKeyMapping mapping in _mappingService.GetShortcutMappings())
foreach (ShortcutKeyMapping mapping in service.GetShortcutMappings())
{
if (!EditorSettings.ShortcutSettingsDictionary.Values.Any(s => s.Shortcut.OriginalKeys == mapping.OriginalKeys))
{
@@ -123,7 +149,7 @@ namespace KeyboardManagerEditorUI.Settings
}
// Process single key to key mappings
foreach (var mapping in _mappingService.GetSingleKeyMappings())
foreach (var mapping in service.GetSingleKeyMappings())
{
var shortcutMapping = new ShortcutKeyMapping
{
@@ -140,7 +166,7 @@ namespace KeyboardManagerEditorUI.Settings
}
// Process single key to text mappings
foreach (var mapping in _mappingService.GetKeyToTextMappings())
foreach (var mapping in service.GetKeyToTextMappings())
{
var shortcutMapping = new ShortcutKeyMapping
{
@@ -158,9 +184,9 @@ namespace KeyboardManagerEditorUI.Settings
}
// Mark inactive mappings
var singleKeyMappings = _mappingService.GetSingleKeyMappings();
var keyToTextMappings = _mappingService.GetKeyToTextMappings();
var shortcutKeyMappings = _mappingService.GetShortcutMappings();
var singleKeyMappings = service.GetSingleKeyMappings();
var keyToTextMappings = service.GetKeyToTextMappings();
var shortcutKeyMappings = service.GetShortcutMappings();
foreach (ShortcutSettings shortcutSettings in EditorSettings.ShortcutSettingsDictionary.Values.ToList())
{