diff --git a/autotests/wayland/plasmawindow_test.cpp b/autotests/wayland/plasmawindow_test.cpp index cd58d0e329..45f02d7eed 100644 --- a/autotests/wayland/plasmawindow_test.cpp +++ b/autotests/wayland/plasmawindow_test.cpp @@ -36,6 +36,7 @@ along with this program. If not, see . #include #include #include +#include //screenlocker #include @@ -211,6 +212,15 @@ void PlasmaWindowTest::testCreateDestroyX11PlasmaWindow() QCOMPARE(client->window(), w); QVERIFY(client->isDecorated()); QVERIFY(client->isActive()); + // verify that it gets the keyboard focus + QVERIFY(!client->surface()); + // we don't have a surface yet, so focused keyboard surface if set is not ours + QVERIFY(!waylandServer()->seat()->focusedKeyboardSurface()); + QSignalSpy surfaceChangedSpy(client, &Toplevel::surfaceChanged); + QVERIFY(surfaceChangedSpy.isValid()); + QVERIFY(surfaceChangedSpy.wait()); + QVERIFY(client->surface()); + QCOMPARE(waylandServer()->seat()->focusedKeyboardSurface(), client->surface()); // now that should also give it to us on client side QVERIFY(plasmaWindowCreatedSpy.wait()); diff --git a/keyboard_input.cpp b/keyboard_input.cpp index cf18a61370..98a0aba19d 100644 --- a/keyboard_input.cpp +++ b/keyboard_input.cpp @@ -374,7 +374,17 @@ void KeyboardInputRedirection::init() connect(workspace(), &QObject::destroyed, this, [this] { m_inited = false; }); connect(waylandServer(), &QObject::destroyed, this, [this] { m_inited = false; }); - connect(workspace(), &Workspace::clientActivated, this, &KeyboardInputRedirection::update); + connect(workspace(), &Workspace::clientActivated, this, + [this] { + disconnect(m_activeClientSurfaceChangedConnection); + if (auto c = workspace()->activeClient()) { + m_activeClientSurfaceChangedConnection = connect(c, &Toplevel::surfaceChanged, this, &KeyboardInputRedirection::update); + } else { + m_activeClientSurfaceChangedConnection = QMetaObject::Connection(); + } + update(); + } + ); if (waylandServer()->hasScreenLockerIntegration()) { connect(ScreenLocker::KSldApp::self(), &ScreenLocker::KSldApp::lockStateChanged, this, &KeyboardInputRedirection::update); } diff --git a/keyboard_input.h b/keyboard_input.h index 8bac81cb92..1e79e9b108 100644 --- a/keyboard_input.h +++ b/keyboard_input.h @@ -126,6 +126,7 @@ private: bool m_inited = false; QScopedPointer m_xkb; QHash m_repeatTimers; + QMetaObject::Connection m_activeClientSurfaceChangedConnection; }; inline diff --git a/platform.cpp b/platform.cpp index 83d444f80c..78eb41c38b 100644 --- a/platform.cpp +++ b/platform.cpp @@ -85,8 +85,10 @@ void Platform::setSoftWareCursor(bool set) m_softWareCursor = set; if (m_softWareCursor) { connect(Cursor::self(), &Cursor::posChanged, this, &Platform::triggerCursorRepaint); + connect(this, &Platform::cursorChanged, this, &Platform::triggerCursorRepaint); } else { disconnect(Cursor::self(), &Cursor::posChanged, this, &Platform::triggerCursorRepaint); + disconnect(this, &Platform::cursorChanged, this, &Platform::triggerCursorRepaint); } } @@ -95,17 +97,14 @@ void Platform::triggerCursorRepaint() if (!Compositor::self()) { return; } - const QPoint &hotSpot = softwareCursorHotspot(); - const QSize &size = softwareCursor().size(); - Compositor::self()->addRepaint(m_cursor.lastRenderedPosition.x() - hotSpot.x(), - m_cursor.lastRenderedPosition.y() - hotSpot.y(), - size.width(), size.height()); + Compositor::self()->addRepaint(m_cursor.lastRenderedGeometry); + Compositor::self()->addRepaint(QRect(Cursor::pos() - softwareCursorHotspot(), softwareCursor().size())); } void Platform::markCursorAsRendered() { if (m_softWareCursor) { - m_cursor.lastRenderedPosition = Cursor::pos(); + m_cursor.lastRenderedGeometry = QRect(Cursor::pos() - softwareCursorHotspot(), softwareCursor().size()); } if (input()->pointer()) { input()->pointer()->markCursorAsRendered(); diff --git a/platform.h b/platform.h index 9254d38932..d6ea45a49b 100644 --- a/platform.h +++ b/platform.h @@ -222,7 +222,7 @@ private: void triggerCursorRepaint(); bool m_softWareCursor = false; struct { - QPoint lastRenderedPosition; + QRect lastRenderedGeometry; } m_cursor; bool m_handlesOutputs = false; bool m_ready = false; diff --git a/toplevel.cpp b/toplevel.cpp index 2a0e8bca01..1407aecb73 100644 --- a/toplevel.cpp +++ b/toplevel.cpp @@ -478,6 +478,7 @@ void Toplevel::setSurface(KWayland::Server::SurfaceInterface *surface) m_surface = nullptr; } ); + emit surfaceChanged(); } void Toplevel::addDamage(const QRegion &damage) diff --git a/toplevel.h b/toplevel.h index 57b30837b5..c80ffd3cfb 100644 --- a/toplevel.h +++ b/toplevel.h @@ -450,6 +450,11 @@ Q_SIGNALS: **/ void hasAlphaChanged(); + /** + * Emitted whenever the Surface for this Toplevel changes. + **/ + void surfaceChanged(); + protected Q_SLOTS: /** * Checks whether the screen number for this Toplevel changed and updates if needed.