diff options
Diffstat (limited to 'src/widgets/widgets/qmainwindowlayout.cpp')
-rw-r--r-- | src/widgets/widgets/qmainwindowlayout.cpp | 43 |
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); |