diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 036666970d..986a1b0120 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -142,7 +142,6 @@ public override void Refresh () Curses.raw (); Curses.noecho (); Curses.refresh (); - ProcessWinChange (); } private void ProcessWinChange () @@ -161,6 +160,10 @@ public override void End () StopReportingMouseMoves (); SetCursorVisibility (CursorVisibility.Default); + // throws away any typeahead that has been typed by + // the user and has not yet been read by the program. + Curses.flushinp (); + Curses.endwin (); } @@ -337,8 +340,12 @@ void ProcessInput () Key k = Key.Null; if (code == Curses.KEY_CODE_YES) { - if (wch == Curses.KeyResize) { + while (code == Curses.KEY_CODE_YES && wch == Curses.KeyResize) { ProcessWinChange (); + code = Curses.get_wch (out wch); + } + if (wch == 0) { + return; } if (wch == Curses.KeyMouse) { int wch2 = wch; @@ -492,8 +499,44 @@ void GetEscSeq (ref int code, ref Key k, ref int wch2, ref KeyEvent key, ref Con } } + MouseFlags lastMouseFlags; + void ProcessMouseEvent (MouseFlags mouseFlag, Point pos) { + bool WasButtonReleased (MouseFlags flag) + { + return flag.HasFlag (MouseFlags.Button1Released) || + flag.HasFlag (MouseFlags.Button2Released) || + flag.HasFlag (MouseFlags.Button3Released) || + flag.HasFlag (MouseFlags.Button4Released); + } + + bool IsButtonNotPressed (MouseFlags flag) + { + return !flag.HasFlag (MouseFlags.Button1Pressed) && + !flag.HasFlag (MouseFlags.Button2Pressed) && + !flag.HasFlag (MouseFlags.Button3Pressed) && + !flag.HasFlag (MouseFlags.Button4Pressed); + } + + bool IsButtonClickedOrDoubleClicked (MouseFlags flag) + { + return flag.HasFlag (MouseFlags.Button1Clicked) || + flag.HasFlag (MouseFlags.Button2Clicked) || + flag.HasFlag (MouseFlags.Button3Clicked) || + flag.HasFlag (MouseFlags.Button4Clicked) || + flag.HasFlag (MouseFlags.Button1DoubleClicked) || + flag.HasFlag (MouseFlags.Button2DoubleClicked) || + flag.HasFlag (MouseFlags.Button3DoubleClicked) || + flag.HasFlag (MouseFlags.Button4DoubleClicked); + } + + if ((WasButtonReleased (mouseFlag) && IsButtonNotPressed (lastMouseFlags)) || + (IsButtonClickedOrDoubleClicked (mouseFlag) && lastMouseFlags == 0)) { + return; + } + + lastMouseFlags = mouseFlag; var me = new MouseEvent () { Flags = mouseFlag, X = pos.X, @@ -529,7 +572,7 @@ public override void PrepareToRun (MainLoop mainLoop, Action keyHandle }); mLoop.WinChanged += () => { - ProcessWinChange (); + ProcessInput (); }; } diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs index 6cb391e97e..f0c7cb9df9 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs @@ -97,8 +97,8 @@ void IMainLoopDriver.Setup (MainLoop mainLoop) { this.mainLoop = mainLoop; pipe (wakeupPipes); - AddWatch (wakeupPipes [0], Condition.PollIn, ml => { - read (wakeupPipes [0], ignore, readHandle); + AddWatch (wakeupPipes [1], Condition.PollIn, ml => { + read (wakeupPipes [1], ignore, readHandle); return true; }); } diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/binding.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/binding.cs index 5e73f065a3..f50f646387 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/binding.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/binding.cs @@ -160,7 +160,10 @@ public static bool CheckWinChange () console_sharp_get_dims (out l, out c); - if (l == 1 || l != lines || c != cols) { + if (l < 1) { + l = 1; + } + if (l != lines || c != cols) { lines = l; cols = c; return true; diff --git a/UnitTests/Drivers/ConsoleDriverTests.cs b/UnitTests/Drivers/ConsoleDriverTests.cs index cf64659209..9c059d1943 100644 --- a/UnitTests/Drivers/ConsoleDriverTests.cs +++ b/UnitTests/Drivers/ConsoleDriverTests.cs @@ -188,8 +188,8 @@ public void Left_And_Top_Is_Always_Zero (Type driverType) Application.Shutdown (); } - - + + [Fact, AutoInitShutdown] public void AddRune_On_Clip_Left_Or_Right_Replace_Previous_Or_Next_Wide_Rune_With_Space () { @@ -311,7 +311,7 @@ public void MakePrintable_Does_Not_Convert_Ansi_Chars_To_Unicode (uint code) } private static object packetLock = new object (); - + /// /// Sometimes when using remote tools EventKeyRecord sends 'virtual keystrokes'. /// These are indicated with the wVirtualKeyCode of 231. When we see this code @@ -319,46 +319,48 @@ public void MakePrintable_Does_Not_Convert_Ansi_Chars_To_Unicode (uint code) /// when telling the rest of the framework what button was pressed. For full details /// see: https://github.com/gui-cs/Terminal.Gui/issues/2008 /// - [Theory, AutoInitShutdown] + [Theory] [ClassData (typeof (PacketTest))] public void TestVKPacket (uint unicodeCharacter, bool shift, bool alt, bool control, uint initialVirtualKey, uint initialScanCode, Key expectedRemapping, uint expectedVirtualKey, uint expectedScanCode) { - var modifiers = new ConsoleModifiers (); - if (shift) modifiers |= ConsoleModifiers.Shift; - if (alt) modifiers |= ConsoleModifiers.Alt; - if (control) modifiers |= ConsoleModifiers.Control; - var mappedConsoleKey = ConsoleKeyMapping.GetConsoleKeyFromKey (unicodeCharacter, modifiers, out uint scanCode, out uint outputChar); + lock (packetLock) { + Application.ForceFakeConsole = true; + Application.Init (); - if ((scanCode > 0 || mappedConsoleKey == 0) && mappedConsoleKey == initialVirtualKey) Assert.Equal (mappedConsoleKey, initialVirtualKey); - else Assert.Equal (mappedConsoleKey, outputChar < 0xff ? outputChar & 0xff | 0xff << 8 : outputChar); - Assert.Equal (scanCode, initialScanCode); + var modifiers = new ConsoleModifiers (); + if (shift) modifiers |= ConsoleModifiers.Shift; + if (alt) modifiers |= ConsoleModifiers.Alt; + if (control) modifiers |= ConsoleModifiers.Control; + var mappedConsoleKey = ConsoleKeyMapping.GetConsoleKeyFromKey (unicodeCharacter, modifiers, out uint scanCode, out uint outputChar); - var keyChar = ConsoleKeyMapping.GetKeyCharFromConsoleKey (mappedConsoleKey, modifiers, out uint consoleKey, out scanCode); + if ((scanCode > 0 || mappedConsoleKey == 0) && mappedConsoleKey == initialVirtualKey) Assert.Equal (mappedConsoleKey, initialVirtualKey); + else Assert.Equal (mappedConsoleKey, outputChar < 0xff ? outputChar & 0xff | 0xff << 8 : outputChar); + Assert.Equal (scanCode, initialScanCode); - //if (scanCode > 0 && consoleKey == keyChar && consoleKey > 48 && consoleKey > 57 && consoleKey < 65 && consoleKey > 91) { - if (scanCode > 0 && keyChar == 0 && consoleKey == mappedConsoleKey) Assert.Equal (0, (double)keyChar); - else Assert.Equal (keyChar, unicodeCharacter); - Assert.Equal (consoleKey, expectedVirtualKey); - Assert.Equal (scanCode, expectedScanCode); + var keyChar = ConsoleKeyMapping.GetKeyCharFromConsoleKey (mappedConsoleKey, modifiers, out uint consoleKey, out scanCode); - var top = Application.Top; + //if (scanCode > 0 && consoleKey == keyChar && consoleKey > 48 && consoleKey > 57 && consoleKey < 65 && consoleKey > 91) { + if (scanCode > 0 && keyChar == 0 && consoleKey == mappedConsoleKey) Assert.Equal (0, (double)keyChar); + else Assert.Equal (keyChar, unicodeCharacter); + Assert.Equal (consoleKey, expectedVirtualKey); + Assert.Equal (scanCode, expectedScanCode); - top.KeyPress += (e) => { - var after = ShortcutHelper.GetModifiersKey (e.KeyEvent); - Assert.Equal (expectedRemapping, after); - e.Handled = true; - Application.RequestStop (); - }; + var top = Application.Top; - var iterations = -1; + top.KeyPress += (e) => { + var after = ShortcutHelper.GetModifiersKey (e.KeyEvent); + Assert.Equal (expectedRemapping, after); + e.Handled = true; + Application.RequestStop (); + }; - Application.Iteration += () => { - iterations++; - if (iterations == 0) Application.Driver.SendKeys ((char)mappedConsoleKey, ConsoleKey.Packet, shift, alt, control); - }; + var iterations = -1; + Application.Iteration += () => { + iterations++; + if (iterations == 0) Application.Driver.SendKeys ((char)mappedConsoleKey, ConsoleKey.Packet, shift, alt, control); + }; - lock (packetLock) { Application.Run (); Application.Shutdown (); }