diff options
Diffstat (limited to 'src/gui/kernel/qwindow.cpp')
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 119 |
1 files changed, 107 insertions, 12 deletions
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 94a34b5c27..93edfe6331 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -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); @@ -605,6 +629,22 @@ WId QWindow::winId() const return d->platformWindow->winId(); } + /*! + Returns the parent window, if any. + + If \a mode is IncludeTransients, then the transient parent is returned + if there is no parent. + + A window without a parent is known as a top level window. + + \since 5.9 +*/ +QWindow *QWindow::parent(AncestorMode mode) const +{ + Q_D(const QWindow); + return d->parentWindow ? d->parentWindow : (mode == IncludeTransients ? transientParent() : nullptr); +} + /*! Returns the parent window, if any. @@ -797,10 +837,15 @@ QSurfaceFormat QWindow::format() const The actual window flags might differ from the flags set with setFlags() if the requested flags could not be fulfilled. + + \sa setFlag() */ void QWindow::setFlags(Qt::WindowFlags flags) { Q_D(QWindow); + if (d->windowFlags == flags) + return; + if (d->platformWindow) d->platformWindow->setWindowFlags(flags); d->windowFlags = flags; @@ -813,6 +858,23 @@ Qt::WindowFlags QWindow::flags() const } /*! + \since 5.9 + + Sets the window flag \a flag on this window if \a on is true; + otherwise clears the flag. + + \sa setFlags(), flags(), type() +*/ +void QWindow::setFlag(Qt::WindowType flag, bool on) +{ + Q_D(QWindow); + if (on) + setFlags(d->windowFlags | flag); + else + setFlags(d->windowFlags & ~flag); +} + +/*! Returns the type of the window. This returns the part of the window flags that represents @@ -920,6 +982,9 @@ QIcon QWindow::icon() const void QWindow::raise() { Q_D(QWindow); + + d->updateSiblingPosition(QWindowPrivate::PositionTop); + if (d->platformWindow) d->platformWindow->raise(); } @@ -932,6 +997,9 @@ void QWindow::raise() void QWindow::lower() { Q_D(QWindow); + + d->updateSiblingPosition(QWindowPrivate::PositionBottom); + if (d->platformWindow) d->platformWindow->lower(); } @@ -1065,11 +1133,10 @@ bool QWindow::isActive() const if (focus == this) return true; - if (!parent() && !transientParent()) { + if (QWindow *p = parent(IncludeTransients)) + return p->isActive(); + else return isAncestorOf(focus); - } else { - return (parent() && parent()->isActive()) || (transientParent() && transientParent()->isActive()); - } } /*! @@ -1233,8 +1300,10 @@ bool QWindow::isAncestorOf(const QWindow *child, AncestorMode mode) const if (child->parent() == this || (mode == IncludeTransients && child->transientParent() == this)) return true; - return (child->parent() && isAncestorOf(child->parent(), mode)) - || (mode == IncludeTransients && child->transientParent() && isAncestorOf(child->transientParent(), mode)); + if (child->parent(mode) && isAncestorOf(child->parent(mode), mode)) + return true; + + return false; } /*! @@ -1455,6 +1524,8 @@ void QWindow::setSizeIncrement(const QSize &size) Sets the geometry of the window, excluding its window frame, to a rectangle constructed from \a posx, \a posy, \a w and \a h. + The geometry is in relation to the virtualGeometry() of its screen. + \sa geometry() */ void QWindow::setGeometry(int posx, int posy, int w, int h) @@ -1465,6 +1536,8 @@ void QWindow::setGeometry(int posx, int posy, int w, int h) /*! \brief Sets the geometry of the window, excluding its window frame, to \a rect. + The geometry is in relation to the virtualGeometry() of its screen. + \sa geometry() */ void QWindow::setGeometry(const QRect &rect) @@ -1526,6 +1599,8 @@ QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry) /*! Returns the geometry of the window, excluding its window frame. + The geometry is in relation to the virtualGeometry() of its screen. + \sa frameMargins(), frameGeometry() */ QRect QWindow::geometry() const @@ -1552,6 +1627,8 @@ QMargins QWindow::frameMargins() const /*! Returns the geometry of the window, including its window frame. + The geometry is in relation to the virtualGeometry() of its screen. + \sa geometry(), frameMargins() */ QRect QWindow::frameGeometry() const @@ -1584,6 +1661,8 @@ QPoint QWindow::framePosition() const /*! Sets the upper left position of the window (\a point) including its window frame. + The position is in relation to the virtualGeometry() of its screen. + \sa setGeometry(), frameGeometry() */ void QWindow::setFramePosition(const QPoint &point) @@ -1601,6 +1680,8 @@ void QWindow::setFramePosition(const QPoint &point) /*! \brief set the position of the window on the desktop to \a pt + The position is in relation to the virtualGeometry() of its screen. + \sa position() */ void QWindow::setPosition(const QPoint &pt) @@ -1611,6 +1692,8 @@ void QWindow::setPosition(const QPoint &pt) /*! \brief set the position of the window on the desktop to \a posx, \a posy + The position is in relation to the virtualGeometry() of its screen. + \sa position() */ void QWindow::setPosition(int posx, int posy) @@ -1787,8 +1870,9 @@ QScreen *QWindow::screen() const If the window has been created, it will be recreated on the \a newScreen. - Note that if the screen is part of a virtual desktop of multiple screens, - the window can appear on any of the screens returned by QScreen::virtualSiblings(). + \note If the screen is part of a virtual desktop of multiple screens, + the window will not move automatically to \a newScreen. To place the + window relative to the screen, use the screen's topLeft() position. This function only works for top level windows. @@ -2377,6 +2461,20 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const return pos - d->globalPosition(); } +QPoint QWindowPrivate::globalPosition() const +{ + Q_Q(const QWindow); + QPoint offset = q->position(); + for (const QWindow *p = q->parent(); p; p = p->parent()) { + if (p->type() != Qt::ForeignWindow) { + offset += p->position(); + } else { // Use mapToGlobal() for foreign windows + offset += p->mapToGlobal(QPoint(0, 0)); + break; + } + } + return offset; +} Q_GUI_EXPORT QWindowPrivate *qt_window_private(QWindow *window) { @@ -2416,10 +2514,7 @@ QWindow *QWindowPrivate::topLevelWindow() const QWindow *window = const_cast<QWindow *>(q); while (window) { - QWindow *parent = window->parent(); - if (!parent) - parent = window->transientParent(); - + QWindow *parent = window->parent(QWindow::IncludeTransients); if (!parent) break; |