mirror of
https://github.com/Stone-Red-Code/RemSox.git
synced 2026-09-04 00:56:19 +02:00
Add unified input event queue and cursor support for window manager
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
using Cosmos.Kernel.System.Graphics;
|
using Cosmos.Kernel.System.Graphics;
|
||||||
|
using Cosmos.Kernel.System.Keyboard;
|
||||||
|
using Cosmos.Kernel.System.Mouse;
|
||||||
|
|
||||||
using RemSox.Processing;
|
using RemSox.Processing;
|
||||||
|
using RemSox.UI;
|
||||||
using RemSox.UI.GUI.Layout;
|
using RemSox.UI.GUI.Layout;
|
||||||
using RemSox.UI.GUI.Rendering;
|
using RemSox.UI.GUI.Rendering;
|
||||||
using RemSox.UI.GUI.UIEelements.Controls;
|
using RemSox.UI.GUI.UIEelements.Controls;
|
||||||
@@ -115,8 +118,13 @@ internal class DesktopProcess() : Process("Desktop Manager")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Point lastLocalMousePos = Point.Empty;
|
||||||
|
private bool lastLocalLeft, lastLocalRight, lastLocalMiddle;
|
||||||
|
|
||||||
internal override void Tick()
|
internal override void Tick()
|
||||||
{
|
{
|
||||||
|
PollLocalHardware();
|
||||||
|
|
||||||
WindowManager.Update();
|
WindowManager.Update();
|
||||||
|
|
||||||
if (tickCount % 5 == 0)
|
if (tickCount % 5 == 0)
|
||||||
@@ -132,6 +140,55 @@ internal class DesktopProcess() : Process("Desktop Manager")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PollLocalHardware()
|
||||||
|
{
|
||||||
|
Point pos = new(MouseManager.X, MouseManager.Y);
|
||||||
|
|
||||||
|
if (pos != lastLocalMousePos)
|
||||||
|
{
|
||||||
|
WindowManager.EnqueueMouseEvent(MouseEvent.Move(pos.X, pos.Y));
|
||||||
|
lastLocalMousePos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool left = MouseManager.LeftButton;
|
||||||
|
if (left != lastLocalLeft)
|
||||||
|
{
|
||||||
|
WindowManager.EnqueueMouseEvent(left
|
||||||
|
? MouseEvent.ButtonDown(pos.X, pos.Y, MouseButton.Left)
|
||||||
|
: MouseEvent.ButtonUp(pos.X, pos.Y, MouseButton.Left));
|
||||||
|
lastLocalLeft = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool right = MouseManager.RightButton;
|
||||||
|
if (right != lastLocalRight)
|
||||||
|
{
|
||||||
|
WindowManager.EnqueueMouseEvent(right
|
||||||
|
? MouseEvent.ButtonDown(pos.X, pos.Y, MouseButton.Right)
|
||||||
|
: MouseEvent.ButtonUp(pos.X, pos.Y, MouseButton.Right));
|
||||||
|
lastLocalRight = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool middle = MouseManager.MiddleButton;
|
||||||
|
if (middle != lastLocalMiddle)
|
||||||
|
{
|
||||||
|
WindowManager.EnqueueMouseEvent(middle
|
||||||
|
? MouseEvent.ButtonDown(pos.X, pos.Y, MouseButton.Middle)
|
||||||
|
: MouseEvent.ButtonUp(pos.X, pos.Y, MouseButton.Middle));
|
||||||
|
lastLocalMiddle = middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scroll = MouseManager.ScrollDelta;
|
||||||
|
if (scroll != 0)
|
||||||
|
{
|
||||||
|
WindowManager.EnqueueMouseEvent(MouseEvent.Wheel(pos.X, pos.Y, scroll));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (KeyboardManager.TryReadKey(out KeyEvent? keyEvent) && keyEvent is not null)
|
||||||
|
{
|
||||||
|
WindowManager.EnqueueKeyEvent(keyEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateWindowButtons()
|
private void UpdateWindowButtons()
|
||||||
{
|
{
|
||||||
List<Window> allWindows = WindowManager.GetAllWindows()
|
List<Window> allWindows = WindowManager.GetAllWindows()
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
using Cosmos.Kernel.System.Keyboard;
|
||||||
|
|
||||||
using RemSox.Networking;
|
using RemSox.Networking;
|
||||||
using RemSox.Processing;
|
using RemSox.Processing;
|
||||||
|
using RemSox.UI;
|
||||||
using RemSox.UI.GUI.Rendering;
|
using RemSox.UI.GUI.Rendering;
|
||||||
using RemSox.UI.GUI.Windows;
|
using RemSox.UI.GUI.Windows;
|
||||||
|
|
||||||
@@ -13,6 +16,12 @@ internal sealed class RemoteDesktopProcess() : Process("Remote Desktop Server")
|
|||||||
|
|
||||||
public int Port { get; private set; }
|
public int Port { get; private set; }
|
||||||
|
|
||||||
|
// Remote input message record types (JSON-serialized over TCP)
|
||||||
|
private sealed record MouseMoveMsg(int X, int Y);
|
||||||
|
private sealed record MouseButtonMsg(int X, int Y, string Button);
|
||||||
|
private sealed record MouseWheelMsg(int X, int Y, int Delta);
|
||||||
|
private sealed record KeyEventMsg(int Key, string KeyChar, bool Shift, bool Alt, bool Control, bool Pressed);
|
||||||
|
|
||||||
internal override void Start(string[] args)
|
internal override void Start(string[] args)
|
||||||
{
|
{
|
||||||
if (args.Length == 0 || !int.TryParse(args[0], out int port) || port <= 0 || port > 65535)
|
if (args.Length == 0 || !int.TryParse(args[0], out int port) || port <= 0 || port > 65535)
|
||||||
@@ -32,6 +41,8 @@ internal sealed class RemoteDesktopProcess() : Process("Remote Desktop Server")
|
|||||||
WindowManager.InvalidateAll();
|
WindowManager.InvalidateAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RegisterInputHandlers();
|
||||||
|
|
||||||
_ = Task.Run(() => server.StartAsync(port, cts.Token));
|
_ = Task.Run(() => server.StartAsync(port, cts.Token));
|
||||||
|
|
||||||
WindowManager.AddRenderSource(networkSource);
|
WindowManager.AddRenderSource(networkSource);
|
||||||
@@ -55,4 +66,55 @@ internal sealed class RemoteDesktopProcess() : Process("Remote Desktop Server")
|
|||||||
|
|
||||||
Logger.Log("Remote desktop server stopped.", Logging.LogSeverity.Info);
|
Logger.Log("Remote desktop server stopped.", Logging.LogSeverity.Info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RegisterInputHandlers()
|
||||||
|
{
|
||||||
|
if (server is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.ListenTo<MouseMoveMsg>("MouseMove", async (msg) =>
|
||||||
|
{
|
||||||
|
WindowManager.EnqueueMouseEvent(MouseEvent.Move(msg.X, msg.Y));
|
||||||
|
});
|
||||||
|
|
||||||
|
server.ListenTo<MouseButtonMsg>("MouseDown", async (msg) =>
|
||||||
|
{
|
||||||
|
MouseButton button = ParseButton(msg.Button);
|
||||||
|
WindowManager.EnqueueMouseEvent(MouseEvent.ButtonDown(msg.X, msg.Y, button));
|
||||||
|
});
|
||||||
|
|
||||||
|
server.ListenTo<MouseButtonMsg>("MouseUp", async (msg) =>
|
||||||
|
{
|
||||||
|
MouseButton button = ParseButton(msg.Button);
|
||||||
|
WindowManager.EnqueueMouseEvent(MouseEvent.ButtonUp(msg.X, msg.Y, button));
|
||||||
|
});
|
||||||
|
|
||||||
|
server.ListenTo<MouseWheelMsg>("MouseWheel", async (msg) =>
|
||||||
|
{
|
||||||
|
WindowManager.EnqueueMouseEvent(MouseEvent.Wheel(msg.X, msg.Y, msg.Delta));
|
||||||
|
});
|
||||||
|
|
||||||
|
server.ListenTo<KeyEventMsg>("KeyEvent", async (msg) =>
|
||||||
|
{
|
||||||
|
ConsoleKeyEx key = (ConsoleKeyEx)msg.Key;
|
||||||
|
char keyChar = msg.KeyChar.Length > 0 ? msg.KeyChar[0] : '\0';
|
||||||
|
bool isPressed = msg.Pressed;
|
||||||
|
|
||||||
|
KeyEvent keyEvent = new(keyChar, key, msg.Shift, msg.Alt, msg.Control, isPressed ? KeyEvent.KeyEventType.Make : KeyEvent.KeyEventType.Break);
|
||||||
|
WindowManager.EnqueueKeyEvent(keyEvent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MouseButton ParseButton(string button)
|
||||||
|
{
|
||||||
|
return button switch
|
||||||
|
{
|
||||||
|
"Left" => MouseButton.Left,
|
||||||
|
"Right" => MouseButton.Right,
|
||||||
|
"Middle" => MouseButton.Middle,
|
||||||
|
_ => MouseButton.None
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Cosmos.Kernel.System.Graphics;
|
using Cosmos.Kernel.System.Graphics;
|
||||||
using Cosmos.Kernel.System.Graphics.Fonts;
|
using Cosmos.Kernel.System.Graphics.Fonts;
|
||||||
using Cosmos.Kernel.System.Mouse;
|
|
||||||
|
|
||||||
using RemSox.UI.GUI.UIEelements;
|
using RemSox.UI.GUI.UIEelements;
|
||||||
using RemSox.Utils;
|
using RemSox.Utils;
|
||||||
@@ -26,6 +25,8 @@ public sealed class CanvasRenderSource : IRenderSource
|
|||||||
private static bool isPositionDirty = true;
|
private static bool isPositionDirty = true;
|
||||||
private static Point lastPointerPosition = new(-1, -1);
|
private static Point lastPointerPosition = new(-1, -1);
|
||||||
|
|
||||||
|
private static Point cursorPosition;
|
||||||
|
|
||||||
private static readonly Lock renderLock = new();
|
private static readonly Lock renderLock = new();
|
||||||
|
|
||||||
public void Render(IEnumerable<RenderCommand> commands)
|
public void Render(IEnumerable<RenderCommand> commands)
|
||||||
@@ -56,6 +57,11 @@ public sealed class CanvasRenderSource : IRenderSource
|
|||||||
RemovePrimitives(command.WindowId, command.ElementId);
|
RemovePrimitives(command.WindowId, command.ElementId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RenderCommandType.SetCursor:
|
||||||
|
cursorPosition = command.Position;
|
||||||
|
isPositionDirty = true;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (windowCanvases.ContainsKey(command.WindowId))
|
if (windowCanvases.ContainsKey(command.WindowId))
|
||||||
{
|
{
|
||||||
@@ -70,7 +76,7 @@ public sealed class CanvasRenderSource : IRenderSource
|
|||||||
public void Composite()
|
public void Composite()
|
||||||
{
|
{
|
||||||
Canvas screenCanvas = FullScreenCanvas.GetFullScreenCanvas();
|
Canvas screenCanvas = FullScreenCanvas.GetFullScreenCanvas();
|
||||||
Point pointerPosition = new(MouseManager.X, MouseManager.Y);
|
Point pointerPosition = cursorPosition;
|
||||||
|
|
||||||
lock (renderLock)
|
lock (renderLock)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ public class RenderCommand
|
|||||||
|
|
||||||
case RenderCommandType.RemovePrimitives:
|
case RenderCommandType.RemovePrimitives:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RenderCommandType.SetCursor:
|
||||||
|
WriteInt16(s, Position.X);
|
||||||
|
WriteInt16(s, Position.Y);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +159,10 @@ public class RenderCommand
|
|||||||
|
|
||||||
case RenderCommandType.RemovePrimitives:
|
case RenderCommandType.RemovePrimitives:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RenderCommandType.SetCursor:
|
||||||
|
pos = new Point(ReadInt16(data, ref offset), ReadInt16(data, ref offset));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RenderCommand
|
return new RenderCommand
|
||||||
|
|||||||
@@ -15,4 +15,6 @@ public enum RenderCommandType : byte
|
|||||||
DrawPoint = 0x16,
|
DrawPoint = 0x16,
|
||||||
|
|
||||||
RemovePrimitives = 0x20,
|
RemovePrimitives = 0x20,
|
||||||
|
|
||||||
|
SetCursor = 0x30,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,6 +254,7 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove old primitives for this element, then emit new ones
|
// Remove old primitives for this element, then emit new ones
|
||||||
|
// TODO: optimize by diffing properties and only updating what changed instead of full remove+add
|
||||||
commands.Add(new RenderCommand
|
commands.Add(new RenderCommand
|
||||||
{
|
{
|
||||||
WindowId = Id,
|
WindowId = Id,
|
||||||
|
|||||||
+114
-25
@@ -1,6 +1,5 @@
|
|||||||
using Cosmos.Kernel.System.Graphics;
|
using Cosmos.Kernel.System.Graphics;
|
||||||
using Cosmos.Kernel.System.Keyboard;
|
using Cosmos.Kernel.System.Keyboard;
|
||||||
using Cosmos.Kernel.System.Mouse;
|
|
||||||
|
|
||||||
using RemSox.Processing;
|
using RemSox.Processing;
|
||||||
using RemSox.UI.GUI.Rendering;
|
using RemSox.UI.GUI.Rendering;
|
||||||
@@ -31,15 +30,39 @@ public static class WindowManager
|
|||||||
|
|
||||||
private static readonly MuliRenderSource renderSource = new([]);
|
private static readonly MuliRenderSource renderSource = new([]);
|
||||||
|
|
||||||
|
private static readonly Queue<MouseEvent> mouseQueue = [];
|
||||||
|
private static readonly Queue<KeyEvent> keyQueue = [];
|
||||||
|
private static readonly Lock inputLock = new();
|
||||||
|
|
||||||
|
/// <summary> Enqueues a mouse event from any input source. </summary>
|
||||||
|
public static void EnqueueMouseEvent(MouseEvent mouseEvent)
|
||||||
|
{
|
||||||
|
lock (inputLock)
|
||||||
|
{
|
||||||
|
mouseQueue.Enqueue(mouseEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Enqueues a keyboard event from any input source. </summary>
|
||||||
|
public static void EnqueueKeyEvent(KeyEvent keyEvent)
|
||||||
|
{
|
||||||
|
lock (inputLock)
|
||||||
|
{
|
||||||
|
keyQueue.Enqueue(keyEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Processes input, updates interaction state, and triggers rendering of all windows.
|
/// Processes queued input and updates interaction state,
|
||||||
|
/// and triggers rendering.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static void Update()
|
internal static void Update()
|
||||||
{
|
{
|
||||||
Point pointerPosition = new(MouseManager.X, MouseManager.Y);
|
InputState input = DrainInput();
|
||||||
bool leftButtonDown = MouseManager.LeftButton;
|
|
||||||
bool rightButtonDown = MouseManager.RightButton;
|
Point pointerPosition = input.Position;
|
||||||
bool middleButtonDown = MouseManager.MiddleButton;
|
bool leftButtonDown = input.LeftButton;
|
||||||
|
bool rightButtonDown = input.RightButton;
|
||||||
|
bool middleButtonDown = input.MiddleButton;
|
||||||
|
|
||||||
Canvas canvas = FullScreenCanvas.GetFullScreenCanvas();
|
Canvas canvas = FullScreenCanvas.GetFullScreenCanvas();
|
||||||
|
|
||||||
@@ -57,20 +80,31 @@ public static class WindowManager
|
|||||||
activeInteractWindow = null;
|
activeInteractWindow = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (KeyboardManager.TryReadKey(out KeyEvent? keyEvent) && keyEvent is not null)
|
foreach (KeyEvent keyEvent in input.KeyEvents)
|
||||||
{
|
{
|
||||||
focusedWindow?.HandleKeyEvent(keyEvent);
|
focusedWindow?.HandleKeyEvent(keyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (focusedWindow is not null)
|
if (focusedWindow is not null)
|
||||||
{
|
{
|
||||||
DispatchMouseEvents(focusedWindow, pointerPosition);
|
DispatchMouseEvents(focusedWindow, pointerPosition,
|
||||||
|
leftButtonDown, wasLeftButtonDown,
|
||||||
|
rightButtonDown, wasRightButtonDown,
|
||||||
|
middleButtonDown, wasMiddleButtonDown,
|
||||||
|
input.ScrollDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
wasLeftButtonDown = leftButtonDown;
|
wasLeftButtonDown = leftButtonDown;
|
||||||
wasRightButtonDown = rightButtonDown;
|
wasRightButtonDown = rightButtonDown;
|
||||||
wasMiddleButtonDown = middleButtonDown;
|
wasMiddleButtonDown = middleButtonDown;
|
||||||
|
|
||||||
|
renderSource.Render([new RenderCommand
|
||||||
|
{
|
||||||
|
Type = RenderCommandType.SetCursor,
|
||||||
|
WindowId = 0,
|
||||||
|
ElementId = 0,
|
||||||
|
Position = pointerPosition,
|
||||||
|
}]);
|
||||||
renderSource.Composite();
|
renderSource.Composite();
|
||||||
|
|
||||||
lastPointerPosition = pointerPosition;
|
lastPointerPosition = pointerPosition;
|
||||||
@@ -382,45 +416,91 @@ public static class WindowManager
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DispatchMouseEvents(Window window, Point pos)
|
private static InputState DrainInput()
|
||||||
{
|
{
|
||||||
int delta = MouseManager.ScrollDelta;
|
List<MouseEvent> mouseEvents;
|
||||||
|
List<KeyEvent> keyEvents;
|
||||||
|
|
||||||
|
lock (inputLock)
|
||||||
|
{
|
||||||
|
mouseEvents = [.. mouseQueue];
|
||||||
|
mouseQueue.Clear();
|
||||||
|
keyEvents = [.. keyQueue];
|
||||||
|
keyQueue.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Point pos = lastPointerPosition;
|
||||||
|
bool left = wasLeftButtonDown, right = wasRightButtonDown, middle = wasMiddleButtonDown;
|
||||||
|
int scroll = 0;
|
||||||
|
|
||||||
|
foreach (MouseEvent e in mouseEvents)
|
||||||
|
{
|
||||||
|
switch (e.Type)
|
||||||
|
{
|
||||||
|
case MouseEventType.Move:
|
||||||
|
pos = new Point(e.X, e.Y);
|
||||||
|
break;
|
||||||
|
case MouseEventType.ButtonDown:
|
||||||
|
if (e.Button == MouseButton.Left) { left = true; }
|
||||||
|
else if (e.Button == MouseButton.Right) { right = true; }
|
||||||
|
else if (e.Button == MouseButton.Middle) { middle = true; }
|
||||||
|
break;
|
||||||
|
case MouseEventType.ButtonUp:
|
||||||
|
if (e.Button == MouseButton.Left) { left = false; }
|
||||||
|
else if (e.Button == MouseButton.Right) { right = false; }
|
||||||
|
else if (e.Button == MouseButton.Middle) { middle = false; }
|
||||||
|
break;
|
||||||
|
case MouseEventType.Wheel:
|
||||||
|
scroll += e.Delta;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new InputState(pos, left, right, middle, scroll, keyEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DispatchMouseEvents(
|
||||||
|
Window window, Point pos,
|
||||||
|
bool leftDown, bool wasLeftDown,
|
||||||
|
bool rightDown, bool wasRightDown,
|
||||||
|
bool middleDown, bool wasMiddleDown,
|
||||||
|
int scrollDelta)
|
||||||
|
{
|
||||||
if (pos != lastPointerPosition)
|
if (pos != lastPointerPosition)
|
||||||
{
|
{
|
||||||
window.HandleMouseEvent(new MouseEvent(MouseEventType.Move, pos.X, pos.Y, MouseButton.None, 0));
|
window.HandleMouseEvent(MouseEvent.Move(pos.X, pos.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MouseManager.LeftButton && !wasLeftButtonDown)
|
if (leftDown && !wasLeftDown)
|
||||||
{
|
{
|
||||||
window.HandleMouseEvent(new MouseEvent(MouseEventType.ButtonDown, pos.X, pos.Y, MouseButton.Left, 0));
|
window.HandleMouseEvent(MouseEvent.ButtonDown(pos.X, pos.Y, MouseButton.Left));
|
||||||
}
|
}
|
||||||
else if (!MouseManager.LeftButton && wasLeftButtonDown)
|
else if (!leftDown && wasLeftDown)
|
||||||
{
|
{
|
||||||
window.HandleMouseEvent(new MouseEvent(MouseEventType.ButtonUp, pos.X, pos.Y, MouseButton.Left, 0));
|
window.HandleMouseEvent(MouseEvent.ButtonUp(pos.X, pos.Y, MouseButton.Left));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MouseManager.RightButton && !wasRightButtonDown)
|
if (rightDown && !wasRightDown)
|
||||||
{
|
{
|
||||||
window.HandleMouseEvent(new MouseEvent(MouseEventType.ButtonDown, pos.X, pos.Y, MouseButton.Right, 0));
|
window.HandleMouseEvent(MouseEvent.ButtonDown(pos.X, pos.Y, MouseButton.Right));
|
||||||
}
|
}
|
||||||
else if (!MouseManager.RightButton && wasRightButtonDown)
|
else if (!rightDown && wasRightDown)
|
||||||
{
|
{
|
||||||
window.HandleMouseEvent(new MouseEvent(MouseEventType.ButtonUp, pos.X, pos.Y, MouseButton.Right, 0));
|
window.HandleMouseEvent(MouseEvent.ButtonUp(pos.X, pos.Y, MouseButton.Right));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MouseManager.MiddleButton && !wasMiddleButtonDown)
|
if (middleDown && !wasMiddleDown)
|
||||||
{
|
{
|
||||||
window.HandleMouseEvent(new MouseEvent(MouseEventType.ButtonDown, pos.X, pos.Y, MouseButton.Middle, 0));
|
window.HandleMouseEvent(MouseEvent.ButtonDown(pos.X, pos.Y, MouseButton.Middle));
|
||||||
}
|
}
|
||||||
else if (!MouseManager.MiddleButton && wasMiddleButtonDown)
|
else if (!middleDown && wasMiddleDown)
|
||||||
{
|
{
|
||||||
window.HandleMouseEvent(new MouseEvent(MouseEventType.ButtonUp, pos.X, pos.Y, MouseButton.Middle, 0));
|
window.HandleMouseEvent(MouseEvent.ButtonUp(pos.X, pos.Y, MouseButton.Middle));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delta != 0)
|
if (scrollDelta != 0)
|
||||||
{
|
{
|
||||||
window.HandleMouseEvent(new MouseEvent(MouseEventType.Wheel, pos.X, pos.Y, MouseButton.None, delta));
|
window.HandleMouseEvent(MouseEvent.Wheel(pos.X, pos.Y, scrollDelta));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,6 +509,15 @@ public static class WindowManager
|
|||||||
return nextWindowId++;
|
return nextWindowId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly record struct InputState(
|
||||||
|
Point Position,
|
||||||
|
bool LeftButton,
|
||||||
|
bool RightButton,
|
||||||
|
bool MiddleButton,
|
||||||
|
int ScrollDelta,
|
||||||
|
List<KeyEvent> KeyEvents
|
||||||
|
);
|
||||||
|
|
||||||
private sealed class MuliRenderSource(List<IRenderSource> sources) : IRenderSource
|
private sealed class MuliRenderSource(List<IRenderSource> sources) : IRenderSource
|
||||||
{
|
{
|
||||||
private readonly Lock sourcesLock = new();
|
private readonly Lock sourcesLock = new();
|
||||||
|
|||||||
Reference in New Issue
Block a user