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.