diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,12 +26,19 @@ # to monitor hotplugging events, since these are signaled as xinput events. # # Users can enable xcb-xinput by building xcb with the configuration flag --enable-xinput. -if(XCB_XINPUT_FOUND) - message(STATUS "Using XCB_XINPUT. Please note this is an unstable API.") +option(USE_XCB_XINPUT "Use XCB_XINPUT" ON) + +if(!XCB_XINPUT_FOUND AND USE_XCB_XINPUT) + message(STATUS "XCB_XINPUT was not found. Falling back to X11_XINPUT") + set(USE_XCB_XINPUT OFF CACHE BOOL "Use XCB_XINPUT" FORCE) +endif() + +if(USE_XCB_XINPUT) + message(STATUS "Using XCB_XINPUT. Please note this is an unstable API.") set(USING_X_LIBRARIES XCB::XINPUT XCB::RANDR ${X11_Xrandr_LIB} ${X11_Xinput_LIB}) add_definitions(-DHAVE_XCB_XINPUT) else() - message(STATUS "Falling back to X11_XINPUT. (Daemon will be unable to monitor hotplugging.)") + message(STATUS "Using X11_XINPUT.") set(USING_X_LIBRARIES XCB::RANDR ${X11_LIBRARIES} ${X11_Xinput_LIB} ${X11_Xrandr_LIB}) endif() diff --git a/src/kded/x11eventnotifier-xlib.cpp b/src/kded/x11eventnotifier-xlib.cpp --- a/src/kded/x11eventnotifier-xlib.cpp +++ b/src/kded/x11eventnotifier-xlib.cpp @@ -37,12 +37,25 @@ #include #include +// Hack for missing xcb xinput, taken from from kcm_keyboard +typedef struct xcb_input_device_presence_notify_event_t { + uint8_t response_type; + uint8_t pad0; + uint16_t sequence; + xcb_timestamp_t time; + uint8_t devchange; + uint8_t device_id; + uint16_t control; + uint8_t pad1[20]; +} xcb_input_device_presence_notify_event_t; + namespace Wacom { class X11EventNotifierPrivate { public: bool isStarted = false; + int xinputEventType = -1; }; } @@ -105,15 +118,23 @@ Q_UNUSED(result); xcb_generic_event_t *event = static_cast(message); - xcb_ge_generic_event_t *cookie = reinterpret_cast(message); - if (event->response_type == XCB_GE_GENERIC && cookie->event_type == XI_HierarchyChanged) { - // handleX11InputEvent(cookie); - } else { - // handleX11ScreenEvent(event); + Q_D (X11EventNotifier); + if (d->xinputEventType != -1 && event->response_type == d->xinputEventType) { + xcb_input_device_presence_notify_event_t *xdpne = reinterpret_cast(event); + if (xdpne->devchange == DeviceEnabled) { + dbgWacom << QString::fromLatin1("New device with id '%1' detected").arg(xdpne->device_id); + X11InputDevice device(xdpne->device_id, QLatin1String("Unknown X11 Device")); + + if (device.isOpen() && device.isTabletDevice()) { + dbgWacom << QString::fromLatin1("Wacom tablet device with X11 id '%1' added.").arg(xdpne->device_id); + emit tabletAdded(xdpne->device_id); + } + } else if (xdpne->devchange == DeviceDisabled) { + dbgWacom << QString::fromLatin1("Device with id '%1' has been disabled").arg(xdpne->device_id); + emit tabletRemoved(xdpne->device_id); + } } - - // return QWidget::x11Event(event); return false; } @@ -123,24 +144,19 @@ void X11EventNotifier::handleX11InputEvent(xcb_ge_generic_event_t* event) { Q_UNUSED(event) - // Sadly there does not seem to be a way to use this functionality :( + // TODO: this function only makes sense in xcb-xinput backend implementation. Split this in a smarter way. } int X11EventNotifier::registerForNewDeviceEvent(xcb_connection_t* conn) { Q_UNUSED(conn) - // This is already done by xcb plugin with more flags, doing this ourselves - // will break Qt's xrandr functionality because connection is shared with Qt. - // TODO: uncomment this again when we use our private connection. -#if 0 - //register RandR events - int rrmask = XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE; - - xcb_randr_select_input(conn, QX11Info::appRootWindow(), 0); - xcb_randr_select_input(conn, QX11Info::appRootWindow(), rrmask); -#endif + Q_D (X11EventNotifier); + auto display = QX11Info::display(); + XEventClass xiclass; + DevicePresence(display, d->xinputEventType, xiclass); + XSelectExtensionEvent(display, DefaultRootWindow(display), &xiclass, 1); return 0; }