implemented linux x11 moving
This commit is contained in:
parent
93ac6f6ee3
commit
a365499455
|
@ -50,6 +50,7 @@ else()
|
|||
if(MACOS)
|
||||
list(APPEND SOURCES utilities_macos.mm)
|
||||
else()
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS X11Extras REQUIRED)
|
||||
list(APPEND SOURCES utilities_linux.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -87,6 +88,14 @@ if(WIN32)
|
|||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
dwmapi
|
||||
)
|
||||
else()
|
||||
if(MACOS)
|
||||
#TODO
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
Qt${QT_VERSION_MAJOR}::X11Extras
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
#include "flwindow.h"
|
||||
#include "../../framelesshelper.h"
|
||||
|
||||
#include <QScreen>
|
||||
|
||||
FRAMELESSHELPER_USE_NAMESPACE
|
||||
|
||||
FLWindow::FLWindow(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
setStyleSheet(QString::fromLatin1("background:blue"));
|
||||
|
||||
setAttribute(Qt::WA_ShowModal);
|
||||
resize(500, 500);
|
||||
move(screen()->geometry().center() - frameGeometry().center());
|
||||
}
|
||||
|
||||
FLWindow::~FLWindow()
|
||||
|
@ -21,7 +22,7 @@ void FLWindow::initFramelessWindow()
|
|||
{
|
||||
FramelessHelper* helper = new FramelessHelper(windowHandle());
|
||||
helper->setResizeBorderThickness(8);
|
||||
helper->setTitleBarHeight(20);
|
||||
helper->setTitleBarHeight(40);
|
||||
helper->setResizable(true);
|
||||
helper->install();
|
||||
}
|
||||
|
|
|
@ -240,6 +240,16 @@ void FramelessHelper::updateHoverStates(const QPoint& pos)
|
|||
m_hoveredFrameSection = mapPosToFrameSection(pos);
|
||||
}
|
||||
|
||||
void FramelessHelper::startMove(QMouseEvent* event)
|
||||
{
|
||||
#ifdef Q_OS_LINUX
|
||||
Utilities::sendX11ButtonRelease(m_window, event->globalPos());
|
||||
Utilities::startX11Moving(m_window, event->globalPos());
|
||||
event->accept();
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
||||
{
|
||||
bool filterOut = false;
|
||||
|
@ -263,7 +273,20 @@ bool FramelessHelper::eventFilter(QObject *object, QEvent *event)
|
|||
}
|
||||
case QEvent::NonClientAreaMouseButtonPress:
|
||||
case QEvent::MouseButtonPress:
|
||||
{
|
||||
auto ev = static_cast<QMouseEvent *>(event);
|
||||
if (isHoverResizeHandler()) {
|
||||
// Start system resize
|
||||
filterOut = true;
|
||||
} else if (isInTitlebarArea(ev->pos())) {
|
||||
// Start system move
|
||||
startMove(ev);
|
||||
filterOut = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case QEvent::NonClientAreaMouseButtonRelease:
|
||||
case QEvent::MouseButtonRelease:
|
||||
break;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
QT_FORWARD_DECLARE_CLASS(QWindow)
|
||||
QT_FORWARD_DECLARE_CLASS(QMouseEvent)
|
||||
QT_END_NAMESPACE
|
||||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
@ -81,6 +82,8 @@ public:
|
|||
void updateMouse(const QPoint& pos);
|
||||
void updateHoverStates(const QPoint& pos);
|
||||
|
||||
void startMove(QMouseEvent* event);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
|
||||
|
|
|
@ -58,6 +58,11 @@ FRAMELESSHELPER_API void updateQtFrameMargins(QWindow *window, const bool enable
|
|||
[[nodiscard]] FRAMELESSHELPER_API QString getSystemErrorMessage(const QString &function);
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
FRAMELESSHELPER_API void sendX11ButtonRelease(QWindow *w, const QPoint &pos);
|
||||
FRAMELESSHELPER_API void startX11Moving(QWindow *w, const QPoint &pos);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
||||
|
|
|
@ -25,9 +25,25 @@
|
|||
#include "utilities.h"
|
||||
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtX11Extras/qx11info_x11.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
FRAMELESSHELPER_BEGIN_NAMESPACE
|
||||
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
|
||||
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
|
||||
#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
|
||||
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
|
||||
#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
|
||||
#define _NET_WM_MOVERESIZE_MOVE 8 /* movement only */
|
||||
#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 /* size via keyboard */
|
||||
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
|
||||
#define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */
|
||||
|
||||
static constexpr int kDefaultResizeBorderThickness = 8;
|
||||
static constexpr int kDefaultCaptionHeight = 23;
|
||||
|
||||
|
@ -106,7 +122,8 @@ bool Utilities::shouldAppsUseDarkMode()
|
|||
ColorizationArea Utilities::getColorizationArea()
|
||||
{
|
||||
// ### TO BE IMPLEMENTED
|
||||
return ColorizationArea::None;
|
||||
//return ColorizationArea::None; // ‘None’ has been defined as a macro in X11 headers.
|
||||
return ColorizationArea::All;
|
||||
}
|
||||
|
||||
bool Utilities::isThemeChanged(const void *data)
|
||||
|
@ -132,4 +149,62 @@ bool Utilities::showSystemMenu(const WId winId, const QPointF &pos)
|
|||
return false;
|
||||
}
|
||||
|
||||
void Utilities::sendX11ButtonRelease(QWindow *w, const QPoint &pos)
|
||||
{
|
||||
QPoint clientPos = w->mapFromGlobal(pos);
|
||||
Display *display = QX11Info::display();
|
||||
int screen = QX11Info::appScreen();
|
||||
unsigned long rootWindow = QX11Info::appRootWindow(screen);
|
||||
|
||||
XEvent event;
|
||||
memset(&event, 0, sizeof (event));
|
||||
|
||||
event.xbutton.button = 0;
|
||||
event.xbutton.same_screen = True;
|
||||
event.xbutton.send_event = True;
|
||||
Window window = w->winId();
|
||||
event.xbutton.window = window;
|
||||
event.xbutton.root = rootWindow;
|
||||
event.xbutton.x_root = pos.x();
|
||||
event.xbutton.y_root = pos.y();
|
||||
event.xbutton.x = clientPos.x();
|
||||
event.xbutton.y = clientPos.y();
|
||||
event.xbutton.type = ButtonRelease;
|
||||
event.xbutton.time = CurrentTime;
|
||||
|
||||
if (XSendEvent(display, window, True, ButtonReleaseMask, &event) == 0)
|
||||
qWarning() << "Cant send ButtonRelease event.";
|
||||
XFlush(display);
|
||||
}
|
||||
|
||||
void Utilities::startX11Moving(QWindow *w, const QPoint &pos)
|
||||
{
|
||||
Display *display = QX11Info::display();
|
||||
int screen = QX11Info::appScreen();
|
||||
unsigned long rootWindow = QX11Info::appRootWindow(screen);
|
||||
static Atom netMoveResize = XInternAtom(display, "_NET_WM_MOVERESIZE", False);
|
||||
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
|
||||
XEvent event;
|
||||
memset(&event, 0x00, sizeof(event));
|
||||
event.xclient.type = ClientMessage;
|
||||
event.xclient.window = w->winId();
|
||||
event.xclient.message_type = netMoveResize;
|
||||
event.xclient.serial = 0;
|
||||
event.xclient.display = display;
|
||||
event.xclient.send_event = True;
|
||||
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[3] = Button1;
|
||||
event.xclient.data.l[4] = 0; /* unused */
|
||||
if (XSendEvent(display, rootWindow,
|
||||
False, SubstructureRedirectMask | SubstructureNotifyMask, &event) == 0)
|
||||
qWarning() << "Cant send Move event.";
|
||||
XFlush(display);
|
||||
}
|
||||
|
||||
|
||||
FRAMELESSHELPER_END_NAMESPACE
|
Loading…
Reference in New Issue