From 501ff149cfc004941e2db132d72b45e507dd1872 Mon Sep 17 00:00:00 2001 From: Altair Wei Date: Mon, 20 Sep 2021 09:10:04 +0800 Subject: [PATCH] implemented X11 resizing --- framelesshelper.cpp | 13 +++++++++++- framelesshelper.h | 1 + utilities.h | 4 +++- utilities_linux.cpp | 52 ++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/framelesshelper.cpp b/framelesshelper.cpp index 336d583..79f5a12 100644 --- a/framelesshelper.cpp +++ b/framelesshelper.cpp @@ -243,13 +243,23 @@ void FramelessHelper::updateHoverStates(const QPoint& pos) void FramelessHelper::startMove(QMouseEvent* event) { #ifdef Q_OS_LINUX - Utilities::sendX11ButtonRelease(m_window, event->globalPos()); + Utilities::sendX11ButtonReleaseEvent(m_window, event->globalPos()); Utilities::startX11Moving(m_window, event->globalPos()); event->accept(); return; #endif } +void FramelessHelper::startResize(QMouseEvent* event, Qt::WindowFrameSection frameSection) +{ +#ifdef Q_OS_LINUX + Utilities::sendX11ButtonReleaseEvent(m_window, event->globalPos()); + Utilities::startX11Resizing(m_window, event->globalPos(), frameSection); + event->accept(); + return; +#endif +} + bool FramelessHelper::eventFilter(QObject *object, QEvent *event) { bool filterOut = false; @@ -277,6 +287,7 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event) auto ev = static_cast(event); if (isHoverResizeHandler()) { // Start system resize + startResize(ev, m_hoveredFrameSection); filterOut = true; } else if (isInTitlebarArea(ev->pos())) { // Start system move diff --git a/framelesshelper.h b/framelesshelper.h index 2654373..f6ef065 100644 --- a/framelesshelper.h +++ b/framelesshelper.h @@ -83,6 +83,7 @@ public: void updateHoverStates(const QPoint& pos); void startMove(QMouseEvent* event); + void startResize(QMouseEvent* event, Qt::WindowFrameSection frameSection); protected: bool eventFilter(QObject *object, QEvent *event) override; diff --git a/utilities.h b/utilities.h index 246f9b0..5e2786b 100644 --- a/utilities.h +++ b/utilities.h @@ -59,8 +59,10 @@ FRAMELESSHELPER_API void updateQtFrameMargins(QWindow *window, const bool enable #endif #ifdef Q_OS_LINUX -FRAMELESSHELPER_API void sendX11ButtonRelease(QWindow *w, const QPoint &pos); +FRAMELESSHELPER_API void sendX11ButtonReleaseEvent(QWindow *w, const QPoint &pos); +FRAMELESSHELPER_API void sendX11MoveResizeEvent(QWindow *w, const QPoint &pos, int section); FRAMELESSHELPER_API void startX11Moving(QWindow *w, const QPoint &pos); +FRAMELESSHELPER_API void startX11Resizing(QWindow *w, const QPoint &pos, Qt::WindowFrameSection frameSection); #endif } diff --git a/utilities_linux.cpp b/utilities_linux.cpp index 40e5609..6394a55 100644 --- a/utilities_linux.cpp +++ b/utilities_linux.cpp @@ -149,7 +149,7 @@ bool Utilities::showSystemMenu(const WId winId, const QPointF &pos) return false; } -void Utilities::sendX11ButtonRelease(QWindow *w, const QPoint &pos) +void Utilities::sendX11ButtonReleaseEvent(QWindow *w, const QPoint &pos) { QPoint clientPos = w->mapFromGlobal(pos); Display *display = QX11Info::display(); @@ -177,7 +177,7 @@ void Utilities::sendX11ButtonRelease(QWindow *w, const QPoint &pos) XFlush(display); } -void Utilities::startX11Moving(QWindow *w, const QPoint &pos) +void Utilities::sendX11MoveResizeEvent(QWindow *w, const QPoint &pos, int section) { Display *display = QX11Info::display(); int screen = QX11Info::appScreen(); @@ -197,14 +197,56 @@ void Utilities::startX11Moving(QWindow *w, const QPoint &pos) event.xclient.format = 32; event.xclient.data.l[0] = pos.x(); event.xclient.data.l[1] = pos.y(); - event.xclient.data.l[2] = _NET_WM_MOVERESIZE_MOVE; + event.xclient.data.l[2] = section; event.xclient.data.l[3] = Button1; - event.xclient.data.l[4] = 0; /* unused */ + event.xclient.data.l[4] = 0; if (XSendEvent(display, rootWindow, False, SubstructureRedirectMask | SubstructureNotifyMask, &event) == 0) - qWarning() << "Cant send Move event."; + qWarning("Cant send Move or Resize event."); XFlush(display); } +void Utilities::startX11Moving(QWindow *w, const QPoint &pos) +{ + sendX11MoveResizeEvent(w, pos, _NET_WM_MOVERESIZE_MOVE); +} + +void Utilities::startX11Resizing(QWindow *w, const QPoint &pos, Qt::WindowFrameSection frameSection) +{ + int section = -1; + + switch (frameSection) + { + case Qt::LeftSection: + section = _NET_WM_MOVERESIZE_SIZE_LEFT; + break; + case Qt::TopLeftSection: + section = _NET_WM_MOVERESIZE_SIZE_TOPLEFT; + break; + case Qt::TopSection: + section = _NET_WM_MOVERESIZE_SIZE_TOP; + break; + case Qt::TopRightSection: + section = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT; + break; + case Qt::RightSection: + section = _NET_WM_MOVERESIZE_SIZE_RIGHT; + break; + case Qt::BottomRightSection: + section = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT; + break; + case Qt::BottomSection: + section = _NET_WM_MOVERESIZE_SIZE_BOTTOM; + break; + case Qt::BottomLeftSection: + section = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT; + break; + default: + break; + } + + if (section != -1) + sendX11MoveResizeEvent(w, pos, section); +} FRAMELESSHELPER_END_NAMESPACE \ No newline at end of file