Introduce Window::closeOnDismissed() flag

This can be used to control the sending of QEvent::Close event.
This commit is contained in:
Vlad Zahorodnii 2023-05-16 17:58:48 +03:00
parent 497d50c4df
commit 5e88f449b0
4 changed files with 46 additions and 24 deletions

View file

@ -35,6 +35,7 @@ public:
Window::Layer layer = Window::LayerTop; Window::Layer layer = Window::LayerTop;
QMargins margins; QMargins margins;
Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow; Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow;
bool closeOnDismissed = true;
}; };
static QMap<QWindow *, Window *> s_map; static QMap<QWindow *, Window *> s_map;
@ -120,6 +121,16 @@ void Window::setScreenConfiguration(Window::ScreenConfiguration screenConfigurat
d->screenConfiguration = screenConfiguration; 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) #if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
void Window::attachPopup(QWindow *window, xdg_popup *popup) void Window::attachPopup(QWindow *window, xdg_popup *popup)
{ {

View file

@ -97,6 +97,15 @@ public:
void setScope(const QString &scope); void setScope(const QString &scope);
QString scope() const; 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 * Gets the LayerShell Window for a given Qt Window
* Ownership is not transferred * Ownership is not transferred

View file

@ -18,12 +18,10 @@ namespace LayerShellQt
QWaylandLayerSurface::QWaylandLayerSurface(QtWayland::zwlr_layer_shell_v1 *shell, QtWaylandClient::QWaylandWindow *window) QWaylandLayerSurface::QWaylandLayerSurface(QtWayland::zwlr_layer_shell_v1 *shell, QtWaylandClient::QWaylandWindow *window)
: QtWaylandClient::QWaylandShellSurface(window) : QtWaylandClient::QWaylandShellSurface(window)
, QtWayland::zwlr_layer_surface_v1() , 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; wl_output *output = nullptr;
if (interface->screenConfiguration() == Window::ScreenFromQWindow) { if (m_interface->screenConfiguration() == Window::ScreenFromQWindow) {
auto waylandScreen = dynamic_cast<QtWaylandClient::QWaylandScreen *>(window->window()->screen()->handle()); auto waylandScreen = dynamic_cast<QtWaylandClient::QWaylandScreen *>(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 // 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 // this will not cast to a QWaylandScreen
@ -33,32 +31,32 @@ QWaylandLayerSurface::QWaylandLayerSurface(QtWayland::zwlr_layer_shell_v1 *shell
output = waylandScreen->output(); output = waylandScreen->output();
} }
} }
init(shell->get_layer_surface(window->waylandSurface()->object(), output, interface->layer(), interface->scope())); init(shell->get_layer_surface(window->waylandSurface()->object(), output, m_interface->layer(), m_interface->scope()));
connect(interface, &Window::layerChanged, this, [this, interface]() { connect(m_interface, &Window::layerChanged, this, [this]() {
setLayer(interface->layer()); setLayer(m_interface->layer());
}); });
set_anchor(interface->anchors()); set_anchor(m_interface->anchors());
connect(interface, &Window::anchorsChanged, this, [this, interface]() { connect(m_interface, &Window::anchorsChanged, this, [this]() {
set_anchor(interface->anchors()); set_anchor(m_interface->anchors());
}); });
setExclusiveZone(interface->exclusionZone()); setExclusiveZone(m_interface->exclusionZone());
connect(interface, &Window::exclusionZoneChanged, this, [this, interface]() { connect(m_interface, &Window::exclusionZoneChanged, this, [this]() {
setExclusiveZone(interface->exclusionZone()); setExclusiveZone(m_interface->exclusionZone());
}); });
setMargins(interface->margins()); setMargins(m_interface->margins());
connect(interface, &Window::marginsChanged, this, [this, interface]() { connect(m_interface, &Window::marginsChanged, this, [this]() {
setMargins(interface->margins()); setMargins(m_interface->margins());
}); });
setKeyboardInteractivity(interface->keyboardInteractivity()); setKeyboardInteractivity(m_interface->keyboardInteractivity());
connect(interface, &Window::keyboardInteractivityChanged, this, [this, interface]() { connect(m_interface, &Window::keyboardInteractivityChanged, this, [this]() {
setKeyboardInteractivity(interface->keyboardInteractivity()); setKeyboardInteractivity(m_interface->keyboardInteractivity());
}); });
QSize size = window->surfaceSize(); QSize size = window->surfaceSize();
const Window::Anchors anchors = interface->anchors(); const Window::Anchors anchors = m_interface->anchors();
if ((anchors & Window::AnchorLeft) && (anchors & Window::AnchorRight)) { if ((anchors & Window::AnchorLeft) && (anchors & Window::AnchorRight)) {
size.setWidth(0); size.setWidth(0);
} }
@ -77,8 +75,10 @@ QWaylandLayerSurface::~QWaylandLayerSurface()
void QWaylandLayerSurface::zwlr_layer_surface_v1_closed() void QWaylandLayerSurface::zwlr_layer_surface_v1_closed()
{ {
if (m_interface->closeOnDismissed()) {
window()->window()->close(); window()->window()->close();
} }
}
void QWaylandLayerSurface::zwlr_layer_surface_v1_configure(uint32_t serial, uint32_t width, uint32_t height) 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) void QWaylandLayerSurface::setWindowGeometry(const QRect &geometry)
{ {
LayerShellQt::Window *interface = Window::get(window()->window()); const bool horizontallyConstrained = m_interface->anchors() & (Window::AnchorLeft & Window::AnchorRight);
const bool horizontallyConstrained = interface->anchors() & (Window::AnchorLeft & Window::AnchorRight); const bool verticallyConstrained = m_interface->anchors() & (Window::AnchorTop & Window::AnchorBottom);
const bool verticallyConstrained = interface->anchors() & (Window::AnchorTop & Window::AnchorBottom);
QSize size = geometry.size(); QSize size = geometry.size();
if (horizontallyConstrained) { if (horizontallyConstrained) {

View file

@ -17,6 +17,8 @@
namespace LayerShellQt namespace LayerShellQt
{ {
class Window;
class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylandShellSurface, public QtWayland::zwlr_layer_surface_v1 class LAYERSHELLQT_EXPORT QWaylandLayerSurface : public QtWaylandClient::QWaylandShellSurface, public QtWayland::zwlr_layer_surface_v1
{ {
Q_OBJECT 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_configure(uint32_t serial, uint32_t width, uint32_t height) override;
void zwlr_layer_surface_v1_closed() override; void zwlr_layer_surface_v1_closed() override;
LayerShellQt::Window *m_interface;
QSize m_pendingSize; QSize m_pendingSize;
bool m_configured = false; bool m_configured = false;
}; };