Improves mouse performance #386. Provides a better async call. Ensures all the cycles of a simple click (Pressed, Released and Clicked). Only clears selected text if other view than MenuBar get focus. (#404)

This commit is contained in:
BDisp
2020-04-23 02:55:35 +01:00
committed by GitHub
parent 2ea8777227
commit a9e62c0626
4 changed files with 46 additions and 36 deletions

View File

@@ -594,6 +594,8 @@ namespace Terminal.Gui {
case WindowsConsole.EventType.Mouse:
mouseHandler (ToDriverMouse (inputEvent.MouseEvent));
if (IsButtonReleased)
mouseHandler (ToDriverMouse (inputEvent.MouseEvent));
break;
case WindowsConsole.EventType.WindowBufferSize:
@@ -635,7 +637,7 @@ namespace Terminal.Gui {
if ((mouseEvent.EventFlags == 0 && LastMouseButtonPressed == null && !IsButtonDoubleClicked) ||
(mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved &&
mouseEvent.ButtonState != 0 && !IsButtonDoubleClicked)) {
mouseEvent.ButtonState != 0 && !IsButtonReleased && !IsButtonDoubleClicked)) {
switch (mouseEvent.ButtonState) {
case WindowsConsole.ButtonState.Button1Pressed:
mouseFlag = MouseFlags.Button1Pressed;
@@ -653,6 +655,7 @@ namespace Terminal.Gui {
if (mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved) {
mouseFlag |= MouseFlags.ReportMousePosition;
point = new Point ();
IsButtonReleased = false;
} else {
point = new Point () {
X = mouseEvent.MousePosition.X,
@@ -660,8 +663,8 @@ namespace Terminal.Gui {
};
}
LastMouseButtonPressed = mouseEvent.ButtonState;
} else if (mouseEvent.EventFlags == 0 && LastMouseButtonPressed != null && !IsButtonReleased &&
!IsButtonDoubleClicked) {
} else if ((mouseEvent.EventFlags == 0 || mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved) &&
LastMouseButtonPressed != null && !IsButtonReleased && !IsButtonDoubleClicked) {
switch (LastMouseButtonPressed) {
case WindowsConsole.ButtonState.Button1Pressed:
mouseFlag = MouseFlags.Button1Released;
@@ -677,7 +680,7 @@ namespace Terminal.Gui {
}
IsButtonReleased = true;
} else if ((mouseEvent.EventFlags == 0 || mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved) &&
IsButtonReleased) {
IsButtonReleased) {
var p = new Point () {
X = mouseEvent.MousePosition.X,
Y = mouseEvent.MousePosition.Y
@@ -696,6 +699,8 @@ namespace Terminal.Gui {
mouseFlag = MouseFlags.Button4Clicked;
break;
}
} else {
mouseFlag = 0;
}
LastMouseButtonPressed = null;
IsButtonReleased = false;

View File

@@ -13,10 +13,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -138,7 +138,7 @@ namespace Mono.Terminal {
AddWatch (wakeupPipes [0], Condition.PollIn, ml => {
read (wakeupPipes [0], ignore, (IntPtr)1);
return true;
});
});
}
/// <summary>
@@ -192,7 +192,7 @@ namespace Mono.Terminal {
}
}
bool IMainLoopDriver.EventsPending (bool wait)
bool IMainLoopDriver.EventsPending (bool wait)
{
long now = DateTime.UtcNow.Ticks;
@@ -214,10 +214,10 @@ namespace Mono.Terminal {
int ic;
lock (mainLoop.idleHandlers)
ic = mainLoop.idleHandlers.Count;
return n > 0 || mainLoop.timeouts.Count > 0 && ((mainLoop.timeouts.Keys [0] - DateTime.UtcNow.Ticks) < 0) || ic > 0;
return n > 0 || mainLoop.timeouts.Count > 0 && ((mainLoop.timeouts.Keys [0] - DateTime.UtcNow.Ticks) < 0) || ic > 0;
}
void IMainLoopDriver.MainIteration ()
void IMainLoopDriver.MainIteration ()
{
if (pollmap != null) {
foreach (var p in pollmap) {
@@ -231,7 +231,7 @@ namespace Mono.Terminal {
if (!watch.Callback (this.mainLoop))
descriptorWatchers.Remove (p.fd);
}
}
}
}
}
@@ -247,7 +247,7 @@ namespace Mono.Terminal {
public Action<ConsoleKeyInfo> WindowsKeyPressed;
MainLoop mainLoop;
public NetMainLoop ()
public NetMainLoop ()
{
}
@@ -258,16 +258,16 @@ namespace Mono.Terminal {
windowsKeyResult = Console.ReadKey (true);
keyReady.Set ();
}
}
}
void IMainLoopDriver.Setup (MainLoop mainLoop)
{
this.mainLoop = mainLoop;
Thread readThread = new Thread (WindowsKeyReader);
readThread.Start ();
readThread.Start ();
}
void IMainLoopDriver.Wakeup ()
void IMainLoopDriver.Wakeup ()
{
}
@@ -298,7 +298,7 @@ namespace Mono.Terminal {
if (WindowsKeyPressed!= null)
WindowsKeyPressed (windowsKeyResult.Value);
windowsKeyResult = null;
}
}
}
}
@@ -346,7 +346,6 @@ namespace Mono.Terminal {
action ();
return false;
});
driver.Wakeup ();
}
/// <summary>
@@ -373,7 +372,7 @@ namespace Mono.Terminal {
{
timeouts.Add ((DateTime.UtcNow + time).Ticks, timeout);
}
/// <summary>
/// Adds a timeout to the mainloop.
/// </summary>
@@ -440,9 +439,9 @@ namespace Mono.Terminal {
idleHandlers.Add (idle);
}
}
bool running;
/// <summary>
/// Stops the mainloop.
/// </summary>
@@ -458,7 +457,7 @@ namespace Mono.Terminal {
/// <remarks>
/// You can use this method if you want to probe if events are pending.
/// Typically used if you need to flush the input queue while still
/// running some of your own code in your main thread.
/// running some of your own code in your main thread.
/// </remarks>
public bool EventsPending (bool wait = false)
{
@@ -486,7 +485,7 @@ namespace Mono.Terminal {
RunIdle();
}
}
/// <summary>
/// Runs the mainloop.
/// </summary>

View File

@@ -432,7 +432,7 @@ namespace Terminal.Gui {
}
host.handled = false;
bool disabled;
if (me.Flags == MouseFlags.Button1Pressed) {
if (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked) {
disabled = false;
if (me.Y < 1)
return true;
@@ -444,7 +444,8 @@ namespace Terminal.Gui {
if (item != null && !disabled)
Run (barItems.Children [meY].Action);
return true;
} else if (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.ReportMousePosition) {
} else if (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked ||
me.Flags == MouseFlags.ReportMousePosition) {
disabled = false;
if (me.Y < 1)
return true;
@@ -984,13 +985,14 @@ namespace Terminal.Gui {
}
handled = false;
if (me.Flags == MouseFlags.Button1Pressed ||
if (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked ||
(me.Flags == MouseFlags.ReportMousePosition && selected > -1)) {
int pos = 1;
int cx = me.X;
for (int i = 0; i < Menus.Length; i++) {
if (cx > pos && me.X < pos + 1 + Menus [i].TitleLength) {
if (selected == i && me.Flags == MouseFlags.Button1Pressed && !isMenuClosed) {
if (selected == i && (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked) &&
!isMenuClosed) {
Application.UngrabMouse ();
if (Menus [i].IsTopLevel) {
var menu = new Menu (this, i, 0, Menus [i]);
@@ -998,7 +1000,8 @@ namespace Terminal.Gui {
} else {
CloseMenu ();
}
} else if (me.Flags == MouseFlags.Button1Pressed && isMenuClosed) {
} else if ((me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked) &&
isMenuClosed) {
if (Menus [i].IsTopLevel) {
var menu = new Menu (this, i, 0, Menus [i]);
menu.Run (Menus [i].Action);
@@ -1033,7 +1036,8 @@ namespace Terminal.Gui {
Application.GrabMouse (me.View);
me.View.MouseEvent (me);
}
} else if (!(me.View is MenuBar || me.View is Menu) && me.Flags.HasFlag (MouseFlags.Button1Pressed)) {
} else if (!(me.View is MenuBar || me.View is Menu) && (me.Flags.HasFlag (MouseFlags.Button1Pressed) ||
me.Flags == MouseFlags.Button1DoubleClicked)) {
Application.UngrabMouse ();
CloseAllMenus ();
handled = false;
@@ -1042,22 +1046,23 @@ namespace Terminal.Gui {
handled = false;
return false;
}
} else if (isMenuClosed && me.Flags.HasFlag (MouseFlags.Button1Pressed)) {
} else if (isMenuClosed && (me.Flags.HasFlag (MouseFlags.Button1Pressed) || me.Flags == MouseFlags.Button1DoubleClicked)) {
Application.GrabMouse (current);
} else {
handled = false;
return false;
}
//if (me.View != this && me.Flags != MouseFlags.Button1Pressed)
//if (me.View != this && (me.Flags != MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked))
// return true;
//else if (me.View != this && me.Flags == MouseFlags.Button1Pressed) {
//else if (me.View != this && (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked)) {
// Application.UngrabMouse ();
// host.CloseAllMenus ();
// return true;
//}
//if (!(me.View is MenuBar) && !(me.View is Menu) && me.Flags != MouseFlags.Button1Pressed)
//if (!(me.View is MenuBar) && !(me.View is Menu) && (me.Flags != MouseFlags.Button1Pressed ||
// me.Flags != MouseFlags.Button1DoubleClicked))
// return false;
//if (Application.mouseGrabView != null) {
@@ -1066,11 +1071,12 @@ namespace Terminal.Gui {
// me.Y -= me.OfY;
// me.View.MouseEvent (me);
// return true;
// } else if (!(me.View is MenuBar || me.View is Menu) && me.Flags == MouseFlags.Button1Pressed) {
// } else if (!(me.View is MenuBar || me.View is Menu) && (me.Flags == MouseFlags.Button1Pressed ||
// me.Flags == MouseFlags.Button1DoubleClicked)) {
// Application.UngrabMouse ();
// CloseAllMenus ();
// }
//} else if (!isMenuClosed && selected == -1 && me.Flags == MouseFlags.Button1Pressed) {
//} else if (!isMenuClosed && selected == -1 && (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked)) {
// Application.GrabMouse (this);
// return true;
//}
@@ -1082,7 +1088,7 @@ namespace Terminal.Gui {
// } else if (me.View != current && me.View is MenuBar && me.View is Menu) {
// Application.UngrabMouse ();
// Application.GrabMouse (me.View);
// } else if (me.Flags == MouseFlags.Button1Pressed) {
// } else if (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked) {
// Application.UngrabMouse ();
// CloseMenu ();
// }

View File

@@ -85,7 +85,7 @@ namespace Terminal.Gui {
{
if (Application.mouseGrabView != null && Application.mouseGrabView == this)
Application.UngrabMouse ();
if (SelectedLength != 0)
if (SelectedLength != 0 && !(Application.mouseGrabView is MenuBar))
ClearAllSelection ();
}