gdk/wayland: set_anchor_rect called with wrong y position in multi monitor setup
Steps to reproduce
- Set up multiple monitors where one is positioned at the top right corner of the other
- Open eg pavucontrol and click on the speaker selection button for an application
Current behavior
The popup is invisible, moving the window to the top, one at some point finds it way below the window (my guess is 1080px, because that's the relative y position of my monitors). I was only able to actually see the popup on sway because there I can move the window over the edge of the screen, on gnome-shell that's not possible.
Expected outcome
The popup should be positioned right under the cursor.
Version information
gtk 3.24.20-1 on Archlinux
Additional information
I was able to track down the issue to the set_anchor_rect call of the xdg_shell protocol. Apparently the y-value wrongly gets the position of the output added to it somewhere. I find it interesting, that it doesn't happen when the monitors are positioned exactly above each other. If the x position is just slightly off (eg the top one at 500 0, the bottom at 0 1080) there seems to also happen some misplacement in x direction of the popup. As this bug happens on sway and gnome-shell I assume it's a gtk bug rather than a compositor one.
Edit: relevant part of the WAYLAND_DEBUG=client log:
[881652,694] -> wl_compositor@6.create_surface(new id wl_surface@40)
[881652,901] -> wl_pointer@11.set_cursor(1620, wl_surface@19, 4, 4)
[881652,972] -> wl_surface@19.attach(wl_buffer@41, 0, 0)
[881653,022] -> wl_surface@19.set_buffer_scale(1)
[881653,045] -> wl_surface@19.damage(0, 0, 24, 24)
[881653,107] -> wl_surface@19.commit()
[881664,663] -> wl_compositor@6.create_surface(new id wl_surface@42)
[881665,724] -> xdg_wm_base@28.create_positioner(new id xdg_positioner@43)
[881665,759] -> xdg_positioner@43.set_size(1109, 89)
[881665,793] -> xdg_positioner@43.set_anchor_rect(517, 1080, 1, 1)
[881665,848] -> xdg_positioner@43.set_anchor(5)
[881665,869] -> xdg_positioner@43.set_gravity(8)
[881665,891] -> xdg_wm_base@28.get_xdg_surface(new id xdg_surface@44, wl_surface@42)
[881665,931] -> xdg_surface@44.get_popup(new id xdg_popup@45, xdg_surface@21, xdg_positioner@43)
[881665,982] -> xdg_positioner@43.destroy()
[881665,999] -> xdg_popup@45.grab(wl_seat@15, 1621)
[881666,067] -> wl_surface@42.commit()
[881666,216] -> wl_pointer@11.set_cursor(1620, wl_surface@19, 4, 4)
[881666,282] -> wl_surface@19.attach(wl_buffer@41, 0, 0)
[881666,327] -> wl_surface@19.set_buffer_scale(1)
[881666,347] -> wl_surface@19.damage(0, 0, 24, 24)
[881666,402] -> wl_surface@19.commit()
[881674,520] -> wl_surface@25.attach(wl_buffer@36, 0, 0)
[881674,607] -> wl_surface@25.set_buffer_scale(1)
[881674,630] -> wl_surface@25.damage(0, 0, 950, 1043)
[881674,687] -> xdg_toplevel@33.set_min_size(306, 142)
[881674,720] -> xdg_toplevel@33.set_max_size(0, 0)
[881674,753] -> xdg_surface@21.set_window_geometry(0, 0, 950, 1043)
[881674,830] -> wl_surface@25.frame(new id wl_callback@46)
[881674,859] -> wl_surface@25.commit()
[881674,941] wl_display@1.delete_id(43)
[881674,969] wl_surface@42.enter(wl_output@23)
[881674,994] xdg_popup@45.configure(517, 1080, 1109, 89)
If the monitors are positioned exactly above each other the set_anchor_rect call looks like that:
[535732,214] -> xdg_positioner@43.set_anchor_rect(419, 179, 1, 1)