qt5base-lts/tests/manual/startsystemmove/main.cpp
Johan Klokkhammer Helsing a611c632bb 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>
2020-01-28 16:52:13 +01:00

112 lines
3.6 KiB
C++

/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui>
constexpr qreal border = 20;
class Window : public QRasterWindow
{
public:
explicit Window(QWindow *parent = nullptr) : QRasterWindow(parent)
{
resize(300, 200);
setMinimumSize(QSize(border*2, border*2));
}
protected:
void resizeOrMove(const QPointF &p);
bool event(QEvent *event) override;
void paintEvent(QPaintEvent *event) override;
};
void Window::resizeOrMove(const QPointF &p)
{
Qt::Edges edges;
if (p.x() > width() - border)
edges |= Qt::RightEdge;
if (p.x() < border)
edges |= Qt::LeftEdge;
if (p.y() < border)
edges |= Qt::TopEdge;
if (p.y() > height() - border)
edges |= Qt::BottomEdge;
if (edges != 0) {
qDebug() << "startSystemResize" << edges;
if (startSystemResize(edges))
qDebug() << " -> supported";
else
qDebug() << " -> not supported";
} else {
qDebug() << "startSystemMove";
if (startSystemMove())
qDebug() << " -> supported";
else
qDebug() << " -> not supported";
}
}
bool Window::event(QEvent *event)
{
switch (event->type()) {
case QEvent::MouseButtonPress:
qDebug() << "Mouse press";
resizeOrMove(static_cast<QMouseEvent *>(event)->localPos());
return true;
case QEvent::TouchUpdate:
qDebug() << "Touch update";
resizeOrMove(static_cast<QTouchEvent *>(event)->touchPoints().first().pos());
return true;
case QEvent::TouchBegin:
qDebug() << "Touch begin";
resizeOrMove(static_cast<QTouchEvent *>(event)->touchPoints().first().pos());
return true;
default:
return QRasterWindow::event(event);
}
}
void Window::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
QRect fullRect(0, 0, width(), height());
QRect innerRect = fullRect.marginsRemoved(QMargins(border, border, border, border));
painter.fillRect(fullRect, QGradient::WarmFlame);
painter.fillRect(innerRect, QGradient::NightFade);
painter.drawText(QRectF(0, 0, width(), height()), Qt::AlignCenter, QStringLiteral("Click mouse or touch to move window\nDrag along the sides to resize."));
}
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
Window window;
window.show();
return app.exec();
}