diff options
author | Matt Hoosier <matt.hoosier@garmin.com> | 2018-06-13 10:29:10 -0500 |
---|---|---|
committer | Matt Hoosier <matt.hoosier@garmin.com> | 2018-06-20 13:13:06 +0000 |
commit | 1eaac3fbcd4cdd7aba3a611d1e94436fe2666b82 (patch) | |
tree | b8415fefa6795b6738423f72753c40eae8521a86 /src/compositor/extensions | |
parent | 5a4769b0757867bbadf3d50e8a5a3b2e061be94b (diff) |
Compositor: make XdgShellV6 reconfigure clients on mode-change
[ChangeLog][Compositor] Made the zxdg_shell_v6 compositor protocol
implementation re-issue configure requests with updated sizes when
the size or available geometry changes on an output used by a
maximized or fullscreen surface.
Change-Id: Ia446511f123e831b2d0a35ba202a6d092a841569
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
Diffstat (limited to 'src/compositor/extensions')
-rw-r--r-- | src/compositor/extensions/qwaylandxdgshellv6integration.cpp | 42 | ||||
-rw-r--r-- | src/compositor/extensions/qwaylandxdgshellv6integration_p.h | 10 |
2 files changed, 48 insertions, 4 deletions
diff --git a/src/compositor/extensions/qwaylandxdgshellv6integration.cpp b/src/compositor/extensions/qwaylandxdgshellv6integration.cpp index 769b426c9..c3cd140e1 100644 --- a/src/compositor/extensions/qwaylandxdgshellv6integration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv6integration.cpp @@ -74,6 +74,7 @@ XdgToplevelV6Integration::XdgToplevelV6Integration(QWaylandQuickShellSurfaceItem handlePopupCreated(item, popup); }); connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgToplevelV6Integration::handleSurfaceSizeChanged); + connect(m_toplevel, &QObject::destroyed, this, &XdgToplevelV6Integration::handleToplevelDestroyed); } bool XdgToplevelV6Integration::mouseMoveEvent(QMouseEvent *event) @@ -145,8 +146,21 @@ void XdgToplevelV6Integration::handleSetMaximized() windowedGeometry.initialPosition = m_item->moveItem()->position(); } - QWaylandOutput *output = m_item->view()->output(); - m_toplevel->sendMaximized(output->availableGeometry().size() / output->scaleFactor()); + // Any prior output-resize handlers are irrelevant at this point. + disconnect(nonwindowedState.sizeChangedConnection); + nonwindowedState.output = m_item->view()->output(); + nonwindowedState.sizeChangedConnection = connect(nonwindowedState.output, &QWaylandOutput::availableGeometryChanged, this, &XdgToplevelV6Integration::handleMaximizedSizeChanged); + handleMaximizedSizeChanged(); +} + +void XdgToplevelV6Integration::handleMaximizedSizeChanged() +{ + // Insurance against handleToplevelDestroyed() not managing to disconnect this + // handler in time. + if (m_toplevel == nullptr) + return; + + m_toplevel->sendMaximized(nonwindowedState.output->availableGeometry().size() / nonwindowedState.output->scaleFactor()); } void XdgToplevelV6Integration::handleUnsetMaximized() @@ -179,8 +193,21 @@ void XdgToplevelV6Integration::handleSetFullscreen() windowedGeometry.initialPosition = m_item->moveItem()->position(); } - QWaylandOutput *output = m_item->view()->output(); - m_toplevel->sendFullscreen(output->geometry().size() / output->scaleFactor()); + // Any prior output-resize handlers are irrelevant at this point. + disconnect(nonwindowedState.sizeChangedConnection); + nonwindowedState.output = m_item->view()->output(); + nonwindowedState.sizeChangedConnection = connect(nonwindowedState.output, &QWaylandOutput::geometryChanged, this, &XdgToplevelV6Integration::handleFullscreenSizeChanged); + handleFullscreenSizeChanged(); +} + +void XdgToplevelV6Integration::handleFullscreenSizeChanged() +{ + // Insurance against handleToplevelDestroyed() not managing to disconnect this + // handler in time. + if (m_toplevel == nullptr) + return; + + m_toplevel->sendFullscreen(nonwindowedState.output->geometry().size() / nonwindowedState.output->scaleFactor()); } void XdgToplevelV6Integration::handleUnsetFullscreen() @@ -221,6 +248,13 @@ void XdgToplevelV6Integration::handleSurfaceSizeChanged() } } +void XdgToplevelV6Integration::handleToplevelDestroyed() +{ + // Disarm any handlers that might fire on the now-stale toplevel pointer + nonwindowedState.output = nullptr; + disconnect(nonwindowedState.sizeChangedConnection); +} + XdgPopupV6Integration::XdgPopupV6Integration(QWaylandQuickShellSurfaceItem *item) : m_item(item) , m_xdgSurface(qobject_cast<QWaylandXdgSurfaceV6 *>(item->shellSurface())) diff --git a/src/compositor/extensions/qwaylandxdgshellv6integration_p.h b/src/compositor/extensions/qwaylandxdgshellv6integration_p.h index afb4964b9..5b56af89b 100644 --- a/src/compositor/extensions/qwaylandxdgshellv6integration_p.h +++ b/src/compositor/extensions/qwaylandxdgshellv6integration_p.h @@ -77,6 +77,9 @@ private Q_SLOTS: void handleFullscreenChanged(); void handleActivatedChanged(); void handleSurfaceSizeChanged(); + void handleToplevelDestroyed(); + void handleMaximizedSizeChanged(); + void handleFullscreenSizeChanged(); private: QWaylandQuickShellSurfaceItem *m_item = nullptr; @@ -110,6 +113,13 @@ private: QSize initialWindowSize; QPointF initialPosition; } windowedGeometry; + + struct { + QWaylandOutput *output = nullptr; + QMetaObject::Connection sizeChangedConnection; // Depending on whether maximized or fullscreen, + // will be hooked to geometry-changed or available- + // geometry-changed. + } nonwindowedState; }; class XdgPopupV6Integration : public QWaylandQuickShellIntegration |