Refactor GlobalHotkeyService to support dynamic hotkey registration and update. Introduce HotkeyModifiers and HotkeyVirtualKey properties in SettingsService for user-defined hotkeys.

This commit is contained in:
2026-02-22 12:14:41 -05:00
parent c1a425a7ad
commit 742c1d70fe
3 changed files with 204 additions and 16 deletions

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Runtime.InteropServices;
using Microsoft.UI.Xaml;
@@ -6,39 +6,49 @@ namespace ClipForge
{
public class GlobalHotkeyService
{
// These two lines talk directly to Windows to register/unregister hotkeys
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
// This is the ID we'll use to identify our clip hotkey
private const int HOTKEY_CLIP = 1;
private const uint MOD_NOREPEAT = 0x4000; // don't fire on key repeat
// Alt key modifier
private const uint MOD_ALT = 0x0001;
// F9 key
private const uint VK_F9 = 0x78;
// This is the "event" that fires when the hotkey is pressed
public event Action? ClipRequested;
private IntPtr _hwnd;
private uint _modifiers;
private uint _vk;
public void Initialize(IntPtr hwnd)
/// <summary>Register the clip hotkey. Use settings values (e.g. HotkeyModifiers, HotkeyVirtualKey).</summary>
public void Initialize(IntPtr hwnd, uint modifiers, uint vk)
{
_hwnd = hwnd;
RegisterHotKey(_hwnd, HOTKEY_CLIP, MOD_ALT, VK_F9);
_modifiers = modifiers;
_vk = vk;
TryRegister();
}
/// <summary>Update the hotkey at runtime (e.g. after user remaps). Unregisters old and registers new.</summary>
public bool UpdateHotkey(uint modifiers, uint vk)
{
UnregisterHotKey(_hwnd, HOTKEY_CLIP);
_modifiers = modifiers;
_vk = vk;
return TryRegister();
}
private bool TryRegister()
{
uint mod = _modifiers | MOD_NOREPEAT;
return RegisterHotKey(_hwnd, HOTKEY_CLIP, mod, _vk);
}
public void ProcessHotkey(int id)
{
if (id == HOTKEY_CLIP)
{
ClipRequested?.Invoke();
}
}
public void Cleanup()