Clamp window position and size within screen bounds during drag/resize and ghsot window rending fixes

This commit is contained in:
Stone_Red
2026-06-10 02:55:13 +02:00
parent b3c98b1b1d
commit f2fd0d9c91
4 changed files with 42 additions and 11 deletions
+3
View File
@@ -32,7 +32,10 @@ public class Kernel : Sys.Kernel
new ViewProcessLogs()
]);
Sys.Graphics.Canvas canvas = Sys.Graphics.FullScreenCanvas.GetFullScreenCanvas();
Sys.Mouse.MouseManager.Initialize();
Sys.Mouse.MouseManager.SetScreenSize((int)canvas.Mode.Width, (int)canvas.Mode.Height);
Sys.Keyboard.KeyboardManager.Initialize();
}
+7 -4
View File
@@ -44,8 +44,11 @@ public sealed class CanvasRenderSource : IRenderSource
continue;
case "WindowMove":
windowPositions[command.WindowId] = command.Position;
isPositionDirty = true;
if (windowCanvases.ContainsKey(command.WindowId))
{
windowPositions[command.WindowId] = command.Position;
isPositionDirty = true;
}
continue;
case "Window":
@@ -56,8 +59,7 @@ public sealed class CanvasRenderSource : IRenderSource
if (!windowCanvases.TryGetValue(command.WindowId, out Canvas? canvas))
{
canvas = new Canvas(160, 120);
windowCanvases[command.WindowId] = canvas;
continue;
}
if (elementRenderers.TryGetValue(command.ElementType, out Action<Canvas, RenderCommand>? renderer))
@@ -145,6 +147,7 @@ public sealed class CanvasRenderSource : IRenderSource
}
windowPositions[id] = command.Position;
isPositionDirty = true;
RenderWindow(windowCanvases[id], command);
}
+11 -5
View File
@@ -1,3 +1,4 @@
using Cosmos.Kernel.System.Graphics;
using RemSox.UI.GUI.Rendering;
using RemSox.UI.GUI.UIEelements;
@@ -288,18 +289,21 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
/// <summary>
/// Updates the drag or resize interaction based on the current pointer position.
/// </summary>
public void UpdateInteraction(Point pointerPosition)
public void UpdateInteraction(Point pointerPosition, Point screenSize)
{
if (currentInteraction == InteractionMode.Drag)
{
int newX = pointerPosition.X - dragOffset.X;
int newY = pointerPosition.Y - dragOffset.Y;
// Cosmos DrawCanvas fails to render if coordinates are negative.
// Clamp to 0,0 to prevent the window from disappearing.
// Clamp left and top edges
newX = Math.Max(0, newX);
newY = Math.Max(0, newY);
// Clamp right and bottom edges
newX = Math.Min(screenSize.X - Size.Width, newX);
newY = Math.Min(screenSize.Y - Size.Height, newY);
Position = new Point(newX, newY);
Flush();
}
@@ -319,24 +323,26 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
if (currentInteraction is InteractionMode.ResizeRight or InteractionMode.ResizeBottomRight or InteractionMode.ResizeTopRight)
{
newW = Math.Max(minWidth, interactionStartBounds.Width + dx);
newW = Math.Min(newW, screenSize.X - newX);
}
if (currentInteraction is InteractionMode.ResizeBottom or InteractionMode.ResizeBottomRight or InteractionMode.ResizeBottomLeft)
{
newH = Math.Max(minHeight, interactionStartBounds.Height + dy);
newH = Math.Min(newH, screenSize.Y - newY);
}
if (currentInteraction is InteractionMode.ResizeLeft or InteractionMode.ResizeBottomLeft or InteractionMode.ResizeTopLeft)
{
int maxDx = interactionStartBounds.Width - minWidth;
int clampedDx = Math.Min(dx, maxDx);
newX = Math.Max(0, interactionStartBounds.X + clampedDx);
newW = interactionStartBounds.Width - clampedDx;
newW = (interactionStartBounds.X + interactionStartBounds.Width) - newX;
}
if (currentInteraction is InteractionMode.ResizeTop or InteractionMode.ResizeTopLeft or InteractionMode.ResizeTopRight)
{
int maxDy = interactionStartBounds.Height - minHeight;
int clampedDy = Math.Min(dy, maxDy);
newY = Math.Max(0, interactionStartBounds.Y + clampedDy);
newH = interactionStartBounds.Height - clampedDy;
newH = (interactionStartBounds.Y + interactionStartBounds.Height) - newY;
}
Position = new Point(newX, newY);
+21 -2
View File
@@ -37,13 +37,15 @@ public static class WindowManager
Point pointerPosition = new(MouseManager.X, MouseManager.Y);
bool leftButtonDown = MouseManager.LeftButton;
Canvas canvas = FullScreenCanvas.GetFullScreenCanvas();
if (leftButtonDown && !wasLeftButtonDown)
{
activeInteractWindow = TryBeginInteract(pointerPosition);
}
else if (leftButtonDown && activeInteractWindow is not null)
{
activeInteractWindow.UpdateInteraction(pointerPosition);
activeInteractWindow.UpdateInteraction(pointerPosition, new Point((int)canvas.Mode.Width, (int)canvas.Mode.Height));
}
else if (!leftButtonDown && activeInteractWindow is not null)
{
@@ -58,7 +60,6 @@ public static class WindowManager
focusedWindow?.HandleKeyEvent(keyEvent);
}
Canvas canvas = FullScreenCanvas.GetFullScreenCanvas();
CanvasRenderSource.CompositeAndDisplay(canvas, pointerPosition);
lastPointerPosition = pointerPosition;
@@ -118,6 +119,15 @@ public static class WindowManager
}
}
if (focusedWindow == window)
{
focusedWindow = null;
}
if (activeInteractWindow == window)
{
activeInteractWindow = null;
}
renderSource.Render([new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() }]);
}
@@ -162,6 +172,15 @@ public static class WindowManager
if (windowsToClose.Count > 0)
{
if (focusedWindow != null && windowsToClose.Contains(focusedWindow))
{
focusedWindow = null;
}
if (activeInteractWindow != null && windowsToClose.Contains(activeInteractWindow))
{
activeInteractWindow = null;
}
List<RenderCommand> closeCommands = [];
foreach (Window window in windowsToClose)
{