Add Wayland docking support#844
Open
mliberty1 wants to merge 1 commit into
Open
Conversation
Wayland does not allow clients to move top level windows in screen coordinates and does not report the global cursor position, so the mouse tracked dragging used on the other platforms cannot work there. This commit implements docking via compositor driven drags instead: - Floating dock containers always use a native window decoration on Wayland, so the compositor (or Qt's client side decoration) handles moving of floating widgets - Undocking executes a QDrag with the MIME types that QWaylandDataDevice translates into an xdg_toplevel_drag_v1 request, so the floating widget window follows the drag cursor (CFloatingDockContainer::startPlatformDrag) - CDockContainerWidget accepts drops and shows the drop overlays driven by the drag and drop event positions instead of QCursor::pos(), which is stale during drag and drop on Wayland - Dragging the tab or title bar of a floating widget's single dock area drags the existing floating widget, so it can be docked back into another container; the dock area title bar stays visible in floating containers on Wayland because it is the only re-dock handle - The floating widget is not a child of the dock manager on Wayland. Showing a child floating widget turns the dock manager's child widgets into native windows; native children are wl_subsurfaces that take part in the compositor's drag and drop target picking and steal the drop focus from the dock container (likewise, the drop overlays must not use WA_TranslucentBackground, which would make them native) - The Qt::Tool stays-on-top emulation in the dock manager event filter is disabled on Wayland: changing window flags of a shown window recreates its surface, which detaches a running toplevel drag Verified on GNOME/Mutter 50.1 (Qt 6.11) with hardware-level input injection: undock, leave floating, move via decoration, and re-dock all work; X11/xcb behavior is unchanged (all changes are guarded by the new ads::internal::isWayland()). # Conflicts: # src/DockOverlay.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thanks for your great work on Qt-ADS! I have been using it in the Joulescope UI for many years, and it has been excellent. I have a number of customers affected by my UI issue #316, poor Wayland support. I tried to get someone on Upwork to fix this, but failed. Today, I worked with Claude Code / Fable to get this done.
This PR is a self-contained fix for Wayland. It's hopefully relatively easy to accept since most changes are gated to only affect Wayland. It does touch a bunch of files, though. The addition of
GlobalPosparameter to a few methods should be a flow-through no-change on other platforms.The overall experience is functional, but definitely not as slick as Windows and macOS. However, functional is an improvement and good enough to address my customers' concerns about slow performance using xcb.
Curated AI-generated summary follows:
Summary
This PR adds support for docking (undocking, moving, and re-docking floating widgets) on Wayland. It implements the approach outlined in #714 and follows the same mechanism that Qt itself uses for
QDockWidget/QToolBaron Wayland.Wayland forbids the techniques the docking system relies on elsewhere: a client cannot move its own top level windows in screen coordinates, cannot query the global cursor position, and cannot position one top level over another. Instead of the mouse tracked drag preview, undocking now performs a compositor driven drag:
QWidgettitle bar cannot).QDragcarrying the MIME types thatQWaylandDataDevicetranslates into anxdg_toplevel_drag_v1request, so the real floating window follows the cursor (no translucent preview).CDockContainerWidgetaccepts drops and drives the drop overlays from the drag-and-drop event positions instead ofQCursor::pos(), which is stale during a drag on Wayland.Platform impact
Every change is guarded by a new
ads::internal::isWayland()helper, so X11, Windows and macOS are unaffected. Where a function is shared (e.g. the drop overlay setup, now factored intoCDockContainerWidget::showDropOverlays()), the behavior is preserved on the other platforms. I verified the X11 mouse-drag path still works unchanged.This change is self-contained and does not depend on any other PR. On the non-Wayland paths the existing top-level
Qt::Tooloverlays are kept exactly as before; only on Wayland are the overlays child widgets.Requirements and behavioral notes (also updated in README)
xdg_toplevel_drag_v1support; on older Qt the code is harmless but the window will not follow the cursor, so X11/XWayland is still recommended there.Testing
Tested on GNOME / Mutter 50.1 with Qt 6.11 (PySide6): undock, move via the decoration, drop on an indicator to re-dock, drop outside to keep floating, re-dock a floating window via its title bar, floating-to-floating drop, and auto-hide undock. The X11/xcb path was regression tested and is unchanged.
Other compositors are not yet covered; on KDE/KWin a benign Qt warning (
This plugin supports grabbing the mouse only for popup windows) is emitted by Qt's own drag-and-drop internals and does not block docking.References