mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-04-20 03:25:02 +00:00
Support for "Customized key mapping" in Linux
Should work in "typical" X11 environments. Tested in Debian Buster / GNOME 3. Hi-DPI code copied from Windows-related parts and untested. Wayland is not supported and considered currently.
This commit is contained in:
parent
fa064df2da
commit
b5d9b02696
5 changed files with 120 additions and 3 deletions
|
@ -104,8 +104,11 @@ QRect VideoForm::getGrabCursorRect()
|
|||
rc.setY(rc.y() + 30);
|
||||
rc.setWidth(rc.width() - 180);
|
||||
rc.setHeight(rc.height() - 60);
|
||||
#else
|
||||
|
||||
#elif defined(Q_OS_LINUX)
|
||||
rc = QRect(ui->keepRadioWidget->mapToGlobal(m_videoWidget->pos()), m_videoWidget->size());
|
||||
// high dpi support -- taken from the WIN32 section and untested
|
||||
rc.setTopLeft(rc.topLeft() * m_videoWidget->devicePixelRatio());
|
||||
rc.setBottomRight(rc.bottomRight() * m_videoWidget->devicePixelRatio());
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
#ifdef Q_OS_OSX
|
||||
#include "cocoamousetap.h"
|
||||
#endif
|
||||
#ifdef Q_OS_LINUX
|
||||
#include "xmousetap.h"
|
||||
#endif
|
||||
|
||||
MouseTap *MouseTap::s_instance = Q_NULLPTR;
|
||||
MouseTap *MouseTap::getInstance()
|
||||
|
@ -19,7 +22,7 @@ MouseTap *MouseTap::getInstance()
|
|||
s_instance = new CocoaMouseTap();
|
||||
#endif
|
||||
#ifdef Q_OS_LINUX
|
||||
Q_ASSERT(false);
|
||||
s_instance = new XMouseTap();
|
||||
#endif
|
||||
}
|
||||
return s_instance;
|
||||
|
|
|
@ -16,3 +16,11 @@ mac {
|
|||
LIBS += -framework Appkit
|
||||
QMAKE_CFLAGS += -mmacosx-version-min=10.6
|
||||
}
|
||||
|
||||
linux {
|
||||
HEADERS += $$PWD/xmousetap.h
|
||||
SOURCES += $$PWD/xmousetap.cpp
|
||||
LIBS += -lxcb
|
||||
QT += x11extras
|
||||
}
|
||||
|
||||
|
|
84
QtScrcpy/util/mousetap/xmousetap.cpp
Normal file
84
QtScrcpy/util/mousetap/xmousetap.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include <QX11Info>
|
||||
|
||||
#include <xcb/xproto.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "xmousetap.h"
|
||||
|
||||
XMouseTap::XMouseTap() {}
|
||||
|
||||
XMouseTap::~XMouseTap() {}
|
||||
|
||||
void XMouseTap::initMouseEventTap() {}
|
||||
|
||||
void XMouseTap::quitMouseEventTap() {}
|
||||
|
||||
static void find_grab_window_recursive(xcb_connection_t *dpy, xcb_window_t window,
|
||||
QRect rc, int16_t offset_x, int16_t offset_y,
|
||||
xcb_window_t *grab_window, uint32_t *grab_window_size) {
|
||||
xcb_query_tree_cookie_t tree_cookie;
|
||||
xcb_query_tree_reply_t *tree;
|
||||
tree_cookie = xcb_query_tree(dpy, window);
|
||||
tree = xcb_query_tree_reply(dpy, tree_cookie, NULL);
|
||||
|
||||
xcb_window_t *children = xcb_query_tree_children(tree);
|
||||
for (int i = 0; i < xcb_query_tree_children_length(tree); i++) {
|
||||
xcb_get_geometry_cookie_t gg_cookie;
|
||||
xcb_get_geometry_reply_t *gg;
|
||||
gg_cookie = xcb_get_geometry(dpy, children[i]);
|
||||
gg = xcb_get_geometry_reply(dpy, gg_cookie, NULL);
|
||||
|
||||
if (gg->x + offset_x <= rc.left() && gg->x + offset_x + gg->width >= rc.right() &&
|
||||
gg->y + offset_y <= rc.top() && gg->y + offset_y + gg->height >= rc.bottom()) {
|
||||
if (!*grab_window || gg->width * gg->height <= *grab_window_size) {
|
||||
*grab_window = children[i];
|
||||
*grab_window_size = gg->width * gg->height;
|
||||
}
|
||||
}
|
||||
|
||||
find_grab_window_recursive(dpy, children[i], rc,
|
||||
gg->x + offset_x, gg->y + offset_y,
|
||||
grab_window, grab_window_size);
|
||||
|
||||
free(gg);
|
||||
}
|
||||
|
||||
free(tree);
|
||||
}
|
||||
|
||||
void XMouseTap::enableMouseEventTap(QRect rc, bool enabled) {
|
||||
if (enabled && rc.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
xcb_connection_t *dpy = QX11Info::connection();
|
||||
|
||||
if (enabled) {
|
||||
// We grab the top-most smallest window
|
||||
xcb_window_t grab_window = 0;
|
||||
uint32_t grab_window_size = 0;
|
||||
|
||||
find_grab_window_recursive(dpy, QX11Info::appRootWindow(QX11Info::appScreen()),
|
||||
rc, 0, 0, &grab_window, &grab_window_size);
|
||||
|
||||
if (grab_window) {
|
||||
xcb_grab_pointer_cookie_t grab_cookie;
|
||||
xcb_grab_pointer_reply_t *grab;
|
||||
grab_cookie = xcb_grab_pointer(dpy, /* owner_events = */ 1,
|
||||
grab_window, /* event_mask = */ 0,
|
||||
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
|
||||
grab_window, XCB_NONE, XCB_CURRENT_TIME);
|
||||
grab = xcb_grab_pointer_reply(dpy, grab_cookie, NULL);
|
||||
|
||||
free(grab);
|
||||
}
|
||||
} else {
|
||||
xcb_void_cookie_t ungrab_cookie;
|
||||
xcb_generic_error_t *error;
|
||||
ungrab_cookie = xcb_ungrab_pointer_checked(dpy, XCB_CURRENT_TIME);
|
||||
error = xcb_request_check(dpy, ungrab_cookie);
|
||||
|
||||
free(error);
|
||||
}
|
||||
}
|
19
QtScrcpy/util/mousetap/xmousetap.h
Normal file
19
QtScrcpy/util/mousetap/xmousetap.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef XMOUSETAP_H
|
||||
#define XMOUSETAP_H
|
||||
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
#include "mousetap.h"
|
||||
|
||||
class XMouseTap : public MouseTap
|
||||
{
|
||||
public:
|
||||
XMouseTap();
|
||||
virtual ~XMouseTap();
|
||||
|
||||
void initMouseEventTap() override;
|
||||
void quitMouseEventTap() override;
|
||||
void enableMouseEventTap(QRect rc, bool enabled) override;
|
||||
};
|
||||
|
||||
#endif // XMOUSETAP_H
|
Loading…
Add table
Reference in a new issue