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 "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 <wayland-xdg-shell-client-protocol.h>
13 
14 namespace KWayland
15 {
16 namespace Client
17 {
18 
19 class XdgShellStable::Private : public XdgShell::Private
20 {
21 public:
22  void setup(xdg_wm_base *shell) override;
23  void release() override;
24  void destroy() override;
25  bool isValid() const override;
26  XdgShellSurface *getXdgSurface(Surface *surface, QObject *parent) override;
27 
28  XdgShellPopup *getXdgPopup(Surface *surface, XdgShellSurface *parentSurface, const XdgPositioner &positioner, QObject *parent) override;
29  XdgShellPopup *getXdgPopup(Surface *surface, XdgShellPopup *parentSurface, const XdgPositioner &positioner, QObject *parent) override;
30 
31  using XdgShell::Private::operator xdg_shell*;
32  using XdgShell::Private::operator zxdg_shell_v6*;
33  operator xdg_wm_base*() override {
34  return xdg_shell_base;
35  }
36  operator xdg_wm_base*() const override {
37  return xdg_shell_base;
38  }
39 
40 private:
41  XdgShellPopup *internalGetXdgPopup(Surface *surface, xdg_surface *parentSurface, const XdgPositioner &positioner, QObject *parent);
42  static void pingCallback(void *data, struct xdg_wm_base *shell, uint32_t serial);
43 
44  WaylandPointer<xdg_wm_base, xdg_wm_base_destroy> xdg_shell_base;
45  static const struct xdg_wm_base_listener s_shellListener;
46 };
47 
48 const struct xdg_wm_base_listener XdgShellStable::Private::s_shellListener = {
49  pingCallback,
50 };
51 
52 void XdgShellStable::Private::pingCallback(void *data, struct xdg_wm_base *shell, uint32_t serial)
53 {
54  Q_UNUSED(data)
55  xdg_wm_base_pong(shell, serial);
56 }
57 
58 void XdgShellStable::Private::setup(xdg_wm_base *shell)
59 {
60  Q_ASSERT(shell);
61  Q_ASSERT(!xdg_shell_base);
62  xdg_shell_base.setup(shell);
63  xdg_wm_base_add_listener(shell, &s_shellListener, this);
64 }
65 
66 void XdgShellStable::Private::release()
67 {
68  xdg_shell_base.release();
69 }
70 
71 void XdgShellStable::Private::destroy()
72 {
73  xdg_shell_base.destroy();
74 }
75 
76 bool XdgShellStable::Private::isValid() const
77 {
78  return xdg_shell_base.isValid();
79 }
80 
81 XdgShellSurface *XdgShellStable::Private::getXdgSurface(Surface *surface, QObject *parent)
82 {
83  Q_ASSERT(isValid());
84  auto ss = xdg_wm_base_get_xdg_surface(xdg_shell_base, *surface);
85 
86  if (!ss) {
87  return nullptr;
88  }
89 
90  auto s = new XdgTopLevelStable(parent);
91  auto toplevel = xdg_surface_get_toplevel(ss);
92  if (queue) {
93  queue->addProxy(ss);
94  queue->addProxy(toplevel);
95  }
96  s->setup(ss, toplevel);
97  return s;
98 }
99 
100 XdgShellPopup *XdgShellStable::Private::getXdgPopup(Surface *surface, XdgShellSurface *parentSurface, const XdgPositioner &positioner, QObject *parent)
101 {
102  return internalGetXdgPopup(surface, *parentSurface, positioner, parent);
103 }
104 
105 XdgShellPopup *XdgShellStable::Private::getXdgPopup(Surface *surface, XdgShellPopup *parentSurface, const XdgPositioner &positioner, QObject *parent)
106 {
107  return internalGetXdgPopup(surface, *parentSurface, positioner, parent);
108 }
109 
110 XdgShellPopup *XdgShellStable::Private::internalGetXdgPopup(Surface *surface, xdg_surface *parentSurface, const XdgPositioner &positioner, QObject *parent)
111 {
112  Q_ASSERT(isValid());
113  auto ss = xdg_wm_base_get_xdg_surface(xdg_shell_base, *surface);
114  if (!ss) {
115  return nullptr;
116  }
117 
118  auto p = xdg_wm_base_create_positioner(xdg_shell_base);
119 
120  auto anchorRect = positioner.anchorRect();
121  xdg_positioner_set_anchor_rect(p, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
122 
123  QSize initialSize = positioner.initialSize();
124  xdg_positioner_set_size(p, initialSize.width(), initialSize.height());
125 
126  QPoint anchorOffset = positioner.anchorOffset();
127  if (!anchorOffset.isNull()) {
128  xdg_positioner_set_offset(p, anchorOffset.x(), anchorOffset.y());
129  }
130 
131  uint32_t anchor = XDG_POSITIONER_ANCHOR_NONE;
132  if (positioner.anchorEdge().testFlag(Qt::TopEdge)) {
133  if (positioner.anchorEdge().testFlag(Qt::LeftEdge) && ((positioner.anchorEdge() & ~Qt::LeftEdge) == Qt::TopEdge)) {
134  anchor = XDG_POSITIONER_ANCHOR_TOP_LEFT;
135  } else if (positioner.anchorEdge().testFlag(Qt::RightEdge) && ((positioner.anchorEdge() & ~Qt::RightEdge) == Qt::TopEdge)) {
136  anchor = XDG_POSITIONER_ANCHOR_TOP_RIGHT;
137  } else if ((positioner.anchorEdge() & ~Qt::TopEdge) == Qt::Edges()) {
138  anchor = XDG_POSITIONER_ANCHOR_TOP;
139  }
140  } else if (positioner.anchorEdge().testFlag(Qt::BottomEdge)) {
141  if (positioner.anchorEdge().testFlag(Qt::LeftEdge) && ((positioner.anchorEdge() & ~Qt::LeftEdge) == Qt::BottomEdge)) {
142  anchor = XDG_POSITIONER_ANCHOR_BOTTOM_LEFT;
143  } else if (positioner.anchorEdge().testFlag(Qt::RightEdge) && ((positioner.anchorEdge() & ~Qt::RightEdge) == Qt::BottomEdge)) {
144  anchor = XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT;
145  } else if ((positioner.anchorEdge() & ~Qt::BottomEdge) == Qt::Edges()) {
146  anchor = XDG_POSITIONER_ANCHOR_BOTTOM;
147  }
148  } else if (positioner.anchorEdge().testFlag(Qt::RightEdge) && ((positioner.anchorEdge() & ~Qt::RightEdge) == Qt::Edges())) {
149  anchor = XDG_POSITIONER_ANCHOR_RIGHT;
150  } else if (positioner.anchorEdge().testFlag(Qt::LeftEdge) && ((positioner.anchorEdge() & ~Qt::LeftEdge) == Qt::Edges())) {
151  anchor = XDG_POSITIONER_ANCHOR_LEFT;
152  }
153  if (anchor != 0) {
154  xdg_positioner_set_anchor(p, anchor);
155  }
156 
157  uint32_t gravity = XDG_POSITIONER_GRAVITY_NONE;
158  if (positioner.gravity().testFlag(Qt::TopEdge)) {
159  if (positioner.gravity().testFlag(Qt::LeftEdge) && ((positioner.gravity() & ~Qt::LeftEdge) == Qt::TopEdge)) {
160  gravity = XDG_POSITIONER_GRAVITY_TOP_LEFT;
161  } else if (positioner.gravity().testFlag(Qt::RightEdge) && ((positioner.gravity() & ~Qt::RightEdge) == Qt::TopEdge)) {
162  gravity = XDG_POSITIONER_GRAVITY_TOP_RIGHT;
163  } else if ((positioner.gravity() & ~Qt::TopEdge) == Qt::Edges()) {
164  gravity = XDG_POSITIONER_GRAVITY_TOP;
165  }
166  } else if (positioner.gravity().testFlag(Qt::BottomEdge)) {
167  if (positioner.gravity().testFlag(Qt::LeftEdge) && ((positioner.gravity() & ~Qt::LeftEdge) == Qt::BottomEdge)) {
168  gravity = XDG_POSITIONER_GRAVITY_BOTTOM_LEFT;
169  } else if (positioner.gravity().testFlag(Qt::RightEdge) && ((positioner.gravity() & ~Qt::RightEdge) == Qt::BottomEdge)) {
170  gravity = XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT;
171  } else if ((positioner.gravity() & ~Qt::BottomEdge) == Qt::Edges()) {
172  gravity = XDG_POSITIONER_GRAVITY_BOTTOM;
173  }
174  } else if (positioner.gravity().testFlag(Qt::RightEdge) && ((positioner.gravity() & ~Qt::RightEdge) == Qt::Edges())) {
175  gravity = XDG_POSITIONER_GRAVITY_RIGHT;
176  } else if (positioner.gravity().testFlag(Qt::LeftEdge) && ((positioner.gravity() & ~Qt::LeftEdge) == Qt::Edges())) {
177  gravity = XDG_POSITIONER_GRAVITY_LEFT;
178  }
179  if (gravity != 0) {
180  xdg_positioner_set_gravity(p, gravity);
181  }
182 
183  uint32_t constraint = XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE;
184  if (positioner.constraints().testFlag(XdgPositioner::Constraint::SlideX)) {
185  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X;
186  }
187  if (positioner.constraints().testFlag(XdgPositioner::Constraint::SlideY)) {
188  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y;
189  }
190  if (positioner.constraints().testFlag(XdgPositioner::Constraint::FlipX)) {
191  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X;
192  }
193  if (positioner.constraints().testFlag(XdgPositioner::Constraint::FlipY)) {
194  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y;
195  }
196  if (positioner.constraints().testFlag(XdgPositioner::Constraint::ResizeX)) {
197  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X;
198  }
199  if (positioner.constraints().testFlag(XdgPositioner::Constraint::ResizeY)) {
200  constraint |= XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y;
201  }
202  if (constraint != 0) {
203  xdg_positioner_set_constraint_adjustment(p, constraint);
204  }
205 
206  XdgShellPopup *s = new XdgShellPopupStable(parent);
207  auto popup = xdg_surface_get_popup(ss, parentSurface, p);
208  if (queue) {
209  //deliberately not adding the positioner because the positioner has no events sent to it
210  queue->addProxy(ss);
211  queue->addProxy(popup);
212  }
213  s->setup(ss, popup);
214 
215  xdg_positioner_destroy(p);
216 
217  return s;
218 }
219 
220 XdgShellStable::XdgShellStable(QObject *parent)
221  : XdgShell(new Private, parent)
222 {
223 }
224 
225 XdgShellStable::~XdgShellStable() = default;
226 
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  return xdgsurface;
245  }
246  operator xdg_surface*() const override {
247  return xdgsurface;
248  }
249  operator xdg_toplevel*() override {
250  return xdgtoplevel;
251  }
252  operator xdg_toplevel*() const override {
253  return xdgtoplevel;
254  }
255 
256  void setTransientFor(XdgShellSurface *parent) override;
257  void setTitle(const QString &title) override;
258  void setAppId(const QByteArray &appId) override;
259  void showWindowMenu(Seat *seat, quint32 serial, qint32 x, qint32 y) override;
260  void move(Seat *seat, quint32 serial) override;
261  void resize(Seat *seat, quint32 serial, Qt::Edges edges) override;
262  void ackConfigure(quint32 serial) override;
263  void setMaximized() override;
264  void unsetMaximized() override;
265  void setFullscreen(Output *output) override;
266  void unsetFullscreen() override;
267  void setMinimized() override;
268  void setMaxSize(const QSize &size) override;
269  void setMinSize(const QSize &size) override;
270  void setWindowGeometry(const QRect &windowGeometry) override;
271 
272 private:
273  QSize pendingSize;
274  States pendingState;
275 
276  static void configureCallback(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *state);
277  static void closeCallback(void *data, xdg_toplevel *xdg_toplevel);
278  static void surfaceConfigureCallback(void *data, xdg_surface *xdg_surface, uint32_t serial);
279 
280  static const struct xdg_toplevel_listener s_toplevelListener;
281  static const struct xdg_surface_listener s_surfaceListener;
282 };
283 
284 const struct xdg_toplevel_listener XdgTopLevelStable::Private::s_toplevelListener = {
285  configureCallback,
286  closeCallback
287 };
288 
289 const struct xdg_surface_listener XdgTopLevelStable::Private::s_surfaceListener = {
290  surfaceConfigureCallback
291 };
292 
293 void XdgTopLevelStable::Private::surfaceConfigureCallback(void *data, struct xdg_surface *surface, uint32_t serial)
294 {
295  Q_UNUSED(surface)
296  auto s = static_cast<Private*>(data);
297  s->q->configureRequested(s->pendingSize, s->pendingState, serial);
298  if (!s->pendingSize.isNull()) {
299  s->q->setSize(s->pendingSize);
300  s->pendingSize = QSize();
301  }
302  s->pendingState = {};
303 }
304 
305 void XdgTopLevelStable::Private::configureCallback(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *state)
306 {
307  Q_UNUSED(xdg_toplevel)
308  auto s = static_cast<Private*>(data);
309  States states;
310 
311  uint32_t *statePtr = static_cast<uint32_t *>(state->data);
312  for (size_t i = 0; i < state->size / sizeof(uint32_t); i++) {
313  switch (statePtr[i]) {
314  case XDG_TOPLEVEL_STATE_MAXIMIZED:
315  states = states | XdgShellSurface::State::Maximized;
316  break;
317  case XDG_TOPLEVEL_STATE_FULLSCREEN:
318  states = states | XdgShellSurface::State::Fullscreen;
319  break;
320  case XDG_TOPLEVEL_STATE_RESIZING:
321  states = states | XdgShellSurface::State::Resizing;
322  break;
323  case XDG_TOPLEVEL_STATE_ACTIVATED:
324  states = states | XdgShellSurface::State::Activated;
325  break;
326  }
327  }
328  s->pendingSize = QSize(width, height);
329  s->pendingState = states;
330 }
331 
332 void XdgTopLevelStable::Private::closeCallback(void *data, xdg_toplevel *xdg_toplevel)
333 {
334  auto s = static_cast<XdgTopLevelStable::Private*>(data);
335  Q_ASSERT(s->xdgtoplevel == xdg_toplevel);
336  emit s->q->closeRequested();
337 }
338 
339 XdgTopLevelStable::Private::Private(XdgShellSurface *q)
340  : XdgShellSurface::Private(q)
341 {
342 }
343 
344 void XdgTopLevelStable::Private::setup(xdg_surface *surface, xdg_toplevel *topLevel)
345 {
346  Q_ASSERT(surface);
347  Q_ASSERT(!xdgtoplevel);
348  xdgsurface.setup(surface);
349  xdgtoplevel.setup(topLevel);
350  xdg_surface_add_listener(xdgsurface, &s_surfaceListener, this);
351  xdg_toplevel_add_listener(xdgtoplevel, &s_toplevelListener, this);
352 }
353 
354 void XdgTopLevelStable::Private::release()
355 {
356  xdgtoplevel.release();
357  xdgsurface.release();
358 }
359 
360 void XdgTopLevelStable::Private::destroy()
361 {
362  xdgtoplevel.destroy();
363  xdgsurface.destroy();
364 }
365 
366 bool XdgTopLevelStable::Private::isValid() const
367 {
368  return xdgtoplevel.isValid() && xdgsurface.isValid();
369 }
370 
371 void XdgTopLevelStable::Private::setTransientFor(XdgShellSurface *parent)
372 {
373  xdg_toplevel *parentSurface = nullptr;
374  if (parent) {
375  parentSurface = *parent;
376  }
377  xdg_toplevel_set_parent(xdgtoplevel, parentSurface);
378 }
379 
380 void XdgTopLevelStable::Private::setTitle(const QString & title)
381 {
382  xdg_toplevel_set_title(xdgtoplevel, title.toUtf8().constData());
383 }
384 
385 void XdgTopLevelStable::Private::setAppId(const QByteArray & appId)
386 {
387  xdg_toplevel_set_app_id(xdgtoplevel, appId.constData());
388 }
389 
390 void XdgTopLevelStable::Private::showWindowMenu(Seat *seat, quint32 serial, qint32 x, qint32 y)
391 {
392  xdg_toplevel_show_window_menu(xdgtoplevel, *seat, serial, x, y);
393 }
394 
395 void XdgTopLevelStable::Private::move(Seat *seat, quint32 serial)
396 {
397  xdg_toplevel_move(xdgtoplevel, *seat, serial);
398 }
399 
400 void XdgTopLevelStable::Private::resize(Seat *seat, quint32 serial, Qt::Edges edges)
401 {
402  uint wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
403  if (edges.testFlag(Qt::TopEdge)) {
404  if (edges.testFlag(Qt::LeftEdge) && ((edges & ~Qt::LeftEdge) == Qt::TopEdge)) {
405  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
406  } else if (edges.testFlag(Qt::RightEdge) && ((edges & ~Qt::RightEdge) == Qt::TopEdge)) {
407  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
408  } else if ((edges & ~Qt::TopEdge) == Qt::Edges()) {
409  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
410  }
411  } else if (edges.testFlag(Qt::BottomEdge)) {
412  if (edges.testFlag(Qt::LeftEdge) && ((edges & ~Qt::LeftEdge) == Qt::BottomEdge)) {
413  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
414  } else if (edges.testFlag(Qt::RightEdge) && ((edges & ~Qt::RightEdge) == Qt::BottomEdge)) {
415  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
416  } else if ((edges & ~Qt::BottomEdge) == Qt::Edges()) {
417  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
418  }
419  } else if (edges.testFlag(Qt::RightEdge) && ((edges & ~Qt::RightEdge) == Qt::Edges())) {
420  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
421  } else if (edges.testFlag(Qt::LeftEdge) && ((edges & ~Qt::LeftEdge) == Qt::Edges())) {
422  wlEdge = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
423  }
424  xdg_toplevel_resize(xdgtoplevel, *seat, serial, wlEdge);
425 }
426 
427 void XdgTopLevelStable::Private::ackConfigure(quint32 serial)
428 {
429  xdg_surface_ack_configure(xdgsurface, serial);
430 }
431 
432 void XdgTopLevelStable::Private::setMaximized()
433 {
434  xdg_toplevel_set_maximized(xdgtoplevel);
435 }
436 
437 void XdgTopLevelStable::Private::unsetMaximized()
438 {
439  xdg_toplevel_unset_maximized(xdgtoplevel);
440 }
441 
442 void XdgTopLevelStable::Private::setFullscreen(Output *output)
443 {
444  wl_output *o = nullptr;
445  if (output) {
446  o = *output;
447  }
448  xdg_toplevel_set_fullscreen(xdgtoplevel, o);
449 }
450 
451 void XdgTopLevelStable::Private::unsetFullscreen()
452 {
453  xdg_toplevel_unset_fullscreen(xdgtoplevel);
454 }
455 
456 void XdgTopLevelStable::Private::setMinimized()
457 {
458  xdg_toplevel_set_minimized(xdgtoplevel);
459 }
460 
461 void XdgTopLevelStable::Private::setMaxSize(const QSize &size)
462 {
463  xdg_toplevel_set_max_size(xdgtoplevel, size.width(), size.height());
464 }
465 
466 void XdgTopLevelStable::Private::setMinSize(const QSize &size)
467 {
468  xdg_toplevel_set_min_size(xdgtoplevel, size.width(), size.height());
469 }
470 
471 void XdgTopLevelStable::Private::setWindowGeometry(const QRect &windowGeometry)
472 {
473  xdg_surface_set_window_geometry(xdgsurface, windowGeometry.x(), windowGeometry.y(), windowGeometry.width(), windowGeometry.height());
474 }
475 
476 XdgTopLevelStable::XdgTopLevelStable(QObject *parent)
477  : XdgShellSurface(new Private(this), parent)
478 {
479 }
480 
481 XdgTopLevelStable::~XdgTopLevelStable() = default;
482 
483 class XdgShellPopupStable::Private : public XdgShellPopup::Private
484 {
485 public:
486  Private(XdgShellPopup *q);
487 
488  void setup(xdg_surface *s, xdg_popup *p) override;
489  void release() override;
490  void destroy() override;
491  bool isValid() const override;
492  void requestGrab(Seat *seat, quint32 serial) override;
493  void ackConfigure(quint32 serial) override;
494  void setWindowGeometry(const QRect &windowGeometry) override;
495 
496  using XdgShellPopup::Private::operator zxdg_popup_v6*;
497  using XdgShellPopup::Private::operator zxdg_surface_v6*;
498  operator xdg_surface*() override {
499  return xdgsurface;
500  }
501  operator xdg_surface*() const override {
502  return xdgsurface;
503  }
504  operator xdg_popup*() override {
505  return xdgpopup;
506  }
507  operator xdg_popup*() const override {
508  return xdgpopup;
509  }
510  WaylandPointer<xdg_surface, xdg_surface_destroy> xdgsurface;
511  WaylandPointer<xdg_popup, xdg_popup_destroy> xdgpopup;
512 
513  QRect pendingRect;
514 
515 private:
516  static void configureCallback(void *data, xdg_popup *xdg_popup, int32_t x, int32_t y, int32_t width, int32_t height);
517  static void popupDoneCallback(void *data, xdg_popup *xdg_popup);
518  static void surfaceConfigureCallback(void *data, xdg_surface *xdg_surface, uint32_t serial);
519 
520  static const struct xdg_popup_listener s_popupListener;
521  static const struct xdg_surface_listener s_surfaceListener;
522 };
523 
524 const struct xdg_popup_listener XdgShellPopupStable::Private::s_popupListener = {
525  configureCallback,
526  popupDoneCallback
527 };
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  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 
572 void XdgShellPopupStable::Private::release()
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 }
int width() const const
int height() const const
int x() const const
int y() const const
const char * constData() const const
QRect windowGeometry() const
windowGeometryChanged
int width() const const
int height() 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.