Commit f2db7ca
Wayland: dock widget drag-and-drop with in-window preview and native window drag (#844)
Qt Advanced Docking System could not dock on Wayland: a client cannot position
top-level windows and the global cursor position is unreliable, so the
mouse-tracked floating-widget drag never worked. This adds Wayland docking by
combining two mechanisms, selected by whether the drag stays inside its source
window.
Native cross-window drag (xdg_toplevel_drag_v1):
- CFloatingDockContainer::startPlatformDrag() runs a compositor-driven drag via
QDrag with the Qt main-window-drag MIME types, so a floating window is moved
by the compositor and can be dropped onto another window.
- Drop targets handle the drag in CDockContainerWidget dragEnter/Move/Leave/drop
events, with a recorded drop-candidate fallback for compositors that do not
deliver a drop event over the dragged window.
- The drop overlays (CDockOverlay) and the in-window drag preview are rendered
as child widgets of the relevant top-level window, because a Qt::Tool
top-level cannot be positioned in screen coordinates on Wayland.
- Floating containers use a native window with no parent on Wayland, and the
DockManager stays-on-top emulation that would recreate window surfaces is
skipped.
In-window preview, native only when leaving the window:
- While the cursor stays inside the source top-level window, a drag uses the
familiar in-window CFloatingDragPreview plus drop overlays (no new window),
driven by the reliable event-supplied position from the grabbing tab or title
bar and confined to the source container.
- When the cursor leaves the window, the preview is torn down and a real
CFloatingDockContainer is created and handed to startPlatformDrag() while the
press's implicit pointer grab is still held - a single continuous gesture.
This covers both the tab (CDockWidgetTab) and title-bar (CDockAreaTitleBar)
drag paths and applies to rearranging widgets inside floating windows too.
- The attach offset that places the new window under the cursor is only honored
while the toplevel is unmapped, so startPlatformDrag() runs QDrag::exec()
without waiting for exposure, and the caller passes the surface-local grab
offset explicitly - shifted by the window frame top and left margins - instead
of deriving it from the unmapped window's (meaningless) geometry, so the
grabbed content point stays under the cursor on both axes.
Style sheets and overlay lifetime:
- A Wayland floating container has no parent widget, so it does not inherit the
dock manager's effective style sheet through the widget hierarchy. The style
sheets along the dock manager parent chain are applied explicitly when the
window is created, and CDockManager re-applies them on QEvent::StyleChange so
a floating window keeps matching the docked content when the style sheet
changes at runtime (an application-wide qApp style sheet is still applied by
Qt automatically).
- The drop overlays are reparented into the top-level window they are shown over
and reparented back to the dock manager's window when hidden, so a
dock-manager-owned overlay is never left as a child of a transient floating
window that gets destroyed.
Saved layouts restore the docked arrangement, floating-window sizes and their
maximized/normal state, but not floating-window or main-window positions:
Wayland does not let a client position its own top-level windows, so the
compositor decides where restored windows appear.
Non-Wayland platforms (X11, Windows, macOS) are unaffected: every behavioral
change is gated on internal::isWayland(), and the shared drag-preview code keeps
using QCursor::pos() and the existing window positioning off Wayland.
Co-authored-by: Agent 01 <agent@jetperch.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 4124dde commit f2db7ca
16 files changed
Lines changed: 1212 additions & 125 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
183 | 183 | | |
184 | 184 | | |
185 | 185 | | |
| 186 | + | |
186 | 187 | | |
187 | 188 | | |
188 | 189 | | |
| |||
408 | 409 | | |
409 | 410 | | |
410 | 411 | | |
411 | | - | |
| 412 | + | |
412 | 413 | | |
413 | 414 | | |
414 | 415 | | |
415 | | - | |
416 | | - | |
| 416 | + | |
417 | 417 | | |
418 | 418 | | |
419 | 419 | | |
420 | 420 | | |
421 | 421 | | |
422 | 422 | | |
423 | 423 | | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
424 | 445 | | |
425 | 446 | | |
426 | 447 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
158 | 158 | | |
159 | 159 | | |
160 | 160 | | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
161 | 169 | | |
162 | 170 | | |
163 | 171 | | |
| |||
291 | 299 | | |
292 | 300 | | |
293 | 301 | | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
294 | 306 | | |
295 | 307 | | |
296 | 308 | | |
| |||
309 | 321 | | |
310 | 322 | | |
311 | 323 | | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
312 | 331 | | |
313 | 332 | | |
314 | 333 | | |
315 | | - | |
| 334 | + | |
316 | 335 | | |
317 | 336 | | |
318 | 337 | | |
| |||
334 | 353 | | |
335 | 354 | | |
336 | 355 | | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
337 | 359 | | |
338 | 360 | | |
339 | 361 | | |
340 | 362 | | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
341 | 399 | | |
342 | 400 | | |
343 | 401 | | |
| |||
691 | 749 | | |
692 | 750 | | |
693 | 751 | | |
694 | | - | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
695 | 762 | | |
696 | 763 | | |
697 | 764 | | |
698 | 765 | | |
699 | 766 | | |
700 | 767 | | |
701 | 768 | | |
702 | | - | |
| 769 | + | |
703 | 770 | | |
704 | 771 | | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
705 | 787 | | |
706 | 788 | | |
707 | 789 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
890 | 890 | | |
891 | 891 | | |
892 | 892 | | |
893 | | - | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
894 | 899 | | |
895 | 900 | | |
896 | 901 | | |
| |||
0 commit comments