1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qwaylandqtsurface_p.h"
5#include <qpa/qwindowsysteminterface.h>
6#include <qpa/qplatformwindow.h>
7
8QT_BEGIN_NAMESPACE
9
10namespace QtWaylandClient {
11
12QWaylandQtSurface::QWaylandQtSurface(struct ::zqt_shell_surface_v1 *shell_surface, QWaylandWindow *window)
13 : QWaylandShellSurface(window)
14 , QtWayland::zqt_shell_surface_v1(shell_surface)
15{
16 sendSizeHints();
17}
18
19QWaylandQtSurface::~QWaylandQtSurface()
20{
21 zqt_shell_surface_v1::destroy();
22}
23
24void QWaylandQtSurface::resetConfiguration()
25{
26 m_pendingPosition = QPoint(-1, -1);
27 m_pendingSize = QSize();
28 m_pendingPositionValid = false;
29 m_pendingStates = m_currentStates;
30}
31
32void QWaylandQtSurface::applyConfigure()
33{
34 if (m_pendingSize.isValid() && m_pendingPositionValid)
35 setGeometryFromApplyConfigure(globalPosition: m_pendingPosition, sizeWithMargins: m_pendingSize);
36 else if (m_pendingSize.isValid())
37 resizeFromApplyConfigure(sizeWithMargins: m_pendingSize);
38 else if (m_pendingPositionValid)
39 repositionFromApplyConfigure(position: m_pendingPosition);
40
41 if (m_pendingStates != m_currentStates) {
42 QWindowSystemInterface::handleWindowStateChanged(window: platformWindow()->window(), newState: m_pendingStates);
43 m_currentStates = m_pendingStates;
44 }
45
46 ack_configure(m_currentConfigureSerial);
47
48 resetConfiguration();
49 m_currentConfigureSerial = UINT32_MAX;
50}
51
52void QWaylandQtSurface::setTitle(const QString &title)
53{
54 set_window_title(title);
55}
56
57void QWaylandQtSurface::zqt_shell_surface_v1_set_capabilities(uint32_t capabilities)
58{
59 m_capabilities = capabilities;
60}
61
62void QWaylandQtSurface::zqt_shell_surface_v1_set_position(uint32_t serial, int32_t x, int32_t y)
63{
64 if (serial < m_currentConfigureSerial && m_currentConfigureSerial != UINT32_MAX)
65 return;
66
67 if (serial != m_currentConfigureSerial) {
68 m_currentConfigureSerial = serial;
69 resetConfiguration();
70 }
71
72 m_pendingPosition = QPoint(x, y);
73 m_pendingPositionValid = true;
74}
75
76void QWaylandQtSurface::zqt_shell_surface_v1_resize(uint32_t serial, int32_t width, int32_t height)
77{
78 if (serial < m_currentConfigureSerial && m_currentConfigureSerial != UINT32_MAX)
79 return;
80
81 if (serial != m_currentConfigureSerial) {
82 m_currentConfigureSerial = serial;
83 resetConfiguration();
84 }
85
86 m_pendingSize = QSize(width, height);
87}
88
89void QWaylandQtSurface::zqt_shell_surface_v1_configure(uint32_t serial)
90{
91 if (serial < m_currentConfigureSerial)
92 return;
93
94 if (serial > m_currentConfigureSerial) {
95 m_currentConfigureSerial = serial;
96 resetConfiguration();
97 }
98
99 applyConfigureWhenPossible();
100}
101
102void QWaylandQtSurface::zqt_shell_surface_v1_close()
103{
104 platformWindow()->window()->close();
105}
106
107void QWaylandQtSurface::zqt_shell_surface_v1_set_frame_margins(uint32_t left, uint32_t right,
108 uint32_t top, uint32_t bottom)
109{
110 QPlatformWindow *win = platformWindow();
111 m_frameMargins = QMargins(left, top, right, bottom);
112 m_pendingPosition = win->geometry().topLeft();
113 m_pendingPositionValid = true;
114 m_pendingSize = win->geometry().size();
115 applyConfigureWhenPossible();
116}
117
118bool QWaylandQtSurface::requestActivate()
119{
120 request_activate();
121 return true;
122}
123
124void QWaylandQtSurface::propagateSizeHints()
125{
126 sendSizeHints();
127}
128
129void QWaylandQtSurface::sendSizeHints()
130{
131 QPlatformWindow *win = platformWindow();
132 if (win) {
133 const int minWidth = qMax(a: 0, b: win->windowMinimumSize().width());
134 const int minHeight = qMax(a: 0, b: win->windowMinimumSize().height());
135 set_minimum_size(minWidth, minHeight);
136
137 int maxWidth = qMax(a: 0, b: win->windowMaximumSize().width());
138 if (maxWidth == QWINDOWSIZE_MAX)
139 maxWidth = -1;
140 int maxHeight = qMax(a: 0, b: win->windowMaximumSize().height());
141 if (maxHeight == QWINDOWSIZE_MAX)
142 maxHeight = -1;
143 set_maximum_size(maxWidth, maxHeight);
144 }
145}
146
147void QWaylandQtSurface::zqt_shell_surface_v1_set_window_state(uint32_t serial, uint32_t state)
148{
149 if (serial < m_currentConfigureSerial && m_currentConfigureSerial != UINT32_MAX)
150 return;
151
152 if (serial != m_currentConfigureSerial) {
153 m_currentConfigureSerial = serial;
154 resetConfiguration();
155 }
156 m_pendingStates = Qt::WindowStates(state);
157}
158
159void QWaylandQtSurface::setWindowGeometry(const QRect &rect)
160{
161 set_size(rect.width(), rect.height());
162}
163
164void QWaylandQtSurface::setWindowPosition(const QPoint &position)
165{
166 reposition(position.x(), position.y());
167}
168
169void QWaylandQtSurface::setWindowFlags(Qt::WindowFlags flags)
170{
171 set_window_flags(flags);
172}
173
174void QWaylandQtSurface::requestWindowStates(Qt::WindowStates states)
175{
176 change_window_state(states & ~Qt::WindowActive);
177}
178
179bool QWaylandQtSurface::resize(QWaylandInputDevice *inputDevice, Qt::Edges edge)
180{
181 if (m_capabilities & ZQT_SHELL_SURFACE_V1_CAPABILITIES_INTERACTIVE_RESIZE) {
182 start_system_resize(getSerial(inputDevice), uint(edge));
183 return true;
184 }
185
186 return false;
187}
188
189bool QWaylandQtSurface::move(QWaylandInputDevice *inputDevice)
190{
191 if (m_capabilities & ZQT_SHELL_SURFACE_V1_CAPABILITIES_INTERACTIVE_RESIZE) {
192 start_system_move(getSerial(inputDevice));
193 return true;
194 }
195
196 return false;
197}
198
199QMargins QWaylandQtSurface::serverSideFrameMargins() const
200{
201 return m_frameMargins;
202}
203
204void QWaylandQtSurface::raise()
205{
206 QtWayland::zqt_shell_surface_v1::raise();
207}
208
209void QWaylandQtSurface::lower()
210{
211 QtWayland::zqt_shell_surface_v1::lower();
212}
213
214}
215
216QT_END_NAMESPACE
217

source code of qtwayland/src/plugins/shellintegration/qt-shell/qwaylandqtsurface.cpp