diff options
author | Axel Spoerl <Axel.Spoerl@qt.io> | 2022-03-04 11:05:47 +0100 |
---|---|---|
committer | Axel Spoerl <axel.spoerl@qt.io> | 2022-04-19 17:12:20 +0000 |
commit | 9ff40b59da58160dc26c54204a615a2456e07405 (patch) | |
tree | 58139d24f3009ace9166c70e0b8f3d92ed432c47 /src/widgets/widgets/qdockarealayout.cpp | |
parent | 908e85cc85d18f56575ee040589bcd5745c62adb (diff) |
Fix QDockWidget parenting and dock permissions
Check DockWidgetArea permissions of QDockWidgetGroupWindows with single
dock widget. Obtain a dock widget's tab position from a dock widget
group window if it can't be established otherwise. Remove hardcoded
assumption that a dock widget is in the left dock. Both cases have lead
to inconsistent entries and dangling pointers in
QDockAreaLayoutInfo::item_list.
Remove warning: QMainWindowLayout::tabPosition called with out-of-bounds
value '0', which becomes obsolete by the fix.
Create a QDockWidgetGroup window prepered to become a floating tab,
whenever a dock widget is being hovered over. Store it in item_list so
it can be found and deleted when required.
No longer call e->ignore() after propagating close events to the first
dock widget and thus preventing others from receiving the event.
Add logging category qt.widgets.dockwidgets
Update dock widget autotest with tests to check the fixes mentioned:
plugging, unplugging, hiding, showing, closing and deleting.
Blackist closeAndDelete, floatingTabs test on macos, QEMU, arm, android
due to flaky isFloating() response after a dock widget has been closed
or plugged.
QSKIP dockPermissions and floatingTabs test on Windows due to mouse
simulation malfunction.
QSKIP hideAndShow test on Linux in case of xcb error (QTBUG-82059)
Fixes: QTBUG-99136
Pick-to: 6.3 6.2
Change-Id: Ibd353e0acc9831a0d67c9f682429ab46b94bdbb0
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/widgets/widgets/qdockarealayout.cpp')
-rw-r--r-- | src/widgets/widgets/qdockarealayout.cpp | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 626710cd54..8d9d81aa83 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -60,6 +60,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaDockWidgets, "qt.widgets.dockwidgets"); + // qmainwindow.cpp extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window); @@ -1223,8 +1225,10 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) continue; - Q_ASSERT(!(item.flags & QDockAreaLayoutItem::GapItem)); + Q_ASSERT_X(!(item.flags & QDockAreaLayoutItem::GapItem), + "QDockAreaLayoutInfo::insertGap", "inserting two gaps after each other"); space += item.size - pick(o, item.minimumSize()); + qCDebug(lcQpaDockWidgets) << "Item space:" << item.flags << this; } } @@ -1249,8 +1253,7 @@ bool QDockAreaLayoutInfo::insertGap(const QList<int> &path, QLayoutItem *dockWid // finally, insert the gap item_list.insert(index, gap_item); - -// dump(qDebug() << "insertGap() after:" << index << tabIndex, *this, QString()); + qCDebug(lcQpaDockWidgets) << "Insert gap after:" << index << this; return true; } @@ -2429,23 +2432,7 @@ QList<int> QDockAreaLayout::gapIndex(const QPoint &pos, bool disallowTabs) const const QDockAreaLayoutInfo &info = docks[i]; if (info.isEmpty()) { - QRect r; - switch (i) { - case QInternal::LeftDock: - r = QRect(rect.left(), rect.top(), EmptyDropAreaSize, rect.height()); - break; - case QInternal::RightDock: - r = QRect(rect.right() - EmptyDropAreaSize, rect.top(), - EmptyDropAreaSize, rect.height()); - break; - case QInternal::TopDock: - r = QRect(rect.left(), rect.top(), rect.width(), EmptyDropAreaSize); - break; - case QInternal::BottomDock: - r = QRect(rect.left(), rect.bottom() - EmptyDropAreaSize, - rect.width(), EmptyDropAreaSize); - break; - } + const QRect r = gapRect(static_cast<QInternal::DockPosition>(i)); if (r.contains(pos)) { if (opts & QMainWindow::ForceTabbedDocks && !info.item_list.isEmpty()) { //in case of ForceTabbedDocks, we pass -1 in order to force the gap to be tabbed @@ -2461,6 +2448,38 @@ QList<int> QDockAreaLayout::gapIndex(const QPoint &pos, bool disallowTabs) const return QList<int>(); } +QRect QDockAreaLayout::gapRect(QInternal::DockPosition dockPos) const +{ + Q_ASSERT_X(mainWindow, "QDockAreaLayout::gapRect", "Called without valid mainWindow pointer."); + + // Warn if main window is too small to create proper docks. + // Do not fail because this can be triggered by the user. + if (mainWindow->height() < (2 * EmptyDropAreaSize)) { + qCWarning(lcQpaDockWidgets, "QDockAreaLayout::gapRect: Main window height %i is too small. Docking will not be possible.", + mainWindow->height()); + + } + if (mainWindow->width() < (2 * EmptyDropAreaSize)) { + qCWarning(lcQpaDockWidgets, "QDockAreaLayout::gapRect: Main window width %i is too small. Docking will not be possible.", + mainWindow->width()); + } + + // Calculate rectangle of requested dock + switch (dockPos) { + case QInternal::LeftDock: + return QRect(rect.left(), rect.top(), EmptyDropAreaSize, rect.height()); + case QInternal::RightDock: + return QRect(rect.right() - EmptyDropAreaSize, rect.top(), EmptyDropAreaSize, rect.height()); + case QInternal::TopDock: + return QRect(rect.left(), rect.top(), rect.width(), EmptyDropAreaSize); + case QInternal::BottomDock: + return QRect(rect.left(), rect.bottom() - EmptyDropAreaSize, rect.width(), EmptyDropAreaSize); + case QInternal::DockCount: + break; + } + return QRect(); +} + QList<int> QDockAreaLayout::findSeparator(const QPoint &pos) const { QList<int> result; |