Skip to content

Commit

Permalink
Support showing ctrl, alt, win keys pressed down without any other key
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
bfritscher committed Jul 17, 2017
1 parent 6f2ae82 commit c3e04a8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 17 deletions.
15 changes: 12 additions & 3 deletions src/Carnac.Logic/KeyProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class KeyProvider : IKeyProvider
readonly IPasswordModeService passwordModeService;
readonly IDesktopLockEventService desktopLockEventService;

private readonly IList<Keys> modifierKeys =
private static readonly IList<Keys> modifierKeys =
new List<Keys>
{
Keys.LControlKey,
Expand Down Expand Up @@ -68,7 +68,7 @@ public IObservable<KeyPress> 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))
Expand All @@ -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);
}
Expand Down Expand Up @@ -123,6 +123,15 @@ static IEnumerable<string> 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)
Expand Down
40 changes: 26 additions & 14 deletions src/Carnac.Logic/Models/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -29,7 +28,6 @@ public Message(KeyPress key)
{
processName = key.Process.ProcessName;
processIcon = key.Process.ProcessIcon;
canBeMerged = !key.HasModifierPressed;

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

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

Expand All @@ -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)
Expand All @@ -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; } }
Expand All @@ -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()
Expand Down Expand Up @@ -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);
Expand All @@ -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();
Expand Down

0 comments on commit c3e04a8

Please sign in to comment.