This document specifies the current behavior and design of the Dialog control as implemented.
For end-user usage and examples, see Dialog.
Terminal.Live(...)) are not a primary target; dialogs are designed to be hosted in fullscreen apps.Width/Height).Content).Title : Visual?Content : Visual?Padding : Thickness (padding between border and Content)Left : int? / Top : int? (position relative to the dialog’s layout slot)Width : int? / Height : int? (optional fixed size)IsModal : bool (implements IModalVisual for window-layer hit-testing)Show() (fullscreen only; adds to the current TerminalApp window layer)Close()HorizontalAlignment = Align.Stretch, VerticalAlignment = Align.Stretch.
src/XenoAtom.Terminal.UI/Controls/Dialog.cssrc/XenoAtom.Terminal.UI/Controls/WindowLayer.cssrc/XenoAtom.Terminal.UI/TerminalApp.cs (ShowWindow, CloseWindow)src/XenoAtom.Terminal.UI.Tests/WindowLayerInteractionTests.cssrc/XenoAtom.Terminal.UI.Tests/OverlaySurfaceTextStyleLeakTests.cssamples/ControlsDemo/Demos/DialogDemo.cssamples/ControlsDemo/Demos/BackdropDemo.cs (dialog + backdrop composition)Show() finds the current TerminalApp via App ?? Dispatcher.AttachedApp and calls TerminalApp.ShowWindow(this).Close() calls TerminalApp.CloseWindow(this) when possible.IsModal = true causes hit-testing/input to be blocked behind the dialog (see WindowLayerInteractionTests).Dialog is still a Visual and can be inserted directly into a tree (e.g. in a ZStack). In that case it renders and supports dragging,
but “modal” semantics are only meaningful when the host respects IModalVisual (the window layer does).
The measured size includes:
Padding inside the border,Content size,Title width (if present).Key rules:
Width / Height (when set) cap the available space for measuring content.Content is measured against:
innerWidth = availableWidth - 2 - padding.HorizontalinnerHeight = availableHeight - 2 - padding.VerticaldesiredWidth = Width ?? (2 + padding.Horizontal + content.DesiredSize.Width)desiredHeight = Height ?? (2 + padding.Vertical + content.DesiredSize.Height)3x3.Title is present, it is measured as a single line (maxHeight = 1) and can increase the desired width to fit titleWidth + 4.Dialog uses PrepareArrangeBounds to choose its final rect within the host slot:
width = min(slot.Width, Width ?? DesiredSize.Width) (at least 3)height = min(slot.Height, Height ?? DesiredSize.Height) (at least 3)Left/Top are null, the dialog is centered in the slot.Title (if present) is arranged on the top border row:
x + 2, y with height 1, and width clamped to finalRect.Width - 4.Content (if present) is arranged inside the inner rect:
x + 1 + padding.Left, y + 1 + padding.TopfinalRect.Width - 2 - padding.HorizontalfinalRect.Height - 2 - padding.VerticalThe dialog renders its own surface and chrome:
Theme.PopupSurface ?? Theme.SurfaceAlt ?? Theme.Surface when available.theme.Lines glyphs and theme.BorderStyle(focused) where focused = HasFocusWithin.Title is present, the title area is “cleared” to spaces and bolded on the top border row behind the title.The dialog explicitly preserves/normalizes text attributes when rendering the surface/chrome (WithTextStyle(...)) so that
decorations like underline from content behind the dialog do not leak into the overlay. This is covered by tests.
uiY == Bounds.Y) starts a drag operation.Left and Top (clamped to the layout slot) so the dialog follows the cursor.WindowLayerInteractionTests:
Left/TopOverlaySurfaceTextStyleLeakTests:
Escape (optional)