Skip to content

Add Server dialogs clamp to the PRIMARY monitor's work area, not the monitor they are on #1891

Description

@erikdarlingdata

The two Add Server dialogs size and reposition themselves against SystemParameters.WorkArea, which always reports the primary monitor's work area regardless of which monitor the dialog is actually on. Raised in review of #1829 (the PR that fixed the off-screen footer) and confirmed still present on dev.

Where

  • Lite/Windows/AddServerDialog.xaml.cs:656 (the SizeChanged clamp)
  • Lite/Windows/AddServerDialog.xaml:6 (MaxHeight="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Height}")
  • Darling/PerformanceMonitor.Darling.Viewer/AddServerDialog.xaml.cs:608 and its .xaml:6 twin

Why it matters

On a multi-monitor setup where the dialog opens on a secondary monitor with a different resolution or work area than the primary, both the clamp and the MaxHeight binding compute against the wrong monitor's bounds. Where the secondary monitor is SHORTER than the primary, this reproduces the exact off-screen-footer bug #1829 fixed: the dialog is allowed to grow to the primary's height and its buttons fall below the secondary's visible area.

The MaxHeight binding is worse than the clamp because it is evaluated once at load and never re-evaluated - moving the window to another monitor does not update it.

This is not a regression from #1829. It mirrors the deprecated Dashboard's SizeToWorkArea() pattern, which has the same limitation, and is inherited rather than introduced. Filing it because screen-overflow correctness is the whole point of that fix, so the remaining hole should be tracked rather than left in a review thread.

Shape of a fix

Resolve the monitor the window is actually on, then clamp to that monitor's work area:

  • System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea (needs a WinForms reference, already a common WPF workaround), or
  • P/Invoke MonitorFromWindow + GetMonitorInfo (no extra reference, more code).

Either way the MaxHeight binding has to become code-behind driven off the same resolution and re-run on LocationChanged, since a static binding cannot follow the window between monitors. Both apps must change together - Lite and the Darling Viewer are twins here.

Not mechanical: it needs a per-monitor DPI/coordinate decision (WinForms Screen reports physical pixels while WPF works in DIPs, so the result has to be converted through the window's PresentationSource transform) and touching the same code path in both apps.

Activity

  1. erikdarlingdata commented on Jul 31, 2026

    @erikdarlingdata
    OwnerAuthor

    Shipped in #1923: per-monitor work-area clamp via MonitorFromWindow + GetMonitorInfo in the shared PerformanceMonitor.Ui (neither app references WinForms, so no Screen.FromHandle). The DIP conversion is load-bearing - GetMonitorInfo answers in physical pixels, and on a 150%-scaled monitor an unconverted clamp is worse than the bug - so the transform comes off the window's own PresentationSource. LocationChanged re-clamps when the dialog moves to a different monitor (the old XAML MaxHeight was read once at load). Every failure path falls back to SystemParameters.WorkArea, so single-monitor behavior is provably unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions