diff --git a/src/interfaces/window.cpp b/src/interfaces/window.cpp index 16dbcad..0219e64 100644 --- a/src/interfaces/window.cpp +++ b/src/interfaces/window.cpp @@ -35,6 +35,7 @@ public: Window::Layer layer = Window::LayerTop; QMargins margins; Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow; + bool closeOnDismissed = true; }; static QMap s_map; @@ -120,6 +121,16 @@ void Window::setScreenConfiguration(Window::ScreenConfiguration screenConfigurat d->screenConfiguration = screenConfiguration; } +bool Window::closeOnDismissed() const +{ + return d->closeOnDismissed; +} + +void Window::setCloseOnDismissed(bool close) +{ + d->closeOnDismissed = close; +} + #if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) void Window::attachPopup(QWindow *window, xdg_popup *popup) { diff --git a/src/interfaces/window.h b/src/interfaces/window.h index 45592e0..7eff583 100644 --- a/src/interfaces/window.h +++ b/src/interfaces/window.h @@ -97,6 +97,15 @@ public: void setScope(const QString &scope); QString scope() const; + /** + * Whether the QWindow should be closed when the layer surface is dismissed by the compositor. + * For example, if the associated screen has been removed. + * + * This can be used to map the window on another screen. + */ + void setCloseOnDismissed(bool close); + bool closeOnDismissed() const; + /** * Gets the LayerShell Window for a given Qt Window * Ownership is not transferred diff --git a/src/qwaylandlayersurface.cpp b/src/qwaylandlayersurface.cpp index 10bc3f5..29fb7ba 100644 --- a/src/qwaylandlayersurface.cpp +++ b/src/qwaylandlayersurface.cpp @@ -18,12 +18,10 @@ namespace LayerShellQt QWaylandLayerSurface::QWaylandLayerSurface(QtWayland::zwlr_layer_shell_v1 *shell, QtWaylandClient::QWaylandWindow *window) : QtWaylandClient::QWaylandShellSurface(window) , QtWayland::zwlr_layer_surface_v1() + , m_interface(Window::get(window->window())) { - LayerShellQt::Window *interface = Window::get(window->window()); - Q_ASSERT(interface); - wl_output *output = nullptr; - if (interface->screenConfiguration() == Window::ScreenFromQWindow) { + if (m_interface->screenConfiguration() == Window::ScreenFromQWindow) { auto waylandScreen = dynamic_cast(window->window()->screen()->handle()); // Qt will always assign a screen to a window, but if the compositor has no screens available a dummy QScreen object is created // this will not cast to a QWaylandScreen @@ -33,32 +31,32 @@ QWaylandLayerSurface::QWaylandLayerSurface(QtWayland::zwlr_layer_shell_v1 *shell output = waylandScreen->output(); } } - init(shell->get_layer_surface(window->waylandSurface()->object(), output, interface->layer(), interface->scope())); - connect(interface, &Window::layerChanged, this, [this, interface]() { - setLayer(interface->layer()); + init(shell->get_layer_surface(window->waylandSurface()->object(), output, m_interface->layer(), m_interface->scope())); + connect(m_interface, &Window::layerChanged, this, [this]() { + setLayer(m_interface->layer()); }); - set_anchor(interface->anchors()); - connect(interface, &Window::anchorsChanged, this, [this, interface]() { - set_anchor(interface->anchors()); + set_anchor(m_interface->anchors()); + connect(m_interface, &Window::anchorsChanged, this, [this]() { + set_anchor(m_interface->anchors()); }); - setExclusiveZone(interface->exclusionZone()); - connect(interface, &Window::exclusionZoneChanged, this, [this, interface]() { - setExclusiveZone(interface->exclusionZone()); + setExclusiveZone(m_interface->exclusionZone()); + connect(m_interface, &Window::exclusionZoneChanged, this, [this]() { + setExclusiveZone(m_interface->exclusionZone()); }); - setMargins(interface->margins()); - connect(interface, &Window::marginsChanged, this, [this, interface]() { - setMargins(interface->margins()); + setMargins(m_interface->margins()); + connect(m_interface, &Window::marginsChanged, this, [this]() { + setMargins(m_interface->margins()); }); - setKeyboardInteractivity(interface->keyboardInteractivity()); - connect(interface, &Window::keyboardInteractivityChanged, this, [this, interface]() { - setKeyboardInteractivity(interface->keyboardInteractivity()); + setKeyboardInteractivity(m_interface->keyboardInteractivity()); + connect(m_interface, &Window::keyboardInteractivityChanged, this, [this]() { + setKeyboardInteractivity(m_interface->keyboardInteractivity()); }); QSize size = window->surfaceSize(); - const Window::Anchors anchors = interface->anchors(); + const Window::Anchors anchors = m_interface->anchors(); if ((anchors & Window::AnchorLeft) && (anchors & Window::AnchorRight)) { size.setWidth(0); } @@ -77,7 +75,9 @@ QWaylandLayerSurface::~QWaylandLayerSurface() void QWaylandLayerSurface::zwlr_layer_surface_v1_closed() { - window()->window()->close(); + if (m_interface->closeOnDismissed()) { + window()->window()->close(); + } } void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) @@ -142,9 +142,8 @@ void QWaylandLayerSurface::setLayer(uint32_t layer) void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry) { - LayerShellQt::Window *interface = Window::get(window()->window()); - const bool horizontallyConstrained = interface->anchors() & (Window::AnchorLeft & Window::AnchorRight); - const bool verticallyConstrained = interface->anchors() & (Window::AnchorTop & Window::AnchorBottom); + const bool horizontallyConstrained = m_interface->anchors() & (Window::AnchorLeft & Window::AnchorRight); + const bool verticallyConstrained = m_interface->anchors() & (Window::AnchorTop & Window::AnchorBottom); QSize size = geometry.size(); if (horizontallyConstrained) { diff --git a/src/qwaylandlayersurface_p.h b/src/qwaylandlayersurface_p.h index 4d61d26..dec2da0 100644 --- a/src/qwaylandlayersurface_p.h +++ b/src/qwaylandlayersurface_p.h @@ -17,6 +17,8 @@ namespace LayerShellQt { +class Window; + class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylandShellSurface, public QtWayland::zwlr_layer_surface_v1 { Q_OBJECT @@ -45,6 +47,7 @@ private: void zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) override; void zwlr_layer_surface_v1_closed() override; + LayerShellQt::Window *m_interface; QSize m_pendingSize; bool m_configured = false; };