[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.
icc-effect-5.14.5
Martin Gräßlin 2015-05-21 10:35:03 +02:00
parent 23b19b4efe
commit 36fa88893e
4 changed files with 47 additions and 13 deletions

View File

@ -92,6 +92,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "effects.h"
#include "composite.h"
#include "screenedge.h"
#if HAVE_WAYLAND
#include "shell_client.h"
#include "wayland_server.h"
#endif
#include <QDebug>
@ -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();
}

View File

@ -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<ShellClient*> &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)

View File

@ -75,6 +75,9 @@ public:
QList<ShellClient*> clients() const {
return m_clients;
}
QList<ShellClient*> 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<ShellClient*> m_clients;
QList<ShellClient*> m_internalClients;
QScopedPointer<QWindow> m_dummyWindow;
KWayland::Client::Surface *m_dummyWindowSurface = nullptr;
QHash<KWayland::Server::ClientConnection*, quint16> m_clientIds;

View File

@ -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);
}