mirror of
https://github.com/Stone-Red-Code/RemSox.git
synced 2026-09-04 09:06:23 +02:00
Add XML docs
This commit is contained in:
@@ -6,56 +6,26 @@ namespace MyKernel.Plugs;
|
|||||||
[Plug("System.Security.Cryptography.RandomNumberGeneratorImplementation")]
|
[Plug("System.Security.Cryptography.RandomNumberGeneratorImplementation")]
|
||||||
public static unsafe class RandomNumberGeneratorImplementationImpl
|
public static unsafe class RandomNumberGeneratorImplementationImpl
|
||||||
{
|
{
|
||||||
// =========================================================
|
// Cryptographic stream generator based on ChaCha20.
|
||||||
// SECURITY NOTE
|
// Initial entropy is limited at boot; depends on hardware events.
|
||||||
// =========================================================
|
|
||||||
// This implementation uses ChaCha20 as its core stream cipher,
|
|
||||||
// which is cryptographically sound. However, the initial seed
|
|
||||||
// quality at boot is LIMITED without hardware entropy sources
|
|
||||||
// (RDTSC / RDRAND). Security improves substantially once
|
|
||||||
// AddMouseEntropy / AddKeyboardEntropy have been called with
|
|
||||||
// real hardware event timing. Do not use this for high-value
|
|
||||||
// key generation before sufficient entropy has been collected.
|
|
||||||
//
|
|
||||||
// To reach true CSPRNG quality, add assembly plugs for:
|
|
||||||
// - RDTSC (real CPU cycle counter)
|
|
||||||
// - RDRAND (hardware RNG, Intel/AMD, post-2012)
|
|
||||||
// and call them from ReadTSC() and EnsureInitialized().
|
|
||||||
// =========================================================
|
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// ChaCha20 state
|
|
||||||
// =========================================================
|
|
||||||
private static uint[] key = new uint[8];
|
private static uint[] key = new uint[8];
|
||||||
private static uint[] counter = new uint[4];
|
private static uint[] counter = new uint[4];
|
||||||
private static uint[] state = new uint[16];
|
private static uint[] state = new uint[16];
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// entropy pool
|
|
||||||
// =========================================================
|
|
||||||
private static ulong e0, e1, e2, e3;
|
private static ulong e0, e1, e2, e3;
|
||||||
private static int entropyCounter;
|
private static int entropyCounter;
|
||||||
private static bool initialized = false;
|
private static bool initialized = false;
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// ChaCha constants ("expand 32-byte k")
|
|
||||||
// =========================================================
|
|
||||||
private static readonly uint[] constants =
|
private static readonly uint[] constants =
|
||||||
{
|
{
|
||||||
0x61707865, 0x3320646E, 0x79622D32, 0x6B206574
|
0x61707865, 0x3320646E, 0x79622D32, 0x6B206574
|
||||||
};
|
};
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// rotate left
|
|
||||||
// =========================================================
|
|
||||||
private static uint RotL(uint x, int n)
|
private static uint RotL(uint x, int n)
|
||||||
{
|
{
|
||||||
return (x << n) | (x >> (32 - n));
|
return (x << n) | (x >> (32 - n));
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// ChaCha quarter round
|
|
||||||
// =========================================================
|
|
||||||
private static void QR(ref uint a, ref uint b, ref uint c, ref uint d)
|
private static void QR(ref uint a, ref uint b, ref uint c, ref uint d)
|
||||||
{
|
{
|
||||||
a += b; d ^= a; d = RotL(d, 16);
|
a += b; d ^= a; d = RotL(d, 16);
|
||||||
@@ -64,9 +34,6 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
c += d; b ^= c; b = RotL(b, 7);
|
c += d; b ^= c; b = RotL(b, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// ChaCha20 block
|
|
||||||
// =========================================================
|
|
||||||
private static void ChaChaBlock(uint[] output)
|
private static void ChaChaBlock(uint[] output)
|
||||||
{
|
{
|
||||||
uint[] x = new uint[16];
|
uint[] x = new uint[16];
|
||||||
@@ -104,16 +71,10 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// FIX: stronger Mix() using a multiplier with good avalanche.
|
|
||||||
// The previous shift-only chain was reversible with linear
|
|
||||||
// algebra. Multiplying by a prime scrambles bits non-linearly.
|
|
||||||
// Using the 64-bit Fibonacci hashing constant (knuth / splitmix64).
|
|
||||||
// =========================================================
|
|
||||||
private static void Mix(ulong v)
|
private static void Mix(ulong v)
|
||||||
{
|
{
|
||||||
e0 ^= v;
|
e0 ^= v;
|
||||||
e0 *= 0x9E3779B97F4A7C15UL; // Fibonacci hash, full avalanche
|
e0 *= 0x9E3779B97F4A7C15UL;
|
||||||
e1 ^= e0 ^ (e0 >> 30);
|
e1 ^= e0 ^ (e0 >> 30);
|
||||||
e1 *= 0xBF58476D1CE4E5B9UL;
|
e1 *= 0xBF58476D1CE4E5B9UL;
|
||||||
e2 ^= e1 ^ (e1 >> 27);
|
e2 ^= e1 ^ (e1 >> 27);
|
||||||
@@ -133,10 +94,8 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
counter[2] ^= (uint)(e2 >> 16);
|
counter[2] ^= (uint)(e2 >> 16);
|
||||||
counter[3] ^= (uint)(e3 >> 16);
|
counter[3] ^= (uint)(e3 >> 16);
|
||||||
|
|
||||||
// wipe pool after folding
|
|
||||||
e0 = 0; e1 = 0; e2 = 0; e3 = 0;
|
e0 = 0; e1 = 0; e2 = 0; e3 = 0;
|
||||||
|
|
||||||
// invalidate output buffer so new key takes effect immediately
|
|
||||||
bufferIndex = 16;
|
bufferIndex = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,45 +105,18 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
Reseed();
|
Reseed();
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// ReadTSC() — HONEST fallback
|
|
||||||
//
|
|
||||||
// Without an assembly plug for RDTSC this cannot provide real
|
|
||||||
// sub-millisecond jitter. The previous spin-loop was removed
|
|
||||||
// because it was deterministic and added no real entropy.
|
|
||||||
//
|
|
||||||
// Replace the body of this method with an RDTSC assembly plug
|
|
||||||
// and this becomes a real entropy source:
|
|
||||||
//
|
|
||||||
// [PlugMethod(assemblyName: "...", methodLabel: "rdtsc")]
|
|
||||||
// public static extern ulong NativeRdtsc();
|
|
||||||
//
|
|
||||||
// Until then, TickCount is used honestly at its actual resolution.
|
|
||||||
// =========================================================
|
|
||||||
private static ulong ReadTSC()
|
private static ulong ReadTSC()
|
||||||
{
|
{
|
||||||
return (ulong)Environment.TickCount;
|
return (ulong)Environment.TickCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// Initial seed
|
|
||||||
//
|
|
||||||
// Mixes the best available non-hardware sources. This is weak
|
|
||||||
// at boot but not zero. Security depends heavily on the first
|
|
||||||
// real entropy events (mouse/keyboard) arriving quickly.
|
|
||||||
// =========================================================
|
|
||||||
private static void EnsureInitialized()
|
private static void EnsureInitialized()
|
||||||
{
|
{
|
||||||
if (initialized) return;
|
if (initialized) return;
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
// Compile-time build nonce — gives a different stream per
|
|
||||||
// build even if all runtime sources are identical.
|
|
||||||
// IMPORTANT: regenerate this value for each release build.
|
|
||||||
const ulong BUILD_NONCE = 0xDEADBEEFCAFEBABEUL;
|
const ulong BUILD_NONCE = 0xDEADBEEFCAFEBABEUL;
|
||||||
|
|
||||||
// Heap pointer: weak in Cosmos (sequential allocator) but
|
|
||||||
// still varies across hardware configs and VM setups.
|
|
||||||
ulong heapBits;
|
ulong heapBits;
|
||||||
fixed (byte* p = new byte[1])
|
fixed (byte* p = new byte[1])
|
||||||
heapBits = (ulong)p;
|
heapBits = (ulong)p;
|
||||||
@@ -192,19 +124,13 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
Mix(BUILD_NONCE);
|
Mix(BUILD_NONCE);
|
||||||
Mix(ReadTSC());
|
Mix(ReadTSC());
|
||||||
Mix(heapBits);
|
Mix(heapBits);
|
||||||
Mix(ReadTSC() ^ (heapBits << 17)); // second sample
|
Mix(ReadTSC() ^ (heapBits << 17));
|
||||||
|
|
||||||
Reseed();
|
Reseed();
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// Thread safety
|
|
||||||
// =========================================================
|
|
||||||
private static readonly Lock _lock = new();
|
private static readonly Lock _lock = new();
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// ChaCha output buffer
|
|
||||||
// =========================================================
|
|
||||||
private static uint[] buffer = new uint[16];
|
private static uint[] buffer = new uint[16];
|
||||||
private static int bufferIndex = 16;
|
private static int bufferIndex = 16;
|
||||||
|
|
||||||
@@ -217,16 +143,6 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
ChaChaBlock(buffer);
|
ChaChaBlock(buffer);
|
||||||
bufferIndex = 0;
|
bufferIndex = 0;
|
||||||
|
|
||||||
// Backtracking resistance: ratchet the key forward by XORing
|
|
||||||
// it with the first 8 words of the fresh keystream.
|
|
||||||
//
|
|
||||||
// XOR rather than replace: assignment would discard all entropy
|
|
||||||
// accumulated via AddMouseEntropy / AddKeyboardEntropy, since
|
|
||||||
// those fold into key[] via Reseed(). XOR preserves that entropy
|
|
||||||
// while still making the new key unpredictable from the old one.
|
|
||||||
//
|
|
||||||
// We then regenerate the block so the 8 words used for ratcheting
|
|
||||||
// are never returned to the caller as output.
|
|
||||||
key[0] ^= buffer[0];
|
key[0] ^= buffer[0];
|
||||||
key[1] ^= buffer[1];
|
key[1] ^= buffer[1];
|
||||||
key[2] ^= buffer[2];
|
key[2] ^= buffer[2];
|
||||||
@@ -242,7 +158,6 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
return buffer[bufferIndex++];
|
return buffer[bufferIndex++];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use all 4 bytes of each uint
|
|
||||||
private static int byteShift = 0;
|
private static int byteShift = 0;
|
||||||
private static uint byteWord = 0;
|
private static uint byteWord = 0;
|
||||||
|
|
||||||
@@ -258,10 +173,6 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
return (byte)(byteWord >> byteShift);
|
return (byte)(byteWord >> byteShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// ENTROPY INPUTS
|
|
||||||
// =========================================================
|
|
||||||
|
|
||||||
public static void AddMouseEntropy(int dx, int dy, int dz, int x, int y)
|
public static void AddMouseEntropy(int dx, int dy, int dz, int x, int y)
|
||||||
{
|
{
|
||||||
ulong tsc = ReadTSC();
|
ulong tsc = ReadTSC();
|
||||||
@@ -291,10 +202,6 @@ public static unsafe class RandomNumberGeneratorImplementationImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================
|
|
||||||
// PUBLIC API
|
|
||||||
// =========================================================
|
|
||||||
|
|
||||||
[PlugMember]
|
[PlugMember]
|
||||||
public static void FillSpan(Span<byte> data)
|
public static void FillSpan(Span<byte> data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,11 +2,25 @@ namespace RemSox.UI.GUI.CLI;
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines a command executable via the CLI or GUI terminal.
|
||||||
|
/// </summary>
|
||||||
public interface ICommand
|
public interface ICommand
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the command used to invoke it.
|
||||||
|
/// </summary>
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a brief description of the command's functionality.
|
||||||
|
/// </summary>
|
||||||
string Description { get; }
|
string Description { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Executes the command.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="arguments">The arguments provided to the command.</param>
|
||||||
|
/// <param name="printLine">A delegate to stream output lines to the current console or terminal.</param>
|
||||||
void Execute(string? arguments, Action<string> printLine);
|
void Execute(string? arguments, Action<string> printLine);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,25 +6,36 @@ using RemSox.UI.GUI.UIEelements;
|
|||||||
|
|
||||||
namespace RemSox.UI.GUI.Windows;
|
namespace RemSox.UI.GUI.Windows;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a window within the GUI system, managing its state, UI elements, and interactions.
|
||||||
|
/// </summary>
|
||||||
public sealed class Window(string title, int processId, int id, IRenderSource renderSource)
|
public sealed class Window(string title, int processId, int id, IRenderSource renderSource)
|
||||||
{
|
{
|
||||||
|
/// <summary> Gets the unique identifier for this window. </summary>
|
||||||
public int Id { get; } = id;
|
public int Id { get; } = id;
|
||||||
|
|
||||||
|
/// <summary> Gets the ID of the process that owns this window. </summary>
|
||||||
public int ProcessId { get; } = processId;
|
public int ProcessId { get; } = processId;
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the title of the window. </summary>
|
||||||
public string Title { get; set; } = title;
|
public string Title { get; set; } = title;
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the Z-order index of the window (higher means more foreground). </summary>
|
||||||
public int ZIndex { get; set; }
|
public int ZIndex { get; set; }
|
||||||
|
|
||||||
|
/// <summary> Gets or sets a value indicating whether changes should automatically trigger a redraw. </summary>
|
||||||
public bool AutoFlush { get; set; } = false;
|
public bool AutoFlush { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary> Event raised when a keyboard event is handled by this window. </summary>
|
||||||
public event Action<Cosmos.Kernel.System.Keyboard.KeyEvent>? OnKeyEvent;
|
public event Action<Cosmos.Kernel.System.Keyboard.KeyEvent>? OnKeyEvent;
|
||||||
|
|
||||||
|
/// <summary> Dispatches a key event to the window's registered event handlers. </summary>
|
||||||
public void HandleKeyEvent(Cosmos.Kernel.System.Keyboard.KeyEvent keyEvent)
|
public void HandleKeyEvent(Cosmos.Kernel.System.Keyboard.KeyEvent keyEvent)
|
||||||
{
|
{
|
||||||
OnKeyEvent?.Invoke(keyEvent);
|
OnKeyEvent?.Invoke(keyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Gets or sets whether this window is currently focused. </summary>
|
||||||
public bool IsFocused
|
public bool IsFocused
|
||||||
{
|
{
|
||||||
get => WindowManager.IsWindowFocused(this);
|
get => WindowManager.IsWindowFocused(this);
|
||||||
@@ -34,16 +45,22 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Gets or sets whether the window is visible. </summary>
|
||||||
public bool IsVisible { get; set; } = true;
|
public bool IsVisible { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary> Gets or sets whether the window is resizable by the user. </summary>
|
||||||
public bool IsResizable { get; set; } = true;
|
public bool IsResizable { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary> Gets or sets whether the window can be dragged by the user. </summary>
|
||||||
public bool IsDraggable { get; set; } = true;
|
public bool IsDraggable { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the position of the window. </summary>
|
||||||
public Point Position { get; set; }
|
public Point Position { get; set; }
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the size of the window. </summary>
|
||||||
public Size Size { get; set; }
|
public Size Size { get; set; }
|
||||||
|
|
||||||
|
/// <summary> Gets whether the window is currently being dragged. </summary>
|
||||||
public bool IsDragging => currentInteraction == InteractionMode.Drag;
|
public bool IsDragging => currentInteraction == InteractionMode.Drag;
|
||||||
|
|
||||||
private readonly object uiElementsLock = new object();
|
private readonly object uiElementsLock = new object();
|
||||||
@@ -64,6 +81,9 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
private int lastRenderedZIndex = -1;
|
private int lastRenderedZIndex = -1;
|
||||||
private bool isFirstRender = true;
|
private bool isFirstRender = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates and registers a new UI element within this window.
|
||||||
|
/// </summary>
|
||||||
public T CreateUIElement<T>(Action<T>? options = null) where T : UIElement, new()
|
public T CreateUIElement<T>(Action<T>? options = null) where T : UIElement, new()
|
||||||
{
|
{
|
||||||
int uiElementId = GetNextUIElementId();
|
int uiElementId = GetNextUIElementId();
|
||||||
@@ -96,12 +116,18 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
return uiElement;
|
return uiElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalidates the window state, forcing a full redraw on the next flush.
|
||||||
|
/// </summary>
|
||||||
public void Invalidate()
|
public void Invalidate()
|
||||||
{
|
{
|
||||||
isFirstRender = true;
|
isFirstRender = true;
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends current window and element state to the renderer.
|
||||||
|
/// </summary>
|
||||||
public void Flush()
|
public void Flush()
|
||||||
{
|
{
|
||||||
if (!IsVisible)
|
if (!IsVisible)
|
||||||
@@ -185,6 +211,9 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a pointer position starts an interaction (drag/resize) and handles focus.
|
||||||
|
/// </summary>
|
||||||
public bool TryBeginInteract(Point pointerPosition)
|
public bool TryBeginInteract(Point pointerPosition)
|
||||||
{
|
{
|
||||||
if (!IsVisible)
|
if (!IsVisible)
|
||||||
@@ -237,6 +266,9 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the drag or resize interaction based on the current pointer position.
|
||||||
|
/// </summary>
|
||||||
public void UpdateInteraction(Point pointerPosition)
|
public void UpdateInteraction(Point pointerPosition)
|
||||||
{
|
{
|
||||||
if (currentInteraction == InteractionMode.Drag)
|
if (currentInteraction == InteractionMode.Drag)
|
||||||
@@ -294,6 +326,9 @@ public sealed class Window(string title, int processId, int id, IRenderSource re
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ends the current drag or resize interaction.
|
||||||
|
/// </summary>
|
||||||
public void EndInteraction()
|
public void EndInteraction()
|
||||||
{
|
{
|
||||||
currentInteraction = InteractionMode.None;
|
currentInteraction = InteractionMode.None;
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ using RemSox.UI.GUI.Rendering;
|
|||||||
|
|
||||||
namespace RemSox.UI.GUI.Windows;
|
namespace RemSox.UI.GUI.Windows;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manages window creation, focus, interaction, and rendering orchestration for the GUI system.
|
||||||
|
/// </summary>
|
||||||
public static class WindowManager
|
public static class WindowManager
|
||||||
{
|
{
|
||||||
private static readonly object windowsLock = new object();
|
private static readonly object windowsLock = new object();
|
||||||
@@ -29,6 +32,9 @@ public static class WindowManager
|
|||||||
|
|
||||||
private static readonly MuliRenderSource renderSource = new([]);
|
private static readonly MuliRenderSource renderSource = new([]);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processes input, updates interaction state, and triggers rendering of all windows.
|
||||||
|
/// </summary>
|
||||||
public static void Update()
|
public static void Update()
|
||||||
{
|
{
|
||||||
mousePollCounter++;
|
mousePollCounter++;
|
||||||
@@ -64,10 +70,19 @@ public static class WindowManager
|
|||||||
lastPointerPosition = pointerPosition;
|
lastPointerPosition = pointerPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a new rendering source to the compositor.
|
||||||
|
/// </summary>
|
||||||
public static void AddRenderSource(IRenderSource source) => renderSource.AddSource(source);
|
public static void AddRenderSource(IRenderSource source) => renderSource.AddSource(source);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes an existing rendering source from the compositor.
|
||||||
|
/// </summary>
|
||||||
public static void RemoveRenderSource(IRenderSource source) => renderSource.RemoveSource(source);
|
public static void RemoveRenderSource(IRenderSource source) => renderSource.RemoveSource(source);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates and registers a new window for the specified process.
|
||||||
|
/// </summary>
|
||||||
public static Window CreateWindow(Process process, string title, Point position, Size size)
|
public static Window CreateWindow(Process process, string title, Point position, Size size)
|
||||||
{
|
{
|
||||||
Window window = new(title, process.Id, GetNextWindowId(), renderSource)
|
Window window = new(title, process.Id, GetNextWindowId(), renderSource)
|
||||||
@@ -90,6 +105,9 @@ public static class WindowManager
|
|||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes a specific window and notifies the renderer.
|
||||||
|
/// </summary>
|
||||||
public static void CloseWindow(Window window)
|
public static void CloseWindow(Window window)
|
||||||
{
|
{
|
||||||
lock (windowsLock)
|
lock (windowsLock)
|
||||||
@@ -103,6 +121,9 @@ public static class WindowManager
|
|||||||
renderSource.Render(new[] { new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() } });
|
renderSource.Render(new[] { new RenderCommand { WindowId = window.Id, ElementId = window.Id, ElementType = "WindowClose", Position = window.Position, Properties = new Dictionary<string, object?>() } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a list of all windows belonging to the given process.
|
||||||
|
/// </summary>
|
||||||
public static List<Window> GetWindowsForProcess(Process process)
|
public static List<Window> GetWindowsForProcess(Process process)
|
||||||
{
|
{
|
||||||
lock (windowsLock)
|
lock (windowsLock)
|
||||||
@@ -116,11 +137,17 @@ public static class WindowManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes all windows belonging to the given process.
|
||||||
|
/// </summary>
|
||||||
public static void CloseWindowsForProcess(Process process)
|
public static void CloseWindowsForProcess(Process process)
|
||||||
{
|
{
|
||||||
CloseWindowsForProcess(process.Id);
|
CloseWindowsForProcess(process.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes all windows belonging to the given process ID.
|
||||||
|
/// </summary>
|
||||||
public static void CloseWindowsForProcess(int processId)
|
public static void CloseWindowsForProcess(int processId)
|
||||||
{
|
{
|
||||||
List<Window> windowsToClose = new();
|
List<Window> windowsToClose = new();
|
||||||
@@ -144,6 +171,9 @@ public static class WindowManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the focus to the specified window, bringing it to the foreground.
|
||||||
|
/// </summary>
|
||||||
public static void FocusWindow(Window? window)
|
public static void FocusWindow(Window? window)
|
||||||
{
|
{
|
||||||
if (focusedWindow == window)
|
if (focusedWindow == window)
|
||||||
@@ -163,11 +193,17 @@ public static class WindowManager
|
|||||||
focusedWindow?.Flush();
|
focusedWindow?.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the specified window is currently focused.
|
||||||
|
/// </summary>
|
||||||
public static bool IsWindowFocused(Window window)
|
public static bool IsWindowFocused(Window window)
|
||||||
{
|
{
|
||||||
return focusedWindow == window;
|
return focusedWindow == window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to begin interaction (drag/resize) with a window at the specified pointer position.
|
||||||
|
/// </summary>
|
||||||
public static Window? TryBeginInteract(Point pointerPosition)
|
public static Window? TryBeginInteract(Point pointerPosition)
|
||||||
{
|
{
|
||||||
List<Window> allWindows;
|
List<Window> allWindows;
|
||||||
@@ -186,6 +222,9 @@ public static class WindowManager
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Forces a full redraw of all windows in the system.
|
||||||
|
/// </summary>
|
||||||
public static void InvalidateAll()
|
public static void InvalidateAll()
|
||||||
{
|
{
|
||||||
List<Window> allWindows;
|
List<Window> allWindows;
|
||||||
|
|||||||
Reference in New Issue
Block a user