Pass pointer events through the effect system
InputRedirection forwards pointer events (currently motion, press and release) through the EffectsHandlerImpl for the case that an effect has intercepted pointer events. If the KWin operation mode is not X11 only, the window for intercepting the mouse events is no longer created.
This commit is contained in:
parent
940d9fb513
commit
6619faa6ac
4 changed files with 87 additions and 0 deletions
20
effects.cpp
20
effects.cpp
|
@ -767,6 +767,9 @@ void EffectsHandlerImpl::startMouseInterception(Effect *effect, Qt::CursorShape
|
|||
if (m_grabbedMouseEffects.size() != 1) {
|
||||
return;
|
||||
}
|
||||
if (kwinApp()->operationMode() != Application::OperationModeX11) {
|
||||
return;
|
||||
}
|
||||
// NOTE: it is intended to not perform an XPointerGrab on X11. See documentation in kwineffects.h
|
||||
// The mouse grab is implemented by using a full screen input only window
|
||||
if (!m_mouseInterceptionWindow.isValid()) {
|
||||
|
@ -794,6 +797,9 @@ void EffectsHandlerImpl::stopMouseInterception(Effect *effect)
|
|||
return;
|
||||
}
|
||||
m_grabbedMouseEffects.removeAll(effect);
|
||||
if (kwinApp()->operationMode() != Application::OperationModeX11) {
|
||||
return;
|
||||
}
|
||||
if (m_grabbedMouseEffects.isEmpty()) {
|
||||
m_mouseInterceptionWindow.unmap();
|
||||
#ifdef KWIN_BUILD_SCREENEDGES
|
||||
|
@ -1291,11 +1297,25 @@ bool EffectsHandlerImpl::checkInputWindowEvent(xcb_motion_notify_event_t *e)
|
|||
return true; // eat event
|
||||
}
|
||||
|
||||
bool EffectsHandlerImpl::checkInputWindowEvent(QMouseEvent *e)
|
||||
{
|
||||
if (m_grabbedMouseEffects.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
foreach (Effect *effect, m_grabbedMouseEffects) {
|
||||
effect->windowInputMouseEvent(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::checkInputWindowStacking()
|
||||
{
|
||||
if (m_grabbedMouseEffects.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (kwinApp()->operationMode() != Application::OperationModeX11) {
|
||||
return;
|
||||
}
|
||||
m_mouseInterceptionWindow.raise();
|
||||
// Raise electric border windows above the input windows
|
||||
// so they can still be triggered. TODO: Do both at once.
|
||||
|
|
|
@ -156,6 +156,7 @@ public:
|
|||
void defineCursor(Qt::CursorShape shape) override;
|
||||
bool checkInputWindowEvent(xcb_button_press_event_t *e);
|
||||
bool checkInputWindowEvent(xcb_motion_notify_event_t *e);
|
||||
bool checkInputWindowEvent(QMouseEvent *e);
|
||||
void checkInputWindowStacking();
|
||||
|
||||
void reserveElectricBorder(ElectricBorder border, Effect *effect) override;
|
||||
|
|
62
input.cpp
62
input.cpp
|
@ -18,6 +18,7 @@ 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 "input.h"
|
||||
#include "effects.h"
|
||||
// TODO: remove xtest
|
||||
#include <xcb/xtest.h>
|
||||
// system
|
||||
|
@ -47,6 +48,14 @@ void InputRedirection::processPointerMotion(const QPointF &pos, uint32_t time)
|
|||
emit globalPointerChanged(m_globalPointer);
|
||||
|
||||
// TODO: check which part of KWin would like to intercept the event
|
||||
// TODO: keyboard modifiers
|
||||
QMouseEvent event(QEvent::MouseMove, m_globalPointer.toPoint(), m_globalPointer.toPoint(),
|
||||
Qt::NoButton, qtButtonStates(), 0);
|
||||
// check whether an effect has a mouse grab
|
||||
if (effects && static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(&event)) {
|
||||
// an effect grabbed the pointer, we do not forward the event to surfaces
|
||||
return;
|
||||
}
|
||||
// TODO: redirect to proper client
|
||||
|
||||
// TODO: don't use xtest
|
||||
|
@ -60,6 +69,14 @@ void InputRedirection::processPointerButton(uint32_t button, InputRedirection::P
|
|||
m_pointerButtons[button] = state;
|
||||
emit pointerButtonStateChanged(button, state);
|
||||
|
||||
// TODO: keyboard modifiers
|
||||
QMouseEvent event(buttonStateToEvent(state), m_globalPointer.toPoint(), m_globalPointer.toPoint(),
|
||||
buttonToQtMouseButton(button), qtButtonStates(), 0);
|
||||
// check whether an effect has a mouse grab
|
||||
if (effects && static_cast<EffectsHandlerImpl*>(effects)->checkInputWindowEvent(&event)) {
|
||||
// an effect grabbed the pointer, we do not forward the event to surfaces
|
||||
return;
|
||||
}
|
||||
// TODO: check which part of KWin would like to intercept the event
|
||||
// TODO: redirect to proper client
|
||||
|
||||
|
@ -96,6 +113,7 @@ void InputRedirection::processPointerAxis(InputRedirection::PointerAxis axis, qr
|
|||
emit pointerAxisChanged(axis, delta);
|
||||
|
||||
// TODO: check which part of KWin would like to intercept the event
|
||||
// TODO: Axis support for effect redirection
|
||||
// TODO: redirect to proper client
|
||||
|
||||
// TODO: don't use xtest
|
||||
|
@ -118,4 +136,48 @@ void InputRedirection::processPointerAxis(InputRedirection::PointerAxis axis, qr
|
|||
}
|
||||
}
|
||||
|
||||
QEvent::Type InputRedirection::buttonStateToEvent(InputRedirection::PointerButtonState state)
|
||||
{
|
||||
switch (state) {
|
||||
case KWin::InputRedirection::PointerButtonReleased:
|
||||
return QEvent::MouseButtonRelease;
|
||||
case KWin::InputRedirection::PointerButtonPressed:
|
||||
return QEvent::MouseButtonPress;
|
||||
}
|
||||
return QEvent::None;
|
||||
}
|
||||
|
||||
Qt::MouseButton InputRedirection::buttonToQtMouseButton(uint32_t button)
|
||||
{
|
||||
switch (button) {
|
||||
case BTN_LEFT:
|
||||
return Qt::LeftButton;
|
||||
case BTN_MIDDLE:
|
||||
return Qt::MiddleButton;
|
||||
case BTN_RIGHT:
|
||||
return Qt::RightButton;
|
||||
case BTN_BACK:
|
||||
return Qt::XButton1;
|
||||
case BTN_FORWARD:
|
||||
return Qt::XButton2;
|
||||
}
|
||||
return Qt::NoButton;
|
||||
}
|
||||
|
||||
Qt::MouseButtons InputRedirection::qtButtonStates() const
|
||||
{
|
||||
Qt::MouseButtons buttons;
|
||||
for (auto it = m_pointerButtons.constBegin(); it != m_pointerButtons.constEnd(); ++it) {
|
||||
if (it.value() == KWin::InputRedirection::PointerButtonReleased) {
|
||||
continue;
|
||||
}
|
||||
Qt::MouseButton button = buttonToQtMouseButton(it.key());
|
||||
if (button != Qt::NoButton) {
|
||||
buttons |= button;
|
||||
}
|
||||
}
|
||||
return buttons;
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
||||
|
|
4
input.h
4
input.h
|
@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <QHash>
|
||||
#include <QObject>
|
||||
#include <QPoint>
|
||||
#include <QEvent>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -99,6 +100,9 @@ Q_SIGNALS:
|
|||
void pointerAxisChanged(PointerAxis axis, qreal delta);
|
||||
|
||||
private:
|
||||
static QEvent::Type buttonStateToEvent(PointerButtonState state);
|
||||
static Qt::MouseButton buttonToQtMouseButton(uint32_t button);
|
||||
Qt::MouseButtons qtButtonStates() const;
|
||||
QPointF m_globalPointer;
|
||||
QHash<uint32_t, PointerButtonState> m_pointerButtons;
|
||||
|
||||
|
|
Loading…
Reference in a new issue