From 485f0a3e061f5e4b043d0a78589400d9de658848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 26 Jul 2013 08:46:31 +0200 Subject: [PATCH] Process mouse events Button Press/Release do no longer fall through to motion notify as there is no shared mouse event in xcb. Also the methods in Effects and TabBox are adjusted to process only button press/release or motion notify. ScreenEdges are no longer checked for button press/release. They don't interact on button press/release so there is no need to check it. --- effects.cpp | 56 +++++++++++++++++++---------------------------- effects.h | 3 ++- events.cpp | 35 +++++++++++++++++++---------- tabbox/tabbox.cpp | 26 +++++++++++++++------- tabbox/tabbox.h | 6 ++++- 5 files changed, 71 insertions(+), 55 deletions(-) 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 {