// Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qwaylandqtsurface_p.h" #include #include QT_BEGIN_NAMESPACE namespace QtWaylandClient { QWaylandQtSurface::QWaylandQtSurface(struct ::zqt_shell_surface_v1 *shell_surface, QWaylandWindow *window) : QWaylandShellSurface(window) , QtWayland::zqt_shell_surface_v1(shell_surface) { sendSizeHints(); } QWaylandQtSurface::~QWaylandQtSurface() { zqt_shell_surface_v1::destroy(); } void QWaylandQtSurface::resetConfiguration() { m_pendingPosition = QPoint(-1, -1); m_pendingSize = QSize(); m_pendingPositionValid = false; m_pendingStates = m_currentStates; } void QWaylandQtSurface::applyConfigure() { ack_configure(m_currentConfigureSerial); if (m_pendingSize.isValid() && m_pendingPositionValid) setGeometryFromApplyConfigure(m_pendingPosition, m_pendingSize); else if (m_pendingSize.isValid()) resizeFromApplyConfigure(m_pendingSize); else if (m_pendingPositionValid) repositionFromApplyConfigure(m_pendingPosition); if (m_pendingStates != m_currentStates) { QWindowSystemInterface::handleWindowStateChanged(platformWindow()->window(), m_pendingStates); m_currentStates = m_pendingStates; } resetConfiguration(); m_currentConfigureSerial = UINT32_MAX; } void QWaylandQtSurface::setTitle(const QString &title) { set_window_title(title); } void QWaylandQtSurface::zqt_shell_surface_v1_set_capabilities(uint32_t capabilities) { m_capabilities = capabilities; } void QWaylandQtSurface::zqt_shell_surface_v1_set_position(uint32_t serial, int32_t x, int32_t y) { if (serial < m_currentConfigureSerial && m_currentConfigureSerial != UINT32_MAX) return; if (serial != m_currentConfigureSerial) { m_currentConfigureSerial = serial; resetConfiguration(); } m_pendingPosition = QPoint(x, y); m_pendingPositionValid = true; } void QWaylandQtSurface::zqt_shell_surface_v1_resize(uint32_t serial, int32_t width, int32_t height) { if (serial < m_currentConfigureSerial && m_currentConfigureSerial != UINT32_MAX) return; if (serial != m_currentConfigureSerial) { m_currentConfigureSerial = serial; resetConfiguration(); } m_pendingSize = QSize(width, height); } void QWaylandQtSurface::zqt_shell_surface_v1_configure(uint32_t serial) { if (serial < m_currentConfigureSerial) return; if (serial > m_currentConfigureSerial) { m_currentConfigureSerial = serial; resetConfiguration(); } applyConfigureWhenPossible(); } void QWaylandQtSurface::zqt_shell_surface_v1_close() { platformWindow()->window()->close(); } void QWaylandQtSurface::zqt_shell_surface_v1_set_frame_margins(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) { QPlatformWindow *win = platformWindow(); m_frameMargins = QMargins(left, top, right, bottom); m_pendingPosition = win->geometry().topLeft(); m_pendingPositionValid = true; m_pendingSize = win->geometry().size(); applyConfigureWhenPossible(); } bool QWaylandQtSurface::requestActivate() { request_activate(); return true; } void QWaylandQtSurface::propagateSizeHints() { sendSizeHints(); } void QWaylandQtSurface::sendSizeHints() { QPlatformWindow *win = platformWindow(); if (win) { const int minWidth = qMax(0, win->windowMinimumSize().width()); const int minHeight = qMax(0, win->windowMinimumSize().height()); set_minimum_size(minWidth, minHeight); int maxWidth = qMax(0, win->windowMaximumSize().width()); if (maxWidth == QWINDOWSIZE_MAX) maxWidth = -1; int maxHeight = qMax(0, win->windowMaximumSize().height()); if (maxHeight == QWINDOWSIZE_MAX) maxHeight = -1; set_maximum_size(maxWidth, maxHeight); } } void QWaylandQtSurface::zqt_shell_surface_v1_set_window_state(uint32_t serial, uint32_t state) { if (serial < m_currentConfigureSerial && m_currentConfigureSerial != UINT32_MAX) return; if (serial != m_currentConfigureSerial) { m_currentConfigureSerial = serial; resetConfiguration(); } m_pendingStates = Qt::WindowStates(state); } void QWaylandQtSurface::setWindowPosition(const QPoint &position) { reposition(position.x(), position.y()); } void QWaylandQtSurface::setWindowSize(const QSize &size) { set_size(size.width(), size.height()); } void QWaylandQtSurface::setWindowFlags(Qt::WindowFlags flags) { set_window_flags(flags); } void QWaylandQtSurface::requestWindowStates(Qt::WindowStates states) { change_window_state(states & ~Qt::WindowActive); } bool QWaylandQtSurface::resize(QWaylandInputDevice *inputDevice, Qt::Edges edge) { if (m_capabilities & ZQT_SHELL_SURFACE_V1_CAPABILITIES_INTERACTIVE_RESIZE) { start_system_resize(getSerial(inputDevice), uint(edge)); return true; } return false; } bool QWaylandQtSurface::move(QWaylandInputDevice *inputDevice) { if (m_capabilities & ZQT_SHELL_SURFACE_V1_CAPABILITIES_INTERACTIVE_RESIZE) { start_system_move(getSerial(inputDevice)); return true; } return false; } QMargins QWaylandQtSurface::serverSideFrameMargins() const { return m_frameMargins; } void QWaylandQtSurface::raise() { QtWayland::zqt_shell_surface_v1::raise(); } void QWaylandQtSurface::lower() { QtWayland::zqt_shell_surface_v1::lower(); } } QT_END_NAMESPACE