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.
This commit is contained in:
parent
d81c45a810
commit
485f0a3e06
5 changed files with 71 additions and 55 deletions
56
effects.cpp
56
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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
35
events.cpp
35
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<xcb_button_press_event_t*>(e);
|
||||
#ifdef KWIN_BUILD_TABBOX
|
||||
if (TabBox::TabBox::self()->isGrabbed()) {
|
||||
return TabBox::TabBox::self()->handleMouseEvent(mouseEvent);
|
||||
}
|
||||
#endif
|
||||
if (effects && static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(mouseEvent)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XCB_MOTION_NOTIFY: {
|
||||
auto *mouseEvent = reinterpret_cast<xcb_motion_notify_event_t*>(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<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(e)) {
|
||||
if (effects && static_cast<EffectsHandlerImpl*>(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<XFixesCursorNotifyEvent*>(e)->cursor_serial);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<EffectsHandlerImpl*>(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<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(e))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TabBox::grabbedKeyEvent(QKeyEvent* event)
|
||||
{
|
||||
emit tabBoxKeyEvent(event);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue