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 | |
8 | QT_BEGIN_NAMESPACE |
9 | |
10 | namespace QtWaylandClient { |
11 | |
12 | QWaylandQtSurface::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 | |
19 | QWaylandQtSurface::~QWaylandQtSurface() |
20 | { |
21 | zqt_shell_surface_v1::destroy(); |
22 | } |
23 | |
24 | void QWaylandQtSurface::resetConfiguration() |
25 | { |
26 | m_pendingPosition = QPoint(-1, -1); |
27 | m_pendingSize = QSize(); |
28 | m_pendingPositionValid = false; |
29 | m_pendingStates = m_currentStates; |
30 | } |
31 | |
32 | void 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 | |
52 | void QWaylandQtSurface::setTitle(const QString &title) |
53 | { |
54 | set_window_title(title); |
55 | } |
56 | |
57 | void QWaylandQtSurface::zqt_shell_surface_v1_set_capabilities(uint32_t capabilities) |
58 | { |
59 | m_capabilities = capabilities; |
60 | } |
61 | |
62 | void 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 | |
76 | void 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 | |
89 | void 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 | |
102 | void QWaylandQtSurface::zqt_shell_surface_v1_close() |
103 | { |
104 | platformWindow()->window()->close(); |
105 | } |
106 | |
107 | void 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 | |
118 | bool QWaylandQtSurface::requestActivate() |
119 | { |
120 | request_activate(); |
121 | return true; |
122 | } |
123 | |
124 | void QWaylandQtSurface::propagateSizeHints() |
125 | { |
126 | sendSizeHints(); |
127 | } |
128 | |
129 | void 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 | |
147 | void 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 | |
159 | void QWaylandQtSurface::setWindowGeometry(const QRect &rect) |
160 | { |
161 | set_size(rect.width(), rect.height()); |
162 | } |
163 | |
164 | void QWaylandQtSurface::setWindowPosition(const QPoint &position) |
165 | { |
166 | reposition(position.x(), position.y()); |
167 | } |
168 | |
169 | void QWaylandQtSurface::setWindowFlags(Qt::WindowFlags flags) |
170 | { |
171 | set_window_flags(flags); |
172 | } |
173 | |
174 | void QWaylandQtSurface::requestWindowStates(Qt::WindowStates states) |
175 | { |
176 | change_window_state(states & ~Qt::WindowActive); |
177 | } |
178 | |
179 | bool 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 | |
189 | bool 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 | |
199 | QMargins QWaylandQtSurface::serverSideFrameMargins() const |
200 | { |
201 | return m_frameMargins; |
202 | } |
203 | |
204 | void QWaylandQtSurface::raise() |
205 | { |
206 | QtWayland::zqt_shell_surface_v1::raise(); |
207 | } |
208 | |
209 | void QWaylandQtSurface::lower() |
210 | { |
211 | QtWayland::zqt_shell_surface_v1::lower(); |
212 | } |
213 | |
214 | } |
215 | |
216 | QT_END_NAMESPACE |
217 | |