QWindow: re-order siblings on raise() and lower()

Same behavior as QWidget, and allows platform plugins to maintain order of
native windows based on the QWindow hierarchy, instead of having to manually
keep track of window levels.

Change-Id: Iacc7e9ee2527f0737c9da6debc7cec101064f782
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
bb10
Tor Arne Vestbø 2016-10-24 18:35:32 +02:00
parent d020af9092
commit 9428bca72e
3 changed files with 57 additions and 0 deletions

View File

@ -343,6 +343,30 @@ void QWindowPrivate::updateVisibility()
emit q->visibilityChanged(visibility);
}
void QWindowPrivate::updateSiblingPosition(SiblingPosition position)
{
Q_Q(QWindow);
if (!q->parent())
return;
QObjectList &siblings = q->parent()->d_ptr->children;
const int siblingCount = siblings.size() - 1;
if (siblingCount == 0)
return;
const int currentPosition = siblings.indexOf(q);
Q_ASSERT(currentPosition >= 0);
const int targetPosition = position == PositionTop ? siblingCount : 0;
if (currentPosition == targetPosition)
return;
siblings.move(currentPosition, targetPosition);
}
inline bool QWindowPrivate::windowRecreationRequired(QScreen *newScreen) const
{
Q_Q(const QWindow);
@ -920,6 +944,9 @@ QIcon QWindow::icon() const
void QWindow::raise()
{
Q_D(QWindow);
d->updateSiblingPosition(QWindowPrivate::PositionTop);
if (d->platformWindow)
d->platformWindow->raise();
}
@ -932,6 +959,9 @@ void QWindow::raise()
void QWindow::lower()
{
Q_D(QWindow);
d->updateSiblingPosition(QWindowPrivate::PositionBottom);
if (d->platformWindow)
d->platformWindow->lower();
}

View File

@ -144,6 +144,9 @@ public:
void updateVisibility();
void _q_clearAlert();
enum SiblingPosition { PositionTop, PositionBottom };
void updateSiblingPosition(SiblingPosition);
bool windowRecreationRequired(QScreen *newScreen) const;
void create(bool recursive);
void setTopLevelScreen(QScreen *newScreen, bool recreate);

View File

@ -65,6 +65,7 @@ private slots:
void positioningDuringMinimized();
void childWindowPositioning_data();
void childWindowPositioning();
void childWindowLevel();
void platformSurface();
void isExposed();
void isActive();
@ -596,6 +597,29 @@ void tst_QWindow::childWindowPositioning()
QCOMPARE(childWindowAfter.framePosition(), topLeftOrigin);
}
void tst_QWindow::childWindowLevel()
{
ColoredWindow topLevel(Qt::green);
topLevel.setObjectName("topLevel");
ColoredWindow yellowChild(Qt::yellow, &topLevel);
yellowChild.setObjectName("yellowChild");
ColoredWindow redChild(Qt::red, &topLevel);
redChild.setObjectName("redChild");
ColoredWindow blueChild(Qt::blue, &topLevel);
blueChild.setObjectName("blueChild");
const QObjectList &siblings = topLevel.children();
QCOMPARE(siblings.constFirst(), &yellowChild);
QCOMPARE(siblings.constLast(), &blueChild);
yellowChild.raise();
QCOMPARE(siblings.constLast(), &yellowChild);
blueChild.lower();
QCOMPARE(siblings.constFirst(), &blueChild);
}
// QTBUG-49709: Verify that the normal geometry is correctly restored
// when executing a sequence of window state changes. So far, Windows
// only where state changes have immediate effect.