diff --git a/shell_client.cpp b/shell_client.cpp
index 93fd2ae544..6b534227ed 100644
--- a/shell_client.cpp
+++ b/shell_client.cpp
@@ -315,6 +315,11 @@ void ShellClient::init()
getShadow();
connect(s, &SurfaceInterface::shadowChanged, this, &Toplevel::getShadow);
+ connect(waylandServer(), &WaylandServer::foreignTransientChanged, this, [this](KWayland::Server::SurfaceInterface *child) {
+ if (child == surface()) {
+ setTransient();
+ }
+ });
setTransient();
// check whether we have a ServerSideDecoration
if (ServerSideDecorationInterface *deco = ServerSideDecorationInterface::get(s)) {
@@ -1392,6 +1397,9 @@ void ShellClient::setTransient()
if (m_xdgShellPopup) {
s = m_xdgShellPopup->transientFor().data();
}
+ if (!s) {
+ s = waylandServer()->findForeignTransientForSurface(surface());
+ }
auto t = waylandServer()->findClient(s);
if (t != transientFor()) {
// remove from main client
diff --git a/wayland_server.cpp b/wayland_server.cpp
index bdd96cf902..78beb7795c 100644
--- a/wayland_server.cpp
+++ b/wayland_server.cpp
@@ -52,6 +52,7 @@ along with this program. If not, see .
#include
#include
#include
+#include
// Qt
#include
@@ -158,6 +159,11 @@ void WaylandServer::createSurface(T *surface)
} else {
connect(client, &ShellClient::windowShown, this, &WaylandServer::shellClientShown);
}
+
+ //not directly connected as the connection is tied to client instead of this
+ connect(m_XdgForeign, &KWayland::Server::XdgForeignInterface::transientChanged, client, [this](KWayland::Server::SurfaceInterface *child, KWayland::Server::SurfaceInterface *parent) {
+ emit foreignTransientChanged(child);
+ });
}
bool WaylandServer::init(const QByteArray &socketName, InitalizationFlags flags)
@@ -308,9 +314,17 @@ bool WaylandServer::init(const QByteArray &socketName, InitalizationFlags flags)
m_display->createSubCompositor(m_display)->create();
+ m_XdgForeign = m_display->createXdgForeignInterface(m_display);
+ m_XdgForeign->create();
+
return true;
}
+SurfaceInterface *WaylandServer::findForeignTransientForSurface(SurfaceInterface *surface)
+{
+ return m_XdgForeign->transientFor(surface);
+}
+
void WaylandServer::shellClientShown(Toplevel *t)
{
ShellClient *c = dynamic_cast(t);
diff --git a/wayland_server.h b/wayland_server.h
index d2a9d7dd8a..d272d9ec25 100644
--- a/wayland_server.h
+++ b/wayland_server.h
@@ -56,6 +56,7 @@ class QtSurfaceExtensionInterface;
class OutputManagementInterface;
class OutputConfigurationInterface;
class XdgShellInterface;
+class XdgForeignInterface;
}
}
@@ -112,6 +113,11 @@ public:
AbstractClient *findAbstractClient(KWayland::Server::SurfaceInterface *surface) const;
ShellClient *findClient(QWindow *w) const;
+ /**
+ * return a transient parent of a surface imported with the foreign protocol, if any
+ */
+ KWayland::Server::SurfaceInterface *findForeignTransientForSurface(KWayland::Server::SurfaceInterface *surface);
+
/**
* @returns file descriptor for Xwayland to connect to.
**/
@@ -189,6 +195,7 @@ Q_SIGNALS:
void shellClientRemoved(KWin::ShellClient*);
void terminatingInternalClientConnection();
void initialized();
+ void foreignTransientChanged(KWayland::Server::SurfaceInterface *child);
private:
void setupX11ClipboardSync();
@@ -232,6 +239,7 @@ private:
KWayland::Server::ClientConnection *client = nullptr;
QPointer ddi;
} m_xclipbaordSync;
+ KWayland::Server::XdgForeignInterface *m_XdgForeign = nullptr;
QList m_clients;
QList m_internalClients;
QHash m_clientIds;