KWayland

xdgshell_stable.cpp
1 /*
2  SPDX-FileCopyrightText: 2017 David Edmundson <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "event_queue.h"
7 #include "output.h"
8 #include "seat.h"
9 #include "surface.h"
10 #include "wayland_pointer_p.h"
11 #include "xdgshell_p.h"
12 #include <wayland-xdg-shell-client-protocol.h>
13 
14 namespace KWayland
15 {
16 namespace Client
17 {
18 class XdgShellStable::Private : public XdgShell::Private
19 {
20 public:
21  void setup(xdg_wm_base *shell) override;
22  void release() override;
23  void destroy() override;
24  bool isValid() const override;
25  XdgShellSurface *getXdgSurface(Surface *surface, QObject *parent) override;
26 
27  XdgShellPopup *getXdgPopup(Surface *surface, XdgShellSurface *parentSurface, const XdgPositioner &positioner, QObject *parent) override;
28  XdgShellPopup *getXdgPopup(Surface *surface, XdgShellPopup *parentSurface, const XdgPositioner &positioner, QObject *parent) override;
29 
30  using XdgShell::Private::operator xdg_shell *;
31  using XdgShell::Private::operator zxdg_shell_v6 *;
32  operator xdg_wm_base *() override
33  {
34  return xdg_shell_base;
35  }
36  operator xdg_wm_base *() const override
37  {
38  return xdg_shell_base;
39  }
40 
41 private:
42  XdgShellPopup *internalGetXdgPopup(Surface *surface, xdg_surface *parentSurface, const XdgPositioner &positioner, QObject *parent);
43  static void pingCallback(void *data, struct xdg_wm_base *shell, uint32_t serial);
44 
45  WaylandPointer<xdg_wm_base, xdg_wm_base_destroy> xdg_shell_base;
46  static const struct xdg_wm_base_listener s_shellListener;
47 };
48 
49 const struct xdg_wm_base_listener XdgShellStable::Private::s_shellListener = {
50  pingCallback,
51 };
52 
53 void XdgShellStable::Private::pingCallback(void *data, struct xdg_wm_base *shell, uint32_t serial)
54 {
55  Q_UNUSED(data)
56  xdg_wm_base_pong(shell, serial);
57 }
58 
59 void XdgShellStable::Private::setup(xdg_wm_base *shell)
60 {
61  Q_ASSERT(shell);
62  Q_ASSERT(!xdg_shell_base);
63  xdg_shell_base.setup(shell);
64  xdg_wm_base_add_listener(shell, &s_shellListener, this);
65 }
66 
68 {
69  xdg_shell_base.release();
70 }
71 
72 void XdgShellStable::Private::destroy()
73 {
74  xdg_shell_base.destroy();
75 }
76 
77 bool XdgShellStable::Private::isValid() const
78 {
79  return xdg_shell_base.isValid();
80 }
81 
82 XdgShellSurface *XdgShellStable::Private::getXdgSurface(Surface *surface, QObject *parent)
83 {
84  Q_ASSERT(isValid());
85  auto ss = xdg_wm_base_get_xdg_surface(xdg_shell_base, *surface);
86 
87  if (!ss) {
88  return nullptr;
89  }
90 
91  auto s = new XdgTopLevelStable(parent);
92  auto toplevel = xdg_surface_get_toplevel(ss);
93  if (queue) {
94  queue->addProxy(ss);
95  queue->addProxy(toplevel);
96  }
97  s->setup(ss, toplevel);
98  return s;
99 }
100 
101 XdgShellPopup *XdgShellStable::Private::getXdgPopup(Surface *surface, XdgShellSurface *parentSurface, const XdgPositioner &positioner, QObject *parent)
102 {
103  return internalGetXdgPopup(surface, *parentSurface, positioner, parent);
104 }
105 
106 XdgShellPopup *XdgShellStable::Private::getXdgPopup(Surface *surface, XdgShellPopup *parentSurface, const XdgPositioner &positioner, QObject *parent)
107 {
108  return internalGetXdgPopup(surface, *parentSurface, positioner, parent);
109 }
110 
111 XdgShellPopup *XdgShellStable::Private::internalGetXdgPopup(Surface *surface, xdg_surface *parentSurface, const XdgPositioner &positioner, QObject *parent)
112 {
113  Q_ASSERT(isValid());
114  auto ss = xdg_wm_base_get_xdg_surface(xdg_shell_base, *surface);
115  if (!ss) {
116  return nullptr;
117  }
118 
119  auto p = xdg_wm_base_create_positioner(xdg_shell_base);
120 
121  auto anchorRect = positioner.anchorRect();
122  xdg_positioner_set_anchor_rect(p, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
123 
124  QSize initialSize = positioner.initialSize();
125  xdg_positioner_set_size(p, initialSize.width(), initialSize.height());
126 
127  QPoint anchorOffset = positioner.anchorOffset();
128  if (!anchorOffset.isNull()) {
129  xdg_positioner_set_offset(p, anchorOffset.x(), anchorOffset.y());
130  }
131 
132  uint32_t anchor = XDG_POSITIONER_ANCHOR_NONE;
133  if (positioner.anchorEdge().testFlag(Qt::TopEdge)) {
134  if (positioner.anchorEdge().testFlag(Qt::LeftEdge) && ((positioner.anchorEdge() & ~Qt::LeftEdge) == Qt::TopEdge)) {
135  anchor = XDG_POSITIONER_ANCHOR_TOP_LEFT;
136  } else if (positioner.anchorEdge().testFlag(Qt::RightEdge) && ((positioner.anchorEdge() & ~Qt::RightEdge) == Qt::TopEdge)) {
137  anchor = XDG_POSITIONER_ANCHOR_TOP_RIGHT;
138  } else if ((positioner.anchorEdge() & ~Qt::TopEdge) == Qt::Edges()) {
139  anchor = XDG_POSITIONER_ANCHOR_TOP;
140  }
141  } else if (positioner.anchorEdge().testFlag(Qt::BottomEdge)) {
142  if (positioner.anchorEdge().testFlag(Qt::LeftEdge) && ((positioner.anchorEdge() & ~Qt::LeftEdge) == Qt::BottomEdge)) {
143  anchor = XDG_POSITIONER_ANCHOR_BOTTOM_LEFT;
144  } else if (positioner.anchorEdge().testFlag(Qt::RightEdge) && ((positioner.anchorEdge() & ~Qt::RightEdge) == Qt::BottomEdge)) {
145  anchor = XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT;
146  } else if ((positioner.anchorEdge() & ~Qt::BottomEdge) == Qt::Edges()) {
147  anchor = XDG_POSITIONER_ANCHOR_BOTTOM;
148  }
149  } else if (positioner.anchorEdge().testFlag(Qt::RightEdge) && ((positioner.anchorEdge() & ~Qt::RightEdge) == Qt::Edges())) {
150  anchor = XDG_POSITIONER_ANCHOR_RIGHT;
151  } else if (positioner.anchorEdge().testFlag(Qt::LeftEdge) && ((positioner.anchorEdge() & ~Qt::LeftEdge) == Qt::Edges())) {
152  anchor = XDG_POSITIONER_ANCHOR_LEFT;
153  }
154  if (anchor != 0) {
155  xdg_positioner_set_anchor(p, anchor);
156  }
157 
158  uint32_t gravity = XDG_POSITIONER_GRAVITY_NONE;
159  if (positioner.gravity().testFlag(Qt::TopEdge)) {
160  if (positioner.gravity().testFlag(Qt::LeftEdge) && ((positioner.gravity() & ~Qt::LeftEdge) == Qt::TopEdge)) {
161  gravity = XDG_POSITIONER_GRAVITY_TOP_LEFT;
162  } else if (positioner.gravity().testFlag(Qt::RightEdge) && ((positioner.gravity() & ~Qt::RightEdge) == Qt::TopEdge)) {
163  gravity = XDG_POSITIONER_GRAVITY_TOP_RIGHT;
164  } else if ((positioner.gravity() & ~Qt::TopEdge) == Qt::Edges()) {
165  gravity = XDG_POSITIONER_GRAVITY_TOP;
166  }
167  } else if (positioner.gravity().testFlag(Qt::BottomEdge)) {
168  if (positioner.gravity().testFlag(Qt::LeftEdge) && ((positioner.gravity() & ~Qt::LeftEdge) == Qt::BottomEdge)) {
169  gravity = XDG_POSITIONER_GRAVITY_BOTTOM_LEFT;
170  } else if (positioner.gravity().testFlag(Qt::RightEdge) && ((positioner.gravity() & ~Qt::RightEdge) == Qt::BottomEdge)) {
171  gravity = XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT;
172  } else if ((positioner.gravity() & ~Qt::BottomEdge) == Qt::Edges()) {
173  gravity = XDG_POSITIONER_GRAVITY_BOTTOM;
174  }
175  } else if (positioner.gravity().testFlag(Qt::RightEdge) && ((positioner.gravity() & ~Qt::RightEdge) == Qt::Edges())) {
176  gravity = XDG_POSITIONER_GRAVITY_RIGHT;
177  } else if (positioner.gravity().testFlag(Qt::LeftEdge) && ((positioner.gravity() & ~Qt::LeftEdge) == Qt::Edges())) {
178  gravity = XDG_POSITIONER_GRAVITY_LEFT;
179  }
180  if (gravity != 0) {
181  xdg_positioner_set_gravity(p, gravity);
182  }
183 
184  uint32_t constraint = XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE;
185  if (positioner.constraints().testFlag(XdgPositioner::Constraint::SlideX)) {
186  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X;
187  }
188  if (positioner.constraints().testFlag(XdgPositioner::Constraint::SlideY)) {
189  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y;
190  }
191  if (positioner.constraints().testFlag(XdgPositioner::Constraint::FlipX)) {
192  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X;
193  }
194  if (positioner.constraints().testFlag(XdgPositioner::Constraint::FlipY)) {
195  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y;
196  }
197  if (positioner.constraints().testFlag(XdgPositioner::Constraint::ResizeX)) {
198  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X;
199  }
200  if (positioner.constraints().testFlag(XdgPositioner::Constraint::ResizeY)) {
201  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y;
202  }
203  if (constraint != 0) {
204  xdg_positioner_set_constraint_adjustment(p, constraint);
205  }
206 
207  XdgShellPopup *s = new XdgShellPopupStable(parent);
208  auto popup = xdg_surface_get_popup(ss, parentSurface, p);
209  if (queue) {
210  // deliberately not adding the positioner because the positioner has no events sent to it
211  queue->addProxy(ss);
212  queue->addProxy(popup);
213  }
214  s->setup(ss, popup);
215 
216  xdg_positioner_destroy(p);
217 
218  return s;
219 }
220 
221 XdgShellStable::XdgShellStable(QObject *parent)
222  : XdgShell(new Private, parent)
223 {
224 }
225 
226 XdgShellStable::~XdgShellStable() = default;
227 
228 // A top level wraps both xdg_surface and xdg_top_level into the public API XdgShelllSurface
229 class XdgTopLevelStable::Private : public XdgShellSurface::Private
230 {
231 public:
232  Private(XdgShellSurface *q);
233  WaylandPointer<xdg_toplevel, xdg_toplevel_destroy> xdgtoplevel;
234  WaylandPointer<xdg_surface, xdg_surface_destroy> xdgsurface;
235 
236  void setup(xdg_surface *surface, xdg_toplevel *toplevel) override;
237  void release() override;
238  void destroy() override;
239  bool isValid() const override;
240 
241  using XdgShellSurface::Private::operator zxdg_toplevel_v6 *;
242  using XdgShellSurface::Private::operator zxdg_surface_v6 *;
243  operator xdg_surface *() override
244  {
245  return xdgsurface;
246  }
247  operator xdg_surface *() const override
248  {
249  return xdgsurface;
250  }
251  operator xdg_toplevel *() override
252  {
253  return xdgtoplevel;
254  }
255  operator xdg_toplevel *() const override
256  {
257  return xdgtoplevel;
258  }
259 
260  void setTransientFor(XdgShellSurface *parent) override;
261  void setTitle(const QString &title) override;
262  void setAppId(const QByteArray &appId) override;
263  void showWindowMenu(Seat *seat, quint32 serial, qint32 x, qint32 y) override;
264  void move(Seat *seat, quint32 serial) override;
265  void resize(Seat *seat, quint32 serial, Qt::Edges edges) override;
266  void ackConfigure(quint32 serial) override;
267  void setMaximized() override;
268  void unsetMaximized() override;
269  void setFullscreen(Output *output) override;
270  void unsetFullscreen() override;
271  void setMinimized() override;
272  void setMaxSize(const QSize &size) override;
273  void setMinSize(const QSize &size) override;
274  void setWindowGeometry(const QRect &windowGeometry) override;
275 
276 private:
277  QSize pendingSize;
278  States pendingState;
279 
280  static void configureCallback(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *state);
281  static void closeCallback(void *data, xdg_toplevel *xdg_toplevel);
282  static void surfaceConfigureCallback(void *data, xdg_surface *xdg_surface, uint32_t serial);
283 
284  static const struct xdg_toplevel_listener s_toplevelListener;
285  static const struct xdg_surface_listener s_surfaceListener;
286 };
287 
288 const struct xdg_toplevel_listener XdgTopLevelStable::Private::s_toplevelListener = {configureCallback, closeCallback};
289 
290 const struct xdg_surface_listener XdgTopLevelStable::Private::s_surfaceListener = {surfaceConfigureCallback};
291 
292 void XdgTopLevelStable::Private::surfaceConfigureCallback(void *data, struct xdg_surface *surface, uint32_t serial)
293 {
294  Q_UNUSED(surface)
295  auto s = static_cast<Private *>(data);
296  s->q->configureRequested(s->pendingSize, s->pendingState, serial);
297  if (!s->pendingSize.isNull()) {
298  s->q->setSize(s->pendingSize);
299  s->pendingSize = QSize();
300  }
301  s->pendingState = {};
302 }
303 
304 void XdgTopLevelStable::Private::configureCallback(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *state)
305 {
306  Q_UNUSED(xdg_toplevel)
307  auto s = static_cast<Private *>(data);
308  States states;
309 
310  uint32_t *statePtr = static_cast<uint32_t *>(state->data);
311  for (size_t i = 0; i < state->size / sizeof(uint32_t); i++) {
312  switch (statePtr[i]) {
313  case XDG_TOPLEVEL_STATE_MAXIMIZED:
314  states = states | XdgShellSurface::State::Maximized;
315  break;
316  case XDG_TOPLEVEL_STATE_FULLSCREEN:
317  states = states | XdgShellSurface::State::Fullscreen;
318  break;
319  case XDG_TOPLEVEL_STATE_RESIZING:
320  states = states | XdgShellSurface::State::Resizing;
321  break;
322  case XDG_TOPLEVEL_STATE_ACTIVATED:
323  states = states | XdgShellSurface::State::Activated;
324  break;
325  }
326  }
327  s->pendingSize = QSize(width, height);
328  s->pendingState = states;
329 }
330 
331 void XdgTopLevelStable::Private::closeCallback(void *data, xdg_toplevel *xdg_toplevel)
332 {
333  auto s = static_cast<XdgTopLevelStable::Private *>(data);
334  Q_ASSERT(s->xdgtoplevel == xdg_toplevel);
335  Q_EMIT s->q->closeRequested();
336 }
337 
338 XdgTopLevelStable::Private::Private(XdgShellSurface *q)
339  : XdgShellSurface::Private(q)
340 {
341 }
342 
343 void XdgTopLevelStable::Private::setup(xdg_surface *surface, xdg_toplevel *topLevel)
344 {
345  Q_ASSERT(surface);
346  Q_ASSERT(!xdgtoplevel);
347  xdgsurface.setup(surface);
348  xdgtoplevel.setup(topLevel);
349  xdg_surface_add_listener(xdgsurface, &s_surfaceListener, this);
350  xdg_toplevel_add_listener(xdgtoplevel, &s_toplevelListener, this);
351 }
352 
354 {
355  xdgtoplevel.release();
356  xdgsurface.release();
357 }
358 
359 void XdgTopLevelStable::Private::destroy()
360 {
361  xdgtoplevel.destroy();
362  xdgsurface.destroy();
363 }
364 
365 bool XdgTopLevelStable::Private::isValid() const
366 {
367  return xdgtoplevel.isValid() && xdgsurface.isValid();
368 }
369 
370 void XdgTopLevelStable::Private::setTransientFor(XdgShellSurface *parent)
371 {
372  xdg_toplevel *parentSurface = nullptr;
373  if (parent) {
374  parentSurface = *parent;
375  }
376  xdg_toplevel_set_parent(xdgtoplevel, parentSurface);
377 }
378 
379 void XdgTopLevelStable::Private::setTitle(const QString &title)
380 {
381  xdg_toplevel_set_title(xdgtoplevel, title.toUtf8().constData());
382 }
383 
384 void XdgTopLevelStable::Private::setAppId(const QByteArray &appId)
385 {
386  xdg_toplevel_set_app_id(xdgtoplevel, appId.constData());
387 }
388 
389 void XdgTopLevelStable::Private::showWindowMenu(Seat *seat, quint32 serial, qint32 x, qint32 y)
390 {
391  xdg_toplevel_show_window_menu(xdgtoplevel, *seat, serial, x, y);
392 }
393 
394 void XdgTopLevelStable::Private::move(Seat *seat, quint32 serial)
395 {
396  xdg_toplevel_move(xdgtoplevel, *seat, serial);
397 }
398 
399 void XdgTopLevelStable::Private::resize(Seat *seat, quint32 serial, Qt::Edges edges)
400 {
401  uint wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
402  if (edges.testFlag(Qt::TopEdge)) {
403  if (edges.testFlag(Qt::LeftEdge) && ((edges & ~Qt::LeftEdge) == Qt::TopEdge)) {
404  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
405  } else if (edges.testFlag(Qt::RightEdge) && ((edges & ~Qt::RightEdge) == Qt::TopEdge)) {
406  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
407  } else if ((edges & ~Qt::TopEdge) == Qt::Edges()) {
408  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
409  }
410  } else if (edges.testFlag(Qt::BottomEdge)) {
411  if (edges.testFlag(Qt::LeftEdge) && ((edges & ~Qt::LeftEdge) == Qt::BottomEdge)) {
412  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
413  } else if (edges.testFlag(Qt::RightEdge) && ((edges & ~Qt::RightEdge) == Qt::BottomEdge)) {
414  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
415  } else if ((edges & ~Qt::BottomEdge) == Qt::Edges()) {
416  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
417  }
418  } else if (edges.testFlag(Qt::RightEdge) && ((edges & ~Qt::RightEdge) == Qt::Edges())) {
419  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
420  } else if (edges.testFlag(Qt::LeftEdge) && ((edges & ~Qt::LeftEdge) == Qt::Edges())) {
421  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
422  }
423  xdg_toplevel_resize(xdgtoplevel, *seat, serial, wlEdge);
424 }
425 
426 void XdgTopLevelStable::Private::ackConfigure(quint32 serial)
427 {
428  xdg_surface_ack_configure(xdgsurface, serial);
429 }
430 
431 void XdgTopLevelStable::Private::setMaximized()
432 {
433  xdg_toplevel_set_maximized(xdgtoplevel);
434 }
435 
436 void XdgTopLevelStable::Private::unsetMaximized()
437 {
438  xdg_toplevel_unset_maximized(xdgtoplevel);
439 }
440 
441 void XdgTopLevelStable::Private::setFullscreen(Output *output)
442 {
443  wl_output *o = nullptr;
444  if (output) {
445  o = *output;
446  }
447  xdg_toplevel_set_fullscreen(xdgtoplevel, o);
448 }
449 
450 void XdgTopLevelStable::Private::unsetFullscreen()
451 {
452  xdg_toplevel_unset_fullscreen(xdgtoplevel);
453 }
454 
455 void XdgTopLevelStable::Private::setMinimized()
456 {
457  xdg_toplevel_set_minimized(xdgtoplevel);
458 }
459 
460 void XdgTopLevelStable::Private::setMaxSize(const QSize &size)
461 {
462  xdg_toplevel_set_max_size(xdgtoplevel, size.width(), size.height());
463 }
464 
465 void XdgTopLevelStable::Private::setMinSize(const QSize &size)
466 {
467  xdg_toplevel_set_min_size(xdgtoplevel, size.width(), size.height());
468 }
469 
470 void XdgTopLevelStable::Private::setWindowGeometry(const QRect &windowGeometry)
471 {
472  xdg_surface_set_window_geometry(xdgsurface, windowGeometry.x(), windowGeometry.y(), windowGeometry.width(), windowGeometry.height());
473 }
474 
475 XdgTopLevelStable::XdgTopLevelStable(QObject *parent)
476  : XdgShellSurface(new Private(this), parent)
477 {
478 }
479 
480 XdgTopLevelStable::~XdgTopLevelStable() = default;
481 
482 class XdgShellPopupStable::Private : public XdgShellPopup::Private
483 {
484 public:
485  Private(XdgShellPopup *q);
486 
487  void setup(xdg_surface *s, xdg_popup *p) override;
488  void release() override;
489  void destroy() override;
490  bool isValid() const override;
491  void requestGrab(Seat *seat, quint32 serial) override;
492  void ackConfigure(quint32 serial) override;
493  void setWindowGeometry(const QRect &windowGeometry) override;
494 
495  using XdgShellPopup::Private::operator zxdg_popup_v6 *;
496  using XdgShellPopup::Private::operator zxdg_surface_v6 *;
497  operator xdg_surface *() override
498  {
499  return xdgsurface;
500  }
501  operator xdg_surface *() const override
502  {
503  return xdgsurface;
504  }
505  operator xdg_popup *() override
506  {
507  return xdgpopup;
508  }
509  operator xdg_popup *() const override
510  {
511  return xdgpopup;
512  }
513  WaylandPointer<xdg_surface, xdg_surface_destroy> xdgsurface;
514  WaylandPointer<xdg_popup, xdg_popup_destroy> xdgpopup;
515 
516  QRect pendingRect;
517 
518 private:
519  static void configureCallback(void *data, xdg_popup *xdg_popup, int32_t x, int32_t y, int32_t width, int32_t height);
520  static void popupDoneCallback(void *data, xdg_popup *xdg_popup);
521  static void surfaceConfigureCallback(void *data, xdg_surface *xdg_surface, uint32_t serial);
522 
523  static const struct xdg_popup_listener s_popupListener;
524  static const struct xdg_surface_listener s_surfaceListener;
525 };
526 
527 const struct xdg_popup_listener XdgShellPopupStable::Private::s_popupListener = {configureCallback, popupDoneCallback};
528 
529 const struct xdg_surface_listener XdgShellPopupStable::Private::s_surfaceListener = {
530  surfaceConfigureCallback,
531 };
532 
533 void XdgShellPopupStable::Private::configureCallback(void *data, xdg_popup *xdg_popup, int32_t x, int32_t y, int32_t width, int32_t height)
534 {
535  Q_UNUSED(xdg_popup)
536  auto s = static_cast<Private *>(data);
537  s->pendingRect = QRect(x, y, width, height);
538 }
539 
540 void XdgShellPopupStable::Private::surfaceConfigureCallback(void *data, struct xdg_surface *surface, uint32_t serial)
541 {
542  Q_UNUSED(surface)
543  auto s = static_cast<Private *>(data);
544  s->q->configureRequested(s->pendingRect, serial);
545  s->pendingRect = QRect();
546 }
547 
548 void XdgShellPopupStable::Private::popupDoneCallback(void *data, xdg_popup *xdg_popup)
549 {
550  auto s = static_cast<XdgShellPopupStable::Private *>(data);
551  Q_ASSERT(s->xdgpopup == xdg_popup);
552  Q_EMIT s->q->popupDone();
553 }
554 
555 XdgShellPopupStable::Private::Private(XdgShellPopup *q)
556  : XdgShellPopup::Private(q)
557 {
558 }
559 
560 void XdgShellPopupStable::Private::setup(xdg_surface *s, xdg_popup *p)
561 {
562  Q_ASSERT(p);
563  Q_ASSERT(!xdgsurface);
564  Q_ASSERT(!xdgpopup);
565 
566  xdgsurface.setup(s);
567  xdgpopup.setup(p);
568  xdg_surface_add_listener(xdgsurface, &s_surfaceListener, this);
569  xdg_popup_add_listener(xdgpopup, &s_popupListener, this);
570 }
571 
573 {
574  xdgpopup.release();
575 }
576 
577 void XdgShellPopupStable::Private::destroy()
578 {
579  xdgpopup.destroy();
580 }
581 
582 bool XdgShellPopupStable::Private::isValid() const
583 {
584  return xdgpopup.isValid();
585 }
586 
587 void XdgShellPopupStable::Private::requestGrab(Seat *seat, quint32 serial)
588 {
589  xdg_popup_grab(xdgpopup, *seat, serial);
590 }
591 
592 void XdgShellPopupStable::Private::ackConfigure(quint32 serial)
593 {
594  xdg_surface_ack_configure(xdgsurface, serial);
595 }
596 
597 void XdgShellPopupStable::Private::setWindowGeometry(const QRect &windowGeometry)
598 {
599  xdg_surface_set_window_geometry(xdgsurface, windowGeometry.x(), windowGeometry.y(), windowGeometry.width(), windowGeometry.height());
600 }
601 
602 XdgShellPopupStable::XdgShellPopupStable(QObject *parent)
603  : XdgShellPopup(new Private(this), parent)
604 {
605 }
606 
607 XdgShellPopupStable::~XdgShellPopupStable() = default;
608 
609 }
610 }
bool isNull() const const
void release()
Releases the xdg_shell interface.
Definition: xdgshell.cpp:46
virtual void release(quint64 objid)
int width() const const
int x() const const
int y() const const
int x() const const
int y() const const
int width() const const
int height() const const
QByteArray toUtf8() const const
void setup(xdg_shell *xdgshellv5)
Setup this XdgShell to manage the xdgshellv5.
Definition: xdgshell.cpp:31
int height() const const
KIOCORE_EXPORT CopyJob * move(const QList< QUrl > &src, const QUrl &dest, JobFlags flags=DefaultFlags)
const char * constData() const const
bool isValid(QStringView ifopt)
void destroy()
Destroys the data held by this XdgShell.
Definition: xdgshell.cpp:51
QObject * parent() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Jan 30 2023 03:56:25 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.