mirror of
https://github.com/tuxdotrs/highminded.git
synced 2025-08-22 23:51:03 +05:30
fix: keybindings trigger
This commit is contained in:
@@ -7,8 +7,8 @@ using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
using highminded.ui.controls;
|
||||
using highminded.utils;
|
||||
using SharpHook;
|
||||
using SharpHook.Data;
|
||||
using KeyBinding = highminded.utils.KeyBinding;
|
||||
|
||||
namespace highminded.ui.windows;
|
||||
|
||||
@@ -32,7 +32,7 @@ public partial class MainWindow : Window
|
||||
private readonly SettingsUserControl _settingsUserControl = new SettingsUserControl();
|
||||
|
||||
// Hotkey
|
||||
private readonly TaskPoolGlobalHook _hook = new TaskPoolGlobalHook();
|
||||
private readonly PreciseKeyBindings _keyBindings = new PreciseKeyBindings();
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
@@ -42,9 +42,7 @@ public partial class MainWindow : Window
|
||||
UControl.Content = _chatUserControl;
|
||||
ChatBtnActive();
|
||||
HideOverlay();
|
||||
// Global Hotkey
|
||||
_hook.KeyPressed += OnKeyPressed;
|
||||
_hook.RunAsync();
|
||||
RegisterKeyBindings();
|
||||
}
|
||||
|
||||
private void OnPointerPressed(object? sender, PointerPressedEventArgs e)
|
||||
@@ -141,50 +139,21 @@ public partial class MainWindow : Window
|
||||
Hide();
|
||||
}
|
||||
|
||||
private void OnKeyPressed(object? sender, KeyboardHookEventArgs e)
|
||||
private void RegisterKeyBindings()
|
||||
{
|
||||
bool hasCtrl = (e.RawEvent.Mask & EventMask.Ctrl) != EventMask.None;
|
||||
bool hasAlt = (e.RawEvent.Mask & EventMask.Alt) != EventMask.None;
|
||||
bool hasShift = (e.RawEvent.Mask & EventMask.Shift) != EventMask.None;
|
||||
bool hasH = e.Data.KeyCode == KeyCode.VcH;
|
||||
bool hasBackslash = e.Data.KeyCode == KeyCode.VcBackslash;
|
||||
bool hasA = e.Data.KeyCode == KeyCode.VcA;
|
||||
bool hasS = e.Data.KeyCode == KeyCode.VcS;
|
||||
bool hasQ = e.Data.KeyCode == KeyCode.VcQ;
|
||||
_keyBindings.AddKeyBinding(
|
||||
new KeyBinding(KeyCode.VcH, ModifierKey.Control, ModifierKey.Alt, ModifierKey.Shift),
|
||||
() => Dispatcher.UIThread.Post(ShowOverlay)
|
||||
);
|
||||
|
||||
if (hasCtrl && hasShift && hasAlt && hasH)
|
||||
{
|
||||
ShowOverlay();
|
||||
}
|
||||
_keyBindings.AddKeyBinding(
|
||||
new KeyBinding(KeyCode.VcQ, ModifierKey.Alt, ModifierKey.Shift),
|
||||
() => Dispatcher.UIThread.Post(() => Environment.Exit(0))
|
||||
);
|
||||
|
||||
if (hasAlt && hasShift && hasS)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() => { _chatUserControl.SendScreenshot(); });
|
||||
}
|
||||
|
||||
if (hasAlt && hasShift && hasA)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
if (!InMemoryDb.Obj.MainViewModel.IsRecording)
|
||||
{
|
||||
_chatUserControl.StartRecord();
|
||||
}
|
||||
else
|
||||
{
|
||||
_chatUserControl.StopRecord();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (hasAlt && hasShift && hasQ)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() => { Environment.Exit(0); });
|
||||
}
|
||||
|
||||
if (hasAlt && hasShift && hasBackslash)
|
||||
{
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
_keyBindings.AddKeyBinding(
|
||||
new KeyBinding(KeyCode.VcBackslash, ModifierKey.Alt, ModifierKey.Shift),
|
||||
() => Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
if (WindowState == WindowState.Minimized || !IsVisible)
|
||||
{
|
||||
@@ -197,7 +166,29 @@ public partial class MainWindow : Window
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
_keyBindings.AddKeyBinding(
|
||||
new KeyBinding(KeyCode.VcA, ModifierKey.Alt, ModifierKey.Shift),
|
||||
() => Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
if (!InMemoryDb.Obj.MainViewModel.IsRecording)
|
||||
{
|
||||
_chatUserControl.StartRecord();
|
||||
}
|
||||
else
|
||||
{
|
||||
_chatUserControl.StopRecord();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
_keyBindings.AddKeyBinding(
|
||||
new KeyBinding(KeyCode.VcS, ModifierKey.Alt, ModifierKey.Shift),
|
||||
() => Dispatcher.UIThread.Post(() => _chatUserControl.SendScreenshot())
|
||||
);
|
||||
|
||||
_keyBindings.Start();
|
||||
}
|
||||
}
|
161
utils/KeyBindings.cs
Normal file
161
utils/KeyBindings.cs
Normal file
@@ -0,0 +1,161 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SharpHook;
|
||||
using SharpHook.Data;
|
||||
|
||||
namespace highminded.utils;
|
||||
|
||||
public enum ModifierKey
|
||||
{
|
||||
Control,
|
||||
Shift,
|
||||
Alt,
|
||||
Meta
|
||||
}
|
||||
|
||||
public class PreciseKeyBindings
|
||||
{
|
||||
private readonly IGlobalHook _hook;
|
||||
private readonly Dictionary<KeyBinding, Action> _keyBindings;
|
||||
private readonly HashSet<KeyCode> _pressedKeys;
|
||||
|
||||
public PreciseKeyBindings()
|
||||
{
|
||||
_hook = new TaskPoolGlobalHook();
|
||||
_keyBindings = new Dictionary<KeyBinding, Action>();
|
||||
_pressedKeys = new HashSet<KeyCode>();
|
||||
|
||||
// Subscribe to key events
|
||||
_hook.KeyPressed += OnKeyPressed;
|
||||
_hook.KeyReleased += OnKeyReleased;
|
||||
}
|
||||
|
||||
public void AddKeyBinding(KeyBinding binding, Action action)
|
||||
{
|
||||
_keyBindings[binding] = action;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_hook.RunAsync();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_hook.Dispose();
|
||||
}
|
||||
|
||||
private void OnKeyPressed(object? sender, KeyboardHookEventArgs e)
|
||||
{
|
||||
_pressedKeys.Add(e.Data.KeyCode);
|
||||
|
||||
// Check if any key binding matches the current pressed keys
|
||||
foreach (var kvp in _keyBindings)
|
||||
{
|
||||
if (IsExactMatch(kvp.Key))
|
||||
{
|
||||
kvp.Value.Invoke();
|
||||
break; // Only trigger the first match
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnKeyReleased(object? sender, KeyboardHookEventArgs e)
|
||||
{
|
||||
_pressedKeys.Remove(e.Data.KeyCode);
|
||||
}
|
||||
|
||||
private bool IsExactMatch(KeyBinding binding)
|
||||
{
|
||||
// Get currently pressed modifiers
|
||||
var pressedModifiers = GetPressedModifiers();
|
||||
|
||||
// Check if the main key is pressed
|
||||
if (!_pressedKeys.Contains(binding.Key))
|
||||
return false;
|
||||
|
||||
// Check if modifiers match exactly
|
||||
if (pressedModifiers.Count != binding.Modifiers.Count)
|
||||
return false;
|
||||
|
||||
foreach (var modifier in binding.Modifiers)
|
||||
{
|
||||
if (!pressedModifiers.Contains(modifier))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private HashSet<ModifierKey> GetPressedModifiers()
|
||||
{
|
||||
var modifiers = new HashSet<ModifierKey>();
|
||||
|
||||
// Check for Control
|
||||
if (_pressedKeys.Contains(KeyCode.VcLeftControl) || _pressedKeys.Contains(KeyCode.VcRightControl))
|
||||
modifiers.Add(ModifierKey.Control);
|
||||
|
||||
// Check for Shift
|
||||
if (_pressedKeys.Contains(KeyCode.VcLeftShift) || _pressedKeys.Contains(KeyCode.VcRightShift))
|
||||
modifiers.Add(ModifierKey.Shift);
|
||||
|
||||
// Check for Alt
|
||||
if (_pressedKeys.Contains(KeyCode.VcLeftAlt) || _pressedKeys.Contains(KeyCode.VcRightAlt))
|
||||
modifiers.Add(ModifierKey.Alt);
|
||||
|
||||
// Check for Meta/Windows key
|
||||
if (_pressedKeys.Contains(KeyCode.VcLeftMeta) || _pressedKeys.Contains(KeyCode.VcRightMeta))
|
||||
modifiers.Add(ModifierKey.Meta);
|
||||
|
||||
return modifiers;
|
||||
}
|
||||
}
|
||||
|
||||
public class KeyBinding : IEquatable<KeyBinding>
|
||||
{
|
||||
public KeyCode Key { get; }
|
||||
public HashSet<ModifierKey> Modifiers { get; }
|
||||
|
||||
public KeyBinding(KeyCode key, params ModifierKey[] modifiers)
|
||||
{
|
||||
Key = key;
|
||||
Modifiers = new HashSet<ModifierKey>(modifiers);
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return Equals(obj as KeyBinding);
|
||||
}
|
||||
|
||||
public bool Equals(KeyBinding? other)
|
||||
{
|
||||
if (other == null) return false;
|
||||
if (Key != other.Key) return false;
|
||||
if (Modifiers.Count != other.Modifiers.Count) return false;
|
||||
|
||||
foreach (var modifier in Modifiers)
|
||||
{
|
||||
if (!other.Modifiers.Contains(modifier))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hash = Key.GetHashCode();
|
||||
foreach (var modifier in Modifiers)
|
||||
{
|
||||
hash ^= modifier.GetHashCode();
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var modStr = string.Join(" + ", Modifiers);
|
||||
return string.IsNullOrEmpty(modStr) ? Key.ToString() : $"{modStr} + {Key}";
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user