mirror of https://github.com/qt/qtbase.git
xcb: Use XCB instead of Xlib for XInput
- Replace xinput2 feature by xcb-xinput, which doesn't depend on xcb-xlib - Remove xi2PrepareXIGenericDeviceEvent() that was used to fix incompatibilty between XCB and libXi structs - Drop XCB_USE_XINPUT21 and XCB_USE_XINPUT22 defines that were needed with libXi Although xcb-xinput was released in version 1.13 of libxcb, it was quite stable in version 1.12, and the parts that we use did not change between versions, so require system xcb-xinput 1.12. [ChangeLog][X11] The xcb plugin was ported to use libxcb-xinput instead of libXi for XInput2 support. The -xinput2 configure option was replaced by -xcb-xinput. Task-number: QTBUG-39624 Change-Id: I37475b09b2bd7057763345c3f33d8c7751a4e831 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
This commit is contained in:
parent
8b16557c35
commit
a692d7cd28
|
@ -297,7 +297,7 @@ Gui, printing, widget options:
|
||||||
-libinput .......... Enable libinput support [auto]
|
-libinput .......... Enable libinput support [auto]
|
||||||
-mtdev ............. Enable mtdev support [auto]
|
-mtdev ............. Enable mtdev support [auto]
|
||||||
-tslib ............. Enable tslib support [auto]
|
-tslib ............. Enable tslib support [auto]
|
||||||
-xinput2 ........... Enable XInput2 support [auto]
|
-xcb-xinput ........ Enable XInput2 support [auto]
|
||||||
-xkbcommon-x11 ..... Select xkbcommon used in combination with xcb
|
-xkbcommon-x11 ..... Select xkbcommon used in combination with xcb
|
||||||
[system/qt/no]
|
[system/qt/no]
|
||||||
-xkbcommon-evdev ... Enable X-less xkbcommon in combination with libinput
|
-xkbcommon-evdev ... Enable X-less xkbcommon in combination with libinput
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
"xcb": { "type": "enum", "values": [ "no", "yes", "qt", "system" ] },
|
"xcb": { "type": "enum", "values": [ "no", "yes", "qt", "system" ] },
|
||||||
"xcb-native-painting": "boolean",
|
"xcb-native-painting": "boolean",
|
||||||
"xcb-xlib": "boolean",
|
"xcb-xlib": "boolean",
|
||||||
"xinput2": "boolean",
|
"xcb-xinput": "boolean",
|
||||||
"xkb": "boolean",
|
"xkb": "boolean",
|
||||||
"xkbcommon": { "type": "enum", "values": [ "no", "qt", "system" ] },
|
"xkbcommon": { "type": "enum", "values": [ "no", "qt", "system" ] },
|
||||||
"xkbcommon-evdev": "boolean",
|
"xkbcommon-evdev": "boolean",
|
||||||
|
@ -566,33 +566,22 @@
|
||||||
"-lxcb-glx -lxcb"
|
"-lxcb-glx -lxcb"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"xinput2": {
|
"xcb_xinput": {
|
||||||
"label": "Xinput2",
|
"label": "XCB XInput",
|
||||||
"test": {
|
"test": {
|
||||||
"include": [ "X11/Xlib.h", "X11/extensions/XInput2.h", "X11/extensions/Xge.h" ],
|
"include": [ "xcb/xcb.h", "xcb/xinput.h" ],
|
||||||
"tail": [
|
|
||||||
"#ifndef XInput_2_0",
|
|
||||||
"# error Missing XInput_2_0 #define",
|
|
||||||
"#endif"
|
|
||||||
],
|
|
||||||
"main": [
|
"main": [
|
||||||
"// need XGenericEventCookie for XInput2 to work",
|
"int primaryScreen = 0;",
|
||||||
"Display *dpy = 0;",
|
"xcb_connection_t *connection = xcb_connect(\"\", &primaryScreen);",
|
||||||
"XEvent xevent;",
|
"xcb_generic_error_t *error = 0;",
|
||||||
"XIEvent *xievent = 0;",
|
"xcb_input_xi_query_version_cookie_t xinput_query_cookie = xcb_input_xi_query_version(",
|
||||||
"XIDeviceEvent *xideviceevent = 0;",
|
" connection, XCB_INPUT_MAJOR_VERSION, XCB_INPUT_MINOR_VERSION);",
|
||||||
"XIHierarchyEvent *xihierarchyevent = 0;",
|
"xcb_input_xi_query_version_reply(connection, xinput_query_cookie, &error);"
|
||||||
"int deviceid = 0;",
|
]
|
||||||
"int len = 0;",
|
|
||||||
"(void) XGetEventData(dpy, &xevent.xcookie);",
|
|
||||||
"XFreeEventData(dpy, &xevent.xcookie);",
|
|
||||||
"(void) XIListProperties(dpy, deviceid, &len);"
|
|
||||||
],
|
|
||||||
"qmake": "CONFIG += x11"
|
|
||||||
},
|
},
|
||||||
"sources": [
|
"sources": [
|
||||||
{ "type": "pkgConfig", "args": "xi" },
|
{ "type": "pkgConfig", "args": "xcb-xinput >= 1.12 xcb" },
|
||||||
"-lXi"
|
"-lxcb-xinput -lxcb"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"xkbcommon": {
|
"xkbcommon": {
|
||||||
|
@ -1352,10 +1341,10 @@
|
||||||
"condition": "features.sessionmanager && libs.x11sm",
|
"condition": "features.sessionmanager && libs.x11sm",
|
||||||
"output": [ "privateFeature" ]
|
"output": [ "privateFeature" ]
|
||||||
},
|
},
|
||||||
"xinput2": {
|
"xcb-xinput": {
|
||||||
"label": "Xinput2",
|
"label": "XCB XInput",
|
||||||
"emitIf": "features.xcb",
|
"emitIf": "features.xcb",
|
||||||
"condition": "features.xcb-xlib && libs.xinput2",
|
"condition": "!features.system-xcb || libs.xcb_xinput",
|
||||||
"output": [ "privateFeature" ]
|
"output": [ "privateFeature" ]
|
||||||
},
|
},
|
||||||
"xkbcommon-evdev": {
|
"xkbcommon-evdev": {
|
||||||
|
@ -1726,7 +1715,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla
|
||||||
"section": "X11",
|
"section": "X11",
|
||||||
"condition": "features.xcb",
|
"condition": "features.xcb",
|
||||||
"entries": [
|
"entries": [
|
||||||
"system-xcb", "egl_x11", "xinput2", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xlib", "xkbcommon-system", "xcb-native-painting"
|
"system-xcb", "egl_x11", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xinput", "xcb-xlib", "xkbcommon-system", "xcb-native-painting"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@ Requires libxcb >= 1.5.
|
||||||
PACKAGE DEPENDENCIES
|
PACKAGE DEPENDENCIES
|
||||||
|
|
||||||
Required packages:
|
Required packages:
|
||||||
libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxcb-xinerama0-dev
|
libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxcb-xinerama0-dev libxcb-xinput0-dev
|
||||||
|
|
||||||
On Ubuntu 11.10 icccm1 is replaced by icccm4 and xcb-render-util is not available:
|
On Ubuntu 11.10 icccm1 is replaced by icccm4 and xcb-render-util is not available:
|
||||||
libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxcb-xinerama0-dev
|
libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxcb-xinerama0-dev
|
||||||
|
@ -21,12 +21,3 @@ REDUCING RUNTIME DEPENDENCIES
|
||||||
The '-qt-xcb' configure option can be used to get rid of most xcb- dependencies. Only libxcb will
|
The '-qt-xcb' configure option can be used to get rid of most xcb- dependencies. Only libxcb will
|
||||||
still be linked dynamically, since it will be most likely be pulled in via other dependencies anyway.
|
still be linked dynamically, since it will be most likely be pulled in via other dependencies anyway.
|
||||||
This should allow for binaries that are portable across most modern Linux distributions.
|
This should allow for binaries that are portable across most modern Linux distributions.
|
||||||
|
|
||||||
PACKAGE VERSION REQUIREMENTS
|
|
||||||
|
|
||||||
When using touch input via XInput 2.2 or higher, there is a potential issue on systems that ship with
|
|
||||||
a libXi older than 1.7.5. This is because XIAllowTouchEvents can deadlock with libXi 1.7.4 and earlier.
|
|
||||||
When touch events are never received, this is not an issue, so plain mouse/keyboard systems are not affected.
|
|
||||||
Qt versions before 5.8 attempted to recognize this scenario based on the pkg-config package version and skip
|
|
||||||
the call. This has been removed starting from 5.8 since relying on pkg-config package versions is unsafe given
|
|
||||||
that Qt must also support systems with limited or incomplete pkg-config setups.
|
|
||||||
|
|
|
@ -76,8 +76,8 @@
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
#include <X11/extensions/XI2proto.h>
|
#include <xcb/xinput.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(xcb_render)
|
#if QT_CONFIG(xcb_render)
|
||||||
|
@ -120,7 +120,7 @@ Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard")
|
||||||
#define XCB_GE_GENERIC 35
|
#define XCB_GE_GENERIC 35
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
|
// Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed:
|
||||||
// - "pad0" became "extension"
|
// - "pad0" became "extension"
|
||||||
// - "pad1" and "pad" became "pad0"
|
// - "pad1" and "pad" became "pad0"
|
||||||
|
@ -138,7 +138,7 @@ static inline bool isXIEvent(xcb_generic_event_t *event, int opCode)
|
||||||
qt_xcb_ge_event_t *e = reinterpret_cast<qt_xcb_ge_event_t *>(event);
|
qt_xcb_ge_event_t *e = reinterpret_cast<qt_xcb_ge_event_t *>(event);
|
||||||
return e->extension == opCode;
|
return e->extension == opCode;
|
||||||
}
|
}
|
||||||
#endif // QT_CONFIG(xinput2)
|
#endif // QT_CONFIG(xcb_xinput)
|
||||||
|
|
||||||
#if QT_CONFIG(xcb_xlib)
|
#if QT_CONFIG(xcb_xlib)
|
||||||
static const char * const xcbConnectionErrors[] = {
|
static const char * const xcbConnectionErrors[] = {
|
||||||
|
@ -572,6 +572,9 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
||||||
#endif
|
#endif
|
||||||
#if QT_CONFIG(xcb_render)
|
#if QT_CONFIG(xcb_render)
|
||||||
&xcb_render_id,
|
&xcb_render_id,
|
||||||
|
#endif
|
||||||
|
#if QT_CONFIG(xcb_xinput)
|
||||||
|
&xcb_input_id,
|
||||||
#endif
|
#endif
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
@ -592,7 +595,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
||||||
initializeScreens();
|
initializeScreens();
|
||||||
|
|
||||||
initializeXRender();
|
initializeXRender();
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
if (!qEnvironmentVariableIsSet("QT_XCB_NO_XI2"))
|
if (!qEnvironmentVariableIsSet("QT_XCB_NO_XI2"))
|
||||||
initializeXInput2();
|
initializeXInput2();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1105,13 +1108,13 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
||||||
handleClientMessageEvent((xcb_client_message_event_t *)event);
|
handleClientMessageEvent((xcb_client_message_event_t *)event);
|
||||||
break;
|
break;
|
||||||
case XCB_ENTER_NOTIFY:
|
case XCB_ENTER_NOTIFY:
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
if (hasXInput2() && !xi2MouseEventsDisabled())
|
if (hasXInput2() && !xi2MouseEventsDisabled())
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
|
HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
|
||||||
case XCB_LEAVE_NOTIFY:
|
case XCB_LEAVE_NOTIFY:
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
if (hasXInput2() && !xi2MouseEventsDisabled())
|
if (hasXInput2() && !xi2MouseEventsDisabled())
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1174,7 +1177,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
case XCB_GE_GENERIC:
|
case XCB_GE_GENERIC:
|
||||||
// Here the windowEventListener is invoked from xi2HandleEvent()
|
// Here the windowEventListener is invoked from xi2HandleEvent()
|
||||||
if (hasXInput2() && isXIEvent(event, m_xiOpCode))
|
if (hasXInput2() && isXIEvent(event, m_xiOpCode))
|
||||||
|
@ -1630,16 +1633,14 @@ void *QXcbConnection::createVisualInfoForDefaultVisualId() const
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
// it is safe to cast XI_* events here as long as we are only touching the first 32 bytes,
|
|
||||||
// after that position event needs memmove, see xi2PrepareXIGenericDeviceEvent
|
|
||||||
static inline bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t type)
|
static inline bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t type)
|
||||||
{
|
{
|
||||||
if (!isXIEvent(event, opCode))
|
if (!isXIEvent(event, opCode))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
|
auto *e = reinterpret_cast<qt_xcb_ge_event_t *>(event);
|
||||||
return xiEvent->evtype == type;
|
return e->event_type == type;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
static inline bool isValid(xcb_generic_event_t *event)
|
static inline bool isValid(xcb_generic_event_t *event)
|
||||||
|
@ -1675,16 +1676,16 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex,
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
// compress XI_* events
|
// compress XI_* events
|
||||||
if (responseType == XCB_GE_GENERIC) {
|
if (responseType == XCB_GE_GENERIC) {
|
||||||
if (!hasXInput2())
|
if (!hasXInput2())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// compress XI_Motion, but not from tablet devices
|
// compress XI_Motion, but not from tablet devices
|
||||||
if (isXIType(event, m_xiOpCode, XI_Motion)) {
|
if (isXIType(event, m_xiOpCode, XCB_INPUT_MOTION)) {
|
||||||
#if QT_CONFIG(tabletevent)
|
#if QT_CONFIG(tabletevent)
|
||||||
xXIDeviceEvent *xdev = reinterpret_cast<xXIDeviceEvent *>(event);
|
auto *xdev = reinterpret_cast<xcb_input_motion_event_t *>(event);
|
||||||
if (!QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents) &&
|
if (!QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents) &&
|
||||||
const_cast<QXcbConnection *>(this)->tabletDataForDevice(xdev->sourceid))
|
const_cast<QXcbConnection *>(this)->tabletDataForDevice(xdev->sourceid))
|
||||||
return false;
|
return false;
|
||||||
|
@ -1693,29 +1694,27 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex,
|
||||||
xcb_generic_event_t *next = eventqueue->at(j);
|
xcb_generic_event_t *next = eventqueue->at(j);
|
||||||
if (!isValid(next))
|
if (!isValid(next))
|
||||||
continue;
|
continue;
|
||||||
if (isXIType(next, m_xiOpCode, XI_Motion))
|
if (isXIType(next, m_xiOpCode, XCB_INPUT_MOTION))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifdef XCB_USE_XINPUT22
|
|
||||||
// compress XI_TouchUpdate for the same touch point id
|
// compress XI_TouchUpdate for the same touch point id
|
||||||
if (isXIType(event, m_xiOpCode, XI_TouchUpdate)) {
|
if (isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) {
|
||||||
xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
|
auto *touchUpdateEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(event);
|
||||||
uint32_t id = xiDeviceEvent->detail % INT_MAX;
|
uint32_t id = touchUpdateEvent->detail % INT_MAX;
|
||||||
for (int j = nextIndex; j < eventqueue->size(); ++j) {
|
for (int j = nextIndex; j < eventqueue->size(); ++j) {
|
||||||
xcb_generic_event_t *next = eventqueue->at(j);
|
xcb_generic_event_t *next = eventqueue->at(j);
|
||||||
if (!isValid(next))
|
if (!isValid(next))
|
||||||
continue;
|
continue;
|
||||||
if (isXIType(next, m_xiOpCode, XI_TouchUpdate)) {
|
if (isXIType(next, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) {
|
||||||
xXIDeviceEvent *xiDeviceNextEvent = reinterpret_cast<xXIDeviceEvent *>(next);
|
auto *touchUpdateNextEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(next);
|
||||||
if (id == xiDeviceNextEvent->detail % INT_MAX)
|
if (id == touchUpdateNextEvent->detail % INT_MAX)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -71,16 +71,6 @@
|
||||||
#include <QTabletEvent>
|
#include <QTabletEvent>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
|
||||||
#include <X11/extensions/XI2.h>
|
|
||||||
#ifdef XIScrollClass
|
|
||||||
#define XCB_USE_XINPUT21 // XI 2.1 adds smooth scrolling support
|
|
||||||
#ifdef XI_TouchBeginMask
|
|
||||||
#define XCB_USE_XINPUT22 // XI 2.2 adds multi-point touch support
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif // QT_CONFIG(xinput2)
|
|
||||||
|
|
||||||
struct xcb_randr_get_output_info_reply_t;
|
struct xcb_randr_get_output_info_reply_t;
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
@ -359,7 +349,7 @@ public:
|
||||||
virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {}
|
virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {}
|
||||||
virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {}
|
virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {}
|
||||||
virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {}
|
virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {}
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
virtual void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource = Qt::MouseEventNotSynthesized) {}
|
virtual void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource = Qt::MouseEventNotSynthesized) {}
|
||||||
virtual void handleXIEnterLeave(xcb_ge_event_t *) {}
|
virtual void handleXIEnterLeave(xcb_ge_event_t *) {}
|
||||||
#endif
|
#endif
|
||||||
|
@ -511,7 +501,7 @@ public:
|
||||||
static bool xEmbedSystemTrayAvailable();
|
static bool xEmbedSystemTrayAvailable();
|
||||||
static bool xEmbedSystemTrayVisualHasAlphaChannel();
|
static bool xEmbedSystemTrayVisualHasAlphaChannel();
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
void xi2SelectStateEvents();
|
void xi2SelectStateEvents();
|
||||||
void xi2SelectDeviceEvents(xcb_window_t window);
|
void xi2SelectDeviceEvents(xcb_window_t window);
|
||||||
void xi2SelectDeviceEventsCompatibility(xcb_window_t window);
|
void xi2SelectDeviceEventsCompatibility(xcb_window_t window);
|
||||||
|
@ -520,13 +510,9 @@ public:
|
||||||
bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; }
|
bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; }
|
||||||
bool isAtLeastXI22() const { return m_xi2Enabled && m_xi2Minor >= 2; }
|
bool isAtLeastXI22() const { return m_xi2Enabled && m_xi2Minor >= 2; }
|
||||||
Qt::MouseButton xiToQtMouseButton(uint32_t b);
|
Qt::MouseButton xiToQtMouseButton(uint32_t b);
|
||||||
#ifdef XCB_USE_XINPUT21
|
|
||||||
void xi2UpdateScrollingDevices();
|
void xi2UpdateScrollingDevices();
|
||||||
#endif
|
|
||||||
#ifdef XCB_USE_XINPUT22
|
|
||||||
bool startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner);
|
bool startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner);
|
||||||
bool isTouchScreen(int id);
|
bool isTouchScreen(int id);
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
QXcbEventReader *eventReader() const { return m_reader; }
|
QXcbEventReader *eventReader() const { return m_reader; }
|
||||||
|
|
||||||
|
@ -568,7 +554,7 @@ private:
|
||||||
bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const;
|
bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const;
|
||||||
|
|
||||||
bool m_xi2Enabled = false;
|
bool m_xi2Enabled = false;
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
int m_xi2Minor = -1;
|
int m_xi2Minor = -1;
|
||||||
void initializeXInput2();
|
void initializeXInput2();
|
||||||
void xi2SetupDevice(void *info, bool removeExisting = true);
|
void xi2SetupDevice(void *info, bool removeExisting = true);
|
||||||
|
@ -596,10 +582,8 @@ private:
|
||||||
void xi2HandleEvent(xcb_ge_event_t *event);
|
void xi2HandleEvent(xcb_ge_event_t *event);
|
||||||
void xi2HandleHierarchyEvent(void *event);
|
void xi2HandleHierarchyEvent(void *event);
|
||||||
void xi2HandleDeviceChangedEvent(void *event);
|
void xi2HandleDeviceChangedEvent(void *event);
|
||||||
int m_xiOpCode, m_xiEventBase, m_xiErrorBase;
|
int m_xiOpCode;
|
||||||
#ifdef XCB_USE_XINPUT22
|
|
||||||
void xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow);
|
void xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow);
|
||||||
#endif // XCB_USE_XINPUT22
|
|
||||||
#if QT_CONFIG(tabletevent)
|
#if QT_CONFIG(tabletevent)
|
||||||
struct TabletData {
|
struct TabletData {
|
||||||
int deviceId = 0;
|
int deviceId = 0;
|
||||||
|
@ -634,14 +618,11 @@ private:
|
||||||
QPointF lastScrollPosition;
|
QPointF lastScrollPosition;
|
||||||
};
|
};
|
||||||
QHash<int, ScrollingDevice> m_scrollingDevices;
|
QHash<int, ScrollingDevice> m_scrollingDevices;
|
||||||
#ifdef XCB_USE_XINPUT21
|
|
||||||
void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice);
|
void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice);
|
||||||
void xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice);
|
void xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice);
|
||||||
ScrollingDevice *scrollingDeviceForId(int id);
|
ScrollingDevice *scrollingDeviceForId(int id);
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value);
|
static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value);
|
||||||
static void xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xcb_connection_t *m_connection = nullptr;
|
xcb_connection_t *m_connection = nullptr;
|
||||||
|
@ -675,16 +656,14 @@ private:
|
||||||
#endif
|
#endif
|
||||||
QXcbEventReader *m_reader = nullptr;
|
QXcbEventReader *m_reader = nullptr;
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
QHash<int, TouchDeviceData> m_touchDevices;
|
QHash<int, TouchDeviceData> m_touchDevices;
|
||||||
#ifdef XCB_USE_XINPUT22
|
|
||||||
struct StartSystemMoveResizeInfo {
|
struct StartSystemMoveResizeInfo {
|
||||||
xcb_window_t window = XCB_NONE;
|
xcb_window_t window = XCB_NONE;
|
||||||
uint16_t deviceid;
|
uint16_t deviceid;
|
||||||
uint32_t pointid;
|
uint32_t pointid;
|
||||||
int corner;
|
int corner;
|
||||||
} m_startSystemMoveResizeInfo;
|
} m_startSystemMoveResizeInfo;
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
WindowMapper m_mapper;
|
WindowMapper m_mapper;
|
||||||
|
|
||||||
|
@ -693,6 +672,9 @@ private:
|
||||||
uint32_t xfixes_first_event = 0;
|
uint32_t xfixes_first_event = 0;
|
||||||
uint32_t xrandr_first_event = 0;
|
uint32_t xrandr_first_event = 0;
|
||||||
uint32_t xkb_first_event = 0;
|
uint32_t xkb_first_event = 0;
|
||||||
|
#if QT_CONFIG(xcb_xinput)
|
||||||
|
uint32_t xinput_first_event = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool has_xfixes = false;
|
bool has_xfixes = false;
|
||||||
bool has_xinerama_extension = false;
|
bool has_xinerama_extension = false;
|
||||||
|
@ -726,7 +708,7 @@ private:
|
||||||
QHash<qint32, qint32> m_peekerToCachedIndex;
|
QHash<qint32, qint32> m_peekerToCachedIndex;
|
||||||
friend class QXcbEventReader;
|
friend class QXcbEventReader;
|
||||||
};
|
};
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
#if QT_CONFIG(tabletevent)
|
#if QT_CONFIG(tabletevent)
|
||||||
Q_DECLARE_TYPEINFO(QXcbConnection::TabletData::ValuatorClassInfo, Q_PRIMITIVE_TYPE);
|
Q_DECLARE_TYPEINFO(QXcbConnection::TabletData::ValuatorClassInfo, Q_PRIMITIVE_TYPE);
|
||||||
Q_DECLARE_TYPEINFO(QXcbConnection::TabletData, Q_MOVABLE_TYPE);
|
Q_DECLARE_TYPEINFO(QXcbConnection::TabletData, Q_MOVABLE_TYPE);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -52,10 +52,8 @@
|
||||||
|
|
||||||
#include <xkbcommon/xkbcommon-keysyms.h>
|
#include <xkbcommon/xkbcommon-keysyms.h>
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
#include <X11/extensions/XI2proto.h>
|
#include <xcb/xinput.h>
|
||||||
#undef KeyPress
|
|
||||||
#undef KeyRelease
|
|
||||||
#endif
|
#endif
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
@ -824,20 +822,20 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo)
|
void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo)
|
||||||
{
|
{
|
||||||
if (m_config && !connection()->hasXKB()) {
|
if (m_config && !connection()->hasXKB()) {
|
||||||
xXIModifierInfo *mods = static_cast<xXIModifierInfo *>(modInfo);
|
auto *mods = static_cast<xcb_input_modifier_info_t *>(modInfo);
|
||||||
xXIGroupInfo *group = static_cast<xXIGroupInfo *>(groupInfo);
|
auto *group = static_cast<xcb_input_group_info_t *>(groupInfo);
|
||||||
const xkb_state_component changedComponents
|
const xkb_state_component changedComponents
|
||||||
= xkb_state_update_mask(m_xkbState.get(),
|
= xkb_state_update_mask(m_xkbState.get(),
|
||||||
mods->base_mods,
|
mods->base,
|
||||||
mods->latched_mods,
|
mods->latched,
|
||||||
mods->locked_mods,
|
mods->locked,
|
||||||
group->base_group,
|
group->base,
|
||||||
group->latched_group,
|
group->latched,
|
||||||
group->locked_group);
|
group->locked);
|
||||||
|
|
||||||
handleStateChanges(changedComponents);
|
handleStateChanges(changedComponents);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
void updateXKBMods();
|
void updateXKBMods();
|
||||||
xkb_mod_mask_t xkbModMask(quint16 state);
|
xkb_mod_mask_t xkbModMask(quint16 state);
|
||||||
void updateXKBStateFromCore(quint16 state);
|
void updateXKBStateFromCore(quint16 state);
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
void updateXKBStateFromXI(void *modInfo, void *groupInfo);
|
void updateXKBStateFromXI(void *modInfo, void *groupInfo);
|
||||||
#endif
|
#endif
|
||||||
#if QT_CONFIG(xkb)
|
#if QT_CONFIG(xkb)
|
||||||
|
|
|
@ -68,6 +68,9 @@
|
||||||
#undef class
|
#undef class
|
||||||
#include <xcb/xfixes.h>
|
#include <xcb/xfixes.h>
|
||||||
#include <xcb/shape.h>
|
#include <xcb/shape.h>
|
||||||
|
#if QT_CONFIG(xcb_xinput)
|
||||||
|
#include <xcb/xinput.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// xcb-icccm 3.8 support
|
// xcb-icccm 3.8 support
|
||||||
#ifdef XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS
|
#ifdef XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS
|
||||||
|
@ -105,11 +108,6 @@
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
|
||||||
#include <X11/extensions/XInput2.h>
|
|
||||||
#include <X11/extensions/XI2proto.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define XCOORD_MAX 16383
|
#define XCOORD_MAX 16383
|
||||||
enum {
|
enum {
|
||||||
defaultWindowWidth = 160,
|
defaultWindowWidth = 160,
|
||||||
|
@ -520,7 +518,7 @@ void QXcbWindow::create()
|
||||||
atom(QXcbAtom::_XEMBED_INFO),
|
atom(QXcbAtom::_XEMBED_INFO),
|
||||||
32, 2, (void *)data);
|
32, 2, (void *)data);
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
if (connection()->hasXInput2()) {
|
if (connection()->hasXInput2()) {
|
||||||
if (connection()->xi2MouseEventsDisabled())
|
if (connection()->xi2MouseEventsDisabled())
|
||||||
connection()->xi2SelectDeviceEventsCompatibility(m_window);
|
connection()->xi2SelectDeviceEventsCompatibility(m_window);
|
||||||
|
@ -2149,7 +2147,7 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
|
||||||
QPoint global(root_x, root_y);
|
QPoint global(root_x, root_y);
|
||||||
|
|
||||||
if (isWheel) {
|
if (isWheel) {
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
if (!connection()->isAtLeastXI21()) {
|
if (!connection()->isAtLeastXI21()) {
|
||||||
#endif
|
#endif
|
||||||
QPoint angleDelta;
|
QPoint angleDelta;
|
||||||
|
@ -2164,7 +2162,7 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
|
||||||
if (modifiers & Qt::AltModifier)
|
if (modifiers & Qt::AltModifier)
|
||||||
std::swap(angleDelta.rx(), angleDelta.ry());
|
std::swap(angleDelta.rx(), angleDelta.ry());
|
||||||
QWindowSystemInterface::handleWheelEvent(window(), timestamp, local, global, QPoint(), angleDelta, modifiers);
|
QWindowSystemInterface::handleWheelEvent(window(), timestamp, local, global, QPoint(), angleDelta, modifiers);
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
@ -2204,7 +2202,7 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn)
|
||||||
if (conn) {
|
if (conn) {
|
||||||
|
|
||||||
const bool mouseButtonsPressed = (conn->buttonState() != Qt::NoButton);
|
const bool mouseButtonsPressed = (conn->buttonState() != Qt::NoButton);
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
return mouseButtonsPressed || (conn->hasXInput2() && !conn->xi2MouseEventsDisabled());
|
return mouseButtonsPressed || (conn->hasXInput2() && !conn->xi2MouseEventsDisabled());
|
||||||
#else
|
#else
|
||||||
return mouseButtonsPressed;
|
return mouseButtonsPressed;
|
||||||
|
@ -2253,7 +2251,7 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in
|
||||||
quint8 mode, quint8 detail, xcb_timestamp_t timestamp)
|
quint8 mode, quint8 detail, xcb_timestamp_t timestamp)
|
||||||
{
|
{
|
||||||
connection()->setTime(timestamp);
|
connection()->setTime(timestamp);
|
||||||
#ifdef XCB_USE_XINPUT21
|
#if QT_CONFIG(xcb_xinput)
|
||||||
// Updates scroll valuators, as user might have done some scrolling outside our X client.
|
// Updates scroll valuators, as user might have done some scrolling outside our X client.
|
||||||
connection()->xi2UpdateScrollingDevices();
|
connection()->xi2UpdateScrollingDevices();
|
||||||
#endif
|
#endif
|
||||||
|
@ -2330,16 +2328,18 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
|
||||||
event->time, QEvent::MouseMove);
|
event->time, QEvent::MouseMove);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
static inline int fixed1616ToInt(FP1616 val)
|
static inline int fixed1616ToInt(xcb_input_fp1616_t val)
|
||||||
{
|
{
|
||||||
return int(qreal(val) / 0x10000);
|
return int(qreal(val) / 0x10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define qt_xcb_mask_is_set(ptr, event) (((unsigned char*)(ptr))[(event)>>3] & (1 << ((event) & 7)))
|
||||||
|
|
||||||
void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source)
|
void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source)
|
||||||
{
|
{
|
||||||
QXcbConnection *conn = connection();
|
QXcbConnection *conn = connection();
|
||||||
xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event);
|
auto *ev = reinterpret_cast<xcb_input_button_press_event_t *>(event);
|
||||||
|
|
||||||
if (ev->buttons_len > 0) {
|
if (ev->buttons_len > 0) {
|
||||||
unsigned char *buttonMask = (unsigned char *) &ev[1];
|
unsigned char *buttonMask = (unsigned char *) &ev[1];
|
||||||
|
@ -2347,16 +2347,16 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource
|
||||||
// XIPointerEmulated being set: https://bugs.freedesktop.org/show_bug.cgi?id=98188
|
// XIPointerEmulated being set: https://bugs.freedesktop.org/show_bug.cgi?id=98188
|
||||||
// Filter them out by other attributes: when their source device is a touch screen
|
// Filter them out by other attributes: when their source device is a touch screen
|
||||||
// and the LMB is pressed.
|
// and the LMB is pressed.
|
||||||
if (XIMaskIsSet(buttonMask, 1) && conn->isTouchScreen(ev->sourceid)) {
|
if (qt_xcb_mask_is_set(buttonMask, 1) && conn->isTouchScreen(ev->sourceid)) {
|
||||||
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
|
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
|
||||||
qCDebug(lcQpaXInput, "XI2 mouse event from touch device %d was ignored", ev->sourceid);
|
qCDebug(lcQpaXInput, "XI2 mouse event from touch device %d was ignored", ev->sourceid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 1; i <= 15; ++i)
|
for (int i = 1; i <= 15; ++i)
|
||||||
conn->setButtonState(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i));
|
conn->setButtonState(conn->translateMouseButton(i), qt_xcb_mask_is_set(buttonMask, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods);
|
const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective);
|
||||||
const int event_x = fixed1616ToInt(ev->event_x);
|
const int event_x = fixed1616ToInt(ev->event_x);
|
||||||
const int event_y = fixed1616ToInt(ev->event_y);
|
const int event_y = fixed1616ToInt(ev->event_y);
|
||||||
const int root_x = fixed1616ToInt(ev->root_x);
|
const int root_x = fixed1616ToInt(ev->root_x);
|
||||||
|
@ -2373,47 +2373,47 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource
|
||||||
sourceName = me.valueToKey(source);
|
sourceName = me.valueToKey(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ev->evtype) {
|
switch (ev->event_type) {
|
||||||
case XI_ButtonPress:
|
case XCB_INPUT_BUTTON_PRESS:
|
||||||
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
|
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
|
||||||
qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName);
|
qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName);
|
||||||
conn->setButtonState(button, true);
|
conn->setButtonState(button, true);
|
||||||
handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonPress, source);
|
handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonPress, source);
|
||||||
break;
|
break;
|
||||||
case XI_ButtonRelease:
|
case XCB_INPUT_BUTTON_RELEASE:
|
||||||
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
|
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
|
||||||
qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName);
|
qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName);
|
||||||
conn->setButtonState(button, false);
|
conn->setButtonState(button, false);
|
||||||
handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonRelease, source);
|
handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonRelease, source);
|
||||||
break;
|
break;
|
||||||
case XI_Motion:
|
case XCB_INPUT_MOTION:
|
||||||
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
|
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
|
||||||
qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName);
|
qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName);
|
||||||
handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, QEvent::MouseMove, source);
|
handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, QEvent::MouseMove, source);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qWarning() << "Unrecognized XI2 mouse event" << ev->evtype;
|
qWarning() << "Unrecognized XI2 mouse event" << ev->event_type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
|
void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
|
||||||
{
|
{
|
||||||
xXIEnterEvent *ev = reinterpret_cast<xXIEnterEvent *>(event);
|
auto *ev = reinterpret_cast<xcb_input_enter_event_t *>(event);
|
||||||
|
|
||||||
// Compare the window with current mouse grabber to prevent deliver events to any other windows.
|
// Compare the window with current mouse grabber to prevent deliver events to any other windows.
|
||||||
// If leave event occurs and the window is under mouse - allow to deliver the leave event.
|
// If leave event occurs and the window is under mouse - allow to deliver the leave event.
|
||||||
QXcbWindow *mouseGrabber = connection()->mouseGrabber();
|
QXcbWindow *mouseGrabber = connection()->mouseGrabber();
|
||||||
if (mouseGrabber && mouseGrabber != this
|
if (mouseGrabber && mouseGrabber != this
|
||||||
&& (ev->evtype != XI_Leave || QGuiApplicationPrivate::currentMouseWindow != window())) {
|
&& (ev->event_type != XCB_INPUT_LEAVE || QGuiApplicationPrivate::currentMouseWindow != window())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int root_x = fixed1616ToInt(ev->root_x);
|
const int root_x = fixed1616ToInt(ev->root_x);
|
||||||
const int root_y = fixed1616ToInt(ev->root_y);
|
const int root_y = fixed1616ToInt(ev->root_y);
|
||||||
|
|
||||||
switch (ev->evtype) {
|
switch (ev->event_type) {
|
||||||
case XI_Enter: {
|
case XCB_INPUT_ENTER: {
|
||||||
const int event_x = fixed1616ToInt(ev->event_x);
|
const int event_x = fixed1616ToInt(ev->event_x);
|
||||||
const int event_y = fixed1616ToInt(ev->event_y);
|
const int event_y = fixed1616ToInt(ev->event_y);
|
||||||
qCDebug(lcQpaXInputEvents, "XI2 mouse enter %d,%d, mode %d, detail %d, time %d",
|
qCDebug(lcQpaXInputEvents, "XI2 mouse enter %d,%d, mode %d, detail %d, time %d",
|
||||||
|
@ -2421,7 +2421,7 @@ void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
|
||||||
handleEnterNotifyEvent(event_x, event_y, root_x, root_y, ev->mode, ev->detail, ev->time);
|
handleEnterNotifyEvent(event_x, event_y, root_x, root_y, ev->mode, ev->detail, ev->time);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case XI_Leave:
|
case XCB_INPUT_LEAVE:
|
||||||
qCDebug(lcQpaXInputEvents, "XI2 mouse leave, mode %d, detail %d, time %d",
|
qCDebug(lcQpaXInputEvents, "XI2 mouse leave, mode %d, detail %d, time %d",
|
||||||
ev->mode, ev->detail, ev->time);
|
ev->mode, ev->detail, ev->time);
|
||||||
connection()->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group);
|
connection()->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group);
|
||||||
|
@ -2563,7 +2563,7 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
|
||||||
if (grab && !connection()->canGrab())
|
if (grab && !connection()->canGrab())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
if (connection()->hasXInput2() && !connection()->xi2MouseEventsDisabled()) {
|
if (connection()->hasXInput2() && !connection()->xi2MouseEventsDisabled()) {
|
||||||
bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab);
|
bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab);
|
||||||
if (grab && result)
|
if (grab && result)
|
||||||
|
@ -2654,7 +2654,7 @@ bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner)
|
||||||
if (!connection()->wmSupport()->isSupportedByWM(moveResize))
|
if (!connection()->wmSupport()->isSupportedByWM(moveResize))
|
||||||
return false;
|
return false;
|
||||||
const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen());
|
const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen());
|
||||||
#ifdef XCB_USE_XINPUT22
|
#if QT_CONFIG(xcb_xinput)
|
||||||
if (connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner))
|
if (connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -139,7 +139,7 @@ public:
|
||||||
void handleFocusInEvent(const xcb_focus_in_event_t *event) override;
|
void handleFocusInEvent(const xcb_focus_in_event_t *event) override;
|
||||||
void handleFocusOutEvent(const xcb_focus_out_event_t *event) override;
|
void handleFocusOutEvent(const xcb_focus_out_event_t *event) override;
|
||||||
void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) override;
|
void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) override;
|
||||||
#if QT_CONFIG(xinput2)
|
#if QT_CONFIG(xcb_xinput)
|
||||||
void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) override;
|
void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) override;
|
||||||
void handleXIEnterLeave(xcb_ge_event_t *) override;
|
void handleXIEnterLeave(xcb_ge_event_t *) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -55,11 +55,10 @@ DEFINES += QT_BUILD_XCB_PLUGIN
|
||||||
|
|
||||||
qtConfig(xcb-xlib) {
|
qtConfig(xcb-xlib) {
|
||||||
QMAKE_USE += xcb_xlib
|
QMAKE_USE += xcb_xlib
|
||||||
|
}
|
||||||
|
|
||||||
qtConfig(xinput2) {
|
qtConfig(xcb-xinput) {
|
||||||
SOURCES += qxcbconnection_xi2.cpp
|
SOURCES += qxcbconnection_xi2.cpp
|
||||||
QMAKE_USE += xinput2
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qtConfig(xcb-sm) {
|
qtConfig(xcb-sm) {
|
||||||
|
@ -86,6 +85,7 @@ qtConfig(vulkan) {
|
||||||
} else {
|
} else {
|
||||||
qtConfig(xkb): QMAKE_USE += xcb_xkb
|
qtConfig(xkb): QMAKE_USE += xcb_xkb
|
||||||
qtConfig(xcb-render): QMAKE_USE += xcb_render
|
qtConfig(xcb-render): QMAKE_USE += xcb_render
|
||||||
|
qtConfig(xcb-xinput): QMAKE_USE += xcb_xinput
|
||||||
QMAKE_USE += xcb_syslibs
|
QMAKE_USE += xcb_syslibs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue