diff options
author | David Redondo <qt@david-redondo.de> | 2023-03-10 16:44:20 +0100 |
---|---|---|
committer | David Redondo <qt@david-redondo.de> | 2023-06-02 19:53:34 +0200 |
commit | 581c4bcb62a9d3cbb4c33df3f0f7a0a965225e74 (patch) | |
tree | 22da571a5a8c0d5fdbfd14a17654cf3a8b28d5ba /src/widgets/widgets/qmainwindowlayout.cpp | |
parent | 1eb4d17cb48a70501ebf51fc8732e14fec2cc12f (diff) |
Use platform drags for drags of docks and toolbars on wayland
On Wayland we can't know where windows are in relation to
each other so the whole mechanism was broken, toolbars
were unmovable once undocked and could be blindly redocked.
Dockwidgets had native toolbars to move them around but could
not be redocked.
This introduces an alternative code path that uses a platform
drag with a special mimetype that enables the platform to
issue a combined drag and window move using the relevant protocol.
Should the protocol not be available this doesn't make things
actively worse as it will be similar broken as before.
Fixes: QTBUG-87332
Change-Id: I3b8bdc0b1bc22569a64cb8bf7ca7d37d223936a6
Reviewed-by: David Edmundson <davidedmundson@kde.org>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/widgets/widgets/qmainwindowlayout.cpp')
-rw-r--r-- | src/widgets/widgets/qmainwindowlayout.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 6fb263f87d..0971ac5d58 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -24,6 +24,10 @@ #endif #include <qapplication.h> +#if QT_CONFIG(draganddrop) +#include <qdrag.h> +#endif +#include <qmimedata.h> #if QT_CONFIG(statusbar) #include <qstatusbar.h> #endif @@ -3008,6 +3012,41 @@ bool QMainWindowLayout::restoreState(QDataStream &stream) return true; } +#if QT_CONFIG(draganddrop) +bool QMainWindowLayout::needsPlatformDrag() +{ + static const bool wayland = + QGuiApplication::platformName().startsWith("wayland"_L1, Qt::CaseInsensitive); + return wayland; +} + +Qt::DropAction QMainWindowLayout::performPlatformWidgetDrag(QLayoutItem *widgetItem, + const QPoint &pressPosition) +{ + draggingWidget = widgetItem; + QWidget *widget = widgetItem->widget(); + auto drag = QDrag(widget); + auto mimeData = new QMimeData(); + auto window = widgetItem->widget()->windowHandle(); + + auto serialize = [](const auto &object) { + QByteArray data; + QDataStream dataStream(&data, QIODevice::WriteOnly); + dataStream << object; + return data; + }; + mimeData->setData("application/x-qt-mainwindowdrag-window"_L1, + serialize(reinterpret_cast<qintptr>(window))); + mimeData->setData("application/x-qt-mainwindowdrag-position"_L1, serialize(pressPosition)); + drag.setMimeData(mimeData); + + auto result = drag.exec(); + + draggingWidget = nullptr; + return result; +} +#endif + QT_END_NAMESPACE #include "moc_qmainwindowlayout_p.cpp" |