From 36fa88893ecba0d6f17e5a95c563f27b3e39fdcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 21 May 2015 10:35:03 +0200 Subject: [PATCH] [wayland] Track the internal ShellClients in WaylandServer Adds all internal ShellClients into a dedicated list. This ensures that we don't perform "normal" window management on them. In addition we add them to the top of the stacking order. This restores behavior as it is on X11: internal windows are using BypassWindowManagerHint and thus on top of everything. --- layers.cpp | 12 ++++++++++++ wayland_server.cpp | 34 +++++++++++++++++++++++++--------- wayland_server.h | 4 ++++ workspace.cpp | 10 ++++++---- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/layers.cpp b/layers.cpp index fc7695e86f..d8328ccafd 100644 --- a/layers.cpp +++ b/layers.cpp @@ -92,6 +92,10 @@ along with this program. If not, see . #include "effects.h" #include "composite.h" #include "screenedge.h" +#if HAVE_WAYLAND +#include "shell_client.h" +#include "wayland_server.h" +#endif #include @@ -688,6 +692,14 @@ ToplevelList Workspace::xStackingOrder() const } } } +#if HAVE_WAYLAND + if (waylandServer()) { + const auto clients = waylandServer()->internalClients(); + for (auto c: clients) { + x_stacking << c; + } + } +#endif if (m_compositor) { const_cast< Workspace* >(this)->m_compositor->checkUnredirect(); } diff --git a/wayland_server.cpp b/wayland_server.cpp index 16eda82570..2d19525195 100644 --- a/wayland_server.cpp +++ b/wayland_server.cpp @@ -116,7 +116,11 @@ void WaylandServer::init(const QByteArray &socketName) if (auto c = Compositor::self()) { connect(client, &Toplevel::needsRepaint, c, &Compositor::scheduleRepaint); } - m_clients << client; + if (client->isInternal()) { + m_internalClients << client; + } else { + m_clients << client; + } emit shellClientAdded(client); } ); @@ -209,6 +213,7 @@ void WaylandServer::uninstallBackend(AbstractBackend *backend) void WaylandServer::removeClient(ShellClient *c) { m_clients.removeAll(c); + m_internalClients.removeAll(c); emit shellClientRemoved(c); } @@ -261,20 +266,31 @@ void WaylandServer::dispatch() m_display->dispatchEvents(0); } +static ShellClient *findClientInList(const QList &clients, quint32 id) +{ + auto it = std::find_if(clients.begin(), clients.end(), + [id] (ShellClient *c) { + return c->windowId() == id; + } + ); + if (it == clients.end()) { + return nullptr; + } + return *it; +} + ShellClient *WaylandServer::findClient(quint32 id) const { if (id == 0) { return nullptr; } - auto it = std::find_if(m_clients.constBegin(), m_clients.constEnd(), - [id] (ShellClient *c) { - return c->windowId() == id; - } - ); - if (it == m_clients.constEnd()) { - return nullptr; + if (ShellClient *c = findClientInList(m_clients, id)) { + return c; } - return *it; + if (ShellClient *c = findClientInList(m_internalClients, id)) { + return c; + } + return nullptr; } quint32 WaylandServer::createWindowId(SurfaceInterface *surface) diff --git a/wayland_server.h b/wayland_server.h index 980cc32edf..ebb32db804 100644 --- a/wayland_server.h +++ b/wayland_server.h @@ -75,6 +75,9 @@ public: QList clients() const { return m_clients; } + QList internalClients() const { + return m_internalClients; + } void removeClient(ShellClient *c); ShellClient *findClient(quint32 id) const; @@ -136,6 +139,7 @@ private: } m_internalConnection; AbstractBackend *m_backend = nullptr; QList m_clients; + QList m_internalClients; QScopedPointer m_dummyWindow; KWayland::Client::Surface *m_dummyWindowSurface = nullptr; QHash m_clientIds; diff --git a/workspace.cpp b/workspace.cpp index 8f9e70acbe..a0b9da9013 100644 --- a/workspace.cpp +++ b/workspace.cpp @@ -378,10 +378,12 @@ void Workspace::init() if (auto w = waylandServer()) { connect(w, &WaylandServer::shellClientAdded, this, [this] (ShellClient *c) { - if (!unconstrained_stacking_order.contains(c)) - unconstrained_stacking_order.append(c); // Raise if it hasn't got any stacking position yet - if (!stacking_order.contains(c)) // It'll be updated later, and updateToolWindows() requires - stacking_order.append(c); // c to be in stacking_order + if (!c->isInternal()) { + if (!unconstrained_stacking_order.contains(c)) + unconstrained_stacking_order.append(c); // Raise if it hasn't got any stacking position yet + if (!stacking_order.contains(c)) // It'll be updated later, and updateToolWindows() requires + stacking_order.append(c); // c to be in stacking_order + } x_stacking_dirty = true; updateStackingOrder(true); }