diff --git a/effects.cpp b/effects.cpp index 301b2b6055..3fee73ad5b 100644 --- a/effects.cpp +++ b/effects.cpp @@ -1184,43 +1184,31 @@ void EffectsHandlerImpl::defineCursor(Qt::CursorShape shape) m_mouseInterceptionWindow.defineCursor(Cursor::x11Cursor(shape)); } -bool EffectsHandlerImpl::checkInputWindowEvent(XEvent* e) +bool EffectsHandlerImpl::checkInputWindowEvent(xcb_button_press_event_t *e) { - if (e->type != ButtonPress && e->type != ButtonRelease && e->type != MotionNotify) - return false; - if (m_grabbedMouseEffects.isEmpty() || m_mouseInterceptionWindow != e->xany.window) { + if (m_grabbedMouseEffects.isEmpty() || m_mouseInterceptionWindow != e->event) { return false; } - foreach (Effect *effect, m_grabbedMouseEffects) { - switch(e->type) { - case ButtonPress: { - XButtonEvent* e2 = &e->xbutton; - Qt::MouseButton button = x11ToQtMouseButton(e2->button); - Qt::MouseButtons buttons = x11ToQtMouseButtons(e2->state) | button; - QMouseEvent ev(QEvent::MouseButtonPress, - QPoint(e2->x, e2->y), QPoint(e2->x_root, e2->y_root), - button, buttons, x11ToQtKeyboardModifiers(e2->state)); - effect->windowInputMouseEvent(&ev); - break; // ---> - } - case ButtonRelease: { - XButtonEvent* e2 = &e->xbutton; - Qt::MouseButton button = x11ToQtMouseButton(e2->button); - Qt::MouseButtons buttons = x11ToQtMouseButtons(e2->state) & ~button; - QMouseEvent ev(QEvent::MouseButtonRelease, - QPoint(e2->x, e2->y), QPoint(e2->x_root, e2->y_root), - button, buttons, x11ToQtKeyboardModifiers(e2->state)); - effect->windowInputMouseEvent(&ev); - break; // ---> - } - case MotionNotify: { - XMotionEvent* e2 = &e->xmotion; - QMouseEvent ev(QEvent::MouseMove, QPoint(e2->x, e2->y), QPoint(e2->x_root, e2->y_root), - Qt::NoButton, x11ToQtMouseButtons(e2->state), x11ToQtKeyboardModifiers(e2->state)); - effect->windowInputMouseEvent(&ev); - break; // ---> - } - } + for (Effect *effect : m_grabbedMouseEffects) { + Qt::MouseButton button = x11ToQtMouseButton(e->detail); + Qt::MouseButtons buttons = x11ToQtMouseButtons(e->state) & ~button; + QMouseEvent ev(((e->response_type & ~0x80) == XCB_BUTTON_PRESS) ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease, + QPoint(e->event_x, e->event_y), QPoint(e->root_x, e->root_y), + button, buttons, x11ToQtKeyboardModifiers(e->state)); + effect->windowInputMouseEvent(&ev); + } + return true; // eat event +} + +bool EffectsHandlerImpl::checkInputWindowEvent(xcb_motion_notify_event_t *e) +{ + if (m_grabbedMouseEffects.isEmpty() || m_mouseInterceptionWindow != e->event) { + return false; + } + for (Effect *effect : m_grabbedMouseEffects) { + QMouseEvent ev(QEvent::MouseMove, QPoint(e->event_x, e->event_y), QPoint(e->root_x, e->root_y), + Qt::NoButton, x11ToQtMouseButtons(e->state), x11ToQtKeyboardModifiers(e->state)); + effect->windowInputMouseEvent(&ev); } return true; // eat event } diff --git a/effects.h b/effects.h index 7d2092faba..01c45db2c0 100644 --- a/effects.h +++ b/effects.h @@ -151,7 +151,8 @@ public: virtual WindowQuadType newWindowQuadType(); virtual void defineCursor(Qt::CursorShape shape); - virtual bool checkInputWindowEvent(XEvent* e); + bool checkInputWindowEvent(xcb_button_press_event_t *e); + bool checkInputWindowEvent(xcb_motion_notify_event_t *e); virtual void checkInputWindowStacking(); virtual void reserveElectricBorder(ElectricBorder border, Effect *effect); diff --git a/events.cpp b/events.cpp index 5150c5f532..c1b22a4801 100644 --- a/events.cpp +++ b/events.cpp @@ -99,31 +99,44 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e) } #endif -#if KWIN_QT5_PORTING // events that should be handled before Clients can get them - switch(e->type) { - case ButtonPress: - case ButtonRelease: + switch (eventType) { + case XCB_BUTTON_PRESS: + case XCB_BUTTON_RELEASE: { was_user_interaction = true; - // fallthrough - case MotionNotify: + auto *mouseEvent = reinterpret_cast(e); +#ifdef KWIN_BUILD_TABBOX + if (TabBox::TabBox::self()->isGrabbed()) { + return TabBox::TabBox::self()->handleMouseEvent(mouseEvent); + } +#endif + if (effects && static_cast(effects)->checkInputWindowEvent(mouseEvent)) { + return true; + } + break; + } + case XCB_MOTION_NOTIFY: { + auto *mouseEvent = reinterpret_cast(e); + const QPoint rootPos(mouseEvent->root_x, mouseEvent->root_y); #ifdef KWIN_BUILD_TABBOX if (TabBox::TabBox::self()->isGrabbed()) { #ifdef KWIN_BUILD_SCREENEDGES - ScreenEdges::self()->check(QPoint(e->xbutton.x_root, e->xbutton.y_root), QDateTime::fromMSecsSinceEpoch(xTime()), true); + ScreenEdges::self()->check(rootPos, QDateTime::fromMSecsSinceEpoch(xTime()), true); #endif - return TabBox::TabBox::self()->handleMouseEvent(e); + return TabBox::TabBox::self()->handleMouseEvent(mouseEvent); } #endif - if (effects && static_cast(effects)->checkInputWindowEvent(e)) { + if (effects && static_cast(effects)->checkInputWindowEvent(mouseEvent)) { return true; } #ifdef KWIN_BUILD_SCREENEDGES if (QWidget::mouseGrabber()) { - ScreenEdges::self()->check(QPoint(e->xbutton.x_root, e->xbutton.y_root), QDateTime::fromMSecsSinceEpoch(xTime()), true); + ScreenEdges::self()->check(rootPos, QDateTime::fromMSecsSinceEpoch(xTime()), true); } #endif break; + } +#if KWIN_QT5_PORTING case KeyPress: { was_user_interaction = true; int keyQt; @@ -353,8 +366,8 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e) Cursor::self()->notifyCursorChanged(reinterpret_cast(e)->cursor_serial); } break; - } #endif + } return false; } diff --git a/tabbox/tabbox.cpp b/tabbox/tabbox.cpp index 3d5cbf4427..62b0b9e284 100644 --- a/tabbox/tabbox.cpp +++ b/tabbox/tabbox.cpp @@ -813,28 +813,27 @@ void TabBox::delayedShow() m_delayedShowTimer.start(m_delayShowTime); } - -bool TabBox::handleMouseEvent(XEvent* e) +bool TabBox::handleMouseEvent(xcb_button_press_event_t *e) { - XAllowEvents(display(), AsyncPointer, xTime()); + xcb_allow_events(connection(), XCB_ALLOW_ASYNC_POINTER, xTime()); if (!m_isShown && isDisplayed()) { // tabbox has been replaced, check effects if (effects && static_cast(effects)->checkInputWindowEvent(e)) return true; } - if (e->type == ButtonPress) { + if (e->response_type & ~0x80 == XCB_BUTTON_PRESS) { // press outside Tabbox? - QPoint pos(e->xbutton.x_root, e->xbutton.y_root); + QPoint pos(e->root_x, e->root_y); if ((!m_isShown && isDisplayed()) || (!m_tabBox->containsPos(pos) && - (e->xbutton.button == Button1 || e->xbutton.button == Button2 || e->xbutton.button == Button3))) { + (e->detail == XCB_BUTTON_INDEX_1 || e->detail == XCB_BUTTON_INDEX_2 || e->detail == XCB_BUTTON_INDEX_3))) { close(); // click outside closes tab return true; } - if (e->xbutton.button == Button5 || e->xbutton.button == Button4) { + if (e->detail == XCB_BUTTON_INDEX_5 || e->detail == XCB_BUTTON_INDEX_4) { // mouse wheel event - const QModelIndex index = m_tabBox->nextPrev(e->xbutton.button == Button5); + const QModelIndex index = m_tabBox->nextPrev(e->detail == XCB_BUTTON_INDEX_5); if (index.isValid()) { setCurrentIndex(index); } @@ -844,6 +843,17 @@ bool TabBox::handleMouseEvent(XEvent* e) return false; } +bool TabBox::handleMouseEvent(xcb_motion_notify_event_t *e) +{ + xcb_allow_events(connection(), XCB_ALLOW_ASYNC_POINTER, xTime()); + if (!m_isShown && isDisplayed()) { + // tabbox has been replaced, check effects + if (effects && static_cast(effects)->checkInputWindowEvent(e)) + return true; + } + return false; +} + void TabBox::grabbedKeyEvent(QKeyEvent* event) { emit tabBoxKeyEvent(event); diff --git a/tabbox/tabbox.h b/tabbox/tabbox.h index 51049ff8b0..bfcf031c2e 100644 --- a/tabbox/tabbox.h +++ b/tabbox/tabbox.h @@ -33,6 +33,9 @@ class KActionCollection; class KConfigGroup; class QKeyEvent; +struct xcb_button_press_event_t; +struct xcb_motion_notify_event_t; + namespace KWin { @@ -156,7 +159,8 @@ public: return m_displayRefcount > 0; }; - bool handleMouseEvent(XEvent* e); + bool handleMouseEvent(xcb_button_press_event_t *e); + bool handleMouseEvent(xcb_motion_notify_event_t *e); void grabbedKeyEvent(QKeyEvent* event); bool isGrabbed() const {