Add unified input event queue and cursor support for window manager

This commit is contained in:
Stone_Red
2026-06-17 00:50:05 +02:00
parent 8d1cd6d369
commit 633ded2d62
7 changed files with 253 additions and 27 deletions
+57
View File
@@ -1,6 +1,9 @@
using Cosmos.Kernel.System.Graphics;
using Cosmos.Kernel.System.Keyboard;
using Cosmos.Kernel.System.Mouse;
using RemSox.Processing;
using RemSox.UI;
using RemSox.UI.GUI.Layout;
using RemSox.UI.GUI.Rendering;
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()
{
PollLocalHardware();
WindowManager.Update();
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()
{
List<Window> allWindows = WindowManager.GetAllWindows()
+62
View File
@@ -1,5 +1,8 @@
using Cosmos.Kernel.System.Keyboard;
using RemSox.Networking;
using RemSox.Processing;
using RemSox.UI;
using RemSox.UI.GUI.Rendering;
using RemSox.UI.GUI.Windows;
@@ -13,6 +16,12 @@ internal sealed class RemoteDesktopProcess() : Process("Remote Desktop Server")
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)
{
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();
});
RegisterInputHandlers();
_ = Task.Run(() => server.StartAsync(port, cts.Token));
WindowManager.AddRenderSource(networkSource);
@@ -55,4 +66,55 @@ internal sealed class RemoteDesktopProcess() : Process("Remote Desktop Server")
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
};
}
}