diff --git a/src/libkwineffects/kwinoffscreenquickview.cpp b/src/libkwineffects/kwinoffscreenquickview.cpp index 6b90eabc68..14baa08085 100644 --- a/src/libkwineffects/kwinoffscreenquickview.cpp +++ b/src/libkwineffects/kwinoffscreenquickview.cpp @@ -435,6 +435,11 @@ QQuickItem *OffscreenQuickView::contentItem() const return d->m_view->contentItem(); } +QQuickWindow *OffscreenQuickView::window() const +{ + return d->m_view; +} + void OffscreenQuickView::setVisible(bool visible) { if (d->m_visible == visible) { diff --git a/src/libkwineffects/kwinoffscreenquickview.h b/src/libkwineffects/kwinoffscreenquickview.h index 40fa70bcfe..8429de0c49 100644 --- a/src/libkwineffects/kwinoffscreenquickview.h +++ b/src/libkwineffects/kwinoffscreenquickview.h @@ -27,6 +27,7 @@ class QKeyEvent; class QQmlContext; class QQuickItem; +class QQuickWindow; namespace KWin { @@ -109,6 +110,7 @@ public: /** The invisble root item of the window*/ QQuickItem *contentItem() const; + QQuickWindow *window() const; /** * @brief Marks the window as visible/invisible diff --git a/src/libkwineffects/kwinquickeffect.cpp b/src/libkwineffects/kwinquickeffect.cpp index c577fb57b6..a67edb3446 100644 --- a/src/libkwineffects/kwinquickeffect.cpp +++ b/src/libkwineffects/kwinquickeffect.cpp @@ -10,6 +10,7 @@ #include #include +#include #include namespace KWin @@ -220,6 +221,19 @@ QuickSceneView *QuickSceneEffect::viewAt(const QPoint &pos) const return nullptr; } +void QuickSceneEffect::activateView(QuickSceneView *view) +{ + for (auto *otherView : d->views) { + if (otherView == view && !view->window()->activeFocusItem()) { + QFocusEvent focusEvent(QEvent::FocusIn, Qt::ActiveWindowFocusReason); + qApp->sendEvent(view->window(), &focusEvent); + } else if (otherView->window()->activeFocusItem()) { + QFocusEvent focusEvent(QEvent::FocusOut, Qt::ActiveWindowFocusReason); + qApp->sendEvent(otherView->window(), &focusEvent); + } + } +} + void QuickSceneEffect::paintScreen(int mask, const QRegion ®ion, ScreenPaintData &data) { Q_UNUSED(mask) @@ -288,6 +302,10 @@ void QuickSceneEffect::addScreen(EffectScreen *screen) properties["width"] = view->geometry().width(); properties["height"] = view->geometry().height(); view->setRootItem(qobject_cast(d->qmlComponent->createWithInitialProperties(properties))); + // we need the focus always set to the view of activescreen at first, and changed only upon user interaction + if (view->contentItem()) { + view->contentItem()->setFocus(false); + } view->setAutomaticRepaint(false); connect(view, &QuickSceneView::repaintNeeded, this, [view]() { @@ -400,16 +418,28 @@ void QuickSceneEffect::windowInputMouseEvent(QEvent *event) } if (target) { + if (buttons) { + activateView(target); + } target->forwardMouseEvent(event); } } void QuickSceneEffect::grabbedKeyboardEvent(QKeyEvent *keyEvent) { - QuickSceneView *screenView = d->views.value(effects->activeScreen()); - if (screenView) { - screenView->contentItem()->setFocus(true); - screenView->forwardKeyEvent(keyEvent); + auto it = std::find_if(d->views.constBegin(), d->views.constEnd(), [](QuickSceneView *v) { + return v->window()->activeFocusItem(); + }); + + if (it == d->views.constEnd()) { + QuickSceneView *screenView = d->views.value(effects->activeScreen()); + if (screenView) { + activateView(screenView); + screenView->forwardKeyEvent(keyEvent); + } + } else { + (*it)->forwardKeyEvent(keyEvent); + return; } } @@ -417,6 +447,7 @@ bool QuickSceneEffect::touchDown(qint32 id, const QPointF &pos, quint32 time) { for (QuickSceneView *screenView : qAsConst(d->views)) { if (screenView->geometry().contains(pos.toPoint())) { + activateView(screenView); return screenView->forwardTouchDown(id, pos, time); } } diff --git a/src/libkwineffects/kwinquickeffect.h b/src/libkwineffects/kwinquickeffect.h index ae98dca611..60b3ad2ffc 100644 --- a/src/libkwineffects/kwinquickeffect.h +++ b/src/libkwineffects/kwinquickeffect.h @@ -92,6 +92,11 @@ public: */ QuickSceneView *viewAt(const QPoint &pos) const; + /** + * Sets the given @a view as active. It will get a focusin event and all the other views will be set as inactive + */ + void activateView(QuickSceneView *view); + /** * Returns the source URL. */