Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -370,12 +370,14 @@ private Key MapKeyModifiers (ConsoleKeyInfo keyInfo, Key key)
return keyMod != Key.Null ? keyMod | key : key;
}

Action<KeyEvent> keyDownHandler;
Action<KeyEvent> keyHandler;
Action<KeyEvent> keyUpHandler;
private CursorVisibility savedCursorVisibility;

public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
{
this.keyDownHandler = keyDownHandler;
this.keyHandler = keyHandler;
this.keyUpHandler = keyUpHandler;

Expand All @@ -386,20 +388,25 @@ public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandle
void ProcessInput (ConsoleKeyInfo consoleKey)
{
keyModifiers = new KeyModifiers ();
var map = MapKey (consoleKey);
if (map == (Key)0xffffffff)
return;

if (consoleKey.Modifiers.HasFlag (ConsoleModifiers.Alt)) {
keyModifiers.Alt = true;
}
if (consoleKey.Modifiers.HasFlag (ConsoleModifiers.Shift)) {
keyModifiers.Shift = true;
}
if (consoleKey.Modifiers.HasFlag (ConsoleModifiers.Alt)) {
keyModifiers.Alt = true;
}
if (consoleKey.Modifiers.HasFlag (ConsoleModifiers.Control)) {
keyModifiers.Ctrl = true;
}
var map = MapKey (consoleKey);
if (map == (Key)0xffffffff) {
if ((consoleKey.Modifiers & (ConsoleModifiers.Shift | ConsoleModifiers.Alt | ConsoleModifiers.Control)) != 0) {
keyDownHandler (new KeyEvent (map, keyModifiers));
keyUpHandler (new KeyEvent (map, keyModifiers));
}
return;
}

keyDownHandler (new KeyEvent (map, keyModifiers));
keyHandler (new KeyEvent (map, keyModifiers));
keyUpHandler (new KeyEvent (map, keyModifiers));
}
Expand Down
20 changes: 16 additions & 4 deletions Terminal.Gui/Core/View.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1932,8 +1932,14 @@ public override bool OnKeyDown (KeyEvent keyEvent)
if (args.Handled) {
return true;
}
if (Focused?.Enabled == true && Focused?.OnKeyDown (keyEvent) == true) {
return true;
if (Focused?.Enabled == true) {
Focused.KeyDown?.Invoke (args);
if (args.Handled) {
return true;
}
if (Focused?.OnKeyDown (keyEvent) == true) {
return true;
}
}

return false;
Expand All @@ -1956,8 +1962,14 @@ public override bool OnKeyUp (KeyEvent keyEvent)
if (args.Handled) {
return true;
}
if (Focused?.Enabled == true && Focused?.OnKeyUp (keyEvent) == true) {
return true;
if (Focused?.Enabled == true) {
Focused.KeyUp?.Invoke (args);
if (args.Handled) {
return true;
}
if (Focused?.OnKeyUp (keyEvent) == true) {
return true;
}
}

return false;
Expand Down
130 changes: 130 additions & 0 deletions UnitTests/ViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3910,5 +3910,135 @@ public void DrawContentComplete_Event_Is_Always_Called ()
Assert.True (viewCalled);
Assert.True (tvCalled);
}

[Fact, AutoInitShutdown]
public void KeyDown_And_KeyUp_Events_Must_Called_Before_OnKeyDown_And_OnKeyUp ()
{
var keyDown = false;
var keyPress = false;
var keyUp = false;

var view = new DerivedView ();
view.KeyDown += (e) => {
Assert.Equal (Key.a, e.KeyEvent.Key);
Assert.False (keyDown);
Assert.False (view.IsKeyDown);
e.Handled = true;
keyDown = true;
};
view.KeyPress += (e) => {
Assert.Equal (Key.a, e.KeyEvent.Key);
Assert.False (keyPress);
Assert.False (view.IsKeyPress);
e.Handled = true;
keyPress = true;
};
view.KeyUp += (e) => {
Assert.Equal (Key.a, e.KeyEvent.Key);
Assert.False (keyUp);
Assert.False (view.IsKeyUp);
e.Handled = true;
keyUp = true;
};

Application.Top.Add (view);

Console.MockKeyPresses.Push (new ConsoleKeyInfo ('a', ConsoleKey.A, false, false, false));

Application.Iteration += () => Application.RequestStop ();

Assert.True (view.CanFocus);

Application.Run ();
Application.Shutdown ();

Assert.True (keyDown);
Assert.True (keyPress);
Assert.True (keyUp);
Assert.False (view.IsKeyDown);
Assert.False (view.IsKeyPress);
Assert.False (view.IsKeyUp);
}

public class DerivedView : View {
public DerivedView ()
{
CanFocus = true;
}

public bool IsKeyDown { get; set; }
public bool IsKeyPress { get; set; }
public bool IsKeyUp { get; set; }

public override bool OnKeyDown (KeyEvent keyEvent)
{
IsKeyDown = true;
return true;
}

public override bool ProcessKey (KeyEvent keyEvent)
{
IsKeyPress = true;
return true;
}

public override bool OnKeyUp (KeyEvent keyEvent)
{
IsKeyUp = true;
return true;
}
}

[Theory, AutoInitShutdown]
[InlineData (true, false, false)]
[InlineData (true, true, false)]
[InlineData (true, true, true)]
public void KeyDown_And_KeyUp_Events_With_Only_Key_Modifiers (bool shift, bool alt, bool control)
{
var keyDown = false;
var keyPress = false;
var keyUp = false;

var view = new DerivedView ();
view.KeyDown += (e) => {
Assert.Equal (-1, e.KeyEvent.KeyValue);
Assert.Equal (shift, e.KeyEvent.IsShift);
Assert.Equal (alt, e.KeyEvent.IsAlt);
Assert.Equal (control, e.KeyEvent.IsCtrl);
Assert.False (keyDown);
Assert.False (view.IsKeyDown);
keyDown = true;
};
view.KeyPress += (e) => {
keyPress = true;
};
view.KeyUp += (e) => {
Assert.Equal (-1, e.KeyEvent.KeyValue);
Assert.Equal (shift, e.KeyEvent.IsShift);
Assert.Equal (alt, e.KeyEvent.IsAlt);
Assert.Equal (control, e.KeyEvent.IsCtrl);
Assert.False (keyUp);
Assert.False (view.IsKeyUp);
keyUp = true;
};

Application.Top.Add (view);

Console.MockKeyPresses.Push (new ConsoleKeyInfo ('\0', (ConsoleKey)'\0', shift, alt, control));

Application.Iteration += () => Application.RequestStop ();

Assert.True (view.CanFocus);

Application.Run ();
Application.Shutdown ();

Assert.True (keyDown);
Assert.False (keyPress);
Assert.True (keyUp);
Assert.True (view.IsKeyDown);
Assert.False (view.IsKeyPress);
Assert.True (view.IsKeyUp);
}
}
}