Split out the X11 mouse event filtering for EffectsHandlerImpl
Summary: This change introduces a dedicated X11EventFilter for the mouse interception on X11. The filter gets created together with the start of mouse interception and destroyed again when the mouse interception ends. Thus we don't need to check for each event like it was the case so far. Unfortunately the existing methods cannot be removed (yet) as they are still used by TabBox. Needs investigation whether this is actually needed. Test Plan: Xephyr+kwin_x11+Present Windows Reviewers: #kwin, #plasma Subscribers: plasma-devel, kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D7842
This commit is contained in:
parent
aa645e9401
commit
0c6fdeef2d
6 changed files with 114 additions and 19 deletions
|
@ -456,6 +456,7 @@ set(kwin_KDEINIT_SRCS
|
|||
egl_context_attribute_builder.cpp
|
||||
was_user_interaction_x11_filter.cpp
|
||||
moving_client_x11_filter.cpp
|
||||
effects_mouse_interception_x11_filter.cpp
|
||||
)
|
||||
|
||||
if(KWIN_BUILD_TABBOX)
|
||||
|
|
|
@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "effects.h"
|
||||
|
||||
#include "effectsadaptor.h"
|
||||
#include "effects_mouse_interception_x11_filter.h"
|
||||
#include "effectloader.h"
|
||||
#ifdef KWIN_BUILD_ACTIVITIES
|
||||
#include "activities.h"
|
||||
|
@ -690,6 +691,7 @@ void EffectsHandlerImpl::startMouseInterception(Effect *effect, Qt::CursorShape
|
|||
}
|
||||
m_mouseInterceptionWindow.map();
|
||||
m_mouseInterceptionWindow.raise();
|
||||
m_x11MouseInterception = std::make_unique<EffectsMouseInterceptionX11Filter>(m_mouseInterceptionWindow, this);
|
||||
// Raise electric border windows above the input windows
|
||||
// so they can still be triggered.
|
||||
ScreenEdges::self()->ensureOnTop();
|
||||
|
@ -707,6 +709,7 @@ void EffectsHandlerImpl::stopMouseInterception(Effect *effect)
|
|||
}
|
||||
if (m_grabbedMouseEffects.isEmpty()) {
|
||||
m_mouseInterceptionWindow.unmap();
|
||||
m_x11MouseInterception.reset();
|
||||
Workspace::self()->stackScreenEdgesUnderOverrideRedirect();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ class Client;
|
|||
class Compositor;
|
||||
class Deleted;
|
||||
class EffectLoader;
|
||||
class EffectsMouseInterceptionX11Filter;
|
||||
class Unmanaged;
|
||||
|
||||
class KWIN_EXPORT EffectsHandlerImpl : public EffectsHandler
|
||||
|
@ -319,6 +320,7 @@ private:
|
|||
QList<Effect*> m_grabbedMouseEffects;
|
||||
EffectLoader *m_effectLoader;
|
||||
int m_trackingCursorChanges;
|
||||
std::unique_ptr<EffectsMouseInterceptionX11Filter> m_x11MouseInterception;
|
||||
};
|
||||
|
||||
class EffectWindowImpl : public EffectWindow
|
||||
|
|
65
effects_mouse_interception_x11_filter.cpp
Normal file
65
effects_mouse_interception_x11_filter.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2017 Martin Flöser <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#include "effects_mouse_interception_x11_filter.h"
|
||||
#include "effects.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
EffectsMouseInterceptionX11Filter::EffectsMouseInterceptionX11Filter(xcb_window_t window, EffectsHandlerImpl *effects)
|
||||
: X11EventFilter(QVector<int>{XCB_BUTTON_PRESS, XCB_BUTTON_RELEASE, XCB_MOTION_NOTIFY})
|
||||
, m_effects(effects)
|
||||
, m_window(window)
|
||||
{
|
||||
}
|
||||
|
||||
bool EffectsMouseInterceptionX11Filter::event(xcb_generic_event_t *event)
|
||||
{
|
||||
const uint8_t eventType = event->response_type & ~0x80;
|
||||
if (eventType == XCB_BUTTON_PRESS || eventType == XCB_BUTTON_RELEASE) {
|
||||
auto *me = reinterpret_cast<xcb_button_press_event_t*>(event);
|
||||
if (m_window == me->event) {
|
||||
const Qt::MouseButton button = x11ToQtMouseButton(me->detail);
|
||||
Qt::MouseButtons buttons = x11ToQtMouseButtons(me->state);
|
||||
const QEvent::Type type = (eventType == XCB_BUTTON_PRESS) ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
|
||||
if (type == QEvent::MouseButtonPress) {
|
||||
buttons |= button;
|
||||
} else {
|
||||
buttons &= ~button;
|
||||
}
|
||||
QMouseEvent ev(type, QPoint(me->event_x, me->event_y), QPoint(me->root_x, me->root_y),
|
||||
button, buttons, x11ToQtKeyboardModifiers(me->state));
|
||||
return m_effects->checkInputWindowEvent(&ev);
|
||||
}
|
||||
} else if (eventType == XCB_MOTION_NOTIFY) {
|
||||
const auto *me = reinterpret_cast<xcb_motion_notify_event_t*>(event);
|
||||
if (m_window == me->event) {
|
||||
QMouseEvent ev(QEvent::MouseMove, QPoint(me->event_x, me->event_y), QPoint(me->root_x, me->root_y),
|
||||
Qt::NoButton, x11ToQtMouseButtons(me->state), x11ToQtKeyboardModifiers(me->state));
|
||||
return m_effects->checkInputWindowEvent(&ev);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
43
effects_mouse_interception_x11_filter.h
Normal file
43
effects_mouse_interception_x11_filter.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2017 Martin Flöser <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#ifndef KWIN_EFFECTS_MOUSE_INTERCEPTION_X11_FILTER_H
|
||||
#define KWIN_EFFECTS_MOUSE_INTERCEPTION_X11_FILTER_H
|
||||
|
||||
#include "x11eventfilter.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
class EffectsHandlerImpl;
|
||||
|
||||
class EffectsMouseInterceptionX11Filter : public X11EventFilter
|
||||
{
|
||||
public:
|
||||
explicit EffectsMouseInterceptionX11Filter(xcb_window_t window, EffectsHandlerImpl *effects);
|
||||
|
||||
bool event(xcb_generic_event_t *event) override;
|
||||
|
||||
private:
|
||||
EffectsHandlerImpl *m_effects;
|
||||
xcb_window_t m_window;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
19
events.cpp
19
events.cpp
|
@ -259,25 +259,6 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
|
|||
|
||||
// events that should be handled before Clients can get them
|
||||
switch (eventType) {
|
||||
case XCB_BUTTON_PRESS:
|
||||
case XCB_BUTTON_RELEASE: {
|
||||
auto *mouseEvent = reinterpret_cast<xcb_button_press_event_t*>(e);
|
||||
if (effects && static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(mouseEvent)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XCB_MOTION_NOTIFY: {
|
||||
if (kwinApp()->operationMode() != Application::OperationModeX11) {
|
||||
// ignore X11 pointer events generated on X windows if we are not on X
|
||||
return true;
|
||||
}
|
||||
auto *mouseEvent = reinterpret_cast<xcb_motion_notify_event_t*>(e);
|
||||
if (effects && static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(mouseEvent)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XCB_CONFIGURE_NOTIFY:
|
||||
if (reinterpret_cast<xcb_configure_notify_event_t*>(e)->event == rootWindow())
|
||||
markXStackingOrderAsDirty();
|
||||
|
|
Loading…
Reference in a new issue