diff options
author | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2018-02-06 17:21:13 +0100 |
---|---|---|
committer | Johan Klokkhammer Helsing <johan.helsing@qt.io> | 2020-01-28 16:52:13 +0100 |
commit | a611c632bb906cf77dd3af29ddd7b166f79ad1b0 (patch) | |
tree | 931493fe4d13116efe738623f9e705c6025f1674 /src/gui/kernel/qwindow.cpp | |
parent | 6c3eb39832876a65291546476b92fd94950b1208 (diff) |
Add QWindow::startSystemMove and startSystemResize
This can be used to create custom client side window decorations.
Refactors the xcb implementation to use edges instead of corners and we now use
the last mouse position for `root_x` and `root_y` in the `_NET_WM_MOVERESIZE`
event. Touch has also been changed, so just pick a point that's currently being
pressed.
The workaround for QTBUG-69716 has now been moved to QSizeGrip, as the comment
in the bug report says that it should ideally be fixed at the widget level.
On Windows, we no longer abort when GetSystemMenu returns false. I assume this
code was added to check whether the window didn't have any decorations and not
resize in that case. However, since the point of this patch is to let windows
without native decorations resize/move, it makes most sense to remove the
check.
Adds a manual test, which calls QWindow::startSystemMove and startSystemResize
on touch and mouse events.
[ChangeLog][QtGui] Added API for starting interactive window resize and move
operations handled by the system.
Fixes: QTBUG-73011
Change-Id: I7e47a0b2cff182af71d3d479d6e3746f08ea30aa
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/gui/kernel/qwindow.cpp')
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index dad1b6ba2d..c099ec9692 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1051,6 +1051,71 @@ void QWindow::lower() } /*! + \brief Start a system-specific resize operation + \since 5.15 + + Calling this will start an interactive resize operation on the window by platforms + that support it. The actual behavior may vary depending on the platform. Usually, + it will make the window resize so that its edge follows the mouse cursor. + + On platforms that support it, this method of resizing windows is preferred over + \c setGeometry, because it allows a more native look-and-feel of resizing windows, e.g. + letting the window manager snap this window against other windows, or special resizing + behavior with animations when dragged to the edge of the screen. + + \a edges should either be a single edge, or two adjacent edges (a corner). Other values + are not allowed. + + Returns true if the operation was supported by the system. +*/ +bool QWindow::startSystemResize(Qt::Edges edges) +{ + Q_D(QWindow); + if (Q_UNLIKELY(!isVisible() || !d->platformWindow || d->maximumSize == d->minimumSize)) + return false; + + const bool isSingleEdge = edges == Qt::TopEdge || edges == Qt::RightEdge || edges == Qt::BottomEdge || edges == Qt::LeftEdge; + const bool isCorner = + edges == (Qt::TopEdge | Qt::LeftEdge) || + edges == (Qt::TopEdge | Qt::RightEdge) || + edges == (Qt::BottomEdge | Qt::RightEdge) || + edges == (Qt::BottomEdge | Qt::LeftEdge); + + if (Q_UNLIKELY(!isSingleEdge && !isCorner)) { + qWarning() << "Invalid edges" << edges << "passed to QWindow::startSystemResize, ignoring."; + return false; + } + + return d->platformWindow->startSystemResize(edges); +} + +/*! + \brief Start a system-specific move operation + \since 5.15 + + Calling this will start an interactive move operation on the window by platforms + that support it. The actual behavior may vary depending on the platform. Usually, + it will make the window follow the mouse cursor until a mouse button is released. + + On platforms that support it, this method of moving windows is preferred over + \c setPosition, because it allows a more native look-and-feel of moving windows, e.g. + letting the window manager snap this window against other windows, or special tiling + or resizing behavior with animations when dragged to the edge of the screen. + Furthermore, on some platforms such as Wayland, \c setPosition is not supported, so + this is the only way the application can influence its position. + + Returns true if the operation was supported by the system. +*/ +bool QWindow::startSystemMove() +{ + Q_D(QWindow); + if (Q_UNLIKELY(!isVisible() || !d->platformWindow)) + return false; + + return d->platformWindow->startSystemMove(); +} + +/*! \property QWindow::opacity \brief The opacity of the window in the windowing system. \since 5.1 @@ -1793,7 +1858,10 @@ void QWindow::setFramePosition(const QPoint &point) The position is in relation to the virtualGeometry() of its screen. - \sa position() + For interactively moving windows, see startSystemMove(). For interactively + resizing windows, see startSystemResize(). + + \sa position(), startSystemMove() */ void QWindow::setPosition(const QPoint &pt) { @@ -1830,6 +1898,8 @@ void QWindow::setPosition(int posx, int posy) set the size of the window, excluding any window frame, to a QSize constructed from width \a w and height \a h + For interactively resizing windows, see startSystemResize(). + \sa size(), geometry() */ void QWindow::resize(int w, int h) |