xfwm4: on a non-default X screen, window constrain uses screen 0's width ⇒ windows cannot be moved to the second monitor of a wider screen

Environment

  • xfwm4 4.20.0 (Xfce 4.20), Debian GNU/Linux 13 (trixie), kernel 6.12.111
  • One X server, two X screens (deliberate: each GPU renders its own screen)
    • Screen 0 = nvidia (Quadro P1000) → :0.0 = DP-3 1920x1080
    • Screen 1 = modesetting (i915) → :0.1 = HDMI-1 1920x1080 +0+0 and DP-2 1920x1080 +1920+0 ⇒ screen is 3840x1080
  • lightdm + xfce session; a single xfwm4 process manages both screens.

代码块

$ DISPLAY=:0.1 xdpyinfo | grep dimensions dimensions: 3840x1080 pixels $ DISPLAY=:0.1 xrandr | grep connected HDMI-1 connected 1920x1080+0+0 ... DP-2 connected 1920x1080+1920+0 ... $ DISPLAY=:0.1 xprop -root _NET_DESKTOP_GEOMETRY _NET_WORKAREA _NET_DESKTOP_GEOMETRY(CARDINAL) = 3840, 1080 _NET_WORKAREA(CARDINAL) = 0, 27, 3840, 1053, ...

Steps to reproduce

  1. On the non-default screen (:0.1, width 3840, made of two 1920 monitors):

    sh

    DISPLAY=:0.1 xclock -geometry 300x300+100+100 & W=$(DISPLAY=:0.1 xdotool search --class xclock | head -1) DISPLAY=:0.1 xdotool windowmove "$W" 3000 150 DISPLAY=:0.1 xwininfo -id "$W" | grep 'Absolute upper-left X'

  2. Observed (xfwm4 4.20.0):

    代码块

    request x=1000 -> got 1005 request x=1500 -> got 1505 request x=1900 -> got 1896 request x=1920 -> got 1896 request x=2100 -> got 1896 request x=2500 -> got 1896 request x=3000 -> got 1896

    ⇒ the window is clamped at x = 1896 = 1920 − 24, i.e. it can never leave the first monitor of the 3840-wide screen. Same result with a 2400 px wide window (so it is not a "window wider than the screen" artifact).

  3. Control: the same experiment on :0.0 (a genuine 1920-wide screen) also clamps at 1896 — correct there.

Expected

On a screen that is 3840 px wide, a window should be placeable at x=2100/3000 (i.e. on the second monitor). _NET_WORKAREA and _NET_DESKTOP_GEOMETRY both already report 3840.

Analysis / hypothesis

The clamp value equals screen 0's width − 24, on both screens, although the EWMH properties for screen 1 report 3840. That points at the constrain path (window move / ConfigureRequest) using a per-display (screen 0 / DefaultScreen) width rather than the screen_info of the client's own screen. _NET_WORKAREA is recomputed from RandR and is correct, so the two paths disagree.

Things already ruled out

  • Not stale state: xfwm4 --replace and a full restart give the same clamp.
  • Not a setting: toggling /general/snap_to_border, /general/tile_on_move, /general/wrap_windows (each off, then restored) does not change it.
  • Not the application: reproduced with xclock (no application involved).
  • Not RandR: outputs are configured at server start-up (DP-2 using initial mode 1920x1080 +1920+0 appears in Xorg's log during initial setup, before the WM starts).

Impact

On multi-monitor X screens other than screen 0, windows can only ever occupy the first monitor: dragging, tiling and programmatic placement all stop at the boundary. The only workaround we found is to make the multi-monitor screen be Screen 0.