diff --git a/src/abstract_client.h b/src/abstract_client.h index 8d7300dacb..cf91c0421e 100644 --- a/src/abstract_client.h +++ b/src/abstract_client.h @@ -598,8 +598,8 @@ public: void endInteractiveMoveResize(); void keyPressEvent(uint key_code); - void pointerEnterEvent(const QPoint &globalPos); - void pointerLeaveEvent(); + virtual void pointerEnterEvent(const QPoint &globalPos); + virtual void pointerLeaveEvent(); /** * These values represent positions inside an area diff --git a/src/input.cpp b/src/input.cpp index 012419b876..b822fc6ebb 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -960,63 +960,33 @@ std::pair performClientWheelAction(QWheelEvent *event, AbstractClien class InternalWindowEventFilter : public InputEventFilter { bool pointerEvent(QMouseEvent *event, quint32 nativeButton) override { Q_UNUSED(nativeButton) - auto internal = input()->pointer()->internalWindow(); - if (!internal) { + if (!input()->pointer()->focus() || !input()->pointer()->focus()->isInternal()) { return false; } - // find client - switch (event->type()) - { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: { - auto s = qobject_cast(workspace()->findInternal(internal)); - if (s && s->isDecorated()) { - // only perform mouse commands on decorated internal windows - const auto actionResult = performClientMouseAction(event, s); - if (actionResult.first) { - return actionResult.second; - } - } - break; - } - default: - break; - } - QMouseEvent e(event->type(), - event->pos() - internal->position(), - event->globalPos(), - event->button(), event->buttons(), event->modifiers()); - e.setAccepted(false); - QCoreApplication::sendEvent(internal, &e); - return e.isAccepted(); + QWindow *internal = static_cast(input()->pointer()->focus())->internalWindow(); + QMouseEvent mouseEvent(event->type(), + event->pos() - internal->position(), + event->globalPos(), + event->button(), event->buttons(), event->modifiers()); + QCoreApplication::sendEvent(internal, &mouseEvent); + return mouseEvent.isAccepted(); } bool wheelEvent(QWheelEvent *event) override { - auto internal = input()->pointer()->internalWindow(); - if (!internal) { + if (!input()->pointer()->focus() || !input()->pointer()->focus()->isInternal()) { return false; } - if (event->angleDelta().y() != 0) { - auto s = qobject_cast(workspace()->findInternal(internal)); - if (s && s->isDecorated()) { - // client window action only on vertical scrolling - const auto actionResult = performClientWheelAction(event, s); - if (actionResult.first) { - return actionResult.second; - } - } - } + QWindow *internal = static_cast(input()->pointer()->focus())->internalWindow(); const QPointF localPos = event->globalPosF() - internal->position(); const Qt::Orientation orientation = (event->angleDelta().x() != 0) ? Qt::Horizontal : Qt::Vertical; const int delta = event->angleDelta().x() != 0 ? event->angleDelta().x() : event->angleDelta().y(); - QWheelEvent e(localPos, event->globalPosF(), QPoint(), - event->angleDelta() * -1, - delta * -1, - orientation, - event->buttons(), - event->modifiers()); - e.setAccepted(false); - QCoreApplication::sendEvent(internal, &e); - return e.isAccepted(); + QWheelEvent wheelEvent(localPos, event->globalPosF(), QPoint(), + event->angleDelta() * -1, + delta * -1, + orientation, + event->buttons(), + event->modifiers()); + QCoreApplication::sendEvent(internal, &wheelEvent); + return wheelEvent.isAccepted(); } bool keyEvent(QKeyEvent *event) override { const QList &clients = workspace()->internalClients(); @@ -1079,12 +1049,12 @@ class InternalWindowEventFilter : public InputEventFilter { } // a new touch point seat->setTimestamp(time); - auto internal = touch->internalWindow(); - if (!internal) { + if (!input()->touch()->focus() || !input()->touch()->focus()->isInternal()) { return false; } touch->setInternalPressId(id); // Qt's touch event API is rather complex, let's do fake mouse events instead + QWindow *internal = static_cast(input()->touch()->focus())->internalWindow(); m_lastGlobalTouchPos = pos; m_lastLocalTouchPos = pos - internal->position(); @@ -1098,8 +1068,7 @@ class InternalWindowEventFilter : public InputEventFilter { } bool touchMotion(qint32 id, const QPointF &pos, quint32 time) override { auto touch = input()->touch(); - auto internal = touch->internalWindow(); - if (!internal) { + if (!input()->touch()->focus() || !input()->touch()->focus()->isInternal()) { return false; } if (touch->internalPressId() == -1) { @@ -1110,6 +1079,7 @@ class InternalWindowEventFilter : public InputEventFilter { // ignore, but filter out return true; } + QWindow *internal = static_cast(input()->touch()->focus())->internalWindow(); m_lastGlobalTouchPos = pos; m_lastLocalTouchPos = pos - QPointF(internal->x(), internal->y()); @@ -1119,11 +1089,7 @@ class InternalWindowEventFilter : public InputEventFilter { } bool touchUp(qint32 id, quint32 time) override { auto touch = input()->touch(); - auto internal = touch->internalWindow(); const bool removed = m_pressedIds.remove(id); - if (!internal) { - return removed; - } if (touch->internalPressId() == -1) { return removed; } @@ -1132,6 +1098,10 @@ class InternalWindowEventFilter : public InputEventFilter { // ignore, but filter out return true; } + if (!input()->touch()->focus() || !input()->touch()->focus()->isInternal()) { + return removed; + } + QWindow *internal = static_cast(input()->touch()->focus())->internalWindow(); // send mouse up QMouseEvent e(QEvent::MouseButtonRelease, m_lastLocalTouchPos, m_lastGlobalTouchPos, Qt::LeftButton, Qt::MouseButtons(), input()->keyboardModifiers()); e.setAccepted(false); @@ -2480,9 +2450,9 @@ void InputRedirection::setupInputFilters() installInputEventFilter(new PopupInputFilter); } installInputEventFilter(new DecorationEventFilter); - installInputEventFilter(new InternalWindowEventFilter); if (waylandServer()) { installInputEventFilter(new WindowActionInputFilter); + installInputEventFilter(new InternalWindowEventFilter); installInputEventFilter(new ForwardInputFilter); installInputEventFilter(new TabletInputFilter); } @@ -2931,18 +2901,11 @@ void InputDeviceHandler::setDecoration(Decoration::DecoratedClientImpl *decorati Q_EMIT decorationChanged(); } -void InputDeviceHandler::setInternalWindow(QWindow *window) -{ - QWindow *oldFocus = m_focus.internalWindow; - m_focus.internalWindow = window; - cleanupInternalWindow(oldFocus, m_focus.internalWindow); -} - void InputDeviceHandler::updateFocus() { Toplevel *focus = m_hover.window; - if (m_hover.window && !m_hover.window->surface()) { + if (m_hover.window && !m_hover.window->surface() && !m_hover.window->isInternal()) { // The surface has not yet been created (special XWayland case). // Therefore listen for its creation. if (!m_hover.surfaceCreatedConnection) { @@ -2977,17 +2940,6 @@ bool InputDeviceHandler::updateDecoration() return true; } -void InputDeviceHandler::updateInternalWindow(QWindow *window) -{ - if (m_focus.internalWindow == window) { - // no change - return; - } - const auto oldInternal = m_focus.internalWindow; - m_focus.internalWindow = window; - cleanupInternalWindow(oldInternal, window); -} - void InputDeviceHandler::update() { if (!m_inited) { @@ -3006,28 +2958,13 @@ void InputDeviceHandler::update() return; } - if (auto client = qobject_cast(toplevel)) { - QWindow *handle = client->internalWindow(); - if (m_focus.internalWindow != handle) { - // changed internal window - updateDecoration(); - updateInternalWindow(handle); - updateFocus(); - } else if (updateDecoration()) { - // went onto or off from decoration, update focus - updateFocus(); - } - } else { - updateInternalWindow(nullptr); - - if (m_focus.window != m_hover.window) { - // focus change - updateDecoration(); - updateFocus(); - } else if (updateDecoration()) { - // went onto or off from decoration, update focus - updateFocus(); - } + if (m_focus.window != m_hover.window) { + // focus change + updateDecoration(); + updateFocus(); + } else if (updateDecoration()) { + // went onto or off from decoration, update focus + updateFocus(); } workspace()->updateFocusMousePosition(position().toPoint()); @@ -3048,11 +2985,6 @@ Decoration::DecoratedClientImpl *InputDeviceHandler::decoration() const return m_focus.decoration; } -QWindow *InputDeviceHandler::internalWindow() const -{ - return m_focus.internalWindow; -} - uint32_t InputDeviceHandler::lastEventTime() const { return m_lastEventTime; diff --git a/src/input.h b/src/input.h index 004b06281f..83ced8df54 100644 --- a/src/input.h +++ b/src/input.h @@ -437,17 +437,11 @@ public: * @return decoration with pointer focus. */ Decoration::DecoratedClientImpl *decoration() const; - /** - * @brief The internal window currently receiving events. - * @return QWindow with pointer focus. - */ - QWindow *internalWindow() const; virtual QPointF position() const = 0; void setFocus(Toplevel *toplevel); void setDecoration(Decoration::DecoratedClientImpl *decoration); - void setInternalWindow(QWindow *window); uint32_t lastEventTime() const; @@ -457,7 +451,6 @@ Q_SIGNALS: protected: explicit InputDeviceHandler(InputRedirection *parent); - virtual void cleanupInternalWindow(QWindow *old, QWindow *now) = 0; virtual void cleanupDecoration(Decoration::DecoratedClientImpl *old, Decoration::DecoratedClientImpl *now) = 0; virtual void focusUpdate(Toplevel *old, Toplevel *now) = 0; @@ -487,7 +480,6 @@ private: bool setHover(Toplevel *toplevel); void updateFocus(); bool updateDecoration(); - void updateInternalWindow(QWindow *window); struct { QPointer window; @@ -497,7 +489,6 @@ private: struct { QPointer window; QPointer decoration; - QPointer internalWindow; } m_focus; bool m_inited = false; diff --git a/src/internal_client.cpp b/src/internal_client.cpp index 4ff548736e..6da0d70fe1 100644 --- a/src/internal_client.cpp +++ b/src/internal_client.cpp @@ -88,6 +88,22 @@ bool InternalClient::hitTest(const QPoint &point) const return true; } +void InternalClient::pointerEnterEvent(const QPoint &globalPos) +{ + AbstractClient::pointerEnterEvent(globalPos); + + QEnterEvent enterEvent(pos(), pos(), globalPos); + QCoreApplication::sendEvent(m_internalWindow, &enterEvent); +} + +void InternalClient::pointerLeaveEvent() +{ + AbstractClient::pointerLeaveEvent(); + + QEvent event(QEvent::Leave); + QCoreApplication::sendEvent(m_internalWindow, &event); +} + bool InternalClient::eventFilter(QObject *watched, QEvent *event) { if (watched == m_internalWindow && event->type() == QEvent::DynamicPropertyChange) { diff --git a/src/internal_client.h b/src/internal_client.h index 765c9b8aa6..b9a823fc4a 100644 --- a/src/internal_client.h +++ b/src/internal_client.h @@ -58,6 +58,8 @@ public: bool hasPopupGrab() const override; void popupDone() override; bool hitTest(const QPoint &point) const override; + void pointerEnterEvent(const QPoint &globalPos) override; + void pointerLeaveEvent() override; void present(const QSharedPointer fbo); void present(const QImage &image, const QRegion &damage); diff --git a/src/pointer_input.cpp b/src/pointer_input.cpp index 1f75e4833d..60e6e7aa13 100644 --- a/src/pointer_input.cpp +++ b/src/pointer_input.cpp @@ -186,11 +186,6 @@ void PointerInputRedirection::updateOnStartMoveResize() void PointerInputRedirection::updateToReset() { - if (internalWindow()) { - QEvent event(QEvent::Leave); - QCoreApplication::sendEvent(internalWindow(), &event); - setInternalWindow(nullptr); - } if (decoration()) { QHoverEvent event(QEvent::HoverLeave, QPointF(), QPointF()); QCoreApplication::instance()->sendEvent(decoration()->decoration(), &event); @@ -510,15 +505,6 @@ bool PointerInputRedirection::focusUpdatesBlocked() return false; } -void PointerInputRedirection::cleanupInternalWindow(QWindow *old, QWindow *now) -{ - if (old) { - // leave internal window - QEvent leaveEvent(QEvent::Leave); - QCoreApplication::sendEvent(old, &leaveEvent); - } -} - void PointerInputRedirection::cleanupDecoration(Decoration::DecoratedClientImpl *old, Decoration::DecoratedClientImpl *now) { disconnect(m_decorationGeometryConnection); @@ -577,13 +563,6 @@ void PointerInputRedirection::focusUpdate(Toplevel *focusOld, Toplevel *focusNow ac->pointerEnterEvent(m_pos.toPoint()); } - if (internalWindow()) { - // enter internal window - const auto pos = hover()->pos(); - QEnterEvent enterEvent(pos, pos, m_pos); - QCoreApplication::sendEvent(internalWindow(), &enterEvent); - } - auto seat = waylandServer()->seat(); if (!focusNow || !focusNow->surface() || decoration()) { // Clean up focused pointer surface if there's no client to take focus, diff --git a/src/pointer_input.h b/src/pointer_input.h index b20622091e..2f3d7225a3 100644 --- a/src/pointer_input.h +++ b/src/pointer_input.h @@ -142,7 +142,6 @@ public: private: void processMotionInternal(const QPointF &pos, const QSizeF &delta, const QSizeF &deltaNonAccelerated, uint32_t time, quint64 timeUsec, InputDevice *device); - void cleanupInternalWindow(QWindow *old, QWindow *now) override; void cleanupDecoration(Decoration::DecoratedClientImpl *old, Decoration::DecoratedClientImpl *now) override; void focusUpdate(Toplevel *focusOld, Toplevel *focusNow) override; diff --git a/src/tablet_input.cpp b/src/tablet_input.cpp index d7c596dc8e..9f229f242f 100644 --- a/src/tablet_input.cpp +++ b/src/tablet_input.cpp @@ -173,14 +173,6 @@ void TabletInputRedirection::cleanupDecoration(Decoration::DecoratedClientImpl * m_decorationDestroyedConnection = connect(now, &QObject::destroyed, this, &TabletInputRedirection::update, Qt::QueuedConnection); } -void TabletInputRedirection::cleanupInternalWindow(QWindow *old, QWindow *now) -{ - Q_UNUSED(old) - Q_UNUSED(now) - - // This method is left blank intentionally. -} - void TabletInputRedirection::focusUpdate(Toplevel *focusOld, Toplevel *focusNow) { Q_UNUSED(focusOld) diff --git a/src/tablet_input.h b/src/tablet_input.h index e2c5c4e631..c5bec7841c 100644 --- a/src/tablet_input.h +++ b/src/tablet_input.h @@ -65,7 +65,6 @@ public: private: void cleanupDecoration(Decoration::DecoratedClientImpl *old, Decoration::DecoratedClientImpl *now) override; - void cleanupInternalWindow(QWindow *old, QWindow *now) override; void focusUpdate(Toplevel *focusOld, Toplevel *focusNow) override; bool m_tipDown = false; diff --git a/src/touch_input.cpp b/src/touch_input.cpp index 0659c1665a..62c3588360 100644 --- a/src/touch_input.cpp +++ b/src/touch_input.cpp @@ -119,14 +119,6 @@ void TouchInputRedirection::focusUpdate(Toplevel *focusOld, Toplevel *focusNow) ); } -void TouchInputRedirection::cleanupInternalWindow(QWindow *old, QWindow *now) -{ - Q_UNUSED(old); - Q_UNUSED(now); - - // nothing to do -} - void TouchInputRedirection::cleanupDecoration(Decoration::DecoratedClientImpl *old, Decoration::DecoratedClientImpl *now) { Q_UNUSED(old); diff --git a/src/touch_input.h b/src/touch_input.h index e49737e990..c1f1d11116 100644 --- a/src/touch_input.h +++ b/src/touch_input.h @@ -67,7 +67,6 @@ public: } private: - void cleanupInternalWindow(QWindow *old, QWindow *now) override; void cleanupDecoration(Decoration::DecoratedClientImpl *old, Decoration::DecoratedClientImpl *now) override; void focusUpdate(Toplevel *focusOld, Toplevel *focusNow) override;