Wrong wl_output.enter and leave events when tiling windows with super+left/right
I have a triple screen setup with a high dpi monitor in the middle. The leftmost screen is in portrait mode.
When I start applications, they appear on the middle screen, tiling them using super+right and super+right I can move them to the right or left side of the middle monitor. However, that often results in the window drawing itself with the wrong DPI.
I looked at the WAYLAND_DEBUG
output and saw that indeed the wl_output.enter/leave
events makes the client think it's on a different output than it actually is (and also that it's briefly entering and leaving outputs it's never been on.
It varies a bit with different applications...
With konsole
$ env WAYLAND_DEBUG=1 QT_QPA_PLATFORM=wayland konsole 2>&1 grep wl_output
[318239.605] wl_registry@2.global(4, "wl_output", 2)
[318239.613] -> wl_registry@2.bind(4, "wl_output", 2, new id [unknown]@6)
[318239.623] wl_registry@2.global(6, "wl_output", 2)
[318239.628] -> wl_registry@2.bind(6, "wl_output", 2, new id [unknown]@8)
[318239.652] -> zxdg_output_manager_v1@10.get_xdg_output(new id zxdg_output_v1@11, wl_output@6)
[318239.657] -> zxdg_output_manager_v1@10.get_xdg_output(new id zxdg_output_v1@12, wl_output@8)
[318239.806] wl_registry@2.global(44, "wl_output", 2)
[318239.811] -> wl_registry@2.bind(44, "wl_output", 2, new id [unknown]@18)
[318239.819] -> zxdg_output_manager_v1@10.get_xdg_output(new id zxdg_output_v1@19, wl_output@18)
[318240.002] wl_output@6.geometry(0, 321, 320, 520, 0, "DEL", "DELL U2412M", 0)
[318240.016] wl_output@6.mode(3, 1200, 1920, 59950)
[318240.033] wl_output@6.scale(1)
[318240.037] wl_output@6.done()
[318240.045] wl_output@8.geometry(5040, 1080, 300, 170, 0, "GEC", "Onlap1303", 0)
[318240.055] wl_output@8.mode(3, 1920, 1080, 59718)
[318240.062] wl_output@8.scale(1)
[318240.065] wl_output@8.done()
// wl_output 18 is the high dpi display in the middle:
[318240.126] wl_output@18.geometry(1200, 0, 620, 340, 0, "LEN", "Pro2840m", 0)
[318240.148] wl_output@18.mode(3, 3840, 2160, 59997)
[318240.154] wl_output@18.scale(2)
[318240.158] wl_output@18.done()
[318257.643] wl_registry@20.global(4, "wl_output", 2)
[318257.649] wl_registry@20.global(6, "wl_output", 2)
[318257.778] wl_registry@20.global(44, "wl_output", 2)
[318489.938] wl_registry@23.global(4, "wl_output", 2)
[318489.945] wl_registry@23.global(6, "wl_output", 2)
[318490.067] wl_registry@23.global(44, "wl_output", 2)
[318649.812] wl_surface@3.enter(wl_output@6) // This is the first bogus event (during application startup)
[318649.980] wl_surface@3.enter(wl_output@18)
[318649.987] wl_surface@3.leave(wl_output@6) // Fortunately there's a leave event so at least the client knows what screen it's on in the tend
// Application has started and is now positioned on the middle display.
// Pressing super+right (application tiles right, and this produces no events, which is good)
// Pressing super+left
[324597.572] wl_surface@3.enter(wl_output@8)
[324597.592] wl_surface@3.leave(wl_output@18)
// Application now thinks it's on the rightmost display,
// but it's actually tiled left on output 18
With weston-terminal
:
$ env WAYLAND_DEBUG=1 weston-terminal 2>&1 | grep wl_output
[1228792.272] wl_registry@2.global(4, "wl_output", 2)
[1228792.284] -> wl_registry@2.bind(4, "wl_output", 2, new id [unknown]@6)
[1228792.294] wl_registry@2.global(6, "wl_output", 2)
[1228792.303] -> wl_registry@2.bind(6, "wl_output", 2, new id [unknown]@7)
[1228792.641] wl_registry@2.global(44, "wl_output", 2)
[1228792.652] -> wl_registry@2.bind(44, "wl_output", 2, new id [unknown]@16)
[1228878.901] wl_output@6.geometry(0, 321, 320, 520, 0, "DEL", "DELL U2412M", 0)
[1228878.930] wl_output@6.mode(3, 1200, 1920, 59950)
[1228878.939] wl_output@6.scale(1)
[1228878.953] wl_output@6.done()
[1228878.956] wl_output@7.geometry(5040, 1080, 300, 170, 0, "GEC", "Onlap1303", 0)
[1228878.965] wl_output@7.mode(3, 1920, 1080, 59718)
[1228878.970] wl_output@7.scale(1)
[1228878.973] wl_output@7.done()
[1228879.027] wl_output@16.geometry(1200, 0, 620, 340, 0, "LEN", "Pro2840m", 0)
[1228879.038] wl_output@16.mode(3, 3840, 2160, 59997)
[1228879.044] wl_output@16.scale(2)
[1228879.047] wl_output@16.done()
[1228926.777] wl_surface@17.enter(wl_output@16)
[1228926.789] wl_surface@17.enter(wl_output@6)
[1229005.483] wl_surface@17.leave(wl_output@6) // Same as konsole, briefly enters the wrong output
// Pressing super+right
[1230332.587] wl_surface@17.enter(wl_output@6)
[1230360.698] wl_surface@17.enter(wl_output@7)
[1230360.721] wl_surface@17.leave(wl_output@6)
// another round of bogus enter/leave events. Client is now tiled
// right and the shadow extends into wl_output 7, so the client
// has the right info in the end
// Pressing super+left
// No events arrive, but the client is now positioned left on
// output 16, with the shadow extending into output 6, but from
// the client's point of view it's still on 16 and 7.
Dragging the windows with the mouse still works as expected.
Edited by Johan Klokkhammer Helsing