From c3e04a80e6989e7f8de8a22e5ba3e6a7c73329d6 Mon Sep 17 00:00:00 2001 From: Boris Fritscher Date: Sat, 15 Jul 2017 00:04:09 +0200 Subject: [PATCH] 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 --- src/Carnac.Logic/KeyProvider.cs | 15 ++++++++--- src/Carnac.Logic/Models/Message.cs | 40 +++++++++++++++++++----------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/Carnac.Logic/KeyProvider.cs b/src/Carnac.Logic/KeyProvider.cs index d5272adb..946caed6 100644 --- a/src/Carnac.Logic/KeyProvider.cs +++ b/src/Carnac.Logic/KeyProvider.cs @@ -20,7 +20,7 @@ public class KeyProvider : IKeyProvider readonly IPasswordModeService passwordModeService; readonly IDesktopLockEventService desktopLockEventService; - private readonly IList modifierKeys = + private static readonly IList modifierKeys = new List { Keys.LControlKey, @@ -68,7 +68,7 @@ public IObservable GetKeyStream() var keyStreamSubsription = interceptKeysSource.GetKeyStream() .Select(DetectWindowsKey) - .Where(k => !IsModifierKeyPress(k) && k.KeyDirection == KeyDirection.Down) + .Where(k => k.KeyDirection == KeyDirection.Down) .Select(ToCarnacKeyPress) .Where(keypress => keypress != null) .Where(k => !passwordModeService.CheckPasswordMode(k.InterceptKeyEventArgs)) @@ -91,7 +91,7 @@ InterceptKeyEventArgs DetectWindowsKey(InterceptKeyEventArgs interceptKeyEventAr return interceptKeyEventArgs; } - bool IsModifierKeyPress(InterceptKeyEventArgs interceptKeyEventArgs) + public static bool IsModifierKeyPress(InterceptKeyEventArgs interceptKeyEventArgs) { return modifierKeys.Contains(interceptKeyEventArgs.Key); } @@ -123,6 +123,15 @@ static IEnumerable ToInputs(bool isLetter, bool isWinKeyPressed, Interce var controlPressed = interceptKeyEventArgs.ControlPressed; var altPressed = interceptKeyEventArgs.AltPressed; var shiftPressed = interceptKeyEventArgs.ShiftPressed; + + if (IsModifierKeyPress(interceptKeyEventArgs)) + { + controlPressed = false; + altPressed = false; + shiftPressed = false; + isWinKeyPressed = false; + } + if (controlPressed) yield return "Ctrl"; if (altPressed) diff --git a/src/Carnac.Logic/Models/Message.cs b/src/Carnac.Logic/Models/Message.cs index 415492b0..ca843b4b 100644 --- a/src/Carnac.Logic/Models/Message.cs +++ b/src/Carnac.Logic/Models/Message.cs @@ -13,7 +13,6 @@ public sealed class Message readonly string processName; readonly ImageSource processIcon; readonly string shortcutName; - readonly bool canBeMerged; readonly bool isShortcut; readonly bool isDeleting; readonly DateTime lastMessage; @@ -29,7 +28,6 @@ public Message(KeyPress key) { processName = key.Process.ProcessName; processIcon = key.Process.ProcessIcon; - canBeMerged = !key.HasModifierPressed; keys = new ReadOnlyCollection(new[] { key }); textCollection = new ReadOnlyCollection(CreateTextSequence(key).ToArray()); @@ -49,7 +47,6 @@ public Message(IEnumerable keys, KeyShortcut shortcut) processIcon = allKeys.First().Process.ProcessIcon; shortcutName = shortcut.Name; isShortcut = true; - canBeMerged = false; this.keys = new ReadOnlyCollection(allKeys); @@ -63,7 +60,6 @@ private Message(Message initial, Message appended) : this(initial.keys.Concat(appended.keys), new KeyShortcut(initial.ShortcutName)) { previous = initial; - canBeMerged = true; } private Message(Message initial, bool isDeleting) @@ -74,14 +70,18 @@ private Message(Message initial, bool isDeleting) lastMessage = initial.lastMessage; } + private Message(Message initial, Message replacer, bool replace) + : this(replacer.keys, new KeyShortcut(replacer.ShortcutName)) + { + previous = initial; + } + public string ProcessName { get { return processName; } } public ImageSource ProcessIcon { get { return processIcon; } } public string ShortcutName { get { return shortcutName; } } - public bool CanBeMerged { get { return canBeMerged; } } - public bool IsShortcut { get { return isShortcut; } } public Message Previous { get { return previous; } } @@ -97,21 +97,35 @@ public Message Merge(Message other) return new Message(this, other); } - static readonly TimeSpan OneSecond = TimeSpan.FromSeconds(1); + public Message Replace(Message newMessage) + { + return new Message(this, newMessage, true); + } + + static readonly TimeSpan OneSecond = TimeSpan.FromSeconds(1); public static Message MergeIfNeeded(Message previousMessage, Message newMessage) { - return ShouldCreateNewMessage(previousMessage, newMessage) - ? newMessage - : previousMessage.Merge(newMessage); + // replace key was after standalone modifier keypress, replace by new Message + if (previousMessage.keys != null && KeyProvider.IsModifierKeyPress(previousMessage.keys[0].InterceptKeyEventArgs)) + { + return previousMessage.Replace(newMessage); + } + + if (ShouldCreateNewMessage(previousMessage, newMessage)) + { + return newMessage; + } + return previousMessage.Merge(newMessage); } static bool ShouldCreateNewMessage(Message previous, Message current) { return previous.ProcessName != current.ProcessName || current.LastMessage.Subtract(previous.LastMessage) > OneSecond || - !previous.CanBeMerged || - !current.CanBeMerged; + KeyProvider.IsModifierKeyPress(current.keys[0].InterceptKeyEventArgs) || + // accumulate also same modifier shortcuts + (previous.keys[0].HasModifierPressed && !previous.keys[0].Input.SequenceEqual(current.keys[0].Input)); } public Message FadeOut() @@ -204,7 +218,6 @@ bool Equals(Message other) && string.Equals(processName, other.processName) && Equals(processIcon, other.processIcon) && string.Equals(shortcutName, other.shortcutName) - && canBeMerged.Equals(other.canBeMerged) && isShortcut.Equals(other.isShortcut) && isDeleting.Equals(other.isDeleting) && lastMessage.Equals(other.lastMessage); @@ -227,7 +240,6 @@ public override int GetHashCode() hashCode = (hashCode * 397) ^ (processName != null ? processName.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (processIcon != null ? processIcon.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (shortcutName != null ? shortcutName.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ canBeMerged.GetHashCode(); hashCode = (hashCode * 397) ^ isShortcut.GetHashCode(); hashCode = (hashCode * 397) ^ isDeleting.GetHashCode(); hashCode = (hashCode * 397) ^ lastMessage.GetHashCode();