QDockWidget: Remove "group" bool trap
The unplug() and startDrag() functions of QMainWindowLayout and QDockWidget used a boolean argument specifying whether a single dock widget or a group of dock widgets should be unplugged. The argument defaulted to true. That has lead to inconsistent unplug operations, broken item_lists and crashes, especially when the methods were called without an argument. To improve code readability, replace bool trap with a meaningful enum. Remove default arguments, in order to force explicit calls. This patch does not change behavior, it is just carved out to facilitate reviews. Task-number: QTBUG-118578 Task-number: QTBUG-118579 Pick-to: 6.5 Change-Id: I50341b055f0bb76c2797b2fb1126a10de1fee7dd Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit c93ab8c2a015b40b9a487ed9f23a72aebea8d52a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
8702853313
commit
b65e1141da
@ -770,7 +770,7 @@ void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca)
|
|||||||
tabbed widgets, and false if the dock widget should always be dragged
|
tabbed widgets, and false if the dock widget should always be dragged
|
||||||
alone.
|
alone.
|
||||||
*/
|
*/
|
||||||
void QDockWidgetPrivate::startDrag(bool group)
|
void QDockWidgetPrivate::startDrag(DragScope scope)
|
||||||
{
|
{
|
||||||
Q_Q(QDockWidget);
|
Q_Q(QDockWidget);
|
||||||
|
|
||||||
@ -782,7 +782,7 @@ void QDockWidgetPrivate::startDrag(bool group)
|
|||||||
|
|
||||||
bool wasFloating = q->isFloating();
|
bool wasFloating = q->isFloating();
|
||||||
|
|
||||||
state->widgetItem = layout->unplug(q, group);
|
state->widgetItem = layout->unplug(q, scope);
|
||||||
if (state->widgetItem == nullptr) {
|
if (state->widgetItem == nullptr) {
|
||||||
/* Dock widget has a QMainWindow parent, but was never inserted with
|
/* Dock widget has a QMainWindow parent, but was never inserted with
|
||||||
QMainWindow::addDockWidget, so the QMainWindowLayout has no
|
QMainWindow::addDockWidget, so the QMainWindowLayout has no
|
||||||
@ -996,7 +996,7 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
startDrag();
|
startDrag(DragScope::Group);
|
||||||
q->grabMouse();
|
q->grabMouse();
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
@ -1105,7 +1105,7 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event)
|
|||||||
break;
|
break;
|
||||||
state->ctrlDrag = (event->modifiers() & Qt::ControlModifier) ||
|
state->ctrlDrag = (event->modifiers() & Qt::ControlModifier) ||
|
||||||
(!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating());
|
(!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating());
|
||||||
startDrag();
|
startDrag(DragScope::Group);
|
||||||
break;
|
break;
|
||||||
case QEvent::NonClientAreaMouseMove:
|
case QEvent::NonClientAreaMouseMove:
|
||||||
if (state == nullptr || !state->dragging)
|
if (state == nullptr || !state->dragging)
|
||||||
|
@ -51,6 +51,11 @@ class QDockWidgetPrivate : public QWidgetPrivate
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class DragScope {
|
||||||
|
Group,
|
||||||
|
Widget
|
||||||
|
};
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void _q_toggleView(bool); // private slot
|
void _q_toggleView(bool); // private slot
|
||||||
void _q_toggleTopLevel(); // private slot
|
void _q_toggleTopLevel(); // private slot
|
||||||
@ -86,7 +91,7 @@ public:
|
|||||||
void setWindowState(bool floating, bool unplug = false, const QRect &rect = QRect());
|
void setWindowState(bool floating, bool unplug = false, const QRect &rect = QRect());
|
||||||
void nonClientAreaMouseEvent(QMouseEvent *event);
|
void nonClientAreaMouseEvent(QMouseEvent *event);
|
||||||
void initDrag(const QPoint &pos, bool nca);
|
void initDrag(const QPoint &pos, bool nca);
|
||||||
void startDrag(bool group = true);
|
void startDrag(DragScope scope);
|
||||||
void endDrag(bool abort = false);
|
void endDrag(bool abort = false);
|
||||||
void moveEvent(QMoveEvent *event);
|
void moveEvent(QMoveEvent *event);
|
||||||
void recalculatePressPos(QResizeEvent *event);
|
void recalculatePressPos(QResizeEvent *event);
|
||||||
|
@ -1792,7 +1792,7 @@ void QMainWindowTabBar::mouseMoveEvent(QMouseEvent *e)
|
|||||||
QDockWidgetPrivate *dockPriv = static_cast<QDockWidgetPrivate *>(QObjectPrivate::get(draggingDock));
|
QDockWidgetPrivate *dockPriv = static_cast<QDockWidgetPrivate *>(QObjectPrivate::get(draggingDock));
|
||||||
QDockWidgetLayout *dwlayout = static_cast<QDockWidgetLayout *>(draggingDock->layout());
|
QDockWidgetLayout *dwlayout = static_cast<QDockWidgetLayout *>(draggingDock->layout());
|
||||||
dockPriv->initDrag(dwlayout->titleArea().center(), true);
|
dockPriv->initDrag(dwlayout->titleArea().center(), true);
|
||||||
dockPriv->startDrag(false);
|
dockPriv->startDrag(QDockWidgetPrivate::DragScope::Widget);
|
||||||
if (dockPriv->state)
|
if (dockPriv->state)
|
||||||
dockPriv->state->ctrlDrag = e->modifiers() & Qt::ControlModifier;
|
dockPriv->state->ctrlDrag = e->modifiers() & Qt::ControlModifier;
|
||||||
}
|
}
|
||||||
@ -2552,25 +2552,25 @@ static QTabBar::Shape tabwidgetPositionToTabBarShape(QWidget *w)
|
|||||||
Returns the QLayoutItem of the dragged element.
|
Returns the QLayoutItem of the dragged element.
|
||||||
The layout item is kept in the layout but set as a gap item.
|
The layout item is kept in the layout but set as a gap item.
|
||||||
*/
|
*/
|
||||||
QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group)
|
QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, QDockWidgetPrivate::DragScope scope)
|
||||||
{
|
{
|
||||||
#if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
|
#if QT_CONFIG(dockwidget) && QT_CONFIG(tabwidget)
|
||||||
auto *groupWindow = qobject_cast<const QDockWidgetGroupWindow *>(widget->parentWidget());
|
auto *groupWindow = qobject_cast<const QDockWidgetGroupWindow *>(widget->parentWidget());
|
||||||
if (!widget->isWindow() && groupWindow) {
|
if (!widget->isWindow() && groupWindow) {
|
||||||
if (group && groupWindow->tabLayoutInfo()) {
|
if (scope == QDockWidgetPrivate::DragScope::Group && groupWindow->tabLayoutInfo()) {
|
||||||
// We are just dragging a floating window as it, not need to do anything, we just have to
|
// We are just dragging a floating window as it, not need to do anything, we just have to
|
||||||
// look up the corresponding QWidgetItem* if it exists
|
// look up the corresponding QWidgetItem* if it exists
|
||||||
if (QDockAreaLayoutInfo *info = dockInfo(widget->parentWidget())) {
|
if (QDockAreaLayoutInfo *info = dockInfo(widget->parentWidget())) {
|
||||||
QList<int> groupWindowPath = info->indexOf(widget->parentWidget());
|
QList<int> groupWindowPath = info->indexOf(widget->parentWidget());
|
||||||
return groupWindowPath.isEmpty() ? nullptr : info->item(groupWindowPath).widgetItem;
|
return groupWindowPath.isEmpty() ? nullptr : info->item(groupWindowPath).widgetItem;
|
||||||
}
|
}
|
||||||
qCDebug(lcQpaDockWidgets) << "Drag only:" << widget << "Group:" << group;
|
qCDebug(lcQpaDockWidgets) << "Drag only:" << widget << "Group:" << (scope == QDockWidgetPrivate::DragScope::Group);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
QList<int> path = groupWindow->layoutInfo()->indexOf(widget);
|
QList<int> path = groupWindow->layoutInfo()->indexOf(widget);
|
||||||
QDockAreaLayoutItem parentItem = groupWindow->layoutInfo()->item(path);
|
QDockAreaLayoutItem parentItem = groupWindow->layoutInfo()->item(path);
|
||||||
QLayoutItem *item = parentItem.widgetItem;
|
QLayoutItem *item = parentItem.widgetItem;
|
||||||
if (group && path.size() > 1
|
if (scope == QDockWidgetPrivate::DragScope::Group && path.size() > 1
|
||||||
&& unplugGroup(this, &item, parentItem)) {
|
&& unplugGroup(this, &item, parentItem)) {
|
||||||
qCDebug(lcQpaDockWidgets) << "Unplugging:" << widget << "from" << item;
|
qCDebug(lcQpaDockWidgets) << "Unplugging:" << widget << "from" << item;
|
||||||
return item;
|
return item;
|
||||||
@ -2663,7 +2663,7 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group)
|
|||||||
if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) {
|
if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) {
|
||||||
Q_ASSERT(path.constFirst() == 1);
|
Q_ASSERT(path.constFirst() == 1);
|
||||||
#if QT_CONFIG(tabwidget)
|
#if QT_CONFIG(tabwidget)
|
||||||
if (group && (dockOptions & QMainWindow::GroupedDragging) && path.size() > 3
|
if (scope == QDockWidgetPrivate::DragScope::Group && (dockOptions & QMainWindow::GroupedDragging) && path.size() > 3
|
||||||
&& unplugGroup(this, &item,
|
&& unplugGroup(this, &item,
|
||||||
layoutState.dockAreaLayout.item(path.mid(1, path.size() - 2)))) {
|
layoutState.dockAreaLayout.item(path.mid(1, path.size() - 2)))) {
|
||||||
path.removeLast();
|
path.removeLast();
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "QtCore/qset.h"
|
#include "QtCore/qset.h"
|
||||||
#include "private/qlayoutengine_p.h"
|
#include "private/qlayoutengine_p.h"
|
||||||
#include "private/qwidgetanimator_p.h"
|
#include "private/qwidgetanimator_p.h"
|
||||||
|
#include "private/qdockwidget_p.h"
|
||||||
|
|
||||||
#if QT_CONFIG(dockwidget)
|
#if QT_CONFIG(dockwidget)
|
||||||
#include "qdockarealayout_p.h"
|
#include "qdockarealayout_p.h"
|
||||||
@ -569,7 +570,7 @@ public:
|
|||||||
|
|
||||||
void hover(QLayoutItem *hoverTarget, const QPoint &mousePos);
|
void hover(QLayoutItem *hoverTarget, const QPoint &mousePos);
|
||||||
bool plug(QLayoutItem *widgetItem);
|
bool plug(QLayoutItem *widgetItem);
|
||||||
QLayoutItem *unplug(QWidget *widget, bool group = false);
|
QLayoutItem *unplug(QWidget *widget, QDockWidgetPrivate::DragScope scope);
|
||||||
void revert(QLayoutItem *widgetItem);
|
void revert(QLayoutItem *widgetItem);
|
||||||
void applyState(QMainWindowLayoutState &newState, bool animate = true);
|
void applyState(QMainWindowLayoutState &newState, bool animate = true);
|
||||||
void restore(bool keepSavedState = false);
|
void restore(bool keepSavedState = false);
|
||||||
|
@ -181,7 +181,7 @@ void QToolBarPrivate::startDrag(bool moving)
|
|||||||
const bool wasFloating = q->isFloating();
|
const bool wasFloating = q->isFloating();
|
||||||
|
|
||||||
if (!moving) {
|
if (!moving) {
|
||||||
state->widgetItem = layout->unplug(q);
|
state->widgetItem = layout->unplug(q, QDockWidgetPrivate::DragScope::Group);
|
||||||
Q_ASSERT(state->widgetItem != nullptr);
|
Q_ASSERT(state->widgetItem != nullptr);
|
||||||
}
|
}
|
||||||
state->dragging = !moving;
|
state->dragging = !moving;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user