diff --git a/effects.cpp b/effects.cpp index 0e62b63a92..6b73b087d4 100644 --- a/effects.cpp +++ b/effects.cpp @@ -1032,6 +1032,13 @@ EffectWindow* EffectsHandlerImpl::findWindow(WId id) const return w->effectWindow(); if (Unmanaged* w = Workspace::self()->findUnmanaged(id)) return w->effectWindow(); +#if HAVE_WAYLAND + if (waylandServer()) { + if (ShellClient *w = waylandServer()->findClient(id)) { + return w->effectWindow(); + } + } +#endif return NULL; } diff --git a/shell_client.cpp b/shell_client.cpp index 0b86f09612..13f0f8c2a1 100644 --- a/shell_client.cpp +++ b/shell_client.cpp @@ -22,10 +22,13 @@ along with this program. If not, see . #include "wayland_server.h" #include "virtualdesktops.h" +#include #include #include #include +#include + using namespace KWayland::Server; namespace KWin @@ -36,6 +39,8 @@ ShellClient::ShellClient(ShellSurfaceInterface *surface) , m_shellSurface(surface) { setSurface(surface->surface()); + findInternalWindow(); + createWindowId(); setupCompositing(); if (surface->surface()->buffer()) { setReadyForPainting(); @@ -43,7 +48,11 @@ ShellClient::ShellClient(ShellSurfaceInterface *surface) } else { ready_for_painting = false; } - setGeometry(QRect(QPoint(0, 0), m_clientSize)); + if (m_internalWindow) { + setGeometry(m_internalWindow->geometry()); + } else { + setGeometry(QRect(QPoint(0, 0), m_clientSize)); + } setDesktop(VirtualDesktopManager::self()->current()); @@ -329,4 +338,31 @@ bool ShellClient::wantsInput() const return true; } +void ShellClient::createWindowId() +{ + if (m_internalWindow) { + m_windowId = m_internalWindow->winId(); + } + // TODO: create internal window ids +} + +void ShellClient::findInternalWindow() +{ + if (m_shellSurface->client() != waylandServer()->qtConnection()) { + return; + } + const QWindowList windows = kwinApp()->topLevelWindows(); + for (QWindow *w: windows) { + QScopedPointer s(KWayland::Client::Surface::fromWindow(w)); + if (!s) { + continue; + } + if (s->id() != surface()->id()) { + continue; + } + m_internalWindow = w; + return; + } +} + } diff --git a/shell_client.h b/shell_client.h index bd93ea24c4..8ccb6c0481 100644 --- a/shell_client.h +++ b/shell_client.h @@ -87,6 +87,10 @@ public: bool userCanSetNoBorder() const override; bool wantsInput() const override; + quint32 windowId() const { + return m_windowId; + } + protected: void addDamage(const QRegion &damage) override; bool belongsToSameApplication(const AbstractClient *other, bool active_hack) const override; @@ -94,11 +98,15 @@ protected: private: void setGeometry(const QRect &rect); void destroyClient(); + void createWindowId(); + void findInternalWindow(); static void deleteClient(ShellClient *c); KWayland::Server::ShellSurfaceInterface *m_shellSurface; QSize m_clientSize; bool m_closing = false; + quint32 m_windowId = 0; + QWindow *m_internalWindow = nullptr; }; } diff --git a/wayland_server.cpp b/wayland_server.cpp index c0a625a52e..9ae4884403 100644 --- a/wayland_server.cpp +++ b/wayland_server.cpp @@ -261,4 +261,20 @@ void WaylandServer::dispatch() m_display->dispatchEvents(0); } +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; + } + return *it; +} + } diff --git a/wayland_server.h b/wayland_server.h index 11c204f6b6..18266d34ef 100644 --- a/wayland_server.h +++ b/wayland_server.h @@ -75,6 +75,7 @@ public: return m_clients; } void removeClient(ShellClient *c); + ShellClient *findClient(quint32 id) const; AbstractBackend *backend() const { return m_backend; @@ -97,6 +98,9 @@ public: KWayland::Server::ClientConnection *xWaylandConnection() const { return m_xwaylandConnection; } + KWayland::Server::ClientConnection *qtConnection() const { + return m_qtConnection; + } KWayland::Server::ClientConnection *internalConnection() const { return m_internalConnection.server; }