Skip to content

Commit

Permalink
Fixes #1475. Selection ending with a white space error. (#1478)
Browse files Browse the repository at this point in the history
* Fixes #1475. Selection ending with a white space error.

* Prevents the mouse  double click processing twice.

* Removing unnecessary variable.

* Sets ScrollViewBar CanFocus to false to ensure the host always focused.

* Only navigates through TabView if winDialog is not null and ensures TextView being focused.

* Fixes both dynamic menu and status bar broken scenarios.

* Fix a bug where the subviews oldEnabled can be overridden, even the superview Enable property hasn't changed.

* Fixes CanFocus when set to false and HasFocus is true.

* Fixes the broken TextView DesiredCursorVisibility.

* Prevents TextField being focused by mouse if CanFocus is false.

* Fixes the CanFocus on content views.

* Fixes #1470. Not all WindowsConsole.InputRecord are caught in WindowsDriver.

* Changing the input for a Queue object.

* Suppress warnings.

* Fixed yet the visibility cursor and adding more unit tests.

* Suppressing more warnings.
  • Loading branch information
BDisp committed Oct 25, 2021
1 parent 2ef4edd commit 58e7698
Show file tree
Hide file tree
Showing 12 changed files with 587 additions and 166 deletions.
127 changes: 64 additions & 63 deletions Terminal.Gui/ConsoleDrivers/WindowsDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ void ProcessInput (WindowsConsole.InputRecord inputEvent)
bool isButtonReleased = false;
bool isButtonDoubleClicked = false;
Point point;
int buttonPressedCount;
//int buttonPressedCount;
bool isOneFingerDoubleClicked = false;
bool processButtonClick;

Expand Down Expand Up @@ -937,66 +937,67 @@ MouseEvent ToDriverMouse (WindowsConsole.MouseEventRecord mouseEvent)
Y = mouseEvent.MousePosition.Y
};

if (!isButtonPressed && buttonPressedCount < 2
&& mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved
&& (mouseEvent.ButtonState == WindowsConsole.ButtonState.Button1Pressed
|| mouseEvent.ButtonState == WindowsConsole.ButtonState.Button2Pressed
|| mouseEvent.ButtonState == WindowsConsole.ButtonState.Button3Pressed)) {
//if (!isButtonPressed && buttonPressedCount < 2
// && mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved
// && (mouseEvent.ButtonState == WindowsConsole.ButtonState.Button1Pressed
// || mouseEvent.ButtonState == WindowsConsole.ButtonState.Button2Pressed
// || mouseEvent.ButtonState == WindowsConsole.ButtonState.Button3Pressed)) {

lastMouseButtonPressed = mouseEvent.ButtonState;
buttonPressedCount++;
} else if (!isButtonPressed && buttonPressedCount > 0 && mouseEvent.ButtonState == 0
&& mouseEvent.EventFlags == 0) {
// lastMouseButtonPressed = mouseEvent.ButtonState;
// buttonPressedCount++;
//} else if (!isButtonPressed && buttonPressedCount > 0 && mouseEvent.ButtonState == 0
// && mouseEvent.EventFlags == 0) {

buttonPressedCount++;
}
// buttonPressedCount++;
//}
//System.Diagnostics.Debug.WriteLine ($"isButtonPressed: {isButtonPressed};buttonPressedCount: {buttonPressedCount};lastMouseButtonPressed: {lastMouseButtonPressed}");
//System.Diagnostics.Debug.WriteLine ($"isOneFingerDoubleClicked: {isOneFingerDoubleClicked}");

