Skip to content

Commit c3e04a8

Browse files
committed
Support showing ctrl, alt, win keys pressed down without any other key
- Removed filtering of modifierkey to allow to handle them in ToInputs. - Filtered triggering of modifier display for modifierkeys themselves in ToInputs. - Exposed IsModifierKeyPress as static to be used in KeyPress and Messages. - KeyPress.HasModifierPress returns false if key is a modifierkey itself (allow the merging in Message). - Removed merge flag in favor of handling the strategy directly in Message.MergeIfNeeded
1 parent 6f2ae82 commit c3e04a8

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

src/Carnac.Logic/KeyProvider.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class KeyProvider : IKeyProvider
2020
readonly IPasswordModeService passwordModeService;
2121
readonly IDesktopLockEventService desktopLockEventService;
2222

23-
private readonly IList<Keys> modifierKeys =
23+
private static readonly IList<Keys> modifierKeys =
2424
new List<Keys>
2525
{
2626
Keys.LControlKey,
@@ -68,7 +68,7 @@ public IObservable<KeyPress> GetKeyStream()
6868

6969
var keyStreamSubsription = interceptKeysSource.GetKeyStream()
7070
.Select(DetectWindowsKey)
71-
.Where(k => !IsModifierKeyPress(k) && k.KeyDirection == KeyDirection.Down)
71+
.Where(k => k.KeyDirection == KeyDirection.Down)
7272
.Select(ToCarnacKeyPress)
7373
.Where(keypress => keypress != null)
7474
.Where(k => !passwordModeService.CheckPasswordMode(k.InterceptKeyEventArgs))
@@ -91,7 +91,7 @@ InterceptKeyEventArgs DetectWindowsKey(InterceptKeyEventArgs interceptKeyEventAr
9191
return interceptKeyEventArgs;
9292
}
9393

94-
bool IsModifierKeyPress(InterceptKeyEventArgs interceptKeyEventArgs)
94+
public static bool IsModifierKeyPress(InterceptKeyEventArgs interceptKeyEventArgs)
9595
{
9696
return modifierKeys.Contains(interceptKeyEventArgs.Key);
9797
}
@@ -123,6 +123,15 @@ static IEnumerable<string> ToInputs(bool isLetter, bool isWinKeyPressed, Interce
123123
var controlPressed = interceptKeyEventArgs.ControlPressed;
124124
var altPressed = interceptKeyEventArgs.AltPressed;
125125
var shiftPressed = interceptKeyEventArgs.ShiftPressed;
126+
127+
if (IsModifierKeyPress(interceptKeyEventArgs))
128+
{
129+
controlPressed = false;
130+
altPressed = false;
131+
shiftPressed = false;
132+
isWinKeyPressed = false;
133+
}
134+
126135
if (controlPressed)
127136
yield return "Ctrl";
128137
if (altPressed)

src/Carnac.Logic/Models/Message.cs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ public sealed class Message
1313
readonly string processName;
1414
readonly ImageSource processIcon;
1515
readonly string shortcutName;
16-
readonly bool canBeMerged;
1716
readonly bool isShortcut;
1817
readonly bool isDeleting;
1918
readonly DateTime lastMessage;
@@ -29,7 +28,6 @@ public Message(KeyPress key)
2928
{
3029
processName = key.Process.ProcessName;
3130
processIcon = key.Process.ProcessIcon;
32-
canBeMerged = !key.HasModifierPressed;
3331

3432
keys = new ReadOnlyCollection<KeyPress>(new[] { key });
3533
textCollection = new ReadOnlyCollection<string>(CreateTextSequence(key).ToArray());
@@ -49,7 +47,6 @@ public Message(IEnumerable<KeyPress> keys, KeyShortcut shortcut)
4947
processIcon = allKeys.First().Process.ProcessIcon;
5048
shortcutName = shortcut.Name;
5149
isShortcut = true;
52-
canBeMerged = false;
5350

5451
this.keys = new ReadOnlyCollection<KeyPress>(allKeys);
5552

@@ -63,7 +60,6 @@ private Message(Message initial, Message appended)
6360
: this(initial.keys.Concat(appended.keys), new KeyShortcut(initial.ShortcutName))
6461
{
6562
previous = initial;
66-
canBeMerged = true;
6763
}
6864

6965
private Message(Message initial, bool isDeleting)
@@ -74,14 +70,18 @@ private Message(Message initial, bool isDeleting)
7470
lastMessage = initial.lastMessage;
7571
}
7672

73+
private Message(Message initial, Message replacer, bool replace)
74+
: this(replacer.keys, new KeyShortcut(replacer.ShortcutName))
75+
{
76+
previous = initial;
77+
}
78+
7779
public string ProcessName { get { return processName; } }
7880

7981
public ImageSource ProcessIcon { get { return processIcon; } }
8082

8183
public string ShortcutName { get { return shortcutName; } }
8284

83-
public bool CanBeMerged { get { return canBeMerged; } }
84-
8585
public bool IsShortcut { get { return isShortcut; } }
8686

8787
public Message Previous { get { return previous; } }
@@ -97,21 +97,35 @@ public Message Merge(Message other)
9797
return new Message(this, other);
9898
}
9999

100-
static readonly TimeSpan OneSecond = TimeSpan.FromSeconds(1);
100+
public Message Replace(Message newMessage)
101+
{
102+
return new Message(this, newMessage, true);
103+
}
104+
105+
static readonly TimeSpan OneSecond = TimeSpan.FromSeconds(1);
101106

102107
public static Message MergeIfNeeded(Message previousMessage, Message newMessage)
103108
{
104-
return ShouldCreateNewMessage(previousMessage, newMessage)
105-
? newMessage
106-
: previousMessage.Merge(newMessage);
109+
// replace key was after standalone modifier keypress, replace by new Message
110+
if (previousMessage.keys != null && KeyProvider.IsModifierKeyPress(previousMessage.keys[0].InterceptKeyEventArgs))
111+
{
112+
return previousMessage.Replace(newMessage);
113+
}
114+
115+
if (ShouldCreateNewMessage(previousMessage, newMessage))
116+
{
117+
return newMessage;
118+
}
119+
return previousMessage.Merge(newMessage);
107120
}
108121

109122
static bool ShouldCreateNewMessage(Message previous, Message current)
110123
{
111124
return previous.ProcessName != current.ProcessName ||
112125
current.LastMessage.Subtract(previous.LastMessage) > OneSecond ||
113-
!previous.CanBeMerged ||
114-
!current.CanBeMerged;
126+
KeyProvider.IsModifierKeyPress(current.keys[0].InterceptKeyEventArgs) ||
127+
// accumulate also same modifier shortcuts
128+
(previous.keys[0].HasModifierPressed && !previous.keys[0].Input.SequenceEqual(current.keys[0].Input));
115129
}
116130

117131
public Message FadeOut()
@@ -204,7 +218,6 @@ bool Equals(Message other)
204218
&& string.Equals(processName, other.processName)
205219
&& Equals(processIcon, other.processIcon)
206220
&& string.Equals(shortcutName, other.shortcutName)
207-
&& canBeMerged.Equals(other.canBeMerged)
208221
&& isShortcut.Equals(other.isShortcut)
209222
&& isDeleting.Equals(other.isDeleting)
210223
&& lastMessage.Equals(other.lastMessage);
@@ -227,7 +240,6 @@ public override int GetHashCode()
227240
hashCode = (hashCode * 397) ^ (processName != null ? processName.GetHashCode() : 0);
228241
hashCode = (hashCode * 397) ^ (processIcon != null ? processIcon.GetHashCode() : 0);
229242
hashCode = (hashCode * 397) ^ (shortcutName != null ? shortcutName.GetHashCode() : 0);
230-
hashCode = (hashCode * 397) ^ canBeMerged.GetHashCode();
231243
hashCode = (hashCode * 397) ^ isShortcut.GetHashCode();
232244
hashCode = (hashCode * 397) ^ isDeleting.GetHashCode();
233245
hashCode = (hashCode * 397) ^ lastMessage.GetHashCode();

0 commit comments

Comments
 (0)