diff --git a/effects.cpp b/effects.cpp
index 822bb5c202..37e1721b43 100644
--- a/effects.cpp
+++ b/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.
diff --git a/effects.h b/effects.h
index 70a5f4120c..50b6d31749 100644
--- a/effects.h
+++ b/effects.h
@@ -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;
diff --git a/input.cpp b/input.cpp
index 90cec16aab..c87db99346 100644
--- a/input.cpp
+++ b/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 .
*********************************************************************/
#include "input.h"
+#include "effects.h"
// TODO: remove xtest
#include
// 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(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(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
diff --git a/input.h b/input.h
index 5da4ccb714..02dca741d8 100644
--- a/input.h
+++ b/input.h
@@ -23,6 +23,7 @@ along with this program. If not, see .
#include
#include
#include
+#include
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 m_pointerButtons;