KWayland

xdgshell_v5.cpp
1 /*
2  SPDX-FileCopyrightText: 2016 Martin Gräßlin <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "../compat/wayland-xdg-shell-v5-client-protocol.h"
7 #include "event_queue.h"
8 #include "output.h"
9 #include "seat.h"
10 #include "surface.h"
11 #include "wayland_pointer_p.h"
12 #include "xdgshell_p.h"
13 
14 namespace KWayland
15 {
16 namespace Client
17 {
18 class XdgShellUnstableV5::Private : public XdgShell::Private
19 {
20 public:
21  void setupV5(xdg_shell *shell) override;
22  void release() override;
23  void destroy() override;
24  bool isValid() const override;
25  XdgShellSurface *getXdgSurface(Surface *surface, QObject *parent) override;
26  XdgShellPopup *getXdgPopup(Surface *surface, Surface *parentSurface, Seat *seat, quint32 serial, const QPoint &parentPos, QObject *parent) override;
27 
28  using XdgShell::Private::operator xdg_wm_base *;
29  using XdgShell::Private::operator zxdg_shell_v6 *;
30  operator xdg_shell *() override
31  {
32  return xdgshellv5;
33  }
34  operator xdg_shell *() const override
35  {
36  return xdgshellv5;
37  }
38 
39  static void pingCallback(void *data, struct xdg_shell *shell, uint32_t serial);
40 
41  WaylandPointer<xdg_shell, zxdg_shell_v5_destroy> xdgshellv5;
42  static const struct zxdg_shell_v5_listener s_shellListener;
43 };
44 
45 const struct zxdg_shell_v5_listener XdgShellUnstableV5::Private::s_shellListener = {
46  pingCallback,
47 };
48 
49 void XdgShellUnstableV5::Private::pingCallback(void *data, struct xdg_shell *shell, uint32_t serial)
50 {
51  Q_UNUSED(data);
52  zxdg_shell_v5_pong(shell, serial);
53 }
54 
55 void XdgShellUnstableV5::Private::setupV5(xdg_shell *shell)
56 {
57  Q_ASSERT(shell);
58  Q_ASSERT(!xdgshellv5);
59  xdgshellv5.setup(shell);
60  zxdg_shell_v5_use_unstable_version(xdgshellv5, 5);
61  zxdg_shell_v5_add_listener(shell, &s_shellListener, this);
62 }
63 
65 {
66  xdgshellv5.release();
67 }
68 
69 void XdgShellUnstableV5::Private::destroy()
70 {
71  xdgshellv5.destroy();
72 }
73 
74 bool XdgShellUnstableV5::Private::isValid() const
75 {
76  return xdgshellv5.isValid();
77 }
78 
79 XdgShellSurface *XdgShellUnstableV5::Private::getXdgSurface(Surface *surface, QObject *parent)
80 {
81  Q_ASSERT(isValid());
82  XdgShellSurface *s = new XdgShellSurfaceUnstableV5(parent);
83  auto w = zxdg_shell_v5_get_xdg_surface(xdgshellv5, *surface);
84  if (queue) {
85  queue->addProxy(w);
86  }
87  s->setup(w);
88  return s;
89 }
90 
91 XdgShellPopup *
92 XdgShellUnstableV5::Private::getXdgPopup(Surface *surface, Surface *parentSurface, Seat *seat, quint32 serial, const QPoint &parentPos, QObject *parent)
93 {
94  Q_ASSERT(isValid());
95  XdgShellPopup *s = new XdgShellPopupUnstableV5(parent);
96  auto w = zxdg_shell_v5_get_xdg_popup(xdgshellv5, *surface, *parentSurface, *seat, serial, parentPos.x(), parentPos.y());
97  if (queue) {
98  queue->addProxy(w);
99  }
100  s->setup(w);
101  return s;
102 }
103 
104 XdgShellUnstableV5::XdgShellUnstableV5(QObject *parent)
105  : XdgShell(new Private, parent)
106 {
107 }
108 
109 XdgShellUnstableV5::~XdgShellUnstableV5() = default;
110 
111 class XdgShellSurfaceUnstableV5::Private : public XdgShellSurface::Private
112 {
113 public:
114  Private(XdgShellSurface *q);
115  WaylandPointer<xdg_surface, zxdg_surface_v5_destroy> xdgsurfacev5;
116 
117  void setupV5(xdg_surface *surface) override;
118  void release() override;
119  void destroy() override;
120  bool isValid() const override;
121 
122  using XdgShellSurface::Private::operator zxdg_surface_v6 *;
123  using XdgShellSurface::Private::operator zxdg_toplevel_v6 *;
124  using XdgShellSurface::Private::operator xdg_toplevel *;
125  operator xdg_surface *() override
126  {
127  return xdgsurfacev5;
128  }
129  operator xdg_surface *() const override
130  {
131  return xdgsurfacev5;
132  }
133 
134  void setTransientFor(XdgShellSurface *parent) override;
135  void setTitle(const QString &title) override;
136  void setAppId(const QByteArray &appId) override;
137  void showWindowMenu(Seat *seat, quint32 serial, qint32 x, qint32 y) override;
138  void move(Seat *seat, quint32 serial) override;
139  void resize(Seat *seat, quint32 serial, Qt::Edges edges) override;
140  void ackConfigure(quint32 serial) override;
141  void setMaximized() override;
142  void unsetMaximized() override;
143  void setFullscreen(Output *output) override;
144  void unsetFullscreen() override;
145  void setMinimized() override;
146  void setMaxSize(const QSize &size) override;
147  void setMinSize(const QSize &size) override;
148 
149 private:
150  static void configureCallback(void *data, xdg_surface *xdg_surface, int32_t width, int32_t height, wl_array *states, uint32_t serial);
151  static void closeCallback(void *data, xdg_surface *xdg_surface);
152 
153  static const struct zxdg_surface_v5_listener s_listener;
154 };
155 
156 const struct zxdg_surface_v5_listener XdgShellSurfaceUnstableV5::Private::s_listener = {configureCallback, closeCallback};
157 
158 void XdgShellSurfaceUnstableV5::Private::configureCallback(void *data,
159  xdg_surface *xdg_surface,
160  int32_t width,
161  int32_t height,
162  wl_array *wlStates,
163  uint32_t serial)
164 {
165  auto s = reinterpret_cast<XdgShellSurfaceUnstableV5::Private *>(data);
166  Q_ASSERT(s->xdgsurfacev5 == xdg_surface);
167  uint32_t *state = reinterpret_cast<uint32_t *>(wlStates->data);
168  size_t numStates = wlStates->size / sizeof(uint32_t);
169  States states;
170  for (size_t i = 0; i < numStates; i++) {
171  switch (state[i]) {
173  states = states | XdgShellSurface::State::Maximized;
174  break;
176  states = states | XdgShellSurface::State::Fullscreen;
177  break;
179  states = states | XdgShellSurface::State::Resizing;
180  break;
182  states = states | XdgShellSurface::State::Activated;
183  break;
184  }
185  }
186  const QSize size = QSize(width, height);
187  Q_EMIT s->q->configureRequested(size, states, serial);
188  if (!size.isNull()) {
189  s->q->setSize(size);
190  }
191 }
192 
193 void XdgShellSurfaceUnstableV5::Private::closeCallback(void *data, xdg_surface *xdg_surface)
194 {
195  auto s = reinterpret_cast<XdgShellSurfaceUnstableV5::Private *>(data);
196  Q_ASSERT(s->xdgsurfacev5 == xdg_surface);
197  Q_EMIT s->q->closeRequested();
198 }
199 
200 XdgShellSurfaceUnstableV5::Private::Private(XdgShellSurface *q)
201  : XdgShellSurface::Private(q)
202 {
203 }
204 
205 void XdgShellSurfaceUnstableV5::Private::setupV5(xdg_surface *surface)
206 {
207  Q_ASSERT(surface);
208  Q_ASSERT(!xdgsurfacev5);
209  xdgsurfacev5.setup(surface);
210  zxdg_surface_v5_add_listener(xdgsurfacev5, &s_listener, this);
211 }
212 
214 {
215  xdgsurfacev5.release();
216 }
217 
218 void XdgShellSurfaceUnstableV5::Private::destroy()
219 {
220  xdgsurfacev5.destroy();
221 }
222 
223 bool XdgShellSurfaceUnstableV5::Private::isValid() const
224 {
225  return xdgsurfacev5.isValid();
226 }
227 
228 void XdgShellSurfaceUnstableV5::Private::setTransientFor(XdgShellSurface *parent)
229 {
230  xdg_surface *parentSurface = nullptr;
231  if (parent) {
232  parentSurface = *parent;
233  }
234  zxdg_surface_v5_set_parent(xdgsurfacev5, parentSurface);
235 }
236 
237 void XdgShellSurfaceUnstableV5::Private::setTitle(const QString &title)
238 {
239  zxdg_surface_v5_set_title(xdgsurfacev5, title.toUtf8().constData());
240 }
241 
242 void XdgShellSurfaceUnstableV5::Private::setAppId(const QByteArray &appId)
243 {
244  zxdg_surface_v5_set_app_id(xdgsurfacev5, appId.constData());
245 }
246 
247 void XdgShellSurfaceUnstableV5::Private::showWindowMenu(Seat *seat, quint32 serial, qint32 x, qint32 y)
248 {
249  zxdg_surface_v5_show_window_menu(xdgsurfacev5, *seat, serial, x, y);
250 }
251 
252 void XdgShellSurfaceUnstableV5::Private::move(Seat *seat, quint32 serial)
253 {
254  zxdg_surface_v5_move(xdgsurfacev5, *seat, serial);
255 }
256 
257 void XdgShellSurfaceUnstableV5::Private::resize(Seat *seat, quint32 serial, Qt::Edges edges)
258 {
259  uint wlEdge = ZXDG_SURFACE_V5_RESIZE_EDGE_NONE;
260  if (edges.testFlag(Qt::TopEdge)) {
261  if (edges.testFlag(Qt::LeftEdge) && ((edges & ~Qt::LeftEdge) == Qt::TopEdge)) {
262  wlEdge = ZXDG_SURFACE_V5_RESIZE_EDGE_TOP_LEFT;
263  } else if (edges.testFlag(Qt::RightEdge) && ((edges & ~Qt::RightEdge) == Qt::TopEdge)) {
264  wlEdge = ZXDG_SURFACE_V5_RESIZE_EDGE_TOP_RIGHT;
265  } else if ((edges & ~Qt::TopEdge) == Qt::Edges()) {
266  wlEdge = ZXDG_SURFACE_V5_RESIZE_EDGE_TOP;
267  }
268  } else if (edges.testFlag(Qt::BottomEdge)) {
269  if (edges.testFlag(Qt::LeftEdge) && ((edges & ~Qt::LeftEdge) == Qt::BottomEdge)) {
270  wlEdge = ZXDG_SURFACE_V5_RESIZE_EDGE_BOTTOM_LEFT;
271  } else if (edges.testFlag(Qt::RightEdge) && ((edges & ~Qt::RightEdge) == Qt::BottomEdge)) {
272  wlEdge = ZXDG_SURFACE_V5_RESIZE_EDGE_BOTTOM_RIGHT;
273  } else if ((edges & ~Qt::BottomEdge) == Qt::Edges()) {
274  wlEdge = ZXDG_SURFACE_V5_RESIZE_EDGE_BOTTOM;
275  }
276  } else if (edges.testFlag(Qt::RightEdge) && ((edges & ~Qt::RightEdge) == Qt::Edges())) {
277  wlEdge = ZXDG_SURFACE_V5_RESIZE_EDGE_RIGHT;
278  } else if (edges.testFlag(Qt::LeftEdge) && ((edges & ~Qt::LeftEdge) == Qt::Edges())) {
279  wlEdge = ZXDG_SURFACE_V5_RESIZE_EDGE_LEFT;
280  }
281  zxdg_surface_v5_resize(xdgsurfacev5, *seat, serial, wlEdge);
282 }
283 
284 void XdgShellSurfaceUnstableV5::Private::ackConfigure(quint32 serial)
285 {
286  zxdg_surface_v5_ack_configure(xdgsurfacev5, serial);
287 }
288 
289 void XdgShellSurfaceUnstableV5::Private::setMaximized()
290 {
291  zxdg_surface_v5_set_maximized(xdgsurfacev5);
292 }
293 
294 void XdgShellSurfaceUnstableV5::Private::unsetMaximized()
295 {
296  zxdg_surface_v5_unset_maximized(xdgsurfacev5);
297 }
298 
299 void XdgShellSurfaceUnstableV5::Private::setFullscreen(Output *output)
300 {
301  wl_output *o = nullptr;
302  if (output) {
303  o = *output;
304  }
305  zxdg_surface_v5_set_fullscreen(xdgsurfacev5, o);
306 }
307 
308 void XdgShellSurfaceUnstableV5::Private::unsetFullscreen()
309 {
310  zxdg_surface_v5_unset_fullscreen(xdgsurfacev5);
311 }
312 
313 void XdgShellSurfaceUnstableV5::Private::setMinimized()
314 {
315  zxdg_surface_v5_set_minimized(xdgsurfacev5);
316 }
317 
318 void XdgShellSurfaceUnstableV5::Private::setMaxSize(const QSize &size)
319 {
320  Q_UNUSED(size)
321  // TODO: notify an error?
322 }
323 
324 void XdgShellSurfaceUnstableV5::Private::setMinSize(const QSize &size)
325 {
326  Q_UNUSED(size)
327  // TODO: notify an error?
328 }
329 
330 XdgShellSurfaceUnstableV5::XdgShellSurfaceUnstableV5(QObject *parent)
331  : XdgShellSurface(new Private(this), parent)
332 {
333 }
334 
335 XdgShellSurfaceUnstableV5::~XdgShellSurfaceUnstableV5() = default;
336 
337 class XdgShellPopupUnstableV5::Private : public XdgShellPopup::Private
338 {
339 public:
340  Private(XdgShellPopup *q);
341 
342  void setupV5(xdg_popup *p) override;
343  void release() override;
344  void destroy() override;
345  bool isValid() const override;
346 
347  using XdgShellPopup::Private::operator xdg_surface *;
348  using XdgShellPopup::Private::operator zxdg_popup_v6 *;
349  using XdgShellPopup::Private::operator zxdg_surface_v6 *;
350  operator xdg_popup *() override
351  {
352  return xdgpopupv5;
353  }
354  operator xdg_popup *() const override
355  {
356  return xdgpopupv5;
357  }
358  WaylandPointer<xdg_popup, zxdg_popup_v5_destroy> xdgpopupv5;
359 
360 private:
361  static void popupDoneCallback(void *data, xdg_popup *xdg_popup);
362  static const struct zxdg_popup_v5_listener s_listener;
363 };
364 
365 const struct zxdg_popup_v5_listener XdgShellPopupUnstableV5::Private::s_listener = {popupDoneCallback};
366 
367 void XdgShellPopupUnstableV5::Private::popupDoneCallback(void *data, xdg_popup *xdg_popup)
368 {
369  auto s = reinterpret_cast<XdgShellPopupUnstableV5::Private *>(data);
370  Q_ASSERT(s->xdgpopupv5 == xdg_popup);
371  Q_EMIT s->q->popupDone();
372 }
373 
374 XdgShellPopupUnstableV5::Private::Private(XdgShellPopup *q)
375  : XdgShellPopup::Private(q)
376 {
377 }
378 
379 void XdgShellPopupUnstableV5::Private::setupV5(xdg_popup *p)
380 {
381  Q_ASSERT(p);
382  Q_ASSERT(!xdgpopupv5);
383  xdgpopupv5.setup(p);
384  zxdg_popup_v5_add_listener(xdgpopupv5, &s_listener, this);
385 }
386 
388 {
389  xdgpopupv5.release();
390 }
391 
392 void XdgShellPopupUnstableV5::Private::destroy()
393 {
394  xdgpopupv5.destroy();
395 }
396 
397 bool XdgShellPopupUnstableV5::Private::isValid() const
398 {
399  return xdgpopupv5.isValid();
400 }
401 
402 XdgShellPopupUnstableV5::XdgShellPopupUnstableV5(QObject *parent)
403  : XdgShellPopup(new Private(this), parent)
404 {
405 }
406 
407 XdgShellPopupUnstableV5::~XdgShellPopupUnstableV5() = default;
408 
409 }
410 }
virtual void release(quint64 objid)
int x() const const
int y() const const
@ ZXDG_SURFACE_V5_STATE_MAXIMIZED
the surface is maximized
QByteArray toUtf8() const const
bool isNull() const const
KIOCORE_EXPORT CopyJob * move(const QList< QUrl > &src, const QUrl &dest, JobFlags flags=DefaultFlags)
const char * constData() const const
@ ZXDG_SURFACE_V5_STATE_RESIZING
the surface is being resized
bool isValid(QStringView ifopt)
@ ZXDG_SURFACE_V5_STATE_FULLSCREEN
the surface is fullscreen
typedef Edges
@ ZXDG_SURFACE_V5_STATE_ACTIVATED
the surface is now activated
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Feb 8 2023 03:59:22 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.