if (buttonPressedCount == 1 && lastMouseButtonPressed != null
&& lastMouseButtonPressed == WindowsConsole.ButtonState.Button1Pressed
|| lastMouseButtonPressed == WindowsConsole.ButtonState.Button2Pressed
|| lastMouseButtonPressed == WindowsConsole.ButtonState.Button3Pressed) {

switch (lastMouseButtonPressed) {
case WindowsConsole.ButtonState.Button1Pressed:
mouseFlag = MouseFlags.Button1DoubleClicked;
break;

case WindowsConsole.ButtonState.Button2Pressed:
mouseFlag = MouseFlags.Button2DoubleClicked;
break;

case WindowsConsole.ButtonState.Button3Pressed:
mouseFlag = MouseFlags.Button3DoubleClicked;
break;
}
isOneFingerDoubleClicked = true;

} else if (buttonPressedCount == 3 && lastMouseButtonPressed != null && isOneFingerDoubleClicked
&& lastMouseButtonPressed == WindowsConsole.ButtonState.Button1Pressed
|| lastMouseButtonPressed == WindowsConsole.ButtonState.Button2Pressed
|| lastMouseButtonPressed == WindowsConsole.ButtonState.Button3Pressed) {
//if (buttonPressedCount == 1 && lastMouseButtonPressed != null && p == point
// && lastMouseButtonPressed == WindowsConsole.ButtonState.Button1Pressed
// || lastMouseButtonPressed == WindowsConsole.ButtonState.Button2Pressed
// || lastMouseButtonPressed == WindowsConsole.ButtonState.Button3Pressed) {

// switch (lastMouseButtonPressed) {
// case WindowsConsole.ButtonState.Button1Pressed:
// mouseFlag = MouseFlags.Button1DoubleClicked;
// break;

// case WindowsConsole.ButtonState.Button2Pressed:
// mouseFlag = MouseFlags.Button2DoubleClicked;
// break;

// case WindowsConsole.ButtonState.Button3Pressed:
// mouseFlag = MouseFlags.Button3DoubleClicked;
// break;
// }
// isOneFingerDoubleClicked = true;

//} else if (buttonPressedCount == 3 && lastMouseButtonPressed != null && isOneFingerDoubleClicked && p == point
// && lastMouseButtonPressed == WindowsConsole.ButtonState.Button1Pressed
// || lastMouseButtonPressed == WindowsConsole.ButtonState.Button2Pressed
// || lastMouseButtonPressed == WindowsConsole.ButtonState.Button3Pressed) {

// switch (lastMouseButtonPressed) {
// case WindowsConsole.ButtonState.Button1Pressed:
// mouseFlag = MouseFlags.Button1TripleClicked;
// break;

// case WindowsConsole.ButtonState.Button2Pressed:
// mouseFlag = MouseFlags.Button2TripleClicked;
// break;

// case WindowsConsole.ButtonState.Button3Pressed:
// mouseFlag = MouseFlags.Button3TripleClicked;
// break;
// }
// buttonPressedCount = 0;
// lastMouseButtonPressed = null;
// isOneFingerDoubleClicked = false;
// isButtonReleased = false;

switch (lastMouseButtonPressed) {
case WindowsConsole.ButtonState.Button1Pressed:
mouseFlag = MouseFlags.Button1TripleClicked;
break;

case WindowsConsole.ButtonState.Button2Pressed:
mouseFlag = MouseFlags.Button2TripleClicked;
break;

case WindowsConsole.ButtonState.Button3Pressed:
mouseFlag = MouseFlags.Button3TripleClicked;
break;
}
buttonPressedCount = 0;
lastMouseButtonPressed = null;
isOneFingerDoubleClicked = false;
isButtonReleased = false;

} else if ((mouseEvent.ButtonState != 0 && mouseEvent.EventFlags == 0 && lastMouseButtonPressed == null && !isButtonDoubleClicked) ||
//}
if ((mouseEvent.ButtonState != 0 && mouseEvent.EventFlags == 0 && lastMouseButtonPressed == null && !isButtonDoubleClicked) ||
(lastMouseButtonPressed == null && mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved &&
mouseEvent.ButtonState != 0 && !isButtonReleased && !isButtonDoubleClicked)) {
switch (mouseEvent.ButtonState) {
Expand Down Expand Up @@ -1173,7 +1174,7 @@ async Task ProcessButtonDoubleClickedAsync ()
await Task.Delay (300);
isButtonDoubleClicked = false;
isOneFingerDoubleClicked = false;
buttonPressedCount = 0;
//buttonPressedCount = 0;
}

async Task ProcessContinuousButtonPressedAsync (WindowsConsole.MouseEventRecord mouseEvent, MouseFlags mouseFlag)
Expand Down Expand Up @@ -1732,7 +1733,7 @@ internal class WindowsMainLoop : IMainLoopDriver {
CancellationTokenSource tokenSource = new CancellationTokenSource ();

// The records that we keep fetching
WindowsConsole.InputRecord [] result = new WindowsConsole.InputRecord [1];
Queue<WindowsConsole.InputRecord []> resultQueue = new Queue<WindowsConsole.InputRecord []> ();

/// <summary>
/// Invoked when a Key is pressed or released.
Expand Down Expand Up @@ -1763,7 +1764,9 @@ void WindowsInputHandler ()
waitForProbe.Wait ();
waitForProbe.Reset ();

result = winConsole.ReadConsoleInput ();
if (resultQueue?.Count == 0) {
resultQueue.Enqueue (winConsole.ReadConsoleInput ());
}

eventReady.Set ();
}
Expand Down Expand Up @@ -1807,7 +1810,6 @@ bool IMainLoopDriver.EventsPending (bool wait)
return true;
}

result = null;
waitForProbe.Set ();
winChange.Set ();

Expand All @@ -1822,7 +1824,7 @@ bool IMainLoopDriver.EventsPending (bool wait)
}

if (!tokenSource.IsCancellationRequested) {
return result != null || CheckTimers (wait, out _) || winChanged;
return resultQueue.Count > 0 || CheckTimers (wait, out _) || winChanged;
}

tokenSource.Dispose ();
Expand Down Expand Up @@ -1855,9 +1857,8 @@ bool CheckTimers (bool wait, out int waitTimeout)

void IMainLoopDriver.MainIteration ()
{
if (result != null) {
var inputEvent = result [0];
result = null;
while (resultQueue.Count > 0) {
var inputEvent = resultQueue.Dequeue()[0];
ProcessInput?.Invoke (inputEvent);
}
if (winChanged) {
Expand Down
9 changes: 9 additions & 0 deletions Terminal.Gui/Core/Border.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,15 @@ public override void Redraw (Rect bounds)
SuperView.SetNeedsDisplay ();
}
}

/// <inheritdoc/>
public override void OnCanFocusChanged ()
{
if (Border.Child != null) {
Border.Child.CanFocus = CanFocus;
}
base.OnCanFocusChanged ();
}
}

