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() new ViewProcessLogs()
]); ]);
Sys.Graphics.Canvas canvas = Sys.Graphics.FullScreenCanvas.GetFullScreenCanvas();
Sys.Mouse.MouseManager.Initialize(); Sys.Mouse.MouseManager.Initialize();
Sys.Mouse.MouseManager.SetScreenSize((int)canvas.Mode.Width, (int)canvas.Mode.Height);
Sys.Keyboard.KeyboardManager.Initialize(); Sys.Keyboard.KeyboardManager.Initialize();
} }
+7 -4
View File
@@ -44,8 +44,11 @@ public sealed class CanvasRenderSource : IRenderSource
continue; continue;
case "WindowMove": case "WindowMove":
windowPositions[command.WindowId] = command.Position; if (windowCanvases.ContainsKey(command.WindowId))
isPositionDirty = true; {
windowPositions[command.WindowId] = command.Position;
isPositionDirty = true;
}
continue; continue;
case "Window": case "Window":
@@ -56,8 +59,7 @@ public sealed class CanvasRenderSource : IRenderSource
if (!windowCanvases.TryGetValue(command.WindowId, out Canvas? canvas)) if (!windowCanvases.TryGetValue(command.WindowId, out Canvas? canvas))
{ {
canvas = new Canvas(160, 120); continue;
windowCanvases[command.WindowId] = canvas;
} }
if (elementRenderers.TryGetValue(command.ElementType, out Action<Canvas, RenderCommand>? renderer)) if (elementRenderers.TryGetValue(command.ElementType, out Action<Canvas, RenderCommand>? renderer))
@@ -145,6 +147,7 @@ public sealed class CanvasRenderSource : IRenderSource
} }
windowPositions[id] = command.Position; windowPositions[id] = command.Position;
isPositionDirty = true;
RenderWindow(windowCanvases[id], command); 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.Rendering;
using RemSox.UI.GUI.UIEelements; using RemSox.UI.GUI.UIEelements;
@@ -288,18 +289,21 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
/// <summary> /// <summary>
/// Updates the drag or resize interaction based on the current pointer position. /// Updates the drag or resize interaction based on the current pointer position.
/// </summary> /// </summary>
public void UpdateInteraction(Point pointerPosition) public void UpdateInteraction(Point pointerPosition, Point screenSize)
{ {
if (currentInteraction == InteractionMode.Drag) if (currentInteraction == InteractionMode.Drag)
{ {
int newX = pointerPosition.X - dragOffset.X; int newX = pointerPosition.X - dragOffset.X;
int newY = pointerPosition.Y - dragOffset.Y; int newY = pointerPosition.Y - dragOffset.Y;
// Cosmos DrawCanvas fails to render if coordinates are negative. // Clamp left and top edges
// Clamp to 0,0 to prevent the window from disappearing.
newX = Math.Max(0, newX); newX = Math.Max(0, newX);
newY = Math.Max(0, newY); 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); Position = new Point(newX, newY);
Flush(); 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) if (currentInteraction is InteractionMode.ResizeRight or InteractionMode.ResizeBottomRight or InteractionMode.ResizeTopRight)
{ {
newW = Math.Max(minWidth, interactionStartBounds.Width + dx); 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) if (currentInteraction is InteractionMode.ResizeBottom or InteractionMode.ResizeBottomRight or InteractionMode.ResizeBottomLeft)
{ {
newH = Math.Max(minHeight, interactionStartBounds.Height + dy); 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) if (currentInteraction is InteractionMode.ResizeLeft or InteractionMode.ResizeBottomLeft or InteractionMode.ResizeTopLeft)
{ {
int maxDx = interactionStartBounds.Width - minWidth; int maxDx = interactionStartBounds.Width - minWidth;
int clampedDx = Math.Min(dx, maxDx); int clampedDx = Math.Min(dx, maxDx);
newX = Math.Max(0, interactionStartBounds.X + clampedDx); 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) if (currentInteraction is InteractionMode.ResizeTop or InteractionMode.ResizeTopLeft or InteractionMode.ResizeTopRight)
{ {
int maxDy = interactionStartBounds.Height - minHeight; int maxDy = interactionStartBounds.Height - minHeight;
int clampedDy = Math.Min(dy, maxDy); int clampedDy = Math.Min(dy, maxDy);
newY = Math.Max(0, interactionStartBounds.Y + clampedDy); newY = Math.Max(0, interactionStartBounds.Y + clampedDy);
newH = interactionStartBounds.Height - clampedDy; newH = (interactionStartBounds.Y + interactionStartBounds.Height) - newY;
} }
Position = new Point(newX, 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); Point pointerPosition = new(MouseManager.X, MouseManager.Y);
bool leftButtonDown = MouseManager.LeftButton; bool leftButtonDown = MouseManager.LeftButton;
Canvas canvas = FullScreenCanvas.GetFullScreenCanvas();
if (leftButtonDown && !wasLeftButtonDown) if (leftButtonDown && !wasLeftButtonDown)
{ {
activeInteractWindow = TryBeginInteract(pointerPosition); activeInteractWindow = TryBeginInteract(pointerPosition);
} }
else if (leftButtonDown && activeInteractWindow is not null) 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) else if (!leftButtonDown && activeInteractWindow is not null)
{ {
@@ -58,7 +60,6 @@ public static class WindowManager
focusedWindow?.HandleKeyEvent(keyEvent); focusedWindow?.HandleKeyEvent(keyEvent);
} }
Canvas canvas = FullScreenCanvas.GetFullScreenCanvas();
CanvasRenderSource.CompositeAndDisplay(canvas, pointerPosition); CanvasRenderSource.CompositeAndDisplay(canvas, pointerPosition);
lastPointerPosition = 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?>() }]); 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 (windowsToClose.Count > 0)
{ {
if (focusedWindow != null && windowsToClose.Contains(focusedWindow))
{
focusedWindow = null;
}
if (activeInteractWindow != null && windowsToClose.Contains(activeInteractWindow))
{
activeInteractWindow = null;
}
List<RenderCommand> closeCommands = []; List<RenderCommand> closeCommands = [];
foreach (Window window in windowsToClose) foreach (Window window in windowsToClose)
{ {