Freshness: 2026-08-05 Β· commit
c77517cΒ· branch0.8.3Β· 65 C# files, ~9 990 lines
Single WPF executable, no server, no client/server split. One project: StageManager/StageManager.csproj
(net10.0-windows10.0.19041.0, WinExe, WPF + WinForms interop, nullable enabled).
App.xaml.cs process entry, single-instance, theme
|
MainWindow sidebar shell, tray menu, input routing
/ | \
SceneManager Animations Controls orchestration / motion / live previews
| | |
Native (Win32) Composition Composition HWND control, DWM-free capture
| | |
user32 WinRT Direct3D 11
| Layer | Namespace | Owns | Map |
|---|---|---|---|
| Shell | StageManager |
MainWindow, App, Log |
this file |
| Orchestration | StageManager , .Strategies , .Services |
scene lifecycle, window hide/show policy, settings, updates | windowing.md |
| Windowing | StageManager.Native.* |
HWND enumeration, WinEvent hooks, positioning | windowing.md |
| State | StageManager.Model |
Scene, SceneModel, WindowModel, event args |
data.md |
| Presentation | StageManager.Controls , .Converters , .Animations |
tiles, overlays, transitions, drag ghosts | rendering.md |
| Capture | StageManager.Composition.* |
frame capture, compositor visuals, D3D device | rendering.md |
Naming note: this app has no backend or frontend. windowing.md covers what the skill template calls
backend (headless orchestration + OS integration); rendering.md covers what it calls frontend.
Arrows = using edges between internal namespaces. Acyclic.
MainWindow ββ> Animations ββ> Controls ββ> Composition ββ> Composition.Interop
β β β β
β ββ> Model ββ> Native.PInvoke
β ββ> Helpers
βββ> SceneManager ββ> Strategies ββ> Native.Window
β βββββββββ> Native.* , Services , Helpers , Model
βββ> Services , Native.Interop
Rules the graph enforces today:
Native.*andModelnever reference UI namespaces β both are reusable headless.Compositiondepends only onComposition.InteropandNative.PInvoke; it knows nothing of scenes.Controlsis the only namespace that owns aCaptureSession;Animationsborrows, never creates (exceptLiveCardHost.TryCreateOwned).Logreaches intoModelfor scene diagnostics β the one downward-facing exception.
App.OnStartupβ single-instance mutex,ThemeManager.ApplyTheme, showMainWindow.MainWindow.OnContentRenderedβ buildWindowsManager,SceneManager, start SharpHook mouse hook, restoreSceneSnapshot, warm the transition overlay.WindowsManagerWinEvent hooks raiseWindowCreated/WindowUpdated/WindowDestroyed.SceneManagergroups windows by process key intoScenes, raisesSceneChanged/CurrentSceneSelectionChanged.MainWindowprojectsSceneβSceneModelintoObservableCollection<SceneModel> Scenes; XAML binds eachWindowModel.Handleto aCompositionThumbnail.- Each tile opens a
CaptureSession(Windows.Graphics.CaptureβWindows.UI.Composition). - Switching or dragging hands the tile's live visual to
SceneTransitionAnimatorviaLiveCardHost.
| Package | Version | Used for |
|---|---|---|
| Vortice.Direct3D11 / Vortice.DXGI | 3.8.1 | D3D11 device behind the capture frame pool |
| SharpHook | 6.1.2 | global low-level mouse hook (edge trigger, drag tracking) |
| Hardcodet.NotifyIcon.Wpf | 2.0.1 | tray icon and menu |
| WpfScreenHelper | 2.1.1 | monitor/work-area geometry |
| ControlzEx | 7.0.1 | window chrome helpers |
| AsyncAwaitBestPractices | 9.0.0 | SafeFireAndForget |
WinRT surface (Windows.Graphics.Capture, Windows.UI.Composition, Windows.Graphics.DirectX) comes
from the 10.0.19041.0 target platform, not a package. That platform floor is what sets the app's
minimum OS.
Every method is [Conditional("DEBUG")], so logging compiles away entirely in Release. Output goes
through a TextWriterTraceListener to stagemanager.log beside the executable
(AppContext.BaseDirectory). Tag strings (CAPSESS, COMPTHUMB, ANIM, TILT, SHUTDOWN) are how
sessions are read back; MainWindow.xaml.cs:1055 emits a fixed-format geometry line that is parsed, so
its shape is an invariant.
- SDK pinned by
global.jsonto10.0.100-rc.2.25502.107,rollForward: latestPatch. SetVersionFromGitTagtarget runsgit describe --tags --abbrev=0, stripsv, setsVersion. A build with no tag reachable stays at1.0.0.Switch.System.Windows.Input.Stylus.DisableStylusAndTouchSupport=trueβ WPF'sPenThreadWorkerthrows on its own thread, which no handler can catch. App takes no pen input.- Release workflow:
.github/workflows/dotnet-desktop.yml, x64 + arm64.
MainWindow.xaml.csis 1 788 lines / ~70 members and mixes six concerns: scene projection, sidebar drag, visibility animation, icon overlay, window-mode switching, and the update UI. Largest single extraction candidates are the drag region (lines 678β980) and the update region (1 674β1 780).SceneManager.csat 885 lines couples grouping, switching, and strategy dispatch.