summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbwindow.cpp
diff options
context:
space:
mode:
authorJohan Klokkhammer Helsing <johan.helsing@qt.io>2018-02-06 17:21:13 +0100
committerJohan Klokkhammer Helsing <johan.helsing@qt.io>2020-01-28 16:52:13 +0100
commita611c632bb906cf77dd3af29ddd7b166f79ad1b0 (patch)
tree931493fe4d13116efe738623f9e705c6025f1674 /src/plugins/platforms/xcb/qxcbwindow.cpp
parent6c3eb39832876a65291546476b92fd94950b1208 (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/plugins/platforms/xcb/qxcbwindow.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp62
1 files changed, 39 insertions, 23 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index adca902c69..96cd3a70ed 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -2161,6 +2161,7 @@ QXcbWindow *QXcbWindow::toWindow() { return this; }
void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source)
{
+ m_lastPointerPosition = local;
connection()->setTime(time);
Qt::MouseButton button = type == QEvent::MouseMove ? Qt::NoButton : connection()->button();
QWindowSystemInterface::handleMouseEvent(window(), time, local, global,
@@ -2345,45 +2346,66 @@ bool QXcbWindow::windowEvent(QEvent *event)
return QPlatformWindow::windowEvent(event);
}
-bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
+bool QXcbWindow::startSystemResize(Qt::Edges edges)
{
- return startSystemMoveResize(pos, corner);
+ return startSystemMoveResize(m_lastPointerPosition, edges);
}
-bool QXcbWindow::startSystemMove(const QPoint &pos)
+bool QXcbWindow::startSystemMove()
{
- return startSystemMoveResize(pos, 4);
+ return startSystemMoveResize(m_lastPointerPosition, 16);
}
-bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner)
+bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int edges)
{
- return false; // ### FIXME QTBUG-69716
const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE);
if (!connection()->wmSupport()->isSupportedByWM(moveResize))
return false;
- const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen());
-
// ### FIXME QTBUG-53389
- bool startedByTouch = connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner);
+ bool startedByTouch = connection()->startSystemMoveResizeForTouch(m_window, edges);
if (startedByTouch) {
- if (connection()->isUnity() || connection()->isGnome()) {
- // These desktops fail to move/resize via _NET_WM_MOVERESIZE (WM bug?).
+ if (connection()->isUnity()) {
+ // Unity fails to move/resize via _NET_WM_MOVERESIZE (WM bug?).
connection()->abortSystemMoveResizeForTouch();
return false;
}
- // KWin, Openbox, AwesomeWM have been tested to work with _NET_WM_MOVERESIZE.
+ // KWin, Openbox, AwesomeWM and Gnome have been tested to work with _NET_WM_MOVERESIZE.
} else { // Started by mouse press.
if (connection()->isUnity())
return false; // _NET_WM_MOVERESIZE on this WM is bouncy (WM bug?).
- doStartSystemMoveResize(globalPos, corner);
+ const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen());
+ doStartSystemMoveResize(globalPos, edges);
}
return true;
}
-void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner)
+static uint qtEdgesToXcbMoveResizeDirection(Qt::Edges edges)
+{
+ if (edges == (Qt::TopEdge | Qt::LeftEdge))
+ return 0;
+ if (edges == Qt::TopEdge)
+ return 1;
+ if (edges == (Qt::TopEdge | Qt::RightEdge))
+ return 2;
+ if (edges == Qt::RightEdge)
+ return 3;
+ if (edges == (Qt::RightEdge | Qt::BottomEdge))
+ return 4;
+ if (edges == Qt::BottomEdge)
+ return 5;
+ if (edges == (Qt::BottomEdge | Qt::LeftEdge))
+ return 6;
+ if (edges == Qt::LeftEdge)
+ return 7;
+
+ qWarning() << "Cannot convert " << edges << "to _NET_WM_MOVERESIZE direction.";
+ return 0;
+}
+
+void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int edges)
{
const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE);
xcb_client_message_event_t xev;
@@ -2394,16 +2416,10 @@ void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner)
xev.format = 32;
xev.data.data32[0] = globalPos.x();
xev.data.data32[1] = globalPos.y();
- if (corner == 4) {
+ if (edges == 16)
xev.data.data32[2] = 8; // move
- } else {
- const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner;
- const bool left = corner == Qt::BottomLeftCorner || corner == Qt::TopLeftCorner;
- if (bottom)
- xev.data.data32[2] = left ? 6 : 4; // bottomleft/bottomright
- else
- xev.data.data32[2] = left ? 0 : 2; // topleft/topright
- }
+ else
+ xev.data.data32[2] = qtEdgesToXcbMoveResizeDirection(Qt::Edges(edges));
xev.data.data32[3] = XCB_BUTTON_INDEX_1;
xev.data.data32[4] = 0;
xcb_ungrab_pointer(connection()->xcb_connection(), XCB_CURRENT_TIME);