Handle ShellClient::windowShown in Workspace

Summary:
When a ShellClient gets unmapped and mapped again the signal windowShown
gets emitted. We need to handle this in Workspace to ensure the window
is in the proper layer and gets focus.

This fixes applications like KRunner/Yakuake not having focus on a
second show. Unfortunately it also brings back the problem that
notifiations steal focus (this needs to be fixed by passing a proper
window type to a notification).

Reviewers: #kwin, #plasma_on_wayland

Subscribers: plasma-devel, kwin

Tags: #plasma_on_wayland, #kwin

Differential Revision: https://phabricator.kde.org/D1864
This commit is contained in:
Martin Gräßlin 2016-06-14 13:46:28 +02:00
parent e5fe3137b8
commit 4560f8d253
2 changed files with 15 additions and 0 deletions

View file

@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "shell_client.h"
#include "screens.h"
#include "wayland_server.h"
#include "workspace.h"
#include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/compositor.h>
@ -170,6 +171,7 @@ void TestShellClient::testMapUnmapMap()
auto client = clientAddedSpy.first().first().value<ShellClient*>();
QVERIFY(client);
QVERIFY(client->isShown(true));
QCOMPARE(workspace()->activeClient(), client);
// now unmap
QSignalSpy hiddenSpy(client, &ShellClient::windowHidden);
@ -180,6 +182,7 @@ void TestShellClient::testMapUnmapMap()
surface->commit(Surface::CommitFlag::None);
QVERIFY(hiddenSpy.wait());
QVERIFY(windowClosedSpy.isEmpty());
QVERIFY(!workspace()->activeClient());
QSignalSpy windowShownSpy(client, &ShellClient::windowShown);
QVERIFY(windowShownSpy.isValid());
@ -190,6 +193,7 @@ void TestShellClient::testMapUnmapMap()
QVERIFY(windowShownSpy.wait());
QCOMPARE(windowShownSpy.count(), 1);
QCOMPARE(clientAddedSpy.count(), 1);
QCOMPARE(workspace()->activeClient(), client);
// let's unmap again
surface->attachBuffer(Buffer::Ptr());

View file

@ -394,6 +394,17 @@ void Workspace::init()
if (c->wantsInput()) {
activateClient(c);
}
connect(c, &ShellClient::windowShown, this,
[this, c] {
updateClientLayer(c);
x_stacking_dirty = true;
updateStackingOrder(true);
updateClientArea();
if (c->wantsInput()) {
activateClient(c);
}
}
);
}
);
connect(w, &WaylandServer::shellClientRemoved, this,