summaryrefslogtreecommitdiffstats
path: root/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp')
-rw-r--r--src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp53
1 files changed, 49 insertions, 4 deletions
diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
index 12c77d80d..7dabd96f2 100644
--- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
+++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp
@@ -54,7 +54,12 @@ QWaylandXdgSurface::Toplevel::Toplevel(QWaylandXdgSurface *xdgSurface)
: QtWayland::xdg_toplevel(xdgSurface->get_toplevel())
, m_xdgSurface(xdgSurface)
{
- requestWindowStates(xdgSurface->window()->window()->windowStates());
+ if (auto *decorationManager = m_xdgSurface->m_shell->decorationManager())
+ m_decoration = decorationManager->createToplevelDecoration(object());
+
+ QWindow *window = xdgSurface->window()->window();
+ requestWindowStates(window->windowStates());
+ requestWindowFlags(window->flags());
}
QWaylandXdgSurface::Toplevel::~Toplevel()
@@ -63,6 +68,11 @@ QWaylandXdgSurface::Toplevel::~Toplevel()
QWaylandWindow *window = m_xdgSurface->window();
window->display()->handleWindowDeactivated(window);
}
+
+ // The protocol spec requires that the decoration object is deleted before xdg_toplevel.
+ delete m_decoration;
+ m_decoration = nullptr;
+
if (isInitialized())
destroy();
}
@@ -91,6 +101,14 @@ void QWaylandXdgSurface::Toplevel::applyConfigure()
m_applied = m_pending;
}
+bool QWaylandXdgSurface::Toplevel::wantsDecorations()
+{
+ if (m_decoration && m_decoration->pending() == QWaylandXdgToplevelDecorationV1::mode_server_side)
+ return false;
+
+ return !(m_pending.states & Qt::WindowFullScreen);
+}
+
void QWaylandXdgSurface::Toplevel::xdg_toplevel_configure(int32_t width, int32_t height, wl_array *states)
{
m_pending.size = QSize(width, height);
@@ -124,6 +142,16 @@ void QWaylandXdgSurface::Toplevel::xdg_toplevel_close()
m_xdgSurface->m_window->window()->close();
}
+void QWaylandXdgSurface::Toplevel::requestWindowFlags(Qt::WindowFlags flags)
+{
+ if (m_decoration) {
+ if (flags & Qt::FramelessWindowHint)
+ m_decoration->requestMode(QWaylandXdgToplevelDecorationV1::mode_client_side);
+ else
+ m_decoration->unsetMode();
+ }
+}
+
void QWaylandXdgSurface::Toplevel::requestWindowStates(Qt::WindowStates states)
{
// Re-send what's different from the applied state
@@ -237,6 +265,12 @@ void QWaylandXdgSurface::setAppId(const QString &appId)
m_toplevel->set_app_id(appId);
}
+void QWaylandXdgSurface::setWindowFlags(Qt::WindowFlags flags)
+{
+ if (m_toplevel)
+ m_toplevel->requestWindowFlags(flags);
+}
+
bool QWaylandXdgSurface::handleExpose(const QRegion &region)
{
if (!m_configured && !region.isEmpty()) {
@@ -261,7 +295,7 @@ void QWaylandXdgSurface::applyConfigure()
bool QWaylandXdgSurface::wantsDecorations() const
{
- return m_toplevel && !(m_toplevel->m_pending.states & Qt::WindowFullScreen);
+ return m_toplevel && m_toplevel->wantsDecorations();
}
void QWaylandXdgSurface::requestWindowStates(Qt::WindowStates states)
@@ -313,13 +347,16 @@ void QWaylandXdgSurface::xdg_surface_configure(uint32_t serial)
}
}
-QWaylandXdgShell::QWaylandXdgShell(struct ::wl_registry *registry, uint32_t id, uint32_t availableVersion)
- : QtWayland::xdg_wm_base(registry, id, qMin(availableVersion, 1u))
+QWaylandXdgShell::QWaylandXdgShell(QWaylandDisplay *display, uint32_t id, uint32_t availableVersion)
+ : QtWayland::xdg_wm_base(display->wl_registry(), id, qMin(availableVersion, 1u))
+ , m_display(display)
{
+ display->addRegistryListener(&QWaylandXdgShell::handleRegistryGlobal, this);
}
QWaylandXdgShell::~QWaylandXdgShell()
{
+ m_display->removeListener(&QWaylandXdgShell::handleRegistryGlobal, this);
destroy();
}
@@ -333,6 +370,14 @@ void QWaylandXdgShell::xdg_wm_base_ping(uint32_t serial)
pong(serial);
}
+void QWaylandXdgShell::handleRegistryGlobal(void *data, wl_registry *registry, uint id,
+ const QString &interface, uint version)
+{
+ QWaylandXdgShell *xdgShell = static_cast<QWaylandXdgShell *>(data);
+ if (interface == QLatin1String(QWaylandXdgDecorationManagerV1::interface()->name))
+ xdgShell->m_xdgDecorationManager.reset(new QWaylandXdgDecorationManagerV1(registry, id, version));
+}
+
}
QT_END_NAMESPACE