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

KDE's Doxygen guidelines are available online.