Files
Lithium/Lithium/HotkeyHandler.cs
TJhost 5f993f98b8 Tweak input polling timings
Increase the hotkey and recoil loop sleep intervals to reduce CPU churn and smooth input handling. The hotkey loop now waits 15ms instead of 8ms, and the recoil loop waits 10ms instead of 2ms, which helps reduce jitter while keeping responsiveness stable. This also updates the packaged release artifact by replacing the older archive with Lithium-0.01.7z.
2026-09-13 18:27:58 -04:00

196 lines
6.2 KiB
C#

using Lua;
using System;
using System.Threading;
namespace Lithium
{
internal static class HotkeyHandler
{
// AA0041
private const int CAPSLOCK = 0x14;
// AA0042
private static bool _nextSetHeld, _prevSetHeld, _refreshHeld, _switchSideHeld, _capsHeld;
// AA0043
private static MainWindow _mainWindow;
// AA0044 - Added: Cancellation token for graceful shutdown
private static CancellationTokenSource _cancellationSource;
// AA0045 - Updated: Accept cancellation token
public static void Start(MainWindow window, CancellationToken cancellationToken = default)
{
_mainWindow = window;
_cancellationSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
try
{
while (!_cancellationSource.Token.IsCancellationRequested)
{
try
{
HandleToggleCapsLock();
HandleNextSet();
HandlePrevSet();
HandleRefresh();
HandleSwitchSide();
HandleQuickSwaps();
Thread.Sleep(15);
}
catch (Exception ex)
{
// Log error but continue running
System.Diagnostics.Debug.WriteLine($"HotkeyHandler error: {ex.Message}");
}
}
}
finally
{
_cancellationSource?.Dispose();
}
}
// AA0046 - Static method to stop the handler gracefully
public static void Stop()
{
_cancellationSource?.Cancel();
}
// AA0047
private static void HandleToggleCapsLock()
{
bool capsDown = Utils.IsPressed(CAPSLOCK);
if (capsDown && !_capsHeld)
{
_capsHeld = true;
_mainWindow.SetRecoilEnabled(!_mainWindow.IsRecoilEnabled);
}
if (!capsDown) _capsHeld = false;
}
// AA0048
private static void HandleNextSet()
{
if (Utils.IsPressed(ConfigLoader.nextSetKey) && !_nextSetHeld)
{
_nextSetHeld = true;
_mainWindow.HandleNextSet();
}
else if (!Utils.IsPressed(ConfigLoader.nextSetKey))
{
_nextSetHeld = false;
}
}
// AA0049
private static void HandlePrevSet()
{
if (Utils.IsPressed(ConfigLoader.prevSetKey) && !_prevSetHeld)
{
_prevSetHeld = true;
_mainWindow.HandlePrevSet();
}
else if (!Utils.IsPressed(ConfigLoader.prevSetKey))
{
_prevSetHeld = false;
}
}
// AA0050
private static void HandleRefresh()
{
if (Utils.IsPressed(ConfigLoader.refreshKey) && !_refreshHeld)
{
_refreshHeld = true;
_mainWindow.HandleRefresh();
}
else if (!Utils.IsPressed(ConfigLoader.refreshKey))
{
_refreshHeld = false;
}
}
// AA0051
private static void HandleSwitchSide()
{
if (Utils.IsPressed(ConfigLoader.switchSideKey) && !_switchSideHeld)
{
_switchSideHeld = true;
_mainWindow.HandleSwitchSide();
}
else if (!Utils.IsPressed(ConfigLoader.switchSideKey))
{
_switchSideHeld = false;
}
}
private static void HandleQuickSwaps()
{
if (ConfigLoader.quickSwaps == null || ConfigLoader.quickSwaps.Count == 0) return;
// Find all bindings that are currently fully pressed
var activeBindings = new System.Collections.Generic.List<Lua.QuickSwapBinding>();
foreach (var qs in ConfigLoader.quickSwaps)
{
bool allPressed = true;
foreach (var k in qs.Keys)
{
if (!Lua.Utils.IsPressed(k))
{
allPressed = false;
break;
}
}
if (allPressed)
{
activeBindings.Add(qs);
}
}
// Filter out bindings that are subsets of other active bindings
var triggeredBindings = new System.Collections.Generic.List<Lua.QuickSwapBinding>();
foreach (var ab in activeBindings)
{
bool hasSuperset = false;
foreach (var other in activeBindings)
{
if (other != ab && other.Keys.Length > ab.Keys.Length)
{
bool isSubset = true;
foreach (var k in ab.Keys)
{
bool found = false;
foreach (var ok in other.Keys)
{
if (ok == k) { found = true; break; }
}
if (!found) { isSubset = false; break; }
}
if (isSubset) { hasSuperset = true; break; }
}
}
if (!hasSuperset)
{
triggeredBindings.Add(ab);
}
}
// Update held status and trigger actions
foreach (var qs in ConfigLoader.quickSwaps)
{
if (triggeredBindings.Contains(qs))
{
if (!qs.IsHeld)
{
qs.IsHeld = true;
_mainWindow.HandleQuickSwap(qs.TargetOperator);
}
}
else
{
qs.IsHeld = false;
}
}
}
}
}