mirror of
https://github.com/Hofknecht/SystemTrayMenu.git
synced 2024-07-09 08:16:41 +12:00
Initial reassign of hotkeys
This commit is contained in:
parent
ce2d9772f6
commit
637cc46e7e
|
@ -39,6 +39,12 @@ namespace SystemTrayMenu.Helpers
|
|||
Key GetKey();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether hotkeys are enabled
|
||||
/// (e.g. during user configuration dialog).
|
||||
/// </summary>
|
||||
internal static bool IsEnabled { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Registers a global hotkey.
|
||||
/// Function is thread safe.
|
||||
|
@ -57,9 +63,9 @@ namespace SystemTrayMenu.Helpers
|
|||
{
|
||||
foreach (var reg in Registrations)
|
||||
{
|
||||
if (id < reg.Id)
|
||||
if (id <= reg.Id)
|
||||
{
|
||||
id = reg.Id;
|
||||
id = reg.Id + 1; // TODO: Rework to re-use gaps
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +108,7 @@ namespace SystemTrayMenu.Helpers
|
|||
/// <returns>true: Success or false: Failure.</returns>
|
||||
internal static bool Unregister(IHotkeyRegistration? registration)
|
||||
{
|
||||
if (registration == null || registration is not HotkeyRegistration reg || Registrations.Contains(reg))
|
||||
if (registration == null || registration is not HotkeyRegistration reg || !Registrations.Contains(reg))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -120,6 +126,61 @@ namespace SystemTrayMenu.Helpers
|
|||
return true;
|
||||
}
|
||||
|
||||
internal static bool Reassign(IHotkeyRegistration? registration, ModifierKeys modifiers, Key key)
|
||||
{
|
||||
if (registration == null || registration is not HotkeyRegistration reg || !Registrations.Contains(reg))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (modifiers == reg.Modifiers && key == reg.Key)
|
||||
{
|
||||
return true; // Yes, nothing changed, but we return true as requested key is properly registered even when unchanged.
|
||||
}
|
||||
|
||||
int virtualKeyCode = KeyInterop.VirtualKeyFromKey(key);
|
||||
int id = 0;
|
||||
|
||||
lock (CriticalSectionLock)
|
||||
{
|
||||
foreach (var regs in Registrations)
|
||||
{
|
||||
if (id <= regs.Id)
|
||||
{
|
||||
id = reg.Id + 1; // TODO: Rework to re-use gaps
|
||||
}
|
||||
}
|
||||
|
||||
if (!NativeMethods.User32RegisterHotKey(HWnd.Handle, id, (uint)modifiers, (uint)virtualKeyCode))
|
||||
{
|
||||
string errorHint = NativeMethods.GetLastErrorHint();
|
||||
throw new InvalidOperationException(Translator.GetText("Could not register the hot key.") + " (" + errorHint + ")");
|
||||
}
|
||||
|
||||
// In case unregister failes, unfortunately registration remains
|
||||
// but will not trigger anything as we change our hotkey registration.
|
||||
// However, this means the hotkey keeps being registered with this application
|
||||
// and the key combination will not be availalbe for re-registration till app restart.
|
||||
// TODO: Decide how to handle this? Restart App? Try keep old registartion and not update it?
|
||||
if (!NativeMethods.User32UnregisterHotKey(HWnd.Handle, reg.Id))
|
||||
{
|
||||
Log.Info("Hotkey registration cannot unregister key " + reg.Modifiers.ToString() + " with modifiers " + reg.Modifiers.ToString());
|
||||
}
|
||||
|
||||
reg.Id = id;
|
||||
reg.Modifiers = modifiers;
|
||||
reg.Key = key;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool Reassign(IHotkeyRegistration? registration, string hotKeyString)
|
||||
{
|
||||
var (modifiers, key) = ParseKeysAndModifiersFromString(hotKeyString);
|
||||
return Reassign(registration, modifiers, key);
|
||||
}
|
||||
|
||||
// TODO: Instead of searching for the registration, it should be passed to the caller instead.
|
||||
// Only this ensures caller and registrator are talking about the SAME registration.
|
||||
internal static IHotkeyRegistration? FindRegistration(string hotKeyString)
|
||||
|
@ -316,7 +377,7 @@ namespace SystemTrayMenu.Helpers
|
|||
const int WmHotkey = 0x0312;
|
||||
|
||||
// check if we got a hot key pressed.
|
||||
if (msg == WmHotkey)
|
||||
if (msg == WmHotkey && IsEnabled)
|
||||
{
|
||||
ModifierKeys modifiers = (ModifierKeys)((int)lParam & 0xFFFF);
|
||||
int virtualKeyCode = ((int)lParam >> 16) & 0xFFFF;
|
||||
|
@ -346,7 +407,7 @@ namespace SystemTrayMenu.Helpers
|
|||
{
|
||||
public event Action<IHotkeyRegistration>? KeyPressed;
|
||||
|
||||
internal int Id { get; init; }
|
||||
internal int Id { get; set; }
|
||||
|
||||
internal ModifierKeys Modifiers { get; set; }
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
private readonly IList<int> needNonAltGrModifier = new List<int>();
|
||||
|
||||
// These variables store the current hotkey and modifier(s)
|
||||
private IHotkeyRegistration? hotkeyHandle;
|
||||
private IHotkeyRegistration? hotkeyRegistration;
|
||||
private Key hotkey = Key.None;
|
||||
private ModifierKeys modifiers = ModifierKeys.None;
|
||||
private Action? handler;
|
||||
|
@ -48,11 +48,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
PreviewKeyDown += HandlePreviewKeyDown;
|
||||
PreviewTextInput += HandlePreviewTextInput;
|
||||
|
||||
GotFocus += (_, _) =>
|
||||
{
|
||||
UnregisterHotKey();
|
||||
Reassigning = true;
|
||||
};
|
||||
GotFocus += (_, _) => GlobalHotkeys.IsEnabled = false;
|
||||
LostFocus += (_, _) =>
|
||||
{
|
||||
#if TODO // HOTKEY
|
||||
|
@ -66,18 +62,14 @@ namespace SystemTrayMenu.UserInterface
|
|||
/// </summary>
|
||||
/// <returns>Whether the hotkeys could be registered to the users content. This also applies if conflicts arise and the user decides to ignore these (i.e. not to register the conflicting hotkey).</returns>
|
||||
RegisterHotkeys(false);
|
||||
#else
|
||||
ReregisterHotKey();
|
||||
#endif
|
||||
Reassigning = false;
|
||||
GlobalHotkeys.IsEnabled = true;
|
||||
};
|
||||
|
||||
PopulateModifierLists();
|
||||
SetHotkeyRegistration((IHotkeyRegistration?)null);
|
||||
}
|
||||
|
||||
internal bool Reassigning { get; private set; }
|
||||
|
||||
public static string HotkeyToString(ModifierKeys modifierKeyCode, Key key)
|
||||
{
|
||||
StringBuilder hotkeyString = new();
|
||||
|
@ -112,11 +104,11 @@ namespace SystemTrayMenu.UserInterface
|
|||
/// <param name="registration">Registration interface.</param>
|
||||
internal void SetHotkeyRegistration(IHotkeyRegistration? registration)
|
||||
{
|
||||
hotkeyHandle = registration;
|
||||
if (hotkeyHandle != null)
|
||||
hotkeyRegistration = registration;
|
||||
if (hotkeyRegistration != null)
|
||||
{
|
||||
hotkey = hotkeyHandle.GetKey();
|
||||
modifiers = hotkeyHandle.GetModifierKeys();
|
||||
hotkey = hotkeyRegistration.GetKey();
|
||||
modifiers = hotkeyRegistration.GetModifierKeys();
|
||||
Background = Brushes.LightGreen;
|
||||
}
|
||||
else
|
||||
|
@ -140,12 +132,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
/// Change the hotkey to given combination.
|
||||
/// </summary>
|
||||
/// <param name="hotkeyString">Hotkey combination string.</param>
|
||||
internal void ChangeHotkey(string hotkeyString)
|
||||
{
|
||||
hotkey = KeyFromString(hotkeyString);
|
||||
modifiers = ModifierKeysFromString(hotkeyString);
|
||||
Redraw(true);
|
||||
}
|
||||
internal void ChangeHotkey(string hotkeyString) => Reassign(hotkeyRegistration, hotkeyString);
|
||||
|
||||
/// <summary>
|
||||
/// Register a hotkey.
|
||||
|
@ -164,7 +151,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
try
|
||||
{
|
||||
hotkeyHandle = Register(modifiers, key);
|
||||
hotkeyRegistration = Register(modifiers, key);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
|
@ -174,26 +161,12 @@ namespace SystemTrayMenu.UserInterface
|
|||
}
|
||||
|
||||
this.handler = handler;
|
||||
hotkeyHandle.KeyPressed += (_) => handler.Invoke();
|
||||
hotkeyRegistration.KeyPressed += (_) => handler.Invoke();
|
||||
|
||||
Background = Brushes.LightGreen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void ReregisterHotKey()
|
||||
{
|
||||
if (handler != null)
|
||||
{
|
||||
RegisterHotKey(modifiers, hotkey, handler);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnregisterHotKey()
|
||||
{
|
||||
Unregister(hotkeyHandle);
|
||||
hotkeyHandle = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current hotkey and resets the TextBox.
|
||||
/// </summary>
|
||||
|
@ -354,6 +327,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
{
|
||||
modifiers = Keyboard.Modifiers;
|
||||
hotkey = e.Key;
|
||||
Reassign(hotkeyRegistration, modifiers, hotkey);
|
||||
Redraw(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
using System.Windows.Input;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Microsoft.Win32;
|
||||
using SystemTrayMenu.Helpers;
|
||||
using SystemTrayMenu.Properties;
|
||||
using SystemTrayMenu.UserInterface.FolderBrowseDialog;
|
||||
using SystemTrayMenu.Utilities;
|
||||
|
@ -445,7 +446,7 @@ namespace SystemTrayMenu.UserInterface
|
|||
|
||||
private void HandlePreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Escape && !textBoxHotkey.Reassigning)
|
||||
if (e.Key == Key.Escape && GlobalHotkeys.IsEnabled)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue