[wayland] Create a windowId for ShellSurface

The internal used window Id consists of two parts identifiying the
Client and one identifying the Surface. That is the first 16 bits
are set to the ClientConnection, the last 16 bits are taken from
the Surface id. As the Surface id is 32 bits, but we only use 16 bits
there is a chance of overlap. So this might need some improvement.
This commit is contained in:
Martin Gräßlin 2015-05-21 09:59:45 +02:00
parent c63605da06
commit 4ed4d4dab4
3 changed files with 48 additions and 1 deletions

View file

@ -343,8 +343,9 @@ void ShellClient::createWindowId()
{
if (m_internalWindow) {
m_windowId = m_internalWindow->winId();
} else {
m_windowId = waylandServer()->createWindowId(m_shellSurface->surface());
}
// TODO: create internal window ids
}
void ShellClient::findInternalWindow()

View file

@ -277,4 +277,46 @@ ShellClient *WaylandServer::findClient(quint32 id) const
return *it;
}
quint32 WaylandServer::createWindowId(SurfaceInterface *surface)
{
auto it = m_clientIds.constFind(surface->client());
quint16 clientId = 0;
if (it != m_clientIds.constEnd()) {
clientId = it.value();
} else {
clientId = createClientId(surface->client());
}
Q_ASSERT(clientId != 0);
quint32 id = clientId;
// TODO: this does not prevent that two surfaces of same client get same id
id = (id << 16) | (surface->id() & 0xFFFF);
if (findClient(id)) {
qCWarning(KWIN_CORE) << "Invalid client windowId generated:" << id;
return 0;
}
return id;
}
quint16 WaylandServer::createClientId(ClientConnection *c)
{
auto ids = m_clientIds.values().toSet();
quint16 id = 1;
if (!ids.isEmpty()) {
for (quint16 i = ids.count() + 1; i >= 1 ; i--) {
if (!ids.contains(i)) {
id = i;
break;
}
}
}
Q_ASSERT(!ids.contains(id));
m_clientIds.insert(c, id);
connect(c, &ClientConnection::disconnected, this,
[this] (ClientConnection *c) {
m_clientIds.remove(c);
}
);
return id;
}
}

View file

@ -41,6 +41,7 @@ class CompositorInterface;
class Display;
class ShellInterface;
class SeatInterface;
class SurfaceInterface;
class OutputInterface;
}
}
@ -111,6 +112,7 @@ public:
return m_internalConnection.client;
}
void dispatch();
quint32 createWindowId(KWayland::Server::SurfaceInterface *surface);
Q_SIGNALS:
void shellClientAdded(ShellClient*);
@ -118,6 +120,7 @@ Q_SIGNALS:
private:
void fakeDummyQtWindowInput();
quint16 createClientId(KWayland::Server::ClientConnection *c);
KWayland::Server::Display *m_display = nullptr;
KWayland::Server::CompositorInterface *m_compositor = nullptr;
KWayland::Server::SeatInterface *m_seat = nullptr;
@ -135,6 +138,7 @@ private:
QList<ShellClient*> m_clients;
QScopedPointer<QWindow> m_dummyWindow;
KWayland::Client::Surface *m_dummyWindowSurface = nullptr;
QHash<KWayland::Server::ClientConnection*, quint16> m_clientIds;
KWIN_SINGLETON(WaylandServer)
};