diff --git a/C#/AutoHotInterception/DeviceHandlers/KeyboardHandler.cs b/C#/AutoHotInterception/DeviceHandlers/KeyboardHandler.cs index cdf8a40..3051c6a 100644 --- a/C#/AutoHotInterception/DeviceHandlers/KeyboardHandler.cs +++ b/C#/AutoHotInterception/DeviceHandlers/KeyboardHandler.cs @@ -16,6 +16,18 @@ namespace AutoHotInterception.DeviceHandlers } + /// + /// Called when we are removing a Subscription or Context Mode + /// If there are no other subscriptions, and Context Mode is disabled, turn the filter off + /// + private void DisableFilterIfNeeded() + { + if (KeyboardMapping != null || KeyboardKeyMappings.Count > 0 || ContextCallback != null) + { + IsFiltered = false; + } + } + /// /// Subscribe to a specific key on this keyboard /// @@ -39,11 +51,7 @@ namespace AutoHotInterception.DeviceHandlers public void UnsubscribeKey(ushort code) { KeyboardKeyMappings.TryRemove(code, out _); - // If we have no other key subscriptions, and no context callback is present, mark this device as not filtered - if (KeyboardKeyMappings.Count == 0 && KeyboardMapping == null && ContextCallback == null) - { - IsFiltered = false; - } + DisableFilterIfNeeded(); } /// @@ -76,11 +84,7 @@ namespace AutoHotInterception.DeviceHandlers } } KeyboardMapping = null; - // If not mapped to any individual keys, or no Context callback is present, mark this device as not filtered - if (KeyboardKeyMappings.Count == 0 && ContextCallback == null) - { - IsFiltered = false; - } + DisableFilterIfNeeded(); } /// @@ -93,6 +97,12 @@ namespace AutoHotInterception.DeviceHandlers IsFiltered = true; } + public void RemoveContextCallback() + { + ContextCallback = null; + DisableFilterIfNeeded(); + } + public override void ProcessStroke(ManagedWrapper.Stroke stroke) { //ManagedWrapper.Send(DeviceContext, _deviceId, ref stroke, 1); diff --git a/C#/AutoHotInterception/Manager.cs b/C#/AutoHotInterception/Manager.cs index 0ef1c8e..241be02 100644 --- a/C#/AutoHotInterception/Manager.cs +++ b/C#/AutoHotInterception/Manager.cs @@ -372,7 +372,26 @@ namespace AutoHotInterception } - SetDeviceFilterState(id, true); + SetFilterState(true); + SetThreadState(true); + } + + public void RemoveContextCallback(int id) + { + SetFilterState(false); + if (id < 1 || id > 20) + throw new ArgumentOutOfRangeException(nameof(id), "DeviceIds must be between 1 and 20"); + + if (id < 11) + { + var device = (KeyboardHandler)DeviceHandlers[id]; + device.RemoveContextCallback(); + } + else + { + + } + SetFilterState(true); SetThreadState(true); } diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ba206e..af1ec8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] ### Added +- Add RemoveContextManager() to remove a Context Manager ### Changed - If you SubscribeKey to subscribe to a specific key on a device, and use SubscribeKeyboard to subscribe to all keys on the same device Then SubscribeKey now takes precedence (SubscribeKey callback fires, and SubscribeKeyboard does not) @@ -13,6 +14,7 @@ Then SubscribeKey now takes precedence (SubscribeKey callback fires, and Subscri ### Fixed - If you had Context Mode enabled for a keyboard, and a SubscribeKey or SubscribeKeyboard subscription for the same keyboard then using UnsubscribeKey or UnsubscribeKeyboard would disable Context Mode +- CreateContextManager now correctly throws an error if one already exists ## [0.6.0] - 2022-01-14 ### Changed diff --git a/Lib/AutoHotInterception.ahk b/Lib/AutoHotInterception.ahk index e66cb27..9bde5ba 100644 --- a/Lib/AutoHotInterception.ahk +++ b/Lib/AutoHotInterception.ahk @@ -224,7 +224,7 @@ class AutoHotInterception { ; ------------- Context Mode ---------------- ; Creates a context class to make it easy to turn on/off the hotkeys CreateContextManager(id) { - if (this._contextManagers.ContainsKey(id)) { + if (this._contextManagers.HasKey(id)) { Msgbox % "ID " id " already has a Context Manager" ExitApp } @@ -233,6 +233,16 @@ class AutoHotInterception { return cm } + RemoveContextManager(id) { + if (!this._contextManagers.HasKey(id)) { + Msgbox % "ID " id " does not have a Context Manager" + ExitApp + } + this._contextManagers[id].Remove() + this._contextManagers.Delete(id) + return cm + } + ; Helper class for dealing with context mode class ContextManager { IsActive := 0 @@ -246,5 +256,9 @@ class AutoHotInterception { Sleep 0 this.IsActive := state } + + Remove(){ + this.parent.Instance.RemoveContextCallback(this.id) + } } } \ No newline at end of file diff --git a/README.md b/README.md index b1f8225..eb7b394 100644 --- a/README.md +++ b/README.md @@ -194,11 +194,14 @@ cm1 := AHI.CreateContextManager(keyboard1Id) #if ; Close the #if block ``` +You can remove a Context Manager using `AHI.RemoveContextManager(keyboard1Id)` + ### Subscription mode In Subscription mode, you bypass AHK's hotkey system completely, and Interception notifies you of key events via callbacks. All forms of input are supported in Subscription Mode. Subscription Mode overrides Context Mode - that is, if a key on a keyboard has been subscribed to with Subscription Mode, then Context Mode will not fire for that key on that keyboard. -Each Subscribe endpont also has a corresponding Unsubscribe endpoint, which removes the subscription and any block associated with it. +SubscribeKey overrides SubscribeKeyboard - that is, if you have subscribed to all keys and a specific key on the same keyboard, then if you press the specific key, it's callback will fire and the callback for SubscribeKeyboard will not. +Each Subscribe endpoint also has a corresponding Unsubscribe endpoint, which removes the subscription and any block associated with it. #### Subscribing to Keyboard keys ##### Subscribe to a specific key on a specific keyboard