diff --git a/Terminal.Gui/Core.cs b/Terminal.Gui/Core.cs
index d0477ef86..e4d2aedaf 100644
--- a/Terminal.Gui/Core.cs
+++ b/Terminal.Gui/Core.cs
@@ -119,8 +119,29 @@ namespace Terminal.Gui {
public virtual bool ProcessColdKey (KeyEvent keyEvent)
{
return false;
- }
-
+ }
+
+ ///
+ /// Method invoked when a key is pressed.
+ ///
+ /// Contains the details about the key that produced the event.
+ /// true if the event was handled
+ public virtual bool KeyDown (KeyEvent keyEvent)
+ {
+ return false;
+ }
+
+ ///
+ /// Method invoked when a key is released.
+ ///
+ /// Contains the details about the key that produced the event.
+ /// true if the event was handled
+ public virtual bool KeyUp (KeyEvent keyEvent)
+ {
+ return false;
+ }
+
+
///
/// Method invoked when a mouse event is generated
///
@@ -1009,8 +1030,31 @@ namespace Terminal.Gui {
if (view.ProcessColdKey (keyEvent))
return true;
return false;
- }
+ }
+
+ /// Contains the details about the key that produced the event.
+ public override bool KeyDown (KeyEvent keyEvent)
+ {
+ if (subviews == null || subviews.Count == 0)
+ return false;
+ foreach (var view in subviews)
+ if (view.KeyDown (keyEvent))
+ return true;
+ return false;
+ }
+
+ /// Contains the details about the key that produced the event.
+ public override bool KeyUp (KeyEvent keyEvent)
+ {
+ if (subviews == null || subviews.Count == 0)
+ return false;
+ foreach (var view in subviews)
+ if (view.KeyUp (keyEvent))
+ return true;
+
+ return false;
+ }
///
/// Finds the first view in the hierarchy that wants to get the focus if nothing is currently focused, otherwise, it does nothing.
///
@@ -1943,6 +1987,7 @@ namespace Terminal.Gui {
static void ProcessKeyEvent (KeyEvent ke)
{
+
var chain = toplevels.ToList();
foreach (var topLevel in chain) {
if (topLevel.ProcessHotKey (ke))
@@ -1965,6 +2010,29 @@ namespace Terminal.Gui {
if (topLevel.Modal)
break;
}
+ }
+
+ static void ProcessKeyDownEvent (KeyEvent ke)
+ {
+ var chain = toplevels.ToList ();
+ foreach (var topLevel in chain) {
+ if (topLevel.KeyDown (ke))
+ return;
+ if (topLevel.Modal)
+ break;
+ }
+ }
+
+
+ static void ProcessKeyUpEvent (KeyEvent ke)
+ {
+ var chain = toplevels.ToList ();
+ foreach (var topLevel in chain) {
+ if (topLevel.KeyUp (ke))
+ return;
+ if (topLevel.Modal)
+ break;
+ }
}
static View FindDeepestView (View start, int x, int y, out int resx, out int resy)
@@ -2092,7 +2160,7 @@ namespace Terminal.Gui {
}
toplevels.Push (toplevel);
Current = toplevel;
- Driver.PrepareToRun (MainLoop, ProcessKeyEvent, ProcessMouseEvent);
+ Driver.PrepareToRun (MainLoop, ProcessKeyEvent, ProcessKeyDownEvent, ProcessKeyUpEvent, ProcessMouseEvent);
if (toplevel.LayoutStyle == LayoutStyle.Computed)
toplevel.RelativeLayout (new Rect (0, 0, Driver.Cols, Driver.Rows));
toplevel.LayoutSubviews ();
diff --git a/Terminal.Gui/Drivers/ConsoleDriver.cs b/Terminal.Gui/Drivers/ConsoleDriver.cs
index 19cdc4e48..9e9511e85 100644
--- a/Terminal.Gui/Drivers/ConsoleDriver.cs
+++ b/Terminal.Gui/Drivers/ConsoleDriver.cs
@@ -469,7 +469,7 @@ namespace Terminal.Gui {
///
///
///
- public abstract void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action mouseHandler);
+ public abstract void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler);
///
/// Updates the screen to reflect all the changes that have been done to the display buffer
diff --git a/Terminal.Gui/Drivers/CursesDriver.cs b/Terminal.Gui/Drivers/CursesDriver.cs
index 2508051db..c51b37b6f 100644
--- a/Terminal.Gui/Drivers/CursesDriver.cs
+++ b/Terminal.Gui/Drivers/CursesDriver.cs
@@ -203,8 +203,9 @@ namespace Terminal.Gui {
keyHandler (new KeyEvent ((Key)wch));
}
- public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action mouseHandler)
+ public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler)
{
+ // Note: Curses doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called
Curses.timeout (-1);
(mainLoop.Driver as Mono.Terminal.UnixMainLoop).AddWatch (0, Mono.Terminal.UnixMainLoop.Condition.PollIn, x => {
diff --git a/Terminal.Gui/Drivers/NetDriver.cs b/Terminal.Gui/Drivers/NetDriver.cs
index 0b5217910..8483182c4 100644
--- a/Terminal.Gui/Drivers/NetDriver.cs
+++ b/Terminal.Gui/Drivers/NetDriver.cs
@@ -320,8 +320,9 @@ namespace Terminal.Gui {
return (Key)(0xffffffff);
}
- public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action mouseHandler)
- {
+ public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler)
+ {
+ // Note: Net doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called
(mainLoop.Driver as NetMainLoop).WindowsKeyPressed = delegate (ConsoleKeyInfo consoleKey) {
var map = MapKey (consoleKey);
if (map == (Key)0xffffffff)
diff --git a/Terminal.Gui/Drivers/WindowsDriver.cs b/Terminal.Gui/Drivers/WindowsDriver.cs
index f48eb6418..f7d21c612 100644
--- a/Terminal.Gui/Drivers/WindowsDriver.cs
+++ b/Terminal.Gui/Drivers/WindowsDriver.cs
@@ -26,6 +26,7 @@
// SOFTWARE.
//
using System;
+using System.CodeDom;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
@@ -537,11 +538,15 @@ namespace Terminal.Gui {
}
Action keyHandler;
+ Action keyDownHandler;
+ Action keyUpHandler;
Action mouseHandler;
- public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action mouseHandler)
+ public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler)
{
this.keyHandler = keyHandler;
+ this.keyDownHandler = keyDownHandler;
+ this.keyUpHandler = keyUpHandler;
this.mouseHandler = mouseHandler;
}
@@ -554,10 +559,14 @@ namespace Terminal.Gui {
var inputEvent = result [0];
switch (inputEvent.EventType) {
case WindowsConsole.EventType.Key:
+ // See how this relies on key up?
if (inputEvent.KeyEvent.bKeyDown == false)
return;
var map = MapKey (ToConsoleKeyInfoEx (inputEvent.KeyEvent));
- if (inputEvent.KeyEvent.UnicodeChar == 0 && map == (Key)0xffffffff)
+ if (inputEvent.KeyEvent.UnicodeChar == 0)
+ keyDownHandler (new KeyEvent (map));
+
+ if (map == (Key)0xffffffff)
return;
keyHandler (new KeyEvent (map));
break;
@@ -837,6 +846,16 @@ namespace Terminal.Gui {
return (Key)((int)Key.F1 + delta);
}
+
+ //if (keyInfo.KeyChar == 0) {
+ // if (keyInfo.Modifiers == ConsoleModifiers.Control)
+ // return (Key)(uint)Key.CharMask;
+ // if (keyInfo.Modifiers == ConsoleModifiers.Alt)
+ // return (Key)(uint)Key.AltMask;
+ // if ((keyInfo.Modifiers & (ConsoleModifiers.Alt | ConsoleModifiers.Control)) != 0) {
+ // return (Key)(uint)(Key.AltMask | Key.CharMask);
+ // }
+ //}
return (Key)(0xffffffff);
}