diff --git a/effects.cpp b/effects.cpp index 0e62b63a9218ee7b594cad970230b74de1f6bf29..6b73b087d425a7f71d32f2dafac40ce0097e831a 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 0b86f09612814759ead2f6a6308c0709e6c18ad9..13f0f8c2a15fc6c8fddd7f66313dae767019d8cf 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 bd93ea24c403b21e8591b0c2fb0af00baa369e58..8ccb6c048120cdaed50eae836873de5b46a56e37 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 c0a625a52ebee7876f2a0f372154d9649a08f9d0..9ae488440323d618d918b368e99f2966c02b6753 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 11c204f6b6d2fe10ca8db68595c71bdacdc8538c..18266d34efb6a00fcf8cb50d7a726a8ea0da7b7f 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; }