Skip to content

Commit bf572dd

Browse files
committed
Revised the Hotkey Manager to send key presses to other applications. Resolves #2779.
1 parent 08d21b2 commit bf572dd

7 files changed

Lines changed: 373 additions & 148 deletions

File tree

ChangeLog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
Full details of the variables available for each noted event, and VoiceAttack integrations, are available in the individual [event pages](https://github.com/EDCD/EDDI/wiki/Events).
44

5+
## 4.1.9
6+
* Core
7+
* Various bug fixes
8+
* Revised the Hotkey Manager to send key presses to other applications rather than blocking those key presses from being sent to other applications. This should improve compatibility other applications using the same keys. (#2779)
9+
510
## 4.1.8
611
* Core
712
* Fixed a bad installer configuration which prevented the 4.1.7 release from running for some users. (#2776)

EddiCore/Hotkeys/HotkeyAction.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ namespace EddiCore.Hotkeys
55
{
66
public class HotkeyAction
77
{
8-
public int? id { get; set; }
98
public string Name { get; set; }
109
public string DisplayName { get; set; }
1110
public Action Action { get; set; }
Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Windows.Input;
45

@@ -8,82 +9,72 @@ public class HotkeyActionCollection
89
{
910
public HotkeyActionCollection ( List<HotkeyAction> hotkeyActions )
1011
{
11-
HotkeyActions = hotkeyActions;
12+
HotkeyActions = hotkeyActions ?? throw new ArgumentNullException( nameof( hotkeyActions ) );
13+
byName = HotkeyActions.ToDictionary( a => a.Name, a => a );
14+
RebuildGestureIndex();
1215
}
1316

1417
public readonly List<HotkeyAction> HotkeyActions;
1518

16-
public void AddGesture ( string name, KeyGesture gesture, int? id = null )
19+
private readonly Dictionary<string, HotkeyAction> byName;
20+
private readonly Dictionary<(Key key, ModifierKeys mods), HotkeyAction> byGesture = new Dictionary<(Key, ModifierKeys), HotkeyAction>();
21+
22+
private void RebuildGestureIndex ()
1723
{
18-
var action = HotkeyActions.FirstOrDefault( a => a.Name == name );
19-
if ( action != null )
24+
byGesture.Clear();
25+
foreach ( var a in HotkeyActions )
2026
{
21-
action.KeyGesture = gesture;
22-
action.id = id;
23-
return;
27+
if ( a.KeyGesture != null )
28+
{
29+
byGesture[ (a.KeyGesture.Key, a.KeyGesture.Modifiers) ] = a;
30+
}
2431
}
25-
26-
throw new KeyNotFoundException( $"The key name '{name}' was not found in the action list." );
2732
}
2833

29-
public void AddId ( string name, int id )
34+
public void AddGesture ( string name, KeyGesture gesture )
3035
{
31-
var action = HotkeyActions.FirstOrDefault( a => a.Name == name );
32-
if ( action != null )
36+
if ( !byName.TryGetValue( name, out var action ) )
3337
{
34-
action.id = id;
35-
return;
38+
throw new KeyNotFoundException( $"The key name '{name}' was not found in the action list." );
3639
}
3740

38-
throw new KeyNotFoundException( $"The key name '{name}' was not found in the action list." );
41+
action.KeyGesture = gesture;
42+
RebuildGestureIndex();
3943
}
4044

4145
public void ClearAllKeyGestures ()
4246
{
4347
foreach ( var action in HotkeyActions )
4448
{
45-
RemoveKeyGestures( action.Name );
49+
action.KeyGesture = null;
4650
}
51+
RebuildGestureIndex();
4752
}
4853

4954
public bool IsKeyGestureAssigned ( string name, Key key, ModifierKeys modifiers )
5055
{
51-
var action = HotkeyActions.FirstOrDefault( a => a.Name == name );
52-
if ( action != null )
56+
if ( !byName.ContainsKey( name ) )
5357
{
54-
return HotkeyActions.Any( a =>
55-
a.Name != name &&
56-
a.KeyGesture != null &&
57-
a.KeyGesture.Key == key &&
58-
a.KeyGesture.Modifiers == modifiers );
58+
throw new KeyNotFoundException( $"The key name '{name}' was not found in the action list." );
5959
}
6060

61-
throw new KeyNotFoundException( $"The key name '{name}' was not found in the action list." );
61+
return byGesture.TryGetValue( (key, modifiers), out var existing ) && existing.Name != name;
6262
}
6363

6464
public void RemoveKeyGestures ( string name )
6565
{
66-
var action = HotkeyActions.FirstOrDefault( a => a.Name == name );
67-
if ( action != null )
66+
if ( !byName.TryGetValue( name, out var action ) )
6867
{
69-
action.id = null;
70-
action.KeyGesture = null;
71-
return;
68+
throw new KeyNotFoundException( $"The key name '{name}' was not found in the action list." );
7269
}
7370

74-
throw new KeyNotFoundException( $"The key name '{name}' was not found in the action list." );
71+
action.KeyGesture = null;
72+
RebuildGestureIndex();
7573
}
7674

77-
public bool TryGetValue ( string name, out HotkeyAction action )
78-
{
79-
action = HotkeyActions.FirstOrDefault( a => a.Name == name );
80-
return action != null;
81-
}
75+
public bool TryGetValue ( string name, out HotkeyAction action ) => byName.TryGetValue( name, out action );
8276

83-
public bool TryGetValue ( int id, out HotkeyAction action )
84-
{
85-
action = HotkeyActions.FirstOrDefault( a => a.id != null && a.id == id );
86-
return action != null;
87-
}
77+
public bool TryGetValue ( Key key, ModifierKeys modifiers, out HotkeyAction action ) =>
78+
byGesture.TryGetValue( ( key, modifiers ), out action );
8879
}
8980
}

EddiCore/Hotkeys/HotkeyManager.cs

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using EddiSpeechService;
2-
using System;
32
using System.Collections.Generic;
43
using System.Runtime.CompilerServices;
54
using System.Windows.Input;
5+
using Utilities;
66

77
[assembly: InternalsVisibleTo( "Tests" )]
88
namespace EddiCore.Hotkeys
@@ -14,41 +14,28 @@ public class HotkeyManager
1414
new HotkeyAction( "EnableEventResponses", Properties.Resources.hotkey_definition_enable_speech, () =>
1515
{
1616
EDDI.Instance.State[ "speechresponder_quiet" ] = false;
17+
Logging.Info("Hotkey action triggered: Enable Speech");
1718
} ),
1819
new HotkeyAction( "DisableEventResponses", Properties.Resources.hotkey_definition_disable_speech, () =>
1920
{
2021
EDDI.Instance.State[ "speechresponder_quiet" ] = true;
2122
SpeechService.Instance.ShutUp();
23+
Logging.Info("Hotkey action triggered: Disable Speech");
2224
} ),
2325
new HotkeyAction( "Shutup", Properties.Resources.hotkey_definition_stop_speech, () =>
2426
{
2527
SpeechService.Instance.ShutUp();
28+
Logging.Info("Hotkey action triggered: Stop the Current Speech");
2629
} )
2730
};
2831

2932
public HotkeyRegistration Hotkeys;
30-
private const int WM_HOTKEY = 0x0312;
3133

32-
public void SetHandle ( IntPtr newHandle )
34+
public void InitializeHotkeys ()
3335
{
34-
Hotkeys?.UnregisterAll();
35-
Hotkeys = new HotkeyRegistration( newHandle, new HotkeyActionCollection( HotkeyActions ) );
36-
Hotkeys.RegisterAll();
37-
}
38-
39-
public IntPtr HandleHotkeyMessage ( int msg, IntPtr wParam, ref bool handled )
40-
{
41-
if ( msg == WM_HOTKEY )
42-
{
43-
var id = wParam.ToInt32();
44-
if ( Hotkeys.Collection?.TryGetValue( id, out var hotkeyAction ) ?? false )
45-
{
46-
hotkeyAction.Action.Invoke();
47-
handled = true;
48-
}
49-
}
50-
51-
return IntPtr.Zero;
36+
Hotkeys?.Dispose(); // unhook any previous instance
37+
Hotkeys = new HotkeyRegistration( new HotkeyActionCollection( HotkeyActions ) );
38+
Hotkeys?.RegisterAll();
5239
}
5340

5441
public void RegisterHotkey ( string name, KeyGesture keyGesture ) => Hotkeys.RegisterHotkey( name, keyGesture );

0 commit comments

Comments
 (0)