diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 4bf96e277f..a66420c364 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -474,6 +474,25 @@ bool QPlatformWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) return false; } +/*! + Reimplement this method to start a system move operation if + the system supports it and return true to indicate success. + + The \a pos is a position of MouseButtonPress event or TouchBegin + event from a sequence of mouse events that triggered the movement. + It must be specified in window coordinates. + + The default implementation is empty and does nothing with \a pos. + + \since 5.11 +*/ + +bool QPlatformWindow::startSystemMove(const QPoint &pos) +{ + Q_UNUSED(pos) + return false; +} + /*! Reimplement this method to set whether frame strut events should be sent to \a enabled. diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 61f1cb624c..84dff681d5 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -129,6 +129,7 @@ public: virtual void windowEvent(QEvent *event); virtual bool startSystemResize(const QPoint &pos, Qt::Corner corner); + virtual bool startSystemMove(const QPoint &pos); virtual void setFrameStrutEventsEnabled(bool enabled); virtual bool frameStrutEventsEnabled() const; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 92825acb6d..07df963ec5 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -523,7 +523,7 @@ public: void xi2UpdateScrollingDevices(); #endif #ifdef XCB_USE_XINPUT22 - bool startSystemResizeForTouchBegin(xcb_window_t window, const QPoint &point, Qt::Corner corner); + bool startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner); bool isTouchScreen(int id); #endif #endif @@ -676,12 +676,12 @@ private: #if QT_CONFIG(xinput2) QHash m_touchDevices; #ifdef XCB_USE_XINPUT22 - struct StartSystemResizeInfo { + struct StartSystemMoveResizeInfo { xcb_window_t window = XCB_NONE; uint16_t deviceid; uint32_t pointid; - Qt::Corner corner; - } m_startSystemResizeInfo; + int corner; + } m_startSystemMoveResizeInfo; #endif #endif WindowMapper m_mapper; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index ba6481082a..39d2857212 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -784,15 +784,15 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo } if (dev->qtTouchDevice->type() == QTouchDevice::TouchScreen && - xiDeviceEvent->event == m_startSystemResizeInfo.window && - xiDeviceEvent->sourceid == m_startSystemResizeInfo.deviceid && - xiDeviceEvent->detail == m_startSystemResizeInfo.pointid) { - QXcbWindow *window = platformWindowFromId(m_startSystemResizeInfo.window); + xiDeviceEvent->event == m_startSystemMoveResizeInfo.window && + xiDeviceEvent->sourceid == m_startSystemMoveResizeInfo.deviceid && + xiDeviceEvent->detail == m_startSystemMoveResizeInfo.pointid) { + QXcbWindow *window = platformWindowFromId(m_startSystemMoveResizeInfo.window); if (window) { XIAllowTouchEvents(static_cast(m_xlib_display), xiDeviceEvent->deviceid, xiDeviceEvent->detail, xiDeviceEvent->event, XIRejectTouch); - window->doStartSystemResize(QPoint(x, y), m_startSystemResizeInfo.corner); - m_startSystemResizeInfo.window = XCB_NONE; + window->doStartSystemMoveResize(QPoint(x, y), m_startSystemMoveResizeInfo.corner); + m_startSystemMoveResizeInfo.window = XCB_NONE; } } break; @@ -825,7 +825,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo touchPoint.state = Qt::TouchPointStationary; } -bool QXcbConnection::startSystemResizeForTouchBegin(xcb_window_t window, const QPoint &point, Qt::Corner corner) +bool QXcbConnection::startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner) { QHash::const_iterator devIt = m_touchDevices.constBegin(); for (; devIt != m_touchDevices.constEnd(); ++devIt) { @@ -834,10 +834,10 @@ bool QXcbConnection::startSystemResizeForTouchBegin(xcb_window_t window, const Q QHash::const_iterator pointIt = deviceData.pointPressedPosition.constBegin(); for (; pointIt != deviceData.pointPressedPosition.constEnd(); ++pointIt) { if (pointIt.value().toPoint() == point) { - m_startSystemResizeInfo.window = window; - m_startSystemResizeInfo.deviceid = devIt.key(); - m_startSystemResizeInfo.pointid = pointIt.key(); - m_startSystemResizeInfo.corner = corner; + m_startSystemMoveResizeInfo.window = window; + m_startSystemMoveResizeInfo.deviceid = devIt.key(); + m_startSystemMoveResizeInfo.pointid = pointIt.key(); + m_startSystemMoveResizeInfo.corner = corner; return true; } } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 46698de158..44b337f555 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2639,19 +2639,29 @@ void QXcbWindow::windowEvent(QEvent *event) } bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) +{ + return startSystemMoveResize(pos, corner); +} + +bool QXcbWindow::startSystemMove(const QPoint &pos) +{ + return startSystemMoveResize(pos, 4); +} + +bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner) { 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()); #ifdef XCB_USE_XINPUT22 - if (connection()->startSystemResizeForTouchBegin(m_window, globalPos, corner)) + if (connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner)) return true; #endif - return doStartSystemResize(globalPos, corner); + return doStartSystemMoveResize(globalPos, corner); } -bool QXcbWindow::doStartSystemResize(const QPoint &globalPos, Qt::Corner corner) +bool QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner) { const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE); xcb_client_message_event_t xev; @@ -2662,12 +2672,16 @@ bool QXcbWindow::doStartSystemResize(const QPoint &globalPos, Qt::Corner corner) xev.format = 32; xev.data.data32[0] = globalPos.x(); xev.data.data32[1] = globalPos.y(); - 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 + if (corner == 4) { + 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 + } xev.data.data32[3] = XCB_BUTTON_INDEX_1; xev.data.data32[4] = 0; xcb_ungrab_pointer(connection()->xcb_connection(), XCB_CURRENT_TIME); diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 638ab26cea..f506d7dd6f 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -110,6 +110,7 @@ public: void windowEvent(QEvent *event) override; bool startSystemResize(const QPoint &pos, Qt::Corner corner) override; + bool startSystemMove(const QPoint &pos) override; void setOpacity(qreal level) override; void setMask(const QRegion ®ion) override; @@ -177,7 +178,8 @@ public: QXcbScreen *xcbScreen() const; - bool doStartSystemResize(const QPoint &globalPos, Qt::Corner corner); + bool startSystemMoveResize(const QPoint &pos, int corner); + bool doStartSystemMoveResize(const QPoint &globalPos, int corner); virtual void create(); virtual void destroy();