diff --git a/src/Artemis.Core/Services/Input/InputService.cs b/src/Artemis.Core/Services/Input/InputService.cs
index 7a03343a3..dff8d7d91 100644
--- a/src/Artemis.Core/Services/Input/InputService.cs
+++ b/src/Artemis.Core/Services/Input/InputService.cs
@@ -47,7 +47,7 @@ namespace Artemis.Core.Services
inputProvider.MouseScrollDataReceived += InputProviderOnMouseScrollDataReceived;
inputProvider.MouseMoveDataReceived += InputProviderOnMouseMoveDataReceived;
_inputProviders.Add(inputProvider);
-
+
inputProvider.OnKeyboardToggleStatusRequested();
}
@@ -296,6 +296,17 @@ namespace Artemis.Core.Services
return modifiers;
}
+ public void ReleaseAll()
+ {
+ foreach (var (device, keys) in _pressedKeys.ToList())
+ {
+ foreach (KeyboardKey keyboardKey in keys)
+ {
+ InputProviderOnKeyboardDataReceived(this, new InputProviderKeyboardEventArgs(device, keyboardKey, false));
+ }
+ }
+ }
+
#endregion
#region Mouse
diff --git a/src/Artemis.Core/Services/Input/Interfaces/IInputService.cs b/src/Artemis.Core/Services/Input/Interfaces/IInputService.cs
index 46c042e1f..3c2936354 100644
--- a/src/Artemis.Core/Services/Input/Interfaces/IInputService.cs
+++ b/src/Artemis.Core/Services/Input/Interfaces/IInputService.cs
@@ -35,6 +35,11 @@ namespace Artemis.Core.Services
///
void StopIdentify();
+ ///
+ /// Flush all currently pressed buttons/keys
+ ///
+ void ReleaseAll();
+
#region Events
///
diff --git a/src/Artemis.Core/Utilities/CurrentProcessUtilities.cs b/src/Artemis.Core/Utilities/Utilities.cs
similarity index 100%
rename from src/Artemis.Core/Utilities/CurrentProcessUtilities.cs
rename to src/Artemis.Core/Utilities/Utilities.cs
diff --git a/src/Artemis.UI/InputProviders/NativeWindowInputProvider.cs b/src/Artemis.UI/InputProviders/NativeWindowInputProvider.cs
index 38da46058..c2dfd8c6c 100644
--- a/src/Artemis.UI/InputProviders/NativeWindowInputProvider.cs
+++ b/src/Artemis.UI/InputProviders/NativeWindowInputProvider.cs
@@ -1,9 +1,14 @@
using System;
+using System.Diagnostics;
+using System.Linq;
using System.Runtime.InteropServices;
+using System.Timers;
using System.Windows.Forms;
using System.Windows.Input;
+using System.Windows.Interop;
using Artemis.Core;
using Artemis.Core.Services;
+using Artemis.UI.Utilities;
using Linearstar.Windows.RawInput;
using Linearstar.Windows.RawInput.Native;
using Serilog;
@@ -14,11 +19,12 @@ namespace Artemis.UI.InputProviders
public class NativeWindowInputProvider : InputProvider
{
private const int WM_INPUT = 0x00FF;
+
private readonly IInputService _inputService;
-
private readonly ILogger _logger;
private DateTime _lastMouseUpdate;
private SpongeWindow _sponge;
+ private System.Timers.Timer _taskManagerTimer;
public NativeWindowInputProvider(ILogger logger, IInputService inputService)
{
@@ -28,10 +34,15 @@ namespace Artemis.UI.InputProviders
_sponge = new SpongeWindow();
_sponge.WndProcCalled += SpongeOnWndProcCalled;
+ _taskManagerTimer = new System.Timers.Timer(500);
+ _taskManagerTimer.Elapsed += TaskManagerTimerOnElapsed;
+ _taskManagerTimer.Start();
+
RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard, RawInputDeviceFlags.InputSink, _sponge.Handle);
RawInputDevice.RegisterDevice(HidUsageAndPage.Mouse, RawInputDeviceFlags.InputSink, _sponge.Handle);
}
+
#region Overrides of InputProvider
///
@@ -51,6 +62,8 @@ namespace Artemis.UI.InputProviders
{
_sponge?.DestroyHandle();
_sponge = null;
+ _taskManagerTimer?.Dispose();
+ _taskManagerTimer = null;
}
base.Dispose(disposing);
@@ -75,6 +88,15 @@ namespace Artemis.UI.InputProviders
}
}
+ private void TaskManagerTimerOnElapsed(object sender, ElapsedEventArgs e)
+ {
+ // If task manager has focus then we can't track keys properly, release everything to avoid them getting stuck
+ // Same goes for Idle which is what you get when you press Ctrl+Alt+Del
+ Process active = Process.GetProcessById(WindowUtilities.GetActiveProcessId());
+ if (active?.ProcessName == "Taskmgr" || active?.ProcessName == "Idle")
+ _inputService.ReleaseAll();
+ }
+
#region Keyboard
private void HandleKeyboardData(RawInputData data, RawInputKeyboardData keyboardData)
diff --git a/src/Artemis.UI/Utilities/WindowUtilities.cs b/src/Artemis.UI/Utilities/WindowUtilities.cs
new file mode 100644
index 000000000..99409febd
--- /dev/null
+++ b/src/Artemis.UI/Utilities/WindowUtilities.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Artemis.UI.Utilities
+{
+ public static class WindowUtilities
+ {
+ public static int GetActiveProcessId()
+ {
+ // Get foreground window handle
+ IntPtr hWnd = GetForegroundWindow();
+
+ GetWindowThreadProcessId(hWnd, out uint processId);
+ return (int) processId;
+ }
+
+ [DllImport("user32.dll")]
+ private static extern IntPtr GetForegroundWindow();
+
+ [DllImport("user32.dll")]
+ private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
+ }
+}
\ No newline at end of file