private class ChildContentView : View {
Expand Down
98 changes: 60 additions & 38 deletions Terminal.Gui/Core/View.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,36 +344,45 @@ public override bool CanFocus {
TabIndex = SuperView != null ? SuperView.tabIndexes.IndexOf (this) : -1;
}
TabStop = value;
}
if (subviews != null && IsInitialized) {
foreach (var view in subviews) {
if (view.CanFocus != value) {
if (!value) {
view.oldCanFocus = view.CanFocus;
view.oldTabIndex = view.tabIndex;
view.CanFocus = value;
view.tabIndex = -1;

if (!value && Application.Top?.Focused == this) {
Application.Top.focused = null;
}
if (!value && HasFocus) {
SetHasFocus (false, this);
EnsureFocus ();
if (Focused == null) {
if (Application.Top.Focused == null) {
Application.Top.FocusNext ();
} else {
if (addingView) {
view.addingView = true;
}
view.CanFocus = view.oldCanFocus;
view.tabIndex = view.oldTabIndex;
view.addingView = false;
var v = Application.Top.GetMostFocused (Application.Top.Focused);
v.SetHasFocus (true, null, true);
}
Application.EnsuresTopOnFront ();
}
}
}
if (!value && HasFocus) {
SetHasFocus (false, this);
EnsureFocus ();
if (Focused == null) {
Application.Top.FocusNext ();
Application.EnsuresTopOnFront ();
if (subviews != null && IsInitialized) {
foreach (var view in subviews) {
if (view.CanFocus != value) {
if (!value) {
view.oldCanFocus = view.CanFocus;
view.oldTabIndex = view.tabIndex;
view.CanFocus = value;
view.tabIndex = -1;
} else {
if (addingView) {
view.addingView = true;
}
view.CanFocus = view.oldCanFocus;
view.tabIndex = view.oldTabIndex;
view.addingView = false;
}
}
}
}
OnCanFocusChanged ();
SetNeedsDisplay ();
}
OnCanFocusChanged ();
SetNeedsDisplay ();
}
}

Expand Down Expand Up @@ -1195,9 +1204,9 @@ public override bool HasFocus {
}
}

void SetHasFocus (bool value, View view)
void SetHasFocus (bool value, View view, bool force = false)
{
if (hasFocus != value) {
if (hasFocus != value || force) {
hasFocus = value;
if (value) {
OnEnter (view);
Expand Down Expand Up @@ -1789,6 +1798,19 @@ public bool FocusNext ()
return false;
}

View GetMostFocused (View view)
{
if (view == null) {
return view;
}

if (view.focused != null) {
return GetMostFocused (view.focused);
} else {
return view;
}
}

/// <summary>
/// Sets the View's <see cref="Frame"/> to the relative coordinates if its container, given the <see cref="Frame"/> for its container.
/// </summary>
Expand Down Expand Up @@ -1875,19 +1897,19 @@ List<View> TopologicalSort (HashSet<View> nodes, HashSet<(View From, View To)> e
}
}

if (edges.Any ()) {
var (from, to) = edges.First ();
if (from != Application.Top) {
if (!ReferenceEquals (from, to)) {
throw new InvalidOperationException ($"TopologicalSort (for Pos/Dim) cannot find {from} linked with {to}. Did you forget to add it to {this}?");
} else {
throw new InvalidOperationException ("TopologicalSort encountered a recursive cycle in the relative Pos/Dim in the views of " + this);
}
}
}
if (edges.Any ()) {
var (from, to) = edges.First ();
if (from != Application.Top) {
if (!ReferenceEquals (from, to)) {
throw new InvalidOperationException ($"TopologicalSort (for Pos/Dim) cannot find {from} linked with {to}. Did you forget to add it to {this}?");
} else {
throw new InvalidOperationException ("TopologicalSort encountered a recursive cycle in the relative Pos/Dim in the views of " + this);
}
}
}

// return L (a topologically sorted order)
return result;
// return L (a topologically sorted order)
return result;
}

/// <summary>
Expand Down
9 changes: 9 additions & 0 deletions Terminal.Gui/Core/Window.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,15 @@ public override void Redraw (Rect bounds)
}
}

/// <inheritdoc/>
public override void OnCanFocusChanged ()
{
if (contentView != null) {
contentView.CanFocus = CanFocus;
}
base.OnCanFocusChanged ();
}

/// <summary>
/// The text displayed by the <see cref="Label"/>.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions Terminal.Gui/Views/FrameView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -268,5 +268,14 @@ public override bool OnEnter (View view)

return base.OnEnter (view);
}

/// <inheritdoc/>
public override void OnCanFocusChanged ()
{
if (contentView != null) {
contentView.CanFocus = CanFocus;
}
base.OnCanFocusChanged ();
}
}
}
Loading

0 comments on commit 58e7698

Please sign in to comment.