diff --git a/wayland_server.cpp b/wayland_server.cpp index 80204e982e..6c8fcbae1a 100644 --- a/wayland_server.cpp +++ b/wayland_server.cpp @@ -205,6 +205,19 @@ void WaylandServer::registerXdgGenericClient(AbstractClient *client) XdgPopupClient *popupClient = qobject_cast(client); if (popupClient) { registerShellClient(popupClient); + + SurfaceInterface *surface = client->surface(); + auto it = std::find_if(m_plasmaShellSurfaces.begin(), m_plasmaShellSurfaces.end(), + [surface] (PlasmaShellSurfaceInterface *plasmaSurface) { + return plasmaSurface->surface() == surface; + } + ); + + if (it != m_plasmaShellSurfaces.end()) { + popupClient->installPlasmaShellSurface(*it); + m_plasmaShellSurfaces.erase(it); + } + return; } qCDebug(KWIN_CORE) << "Received invalid xdg client:" << client->surface(); @@ -366,10 +379,11 @@ bool WaylandServer::init(const QByteArray &socketName, InitializationFlags flags m_plasmaShell->create(); connect(m_plasmaShell, &PlasmaShellInterface::surfaceCreated, [this] (PlasmaShellSurfaceInterface *surface) { - if (XdgToplevelClient *client = findXdgToplevelClient(surface->surface())) { + if (XdgSurfaceClient *client = findXdgSurfaceClient(surface->surface())) { client->installPlasmaShellSurface(surface); return; } + m_plasmaShellSurfaces.append(surface); connect(surface, &QObject::destroyed, this, [this, surface] { m_plasmaShellSurfaces.removeOne(surface); @@ -756,6 +770,11 @@ XdgToplevelClient *WaylandServer::findXdgToplevelClient(SurfaceInterface *surfac return qobject_cast(findClient(surface)); } +XdgSurfaceClient *WaylandServer::findXdgSurfaceClient(SurfaceInterface *surface) const +{ + return qobject_cast(findClient(surface)); +} + quint32 WaylandServer::createWindowId(SurfaceInterface *surface) { auto it = m_clientIds.constFind(surface->client()); diff --git a/wayland_server.h b/wayland_server.h index 97f71a4183..8fd9b7d6ab 100644 --- a/wayland_server.h +++ b/wayland_server.h @@ -78,6 +78,7 @@ namespace KWin class AbstractClient; class Toplevel; class XdgPopupClient; +class XdgSurfaceClient; class XdgToplevelClient; class KWIN_EXPORT WaylandServer : public QObject @@ -149,6 +150,7 @@ public: AbstractClient *findClient(quint32 id) const; AbstractClient *findClient(KWaylandServer::SurfaceInterface *surface) const; XdgToplevelClient *findXdgToplevelClient(KWaylandServer::SurfaceInterface *surface) const; + XdgSurfaceClient *findXdgSurfaceClient(KWaylandServer::SurfaceInterface *surface) const; /** * @returns a transient parent of a surface imported with the foreign protocol, if any diff --git a/xdgshellclient.cpp b/xdgshellclient.cpp index 3a527b9225..c42c47af96 100644 --- a/xdgshellclient.cpp +++ b/xdgshellclient.cpp @@ -337,6 +337,11 @@ QRect XdgSurfaceClient::adjustMoveResizeGeometry(const QRect &rect) const return geometry; } +bool XdgSurfaceClient::isInitialPositionSet() const +{ + return m_plasmaShellSurface ? m_plasmaShellSurface->isPositionSet() : false; +} + /** * Sets the frame geometry of the XdgSurfaceClient to \a rect. * @@ -919,11 +924,6 @@ void XdgToplevelClient::showOnScreenEdge() } } -bool XdgToplevelClient::isInitialPositionSet() const -{ - return m_plasmaShellSurface ? m_plasmaShellSurface->isPositionSet() : false; -} - void XdgToplevelClient::closeWindow() { if (isCloseable()) { @@ -2171,5 +2171,15 @@ void XdgPopupClient::initialize() scheduleConfigure(); } +void XdgPopupClient::installPlasmaShellSurface(PlasmaShellSurfaceInterface *shellSurface) +{ + m_plasmaShellSurface = shellSurface; + + auto updatePosition = [this, shellSurface] { move(shellSurface->position()); }; + connect(shellSurface, &PlasmaShellSurfaceInterface::positionChanged, this, updatePosition); + if (shellSurface->isPositionSet()) { + updatePosition(); + } +} } // namespace KWin diff --git a/xdgshellclient.h b/xdgshellclient.h index b0a8e5ed12..74ec7fcd30 100644 --- a/xdgshellclient.h +++ b/xdgshellclient.h @@ -72,6 +72,7 @@ public: void move(int x, int y, ForceGeometry_t force = NormalGeometrySet) override; bool isShown(bool shaded_is_shown) const override; bool isHiddenInternal() const override; + bool isInitialPositionSet() const override; void hideClient(bool hide) override; void destroyClient() override; @@ -84,6 +85,8 @@ public: QRect clientGeometry() const; bool isHidden() const; + virtual void installPlasmaShellSurface(KWaylandServer::PlasmaShellSurfaceInterface *shellSurface) = 0; + protected: void addDamage(const QRegion &damage) override; @@ -97,6 +100,8 @@ protected: void requestGeometry(const QRect &rect); void updateGeometry(const QRect &rect); + QPointer m_plasmaShellSurface; + private: void handleConfigureAcknowledged(quint32 serial); void handleCommit(); @@ -169,14 +174,13 @@ public: bool dockWantsInput() const override; bool hasStrut() const override; void showOnScreenEdge() override; - bool isInitialPositionSet() const override; void setFullScreen(bool set, bool user) override; void closeWindow() override; void installAppMenu(KWaylandServer::AppMenuInterface *appMenu); void installServerDecoration(KWaylandServer::ServerSideDecorationInterface *decoration); void installPalette(KWaylandServer::ServerSideDecorationPaletteInterface *palette); - void installPlasmaShellSurface(KWaylandServer::PlasmaShellSurfaceInterface *shellSurface); + void installPlasmaShellSurface(KWaylandServer::PlasmaShellSurfaceInterface *shellSurface) override; void installXdgDecoration(KWaylandServer::XdgToplevelDecorationV1Interface *decoration); protected: @@ -222,7 +226,6 @@ private: MaximizeMode initialMaximizeMode() const; bool initialFullScreenMode() const; - QPointer m_plasmaShellSurface; QPointer m_appMenuInterface; QPointer m_paletteInterface; QPointer m_serverDecoration; @@ -272,6 +275,7 @@ public: bool wantsInput() const override; bool takeFocus() override; bool supportsWindowRules() const override; + void installPlasmaShellSurface(KWaylandServer::PlasmaShellSurfaceInterface *shellSurface) override; protected: bool acceptsFocus() const override;