| name | reactor-windowing |
| description | Reactor top-level windowing cookbook: WindowSpec, OpenWindow, draggable windows, borderless/tool windows, placement persistence, taskbar visibility, z-order, aspect ratio, SizeToContent, displays, taskbar integration, and picker HWND wiring. |
| when_to_invoke | ["open a window","secondary window","make a window draggable","remember window position","restore window placement","tool palette","command palette","window aspect ratio","borderless window","always on top","taskbar progress","file picker"] |
Reactor Windowing
Use this skill when a task involves top-level windows, placement, shell chrome,
taskbar features, displays, or native pickers.
Core APIs
var win = ReactorApp.OpenWindow(
new WindowSpec { Title = "Settings", Width = 520, Height = 420 },
() => new SettingsWindow());
win.Activate();
win.Close();
WindowSpec is immutable startup intent. ReactorWindow is the live handle for
runtime mutators (SetSize, SetPosition, SetAspectRatio, BeginDragMove,
SavePlacement, Update).
Size and resize
new WindowSpec
{
ResizeMode = WindowResizeMode.CanMinimize,
AspectRatio = 16.0 / 9.0,
MinWidth = 480,
SizeToContent = WindowSizeToContent.Manual,
};
UseWindow()?.SetAspectRatio(4.0 / 3.0);
UseWindowAspectRatio(1.0);
Rules:
AspectRatio cannot combine with ResizeMode.NoResize.
AspectRatio cannot combine with SizeToContent.
SizeToContent ignores maximized windows and may settle one frame after mount.
Movement, drag, and persistence
new WindowSpec
{
StartPosition = WindowStartPosition.CenterOnCurrent,
IsMovableByBackground = true,
};
var (x, y) = UseWindowPosition();
var drag = UseWindowDragMove();
Button("Drag", drag);
Border(customEditor).Drag(false);
var spec = new WindowSpec { Title = "Shell" }
.WithPersistence("shell-main", WindowStartPosition.CenterOnCurrent);
UseWindow()?.SavePlacement();
Persistence requires PersistPlacement; use .WithPersistence(...) for the
common case. PersistenceId alone is only identity for persistence systems.
Z-order, taskbar, and chrome
new WindowSpec
{
ShowInTaskbar = false,
ShowInSwitcher = true,
Level = WindowLevel.Floating,
Style = WindowStyle.ToolWindow,
CornerStyle = WindowCornerStyle.RoundedSmall,
};
Notes:
Floating stays above owners and sibling Reactor app windows.
ToolWindow hides from the taskbar by default unless ShowInTaskbar is explicit.
WindowStyle.None should normally set IsMovableByBackground = true.
UseIsCovered() is a z-order hint, not pixel-accurate occlusion.
Title bar and backdrop
VStack(
TitleBar("My App"),
Body());
A TitleBar(...) element infers ExtendsContentIntoTitleBar = true when the
spec value is null. Explicit true or false wins.
VStack(...).Backdrop(BackdropKind.Mica);
new WindowSpec { Backdrop = BackdropChoice.Of(BackdropKind.DesktopAcrylic) };
BackdropKind.Transparent falls back to no backdrop when unsupported by the
referenced Windows App SDK.
Taskbar, displays, and pickers
var taskbar = UseWindow()!.TaskbarItem;
taskbar.Description = "Exporting";
taskbar.Progress.State = TaskbarProgressState.Normal;
taskbar.Progress.Value = 0.25;
var displays = UseDisplays();
var nearest = ReactorDisplay.NearestTo(window.Position.X, window.Position.Y);
var file = await UseFilePickerAsync(new FilePickerOptions(FileTypeFilter: [".txt"]));
var folder = await UseFolderPickerAsync(new FolderPickerOptions());
Picker hooks must run on the owning window's UI thread and use the owning HWND;
there is no arbitrary HWND parameter.
Recipe: Command Palette
PowerToys Run-style launcher. See samples/apps/command-palette-window/.
new WindowSpec
{
Style = WindowStyle.None,
IsMovableByBackground = true,
Level = WindowLevel.AlwaysOnTop,
CornerStyle = WindowCornerStyle.Rounded,
StartPosition = WindowStartPosition.CenterOnCurrent,
ShowInTaskbar = false,
ShowInSwitcher = false,
};
Recipe: Tool Palette
Photoshop-style owned floating palette. See samples/apps/tool-palette/.
var main = ReactorApp.OpenWindow(new WindowSpec { Title = "Editor" }, () => new Editor());
ReactorApp.OpenWindow(new WindowSpec
{
Title = "Tools",
Owner = main,
Style = WindowStyle.ToolWindow,
Level = WindowLevel.Floating,
CornerStyle = WindowCornerStyle.RoundedSmall,
}, () => new ToolPalette());
Recipe: Media Player (aspect-locked)
new WindowSpec
{
Title = "Player",
Width = 960,
Height = 540,
AspectRatio = 16.0 / 9.0,
};
UseWindow()?.SetAspectRatio(videoWidth / (double)videoHeight);
UseWindowAspectRatio(16.0 / 9.0);