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/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.