181void QXcbConnection::printXcbEvent(
const QLoggingCategory &log,
const char *message,
182 xcb_generic_event_t *event)
const
184 quint8 response_type = event->response_type & ~0x80;
185 quint16 sequence = event->sequence;
187#define PRINT_AND_RETURN(name) {
188 qCDebug(log, "%s | %s(%d) | sequence: %d", message, name, response_type, sequence);
190}
191#define CASE_PRINT_AND_RETURN(name) case name : PRINT_AND_RETURN(#name);
193#define XI_PRINT_AND_RETURN(name) {
194 qCDebug(log, "%s | XInput Event(%s) | sequence: %d", message, name, sequence);
196}
199 switch (response_type) {
233 case XCB_GE_GENERIC: {
234 if (hasXInput2() && isXIEvent(event)) {
235 auto *xiDeviceEvent =
reinterpret_cast<
const xcb_input_button_press_event_t*>(event);
236 switch (xiDeviceEvent->event_type) {
263 qCDebug(log,
"%s | XInput Event(other type) | sequence: %d", message, sequence);
267 qCDebug(log,
"%s | %s(%d) | sequence: %d", message,
"XCB_GE_GENERIC", response_type, sequence);
273 if (isXFixesType(response_type, XCB_XFIXES_SELECTION_NOTIFY))
277 if (isXRandrType(response_type, XCB_RANDR_NOTIFY))
279 if (isXRandrType(response_type, XCB_RANDR_SCREEN_CHANGE_NOTIFY))
283 if (isXkbType(response_type))
287 qCDebug(log,
"%s | unknown(%d) | sequence: %d", message, response_type, sequence);
289#undef PRINT_AND_RETURN
290#undef CASE_PRINT_AND_RETURN
533void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
535 if (Q_UNLIKELY(lcQpaEvents().isDebugEnabled()))
536 printXcbEvent(lcQpaEvents(),
"Event", event);
539 if (QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance()) {
540 if (dispatcher->filterNativeEvent(m_nativeInterface->nativeEventType(), event, &result))
544 uint response_type = event->response_type & ~0x80;
547 switch (response_type) {
550 case XCB_BUTTON_PRESS: {
551 auto ev =
reinterpret_cast<xcb_button_press_event_t *>(event);
553 m_keyboard->updateXKBStateFromCore(ev->state);
556 m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
557 setButtonState(translateMouseButton(ev->detail),
true);
558 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
559 qCDebug(lcQpaXInputEvents,
"legacy mouse press, button %d state %X",
560 ev->detail,
static_cast<
unsigned int>(m_buttonState));
563 case XCB_BUTTON_RELEASE: {
564 auto ev =
reinterpret_cast<xcb_button_release_event_t *>(event);
566 if (m_duringSystemMoveResize && ev->root != XCB_NONE)
567 abortSystemMoveResize(ev->root);
568 m_keyboard->updateXKBStateFromCore(ev->state);
569 m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
570 setButtonState(translateMouseButton(ev->detail),
false);
571 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
572 qCDebug(lcQpaXInputEvents,
"legacy mouse release, button %d state %X",
573 ev->detail,
static_cast<
unsigned int>(m_buttonState));
576 case XCB_MOTION_NOTIFY: {
577 auto ev =
reinterpret_cast<xcb_motion_notify_event_t *>(event);
579 m_keyboard->updateXKBStateFromCore(ev->state);
580 m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
581 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
582 qCDebug(lcQpaXInputEvents,
"legacy mouse move %d,%d button %d state %X",
583 ev->event_x, ev->event_y, ev->detail,
static_cast<
unsigned int>(m_buttonState));
586 case XCB_CONFIGURE_NOTIFY: {
587 if (isAtLeastXRandR15()) {
588 auto ev =
reinterpret_cast<xcb_configure_notify_event_t *>(event);
589 if (ev->event == rootWindow())
590 initializeScreens(
true);
596 case XCB_UNMAP_NOTIFY:
598 case XCB_DESTROY_NOTIFY:
600 case XCB_CLIENT_MESSAGE: {
601 auto clientMessage =
reinterpret_cast<xcb_client_message_event_t *>(event);
602 if (clientMessage->format != 32)
604#if QT_CONFIG(draganddrop)
605 if (clientMessage->type == atom(QXcbAtom::AtomXdndStatus))
606 drag()->handleStatus(clientMessage);
607 else if (clientMessage->type == atom(QXcbAtom::AtomXdndFinished))
608 drag()->handleFinished(clientMessage);
610 if (m_systemTrayTracker && clientMessage->type == atom(QXcbAtom::AtomMANAGER))
611 m_systemTrayTracker->notifyManagerClientMessageEvent(clientMessage);
614 case XCB_ENTER_NOTIFY:
619 setTime(
reinterpret_cast<xcb_enter_notify_event_t *>(event)->time);
621 case XCB_LEAVE_NOTIFY:
627 auto ev =
reinterpret_cast<xcb_leave_notify_event_t *>(event);
629 m_keyboard->updateXKBStateFromCore(ev->state);
638 auto keyPress =
reinterpret_cast<xcb_key_press_event_t *>(event);
639 setTime(keyPress->time);
640 m_keyboard->updateXKBStateFromCore(keyPress->state);
641 setTime(keyPress->time);
644 case XCB_KEY_RELEASE:
646 auto keyRelease =
reinterpret_cast<xcb_key_release_event_t *>(event);
647 setTime(keyRelease->time);
648 m_keyboard->updateXKBStateFromCore(keyRelease->state);
651 case XCB_MAPPING_NOTIFY:
652 m_keyboard->updateKeymap(
reinterpret_cast<xcb_mapping_notify_event_t *>(event));
654 case XCB_SELECTION_REQUEST:
656#if QT_CONFIG(draganddrop) || QT_CONFIG(clipboard)
657 auto selectionRequest =
reinterpret_cast<xcb_selection_request_event_t *>(event);
658 setTime(selectionRequest->time);
660#if QT_CONFIG(draganddrop)
661 if (selectionRequest->selection == atom(QXcbAtom::AtomXdndSelection))
662 m_drag->handleSelectionRequest(selectionRequest);
666#ifndef QT_NO_CLIPBOARD
667 m_clipboard->handleSelectionRequest(selectionRequest);
672 case XCB_SELECTION_CLEAR:
673 setTime((
reinterpret_cast<xcb_selection_clear_event_t *>(event))->time);
674#ifndef QT_NO_CLIPBOARD
675 m_clipboard->handleSelectionClearRequest(
reinterpret_cast<xcb_selection_clear_event_t *>(event));
678 case XCB_SELECTION_NOTIFY:
679 setTime((
reinterpret_cast<xcb_selection_notify_event_t *>(event))->time);
681 case XCB_PROPERTY_NOTIFY:
683 auto propertyNotify =
reinterpret_cast<xcb_property_notify_event_t *>(event);
684 setTime(propertyNotify->time);
685#ifndef QT_NO_CLIPBOARD
686 if (m_clipboard->handlePropertyNotify(event))
689 if (propertyNotify->atom == atom(QXcbAtom::Atom_NET_WORKAREA)) {
690 QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
692 virtualDesktop->updateWorkArea();
693 }
else if (propertyNotify->atom == atom(QXcbAtom::Atom_NET_SUPPORTED)) {
694 m_wmSupport->updateNetWMAtoms();
702 if (hasXInput2() && isXIEvent(event))
703 xi2HandleEvent(
reinterpret_cast<xcb_ge_event_t *>(event));
714 if (isXFixesType(response_type, XCB_XFIXES_SELECTION_NOTIFY)) {
715 auto notify_event =
reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(event);
716 setTime(notify_event->timestamp);
717#ifndef QT_NO_CLIPBOARD
718 m_clipboard->handleXFixesSelectionRequest(notify_event);
720 for (QXcbVirtualDesktop *virtualDesktop : std::as_const(m_virtualDesktops))
721 virtualDesktop->handleXFixesSelectionNotify(notify_event);
722 }
else if (isXRandrType(response_type, XCB_RANDR_NOTIFY)) {
723 if (!isAtLeastXRandR15())
724 updateScreens(
reinterpret_cast<xcb_randr_notify_event_t *>(event));
725 }
else if (isXRandrType(response_type, XCB_RANDR_SCREEN_CHANGE_NOTIFY)) {
726 if (!isAtLeastXRandR15()) {
727 auto change_event =
reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
728 if (
auto virtualDesktop = virtualDesktopForRootWindow(change_event->root))
729 virtualDesktop->handleScreenChange(change_event);
731 }
else if (isXkbType(response_type)) {
732 auto xkb_event =
reinterpret_cast<_xkb_event *>(event);
733 if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
734 switch (xkb_event->any.xkbType) {
737 case XCB_XKB_STATE_NOTIFY:
738 m_keyboard->updateXKBState(&xkb_event->state_notify);
740 case XCB_XKB_MAP_NOTIFY:
741 m_keyboard->updateKeymap();
743 case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
744 xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
745 if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
746 m_keyboard->updateKeymap();
761 m_glIntegration->handleXcbEvent(event, response_type);
1028bool QXcbConnection::isUserInputEvent(xcb_generic_event_t *event)
const
1030 auto eventType = event->response_type & ~0x80;
1031 bool isInputEvent = eventType == XCB_BUTTON_PRESS ||
1032 eventType == XCB_BUTTON_RELEASE ||
1033 eventType == XCB_KEY_PRESS ||
1034 eventType == XCB_KEY_RELEASE ||
1035 eventType == XCB_MOTION_NOTIFY ||
1036 eventType == XCB_ENTER_NOTIFY ||
1037 eventType == XCB_LEAVE_NOTIFY;
1041 if (connection()->hasXInput2()) {
1042 isInputEvent = isXIType(event, XCB_INPUT_BUTTON_PRESS) ||
1043 isXIType(event, XCB_INPUT_BUTTON_RELEASE) ||
1044 isXIType(event, XCB_INPUT_MOTION) ||
1045 isXIType(event, XCB_INPUT_TOUCH_BEGIN) ||
1046 isXIType(event, XCB_INPUT_TOUCH_UPDATE) ||
1047 isXIType(event, XCB_INPUT_TOUCH_END) ||
1048 isXIType(event, XCB_INPUT_ENTER) ||
1049 isXIType(event, XCB_INPUT_LEAVE) ||
1051 isXIType(event, XCB_INPUT_PROPERTY);
1056 if (eventType == XCB_CLIENT_MESSAGE) {
1057 auto clientMessage =
reinterpret_cast<
const xcb_client_message_event_t *>(event);
1058 if (clientMessage->format == 32 && clientMessage->type == atom(QXcbAtom::AtomWM_PROTOCOLS))
1059 if (clientMessage->data.data32[0] == atom(QXcbAtom::AtomWM_DELETE_WINDOW))
1060 isInputEvent =
true;
1063 return isInputEvent;