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