summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qdockarealayout.cpp
diff options
context:
space:
mode:
authorAxel Spoerl <Axel.Spoerl@qt.io>2022-03-04 11:05:47 +0100
committerAxel Spoerl <axel.spoerl@qt.io>2022-04-19 17:12:20 +0000
commit9ff40b59da58160dc26c54204a615a2456e07405 (patch)
tree58139d24f3009ace9166c70e0b8f3d92ed432c47 /src/widgets/widgets/qdockarealayout.cpp
parent908e85cc85d18f56575ee040589bcd5745c62adb (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.cpp59
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;