Tight loop moving window between monitors
If I have:
- A hidpi main output(2160x1440)
- An external 1080p monitor
- Open (say) a gedit window
- Drag it from the headerbar, from the main output to the secondary monitor till it scales down, and
- Keep dragging it to the bottom of the secondary monitor, and
- Keep dragging it slowly to the primary output along the bottom edge
I pretty reliably get gnome-shell stuck in a tight loop, till I kill the affected window. What happens is:
- While dragging, meta_window_move_resize_internal() is called with META_MOVE_RESIZE_USER_ACTION enabled.
- Eventually, meta_window_calculate_main_logical_monitor() finds the majority of the area of the window is on the primary monitor, and meta_window_update_main_monitor() changes it and rescales the window to 2x.
- The window goes from being "in all workspaces" to being in one, which between other things schedules a META_QUEUE_MOVE_RESIZE
- This ends up doing meta_window_resize_now() in a high priority enough idle that other stuff gets starved.
- This function ends up in move_resize_internal() with META_MOVE_RESIZE_USER_ACTION disabled
- As it's "not an user operation", different constraints that were ignored int he first move_resize_internal() call now apply
- constrain_fully_onscreen() is between them, and pushes the window upwards
- Of a sudden, the majority of the surface area is again on the secondary monitor, meta_window_update_main_monitor() moves it back to the secondary monitor, the window scales down to 1
- The workspace switches again to being "in all workspaces", another META_QUEUE_MOVE_RESIZE is scheduled
I have a patch that tries to avoid the META_QUEUE_MOVE_RESIZE if we are within a grab op so we don't apply unintended constrains, but I'm all ears if there's other ideas about how to cut this loop short.