summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qmainwindowlayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets/qmainwindowlayout.cpp')
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp43
1 files changed, 38 insertions, 5 deletions
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index db17e50d5c..34c18c8f88 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -1931,6 +1931,11 @@ bool QMainWindowTabBar::contains(const QDockWidget *dockWidget) const
return false;
}
+// When a dock widget is removed from a floating tab,
+// Events need to be processed for the tab bar to realize that the dock widget is gone.
+// In this case count() counts the dock widget in transition and accesses dockAt
+// with an out-of-bounds index.
+// => return nullptr in contrast to other xxxxxAt() functions
QDockWidget *QMainWindowTabBar::dockAt(int index) const
{
QMainWindowTabBar *that = const_cast<QMainWindowTabBar *>(this);
@@ -1938,10 +1943,39 @@ QDockWidget *QMainWindowTabBar::dockAt(int index) const
QDockAreaLayoutInfo *info = mlayout->dockInfo(that);
if (!info)
return nullptr;
+
const int itemIndex = info->tabIndexToListIndex(index);
- Q_ASSERT(itemIndex >= 0 && itemIndex < info->item_list.count());
- const QDockAreaLayoutItem &item = info->item_list.at(itemIndex);
- return item.widgetItem ? qobject_cast<QDockWidget *>(item.widgetItem->widget()) : nullptr;
+ if (itemIndex >= 0) {
+ Q_ASSERT(itemIndex < info->item_list.count());
+ const QDockAreaLayoutItem &item = info->item_list.at(itemIndex);
+ return item.widgetItem ? qobject_cast<QDockWidget *>(item.widgetItem->widget()) : nullptr;
+ }
+
+ return nullptr;
+}
+
+/*!
+ \internal
+ Move \a dockWidget to its ideal unplug position.
+ \list
+ \li If \a dockWidget has a title bar widget, place its center under the mouse cursor.
+ \li Otherwise place it in the middle of the title bar's long side, with a
+ QApplication::startDragDistance() offset on the short side.
+ \endlist
+ */
+static void moveToUnplugPosition(QPoint mouse, QDockWidget *dockWidget)
+{
+ Q_ASSERT(dockWidget);
+
+ if (auto *tbWidget = dockWidget->titleBarWidget()) {
+ dockWidget->move(mouse - tbWidget->rect().center());
+ return;
+ }
+
+ const bool vertical = dockWidget->features().testFlag(QDockWidget::DockWidgetVerticalTitleBar);
+ const int deltaX = vertical ? QApplication::startDragDistance() : dockWidget->width() / 2;
+ const int deltaY = vertical ? dockWidget->height() / 2 : QApplication::startDragDistance();
+ dockWidget->move(mouse - QPoint(deltaX, deltaY));
}
void QMainWindowTabBar::mouseMoveEvent(QMouseEvent *e)
@@ -1981,9 +2015,8 @@ void QMainWindowTabBar::mouseMoveEvent(QMouseEvent *e)
if (draggingDock) {
QDockWidgetPrivate *dockPriv = static_cast<QDockWidgetPrivate *>(QObjectPrivate::get(draggingDock));
if (dockPriv->state && dockPriv->state->dragging) {
- QPoint pos = e->globalPosition().toPoint() - dockPriv->state->pressPos;
- draggingDock->move(pos);
// move will call QMainWindowLayout::hover
+ moveToUnplugPosition(e->globalPosition().toPoint(), draggingDock);
}
}
QTabBar::mouseMoveEvent(e);