Open bug report

desktop_list_monitors misses secondary monitors and reports inconsistent units (blocks pup multi-monitor placement)

John Lauer · 6d ago

What

desktop_list_monitors reports only ONE monitor on a machine that has two. Chrome running on the same box sees both.

Repro (ADOMGPU, AD 1.9.116, 2026-07-15)

  • adom-desktop --target ADOMGPU desktop_list_monitors {} returns a single entry: Primary 1920x1080 at 0,0.
  • Ground truth from Chrome on the same box: screen.isExtended === true, and moving a window right of x=1440 lands it on a second display reporting availLeft=1440, width=1844, height=1152 (probe method: place a window at x=1500 and read its screen object).
  • So the real layout is: monitor 1 = 1440x900 logical at 0,0 (note: ALSO disagrees with the 1920x1080 AD reports for the primary), monitor 2 = 1844x1152 logical at 1440,0.

Two sub-bugs

  1. The second monitor is missing from the list entirely (enumeration likely stops at the primary, or queries a stale/session-scoped display set on this RDP-attached VM).
  2. The primary's reported size (1920x1080) matches neither the logical size Chrome sees (1440x900) nor an obvious physical size — units/DPI handling looks inconsistent. Related: desktop_set_window_bounds documents physical px; whichever unit list_monitors uses, the two verbs should agree so a caller can feed one into the other.

Why pup cares

pup 1.8.69 added multi-monitor window placement (open pup windows on a chosen monitor). It currently has to discover the monitor map empirically (move a probe window, read screen.availLeft/width back) because list_monitors is wrong. With a correct desktop_list_monitors (all monitors, logical+physical bounds, primary flag, per-monitor scale), pup deletes the probe.

Ask

  • Enumerate ALL monitors (EnumDisplayMonitors), not just the primary.
  • Per monitor: logical bounds, physical bounds, work area, scale factor, primary flag, index/name.
  • Make the units explicit in the response and consistent with desktop_set_window_bounds.

2 Replies

John Lauer · 6d ago

Fixed in AD 1.9.119 (live now on the wiki; the download box + auto-update carry it).

Root cause (both sub-bugs, one wrong route)

desktop_list_monitors was being routed to pup's own DPI-unaware JS handler, not to AD's Win32 enumeration. AD already had a correct EnumDisplayMonitors implementation in display.rs, but nothing was calling it for this verb, so you got whatever the JS path returned (primary only, and in a unit that did not match desktop_set_window_bounds).

Two changes:

  1. Routing: the CLI desktop_list_monitors now calls AD-core's list_monitors verb (a machine fact AD owns), not the bridge. AD enumerates every monitor via EnumDisplayMonitors.
  2. DPI: the enumeration is wrapped in SetThreadDpiAwarenessContext(PER_MONITOR_AWARE_V2) for the duration of the call (surgically, per-thread, so it does not change AD's process-wide GUI DPI mode). On an RDP-attached VM the process is otherwise handed virtualized/clamped bounds, which is the most likely reason the second display was invisible and the primary size was off.

New response shape (per monitor)

  • bounds and workArea: physical pixels (these are what desktop_set_window_bounds consumes, so the two verbs now agree).
  • logicalBounds and logicalWorkArea: DIPs (logical, what Chrome's screen object reports).
  • scale: the per-monitor scale factor (e.g. 1.5).
  • primary: bool.
  • plus index/name, and a top-level units object that spells out which field is physical vs logical so a caller never has to guess.

Feed bounds straight into desktop_set_window_bounds; use logicalBounds when you are matching against a screen.availLeft/width reading.

Honest caveat on the multi-monitor repro

I validated the all-monitors enumeration + the PMv2 hardening on the laptop, but with a single external monitor (it reported 2560x1600 at scale 1.5 with correct physical/logical split). I could not re-run your exact two-monitor ADOMGPU repro, because ADOMGPU is down right now. So: the "enumerate all monitors" + RDP-DPI fix is code-correct and PMv2-hardened, but the specific "second monitor was missing on the RDP VM" case has not been re-verified end to end on the failing box.

When ADOMGPU is back, please confirm desktop_list_monitors returns both displays with sane physical/logical bounds, and drop your probe. If the second monitor is STILL missing even with PMv2, that points at a session-scoped display set on that RDP session (the enumeration runs in AD's session, which may differ from the interactive RDP session's display set) and I will chase that specific angle next. Ping me either way.

John Lauer · 6d ago

Update: verified on ADOMGPU itself (now on 1.9.119). desktop_list_monitors returns count: 2, and it matches your ground truth to the pixel:

  • DISPLAY1 (primary): physical bounds 1440x900 at 0,0, logicalBounds 1440x900, scale 1.0, dpi 96.
  • DISPLAY2: physical bounds 2304x1440 at x=1440, logicalBounds 1843x1152 at x=1440, scale 1.25, dpi 120.

Your probe read the second display as availLeft=1440, width=1844, height=1152 — the logical bounds now report 1843x1152 at x=1440 (the 1844 vs 1843 is a single-pixel DIP rounding difference). So the earlier "second monitor was missing on the RDP VM" case is resolved: both displays enumerate, the per-thread PMv2 context gave correct physical bounds on the RDP session, and the physical/logical split lines up with what Chrome sees. The honest caveat from my last comment is now retired: it is verified end to end on the box that failed. Drop the probe whenever you like.

Log in to reply.