فهرست منبع

Fixes #1402. Only WindowsDriver supports horizontal scroll. (#1403)

* Fixes #1402. Only WindowsDriver supports horizontal scroll.

* Fixes ProcessContinuousButtonPressedAsync on all drivers.
BDisp 4 سال پیش
والد
کامیت
b193aaaa56

+ 34 - 32
Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

@@ -248,8 +248,8 @@ namespace Terminal.Gui {
 			}
 		}
 
-		Curses.Event? LastMouseButtonPressed;
-		bool IsButtonPressed;
+		Curses.Event? lastMouseButtonPressed;
+		bool isButtonPressed;
 		bool cancelButtonClicked;
 		bool isReportMousePosition;
 		Point point;
@@ -258,31 +258,31 @@ namespace Terminal.Gui {
 		{
 			MouseFlags mouseFlag = MouseFlags.AllEvents;
 
-			if (LastMouseButtonPressed != null && cev.ButtonState != Curses.Event.ReportMousePosition) {
-				LastMouseButtonPressed = null;
-				IsButtonPressed = false;
+			if (lastMouseButtonPressed != null && cev.ButtonState != Curses.Event.ReportMousePosition) {
+				lastMouseButtonPressed = null;
+				isButtonPressed = false;
 			}
 
 
 			if ((cev.ButtonState == Curses.Event.Button1Clicked || cev.ButtonState == Curses.Event.Button2Clicked ||
 				cev.ButtonState == Curses.Event.Button3Clicked) &&
-				LastMouseButtonPressed == null) {
+				lastMouseButtonPressed == null) {
 
-				IsButtonPressed = false;
+				isButtonPressed = false;
 				mouseFlag = ProcessButtonClickedEvent (cev);
 
 			} else if (((cev.ButtonState == Curses.Event.Button1Pressed || cev.ButtonState == Curses.Event.Button2Pressed ||
-				cev.ButtonState == Curses.Event.Button3Pressed) && LastMouseButtonPressed == null) ||
-				IsButtonPressed && cev.ButtonState == Curses.Event.ReportMousePosition) {
+				cev.ButtonState == Curses.Event.Button3Pressed) && lastMouseButtonPressed == null) ||
+				isButtonPressed && cev.ButtonState == Curses.Event.ReportMousePosition) {
 
 				mouseFlag = MapCursesButton (cev.ButtonState);
 				if (cev.ButtonState != Curses.Event.ReportMousePosition)
-					LastMouseButtonPressed = cev.ButtonState;
-				IsButtonPressed = true;
+					lastMouseButtonPressed = cev.ButtonState;
+				isButtonPressed = true;
 				isReportMousePosition = false;
 
 				if (cev.ButtonState == Curses.Event.ReportMousePosition) {
-					mouseFlag = MapCursesButton ((Curses.Event)LastMouseButtonPressed) | MouseFlags.ReportMousePosition;
+					mouseFlag = MapCursesButton ((Curses.Event)lastMouseButtonPressed) | MouseFlags.ReportMousePosition;
 					point = new Point ();
 					cancelButtonClicked = true;
 				} else {
@@ -293,7 +293,10 @@ namespace Terminal.Gui {
 				}
 
 				if ((mouseFlag & MouseFlags.ReportMousePosition) == 0) {
-					ProcessContinuousButtonPressedAsync (cev, mouseFlag).ConfigureAwait (false);
+					Application.MainLoop.AddIdle (() => {
+						Task.Run (async () => await ProcessContinuousButtonPressedAsync (cev, mouseFlag));
+						return false;
+					});
 				}
 
 
@@ -301,7 +304,7 @@ namespace Terminal.Gui {
 				cev.ButtonState == Curses.Event.Button3Released)) {
 
 				mouseFlag = ProcessButtonReleasedEvent (cev);
-				IsButtonPressed = false;
+				isButtonPressed = false;
 
 			} else if (cev.ButtonState == Curses.Event.ButtonWheeledUp) {
 
@@ -320,9 +323,13 @@ namespace Terminal.Gui {
 				mouseFlag = MouseFlags.WheeledRight;
 
 			} else if (cev.ButtonState == Curses.Event.ReportMousePosition) {
-
-				mouseFlag = MouseFlags.ReportMousePosition;
-				isReportMousePosition = true;
+				if (cev.X != point.X || cev.Y != point.Y) {
+					mouseFlag = MouseFlags.ReportMousePosition;
+					isReportMousePosition = true;
+					point = new Point ();
+				} else {
+					mouseFlag = 0;
+				}
 
 			} else {
 				mouseFlag = 0;
@@ -336,11 +343,6 @@ namespace Terminal.Gui {
 
 			mouseFlag = SetControlKeyStates (cev, mouseFlag);
 
-			point = new Point () {
-				X = cev.X,
-				Y = cev.Y
-			};
-
 			return new MouseEvent () {
 				X = cev.X,
 				Y = cev.Y,
@@ -351,24 +353,24 @@ namespace Terminal.Gui {
 
 		MouseFlags ProcessButtonClickedEvent (Curses.MouseEvent cev)
 		{
-			LastMouseButtonPressed = cev.ButtonState;
+			lastMouseButtonPressed = cev.ButtonState;
 			var mf = GetButtonState (cev, true);
 			mouseHandler (ProcessButtonState (cev, mf));
-			if (LastMouseButtonPressed != null && LastMouseButtonPressed == cev.ButtonState) {
+			if (lastMouseButtonPressed != null && lastMouseButtonPressed == cev.ButtonState) {
 				mf = GetButtonState (cev, false);
 				mouseHandler (ProcessButtonState (cev, mf));
-				if (LastMouseButtonPressed != null && LastMouseButtonPressed == cev.ButtonState) {
+				if (lastMouseButtonPressed != null && lastMouseButtonPressed == cev.ButtonState) {
 					mf = MapCursesButton (cev.ButtonState);
 				}
 			}
-			LastMouseButtonPressed = null;
+			lastMouseButtonPressed = null;
 			return mf;
 		}
 
 		MouseFlags ProcessButtonReleasedEvent (Curses.MouseEvent cev)
 		{
 			var mf = MapCursesButton (cev.ButtonState);
-			if (!cancelButtonClicked && LastMouseButtonPressed == null && !isReportMousePosition) {
+			if (!cancelButtonClicked && lastMouseButtonPressed == null && !isReportMousePosition) {
 				mouseHandler (ProcessButtonState (cev, mf));
 				mf = GetButtonState (cev);
 			} else if (isReportMousePosition) {
@@ -380,7 +382,8 @@ namespace Terminal.Gui {
 
 		async Task ProcessContinuousButtonPressedAsync (Curses.MouseEvent cev, MouseFlags mouseFlag)
 		{
-			while (IsButtonPressed && LastMouseButtonPressed != null) {
+			await Task.Delay (200);
+			while (isButtonPressed && lastMouseButtonPressed != null) {
 				await Task.Delay (100);
 				var me = new MouseEvent () {
 					X = cev.X,
@@ -391,9 +394,8 @@ namespace Terminal.Gui {
 				var view = Application.wantContinuousButtonPressedView;
 				if (view == null)
 					break;
-				if (IsButtonPressed && LastMouseButtonPressed != null && (mouseFlag & MouseFlags.ReportMousePosition) == 0) {
-					mouseHandler (me);
-					//mainLoop.Driver.Wakeup ();
+				if (isButtonPressed && lastMouseButtonPressed != null && (mouseFlag & MouseFlags.ReportMousePosition) == 0) {
+					Application.MainLoop.Invoke (() => mouseHandler (me));
 				}
 			}
 		}
@@ -435,7 +437,6 @@ namespace Terminal.Gui {
 				mf = MouseFlags.Button3Clicked;
 				break;
 
-
 			}
 			return mf;
 		}
@@ -518,6 +519,7 @@ namespace Terminal.Gui {
 		{
 			int wch;
 			var code = Curses.get_wch (out wch);
+			//System.Diagnostics.Debug.WriteLine ($"code: {code}; wch: {wch}");
 			if (code == Curses.ERR)
 				return;
 

+ 76 - 56
Terminal.Gui/ConsoleDrivers/NetDriver.cs

@@ -302,7 +302,7 @@ namespace Terminal.Gui {
 				for (int i = 0; i < cki.Length; i++) {
 					var ck = cki [i];
 					if (NumberOfCSI > 0 && nCSI - curCSI > NumberOfCSI) {
-						if (cki [i + 1].KeyChar == '\x1b' && previousKChar != '\0') {
+						if (i + 1 < cki.Length && cki [i + 1].KeyChar == '\x1b' && previousKChar != '\0') {
 							curCSI++;
 							previousKChar = '\0';
 						} else {
@@ -506,7 +506,8 @@ namespace Terminal.Gui {
 		bool isButtonDoubleClicked;
 		bool isButtonTripleClicked;
 		bool isProcContBtnPressedRuning;
-		bool isButtonReleased;
+		Point point = new Point ();
+		//bool isButtonReleased;
 
 		void GetMouseEvent (ConsoleKeyInfo [] cki)
 		{
@@ -695,6 +696,7 @@ namespace Terminal.Gui {
 			mouseEvent.Position.X = point.X;
 			mouseEvent.Position.Y = point.Y;
 			mouseEvent.ButtonState = buttonState;
+			//System.Diagnostics.Debug.WriteLine ($"ButtonState: {mouseEvent.ButtonState} X: {mouseEvent.Position.X} Y: {mouseEvent.Position.Y}");
 
 			if ((buttonState & MouseButtonState.Button1Pressed) != 0
 				|| (buttonState & MouseButtonState.Button2Pressed) != 0
@@ -715,7 +717,10 @@ namespace Terminal.Gui {
 			if (isButtonClicked && !isButtonDoubleClicked && lastMouseEvent.Position != default && lastMouseEvent.Position == point
 				&& ((buttonState & MouseButtonState.Button1Pressed) != 0
 				|| (buttonState & MouseButtonState.Button2Pressed) != 0
-				|| (buttonState & MouseButtonState.Button3Pressed) != 0)) {
+				|| (buttonState & MouseButtonState.Button3Pressed) != 0
+				|| (buttonState & MouseButtonState.Button1Released) != 0
+				|| (buttonState & MouseButtonState.Button2Released) != 0
+				|| (buttonState & MouseButtonState.Button3Released) != 0)) {
 				isButtonDoubleClicked = true;
 				ProcessButtonDoubleClicked (mouseEvent);
 				Application.MainLoop.AddIdle (() => {
@@ -731,22 +736,25 @@ namespace Terminal.Gui {
 			if (isButtonDoubleClicked && lastMouseEvent.Position != default && lastMouseEvent.Position == point
 				&& ((buttonState & MouseButtonState.Button1Pressed) != 0
 				|| (buttonState & MouseButtonState.Button2Pressed) != 0
-				|| (buttonState & MouseButtonState.Button3Pressed) != 0)) {
+				|| (buttonState & MouseButtonState.Button3Pressed) != 0
+				|| (buttonState & MouseButtonState.Button1Released) != 0
+				|| (buttonState & MouseButtonState.Button2Released) != 0
+				|| (buttonState & MouseButtonState.Button3Released) != 0)) {
 				isButtonTripleClicked = true;
 				ProcessButtonTripleClicked (mouseEvent);
 				inputReady.Set ();
 				return;
 			}
 
-			if (!isButtonPressed && !isButtonClicked && !isButtonDoubleClicked && !isButtonTripleClicked
-				&& !isButtonReleased
-				&& ((buttonState & MouseButtonState.Button1Released) == 0
-				&& (buttonState & MouseButtonState.Button2Released) == 0
-				&& (buttonState & MouseButtonState.Button3Released) == 0)) {
-				ProcessButtonReleased (lastMouseEvent);
-				inputReady.Set ();
-				return;
-			}
+			//if (!isButtonPressed && !isButtonClicked && !isButtonDoubleClicked && !isButtonTripleClicked
+			//	&& !isButtonReleased && lastMouseEvent.ButtonState != 0
+			//	&& ((buttonState & MouseButtonState.Button1Released) == 0
+			//	&& (buttonState & MouseButtonState.Button2Released) == 0
+			//	&& (buttonState & MouseButtonState.Button3Released) == 0)) {
+			//	ProcessButtonReleased (lastMouseEvent);
+			//	inputReady.Set ();
+			//	return;
+			//}
 
 			inputResultQueue.Enqueue (new InputResult () {
 				EventType = EventType.Mouse,
@@ -773,11 +781,21 @@ namespace Terminal.Gui {
 
 			lastMouseEvent = mouseEvent;
 			if (isButtonPressed && !isButtonClicked && !isButtonDoubleClicked && !isButtonTripleClicked && !isProcContBtnPressedRuning) {
-				isButtonReleased = false;
-				Application.MainLoop.AddIdle (() => {
-					ProcessContinuousButtonPressedAsync ().ConfigureAwait (false);
-					return false;
-				});
+				//isButtonReleased = false;
+				if ((buttonState & MouseButtonState.ReportMousePosition) != 0) {
+					point = new Point ();
+				} else {
+					point = new Point () {
+						X = mouseEvent.Position.X,
+						Y = mouseEvent.Position.Y
+					};
+				}
+				if ((buttonState & MouseButtonState.ReportMousePosition) == 0) {
+					Application.MainLoop.AddIdle (() => {
+						Task.Run (async () => await ProcessContinuousButtonPressedAsync (mouseEvent));
+						return false;
+					});
+				}
 			}
 
 			inputReady.Set ();
@@ -799,7 +817,7 @@ namespace Terminal.Gui {
 				me.ButtonState &= ~MouseButtonState.Button3Released;
 				me.ButtonState |= MouseButtonState.Button3Clicked;
 			}
-			isButtonReleased = true;
+			//isButtonReleased = true;
 
 			inputResultQueue.Enqueue (new InputResult () {
 				EventType = EventType.Mouse,
@@ -823,7 +841,7 @@ namespace Terminal.Gui {
 				me.ButtonState &= ~MouseButtonState.Button3Pressed;
 				me.ButtonState |= MouseButtonState.Button3DoubleClicked;
 			}
-			isButtonReleased = true;
+			//isButtonReleased = true;
 
 			inputResultQueue.Enqueue (new InputResult () {
 				EventType = EventType.Mouse,
@@ -847,7 +865,7 @@ namespace Terminal.Gui {
 				me.ButtonState &= ~MouseButtonState.Button3Pressed;
 				me.ButtonState |= MouseButtonState.Button3TripleClicked;
 			}
-			isButtonReleased = true;
+			//isButtonReleased = true;
 
 			inputResultQueue.Enqueue (new InputResult () {
 				EventType = EventType.Mouse,
@@ -855,54 +873,56 @@ namespace Terminal.Gui {
 			});
 		}
 
-		async Task ProcessContinuousButtonPressedAsync ()
+		async Task ProcessContinuousButtonPressedAsync (MouseEvent mouseEvent)
 		{
 			isProcContBtnPressedRuning = true;
-			Point point = new Point ();
+			await Task.Delay (200);
 			while (isButtonPressed) {
-				await Task.Delay (200);
+				await Task.Delay (100);
+				var me = new MouseEvent () {
+					Position = new Point (mouseEvent.Position.X, mouseEvent.Position.Y),
+					ButtonState=mouseEvent.ButtonState
+				};
 				var view = Application.wantContinuousButtonPressedView;
-				if (isButtonPressed && !Console.KeyAvailable
-					&& !isButtonClicked && !isButtonDoubleClicked && !isButtonTripleClicked
-					&& (view != null || view == null && lastMouseEvent.Position != point)) {
-					point = lastMouseEvent.Position;
+				if (view == null) {
+					break;
+				}
+				if (isButtonPressed && (mouseEvent.ButtonState & MouseButtonState.ReportMousePosition) == 0) {
 					inputResultQueue.Enqueue (new InputResult () {
 						EventType = EventType.Mouse,
-						MouseEvent = lastMouseEvent
+						MouseEvent = me
 					});
 					inputReady.Set ();
-				} else {
-					break;
 				}
 			}
 			isProcContBtnPressedRuning = false;
 			//isButtonPressed = false;
 		}
 
-		void ProcessButtonReleased (MouseEvent mouseEvent)
-		{
-			var me = new MouseEvent () {
-				Position = mouseEvent.Position,
-				ButtonState = mouseEvent.ButtonState
-			};
-			if ((mouseEvent.ButtonState & MouseButtonState.Button1Pressed) != 0) {
-				me.ButtonState &= ~(MouseButtonState.Button1Pressed | MouseButtonState.ReportMousePosition);
-				me.ButtonState |= MouseButtonState.Button1Released;
-			} else if ((mouseEvent.ButtonState & MouseButtonState.Button2Pressed) != 0) {
-				me.ButtonState &= ~(MouseButtonState.Button2Pressed | MouseButtonState.ReportMousePosition);
-				me.ButtonState |= MouseButtonState.Button2Released;
-			} else if ((mouseEvent.ButtonState & MouseButtonState.Button3Pressed) != 0) {
-				me.ButtonState &= ~(MouseButtonState.Button3Pressed | MouseButtonState.ReportMousePosition);
-				me.ButtonState |= MouseButtonState.Button3Released;
-			}
-			isButtonReleased = true;
-			lastMouseEvent = me;
-
-			inputResultQueue.Enqueue (new InputResult () {
-				EventType = EventType.Mouse,
-				MouseEvent = me
-			});
-		}
+		//void ProcessButtonReleased (MouseEvent mouseEvent)
+		//{
+		//	var me = new MouseEvent () {
+		//		Position = mouseEvent.Position,
+		//		ButtonState = mouseEvent.ButtonState
+		//	};
+		//	if ((mouseEvent.ButtonState & MouseButtonState.Button1Pressed) != 0) {
+		//		me.ButtonState &= ~(MouseButtonState.Button1Pressed | MouseButtonState.ReportMousePosition);
+		//		me.ButtonState |= MouseButtonState.Button1Released;
+		//	} else if ((mouseEvent.ButtonState & MouseButtonState.Button2Pressed) != 0) {
+		//		me.ButtonState &= ~(MouseButtonState.Button2Pressed | MouseButtonState.ReportMousePosition);
+		//		me.ButtonState |= MouseButtonState.Button2Released;
+		//	} else if ((mouseEvent.ButtonState & MouseButtonState.Button3Pressed) != 0) {
+		//		me.ButtonState &= ~(MouseButtonState.Button3Pressed | MouseButtonState.ReportMousePosition);
+		//		me.ButtonState |= MouseButtonState.Button3Released;
+		//	}
+		//	isButtonReleased = true;
+		//	lastMouseEvent = me;
+
+		//	inputResultQueue.Enqueue (new InputResult () {
+		//		EventType = EventType.Mouse,
+		//		MouseEvent = me
+		//	});
+		//}
 
 		ConsoleModifiers GetConsoleModifiers (uint keyChar)
 		{
@@ -1104,7 +1124,7 @@ namespace Terminal.Gui {
 			} else {
 				if (CursesDriver.Is_WSL_Platform ()) {
 					Clipboard = new WSLClipboard ();
-				}else{
+				} else {
 					Clipboard = new CursesClipboard ();
 				}
 			}

+ 54 - 44
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -240,9 +240,7 @@ namespace Terminal.Gui {
 			Button2Pressed = 4,
 			Button3Pressed = 8,
 			Button4Pressed = 16,
-			RightmostButtonPressed = 2,
-			WheeledUp = unchecked((int)0x780000),
-			WheeledDown = unchecked((int)0xFF880000),
+			RightmostButtonPressed = 2
 		}
 
 		[Flags]
@@ -771,7 +769,7 @@ namespace Terminal.Gui {
 
 			case WindowsConsole.EventType.Mouse:
 				mouseHandler (ToDriverMouse (inputEvent.MouseEvent));
-				if (IsButtonReleased)
+				if (isButtonReleased)
 					mouseHandler (ToDriverMouse (inputEvent.MouseEvent));
 				break;
 
@@ -788,19 +786,19 @@ namespace Terminal.Gui {
 			}
 		}
 
-		WindowsConsole.ButtonState? LastMouseButtonPressed = null;
-		bool IsButtonPressed = false;
-		bool IsButtonReleased = false;
-		bool IsButtonDoubleClicked = false;
+		WindowsConsole.ButtonState? lastMouseButtonPressed = null;
+		bool isButtonPressed = false;
+		bool isButtonReleased = false;
+		bool isButtonDoubleClicked = false;
 		Point point;
 
 		MouseEvent ToDriverMouse (WindowsConsole.MouseEventRecord mouseEvent)
 		{
 			MouseFlags mouseFlag = MouseFlags.AllEvents;
 
-			if (IsButtonDoubleClicked) {
+			if (isButtonDoubleClicked) {
 				Application.MainLoop.AddIdle (() => {
-					ProcessButtonDoubleClickedAsync ().ConfigureAwait (false);
+					Task.Run (async () => await ProcessButtonDoubleClickedAsync ());
 					return false;
 				});
 			}
@@ -810,10 +808,10 @@ namespace Terminal.Gui {
 			// be fired with it's bit set to 0. So when the button is up ButtonState will be 0.
 			// To map to the correct driver events we save the last pressed mouse button so we can
 			// map to the correct clicked event.
-			if ((LastMouseButtonPressed != null || IsButtonReleased) && mouseEvent.ButtonState != 0) {
-				LastMouseButtonPressed = null;
-				IsButtonPressed = false;
-				IsButtonReleased = false;
+			if ((lastMouseButtonPressed != null || isButtonReleased) && mouseEvent.ButtonState != 0) {
+				lastMouseButtonPressed = null;
+				isButtonPressed = false;
+				isButtonReleased = false;
 			}
 
 			var p = new Point () {
@@ -821,9 +819,9 @@ namespace Terminal.Gui {
 				Y = mouseEvent.MousePosition.Y
 			};
 
-			if ((mouseEvent.ButtonState != 0 && mouseEvent.EventFlags == 0 && LastMouseButtonPressed == null && !IsButtonDoubleClicked) ||
+			if ((mouseEvent.ButtonState != 0 && mouseEvent.EventFlags == 0 && lastMouseButtonPressed == null && !isButtonDoubleClicked) ||
 				(mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved &&
-				mouseEvent.ButtonState != 0 && !IsButtonReleased && !IsButtonDoubleClicked)) {
+				mouseEvent.ButtonState != 0 && !isButtonReleased && !isButtonDoubleClicked)) {
 				switch (mouseEvent.ButtonState) {
 				case WindowsConsole.ButtonState.Button1Pressed:
 					mouseFlag = MouseFlags.Button1Pressed;
@@ -841,26 +839,27 @@ namespace Terminal.Gui {
 				if (mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved) {
 					mouseFlag |= MouseFlags.ReportMousePosition;
 					point = new Point ();
-					IsButtonReleased = false;
+					isButtonReleased = false;
 				} else {
 					point = new Point () {
 						X = mouseEvent.MousePosition.X,
 						Y = mouseEvent.MousePosition.Y
 					};
 				}
-				LastMouseButtonPressed = mouseEvent.ButtonState;
-				IsButtonPressed = true;
+				lastMouseButtonPressed = mouseEvent.ButtonState;
+				isButtonPressed = true;
 
 				if ((mouseFlag & MouseFlags.ReportMousePosition) == 0) {
 					Application.MainLoop.AddIdle (() => {
-						ProcessContinuousButtonPressedAsync (mouseEvent, mouseFlag).ConfigureAwait (false);
+						Task.Run (async () => await ProcessContinuousButtonPressedAsync (mouseEvent, mouseFlag));
 						return false;
 					});
 				}
 
+
 			} else if ((mouseEvent.EventFlags == 0 || mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved) &&
-				LastMouseButtonPressed != null && !IsButtonReleased && !IsButtonDoubleClicked) {
-				switch (LastMouseButtonPressed) {
+				lastMouseButtonPressed != null && !isButtonReleased && !isButtonDoubleClicked) {
+				switch (lastMouseButtonPressed) {
 				case WindowsConsole.ButtonState.Button1Pressed:
 					mouseFlag = MouseFlags.Button1Released;
 					break;
@@ -873,11 +872,11 @@ namespace Terminal.Gui {
 					mouseFlag = MouseFlags.Button3Released;
 					break;
 				}
-				IsButtonPressed = false;
-				IsButtonReleased = true;
+				isButtonPressed = false;
+				isButtonReleased = true;
 			} else if ((mouseEvent.EventFlags == 0 || mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved) &&
-				  IsButtonReleased && p == point) {
-				switch (LastMouseButtonPressed) {
+				  isButtonReleased && p == point) {
+				switch (lastMouseButtonPressed) {
 				case WindowsConsole.ButtonState.Button1Pressed:
 					mouseFlag = MouseFlags.Button1Clicked;
 					break;
@@ -894,8 +893,8 @@ namespace Terminal.Gui {
 					X = mouseEvent.MousePosition.X,
 					Y = mouseEvent.MousePosition.Y
 				};
-				LastMouseButtonPressed = null;
-				IsButtonReleased = false;
+				lastMouseButtonPressed = null;
+				isButtonReleased = false;
 			} else if (mouseEvent.EventFlags.HasFlag (WindowsConsole.EventFlags.DoubleClick)) {
 				switch (mouseEvent.ButtonState) {
 				case WindowsConsole.ButtonState.Button1Pressed:
@@ -910,8 +909,8 @@ namespace Terminal.Gui {
 					mouseFlag = MouseFlags.Button3DoubleClicked;
 					break;
 				}
-				IsButtonDoubleClicked = true;
-			} else if (mouseEvent.EventFlags == 0 && mouseEvent.ButtonState != 0 && IsButtonDoubleClicked) {
+				isButtonDoubleClicked = true;
+			} else if (mouseEvent.EventFlags == 0 && mouseEvent.ButtonState != 0 && isButtonDoubleClicked) {
 				switch (mouseEvent.ButtonState) {
 				case WindowsConsole.ButtonState.Button1Pressed:
 					mouseFlag = MouseFlags.Button1TripleClicked;
@@ -925,26 +924,37 @@ namespace Terminal.Gui {
 					mouseFlag = MouseFlags.Button3TripleClicked;
 					break;
 				}
-				IsButtonDoubleClicked = false;
+				isButtonDoubleClicked = false;
 			} else if (mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseWheeled) {
-				switch (mouseEvent.ButtonState) {
-				case WindowsConsole.ButtonState.WheeledUp:
+				switch ((int)mouseEvent.ButtonState) {
+				case int v when v > 0:
 					mouseFlag = MouseFlags.WheeledUp;
 					break;
 
-				case WindowsConsole.ButtonState.WheeledDown:
+				case int v when v < 0:
 					mouseFlag = MouseFlags.WheeledDown;
 					break;
 				}
 
 			} else if (mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseWheeled &&
 				mouseEvent.ControlKeyState == WindowsConsole.ControlKeyState.ShiftPressed) {
-				switch (mouseEvent.ButtonState) {
-				case WindowsConsole.ButtonState.WheeledUp:
+				switch ((int)mouseEvent.ButtonState) {
+				case int v when v > 0:
+					mouseFlag = MouseFlags.WheeledLeft;
+					break;
+
+				case int v when v < 0:
+					mouseFlag = MouseFlags.WheeledRight;
+					break;
+				}
+
+			} else if (mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseHorizontalWheeled) {
+				switch ((int)mouseEvent.ButtonState) {
+				case int v when v < 0:
 					mouseFlag = MouseFlags.WheeledLeft;
 					break;
 
-				case WindowsConsole.ButtonState.WheeledDown:
+				case int v when v > 0:
 					mouseFlag = MouseFlags.WheeledRight;
 					break;
 				}
@@ -972,12 +982,13 @@ namespace Terminal.Gui {
 		async Task ProcessButtonDoubleClickedAsync ()
 		{
 			await Task.Delay (200);
-			IsButtonDoubleClicked = false;
+			isButtonDoubleClicked = false;
 		}
 
 		async Task ProcessContinuousButtonPressedAsync (WindowsConsole.MouseEventRecord mouseEvent, MouseFlags mouseFlag)
 		{
-			while (IsButtonPressed) {
+			await Task.Delay (200);
+			while (isButtonPressed) {
 				await Task.Delay (100);
 				var me = new MouseEvent () {
 					X = mouseEvent.MousePosition.X,
@@ -989,8 +1000,8 @@ namespace Terminal.Gui {
 				if (view == null) {
 					break;
 				}
-				if (IsButtonPressed && (mouseFlag & MouseFlags.ReportMousePosition) == 0) {
-					mouseHandler (me);
+				if (isButtonPressed && (mouseFlag & MouseFlags.ReportMousePosition) == 0) {
+					Application.MainLoop.Invoke (() => mouseHandler (me));
 				}
 			}
 		}
@@ -1472,8 +1483,7 @@ namespace Terminal.Gui {
 
 			try {
 				ProcessInput (input);
-			} catch (OverflowException) { }
-			finally {
+			} catch (OverflowException) { } finally {
 				keyEvent.bKeyDown = false;
 				input.KeyEvent = keyEvent;
 				ProcessInput (input);
@@ -1526,7 +1536,7 @@ namespace Terminal.Gui {
 		{
 			this.mainLoop = mainLoop;
 			Task.Run (WindowsInputHandler);
-			// Nor working yet.
+			// Not working yet.
 			//Task.Run (CheckWinChange);
 		}