[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:
parent
c63605da06
commit
4ed4d4dab4
3 changed files with 48 additions and 1 deletions
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue