6 #include "event_queue.h"
10 #include "wayland_pointer_p.h"
11 #include "xdgshell_p.h"
12 #include <wayland-xdg-shell-v6-client-protocol.h>
20 class XdgShellUnstableV6::Private :
public XdgShell::Private
23 void setupV6(zxdg_shell_v6 *shell)
override;
25 void destroy()
override;
27 XdgShellSurface *getXdgSurface(Surface *surface,
QObject *parent)
override;
29 XdgShellPopup *getXdgPopup(Surface *surface, XdgShellSurface *parentSurface,
const XdgPositioner &positioner,
QObject *parent)
override;
30 XdgShellPopup *getXdgPopup(Surface *surface, XdgShellPopup *parentSurface,
const XdgPositioner &positioner,
QObject *parent)
override;
32 using XdgShell::Private::operator xdg_wm_base *;
33 using XdgShell::Private::operator xdg_shell *;
34 operator zxdg_shell_v6 *()
override
38 operator zxdg_shell_v6 *()
const override
44 XdgShellPopup *internalGetXdgPopup(Surface *surface, zxdg_surface_v6 *parentSurface,
const XdgPositioner &positioner,
QObject *parent);
45 static void pingCallback(
void *data,
struct zxdg_shell_v6 *shell, uint32_t serial);
47 WaylandPointer<zxdg_shell_v6, zxdg_shell_v6_destroy> xdgshellv6;
48 static const struct zxdg_shell_v6_listener s_shellListener;
51 const struct zxdg_shell_v6_listener XdgShellUnstableV6::Private::s_shellListener = {
55 void XdgShellUnstableV6::Private::pingCallback(
void *data,
struct zxdg_shell_v6 *shell, uint32_t serial)
58 zxdg_shell_v6_pong(shell, serial);
61 void XdgShellUnstableV6::Private::setupV6(zxdg_shell_v6 *shell)
64 Q_ASSERT(!xdgshellv6);
65 xdgshellv6.setup(shell);
66 zxdg_shell_v6_add_listener(shell, &s_shellListener,
this);
74 void XdgShellUnstableV6::Private::destroy()
79 bool XdgShellUnstableV6::Private::isValid()
const
81 return xdgshellv6.isValid();
84 XdgShellSurface *XdgShellUnstableV6::Private::getXdgSurface(Surface *surface,
QObject *parent)
87 auto ss = zxdg_shell_v6_get_xdg_surface(xdgshellv6, *surface);
93 auto s =
new XdgTopLevelUnstableV6(parent);
94 auto toplevel = zxdg_surface_v6_get_toplevel(ss);
97 queue->addProxy(toplevel);
99 s->setup(ss, toplevel);
103 XdgShellPopup *XdgShellUnstableV6::Private::getXdgPopup(Surface *surface, XdgShellSurface *parentSurface,
const XdgPositioner &positioner,
QObject *parent)
105 return internalGetXdgPopup(surface, *parentSurface, positioner, parent);
108 XdgShellPopup *XdgShellUnstableV6::Private::getXdgPopup(Surface *surface, XdgShellPopup *parentSurface,
const XdgPositioner &positioner,
QObject *parent)
110 return internalGetXdgPopup(surface, *parentSurface, positioner, parent);
114 XdgShellUnstableV6::Private::internalGetXdgPopup(Surface *surface, zxdg_surface_v6 *parentSurface,
const XdgPositioner &positioner,
QObject *parent)
117 auto ss = zxdg_shell_v6_get_xdg_surface(xdgshellv6, *surface);
122 auto p = zxdg_shell_v6_create_positioner(xdgshellv6);
124 auto anchorRect = positioner.anchorRect();
125 zxdg_positioner_v6_set_anchor_rect(p, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height());
127 QSize initialSize = positioner.initialSize();
128 zxdg_positioner_v6_set_size(p, initialSize.
width(), initialSize.
height());
130 QPoint anchorOffset = positioner.anchorOffset();
131 if (!anchorOffset.
isNull()) {
132 zxdg_positioner_v6_set_offset(p, anchorOffset.
x(), anchorOffset.
y());
137 anchor |= ZXDG_POSITIONER_V6_ANCHOR_LEFT;
139 if (positioner.anchorEdge().testFlag(
Qt::TopEdge)) {
140 anchor |= ZXDG_POSITIONER_V6_ANCHOR_TOP;
143 anchor |= ZXDG_POSITIONER_V6_ANCHOR_RIGHT;
146 anchor |= ZXDG_POSITIONER_V6_ANCHOR_BOTTOM;
149 zxdg_positioner_v6_set_anchor(p, anchor);
152 uint32_t gravity = 0;
154 gravity |= ZXDG_POSITIONER_V6_GRAVITY_LEFT;
157 gravity |= ZXDG_POSITIONER_V6_GRAVITY_TOP;
160 gravity |= ZXDG_POSITIONER_V6_GRAVITY_RIGHT;
163 gravity |= ZXDG_POSITIONER_V6_GRAVITY_BOTTOM;
166 zxdg_positioner_v6_set_gravity(p, gravity);
169 uint32_t constraint = 0;
171 if (positioner.constraints().testFlag(XdgPositioner::Constraint::SlideX)) {
172 constraint |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_X;
174 if (positioner.constraints().testFlag(XdgPositioner::Constraint::SlideY)) {
175 constraint |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_SLIDE_Y;
177 if (positioner.constraints().testFlag(XdgPositioner::Constraint::FlipX)) {
178 constraint |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_X;
180 if (positioner.constraints().testFlag(XdgPositioner::Constraint::FlipY)) {
181 constraint |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_FLIP_Y;
183 if (positioner.constraints().testFlag(XdgPositioner::Constraint::ResizeX)) {
184 constraint |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_X;
186 if (positioner.constraints().testFlag(XdgPositioner::Constraint::ResizeY)) {
187 constraint |= ZXDG_POSITIONER_V6_CONSTRAINT_ADJUSTMENT_RESIZE_Y;
189 if (constraint != 0) {
190 zxdg_positioner_v6_set_constraint_adjustment(p, constraint);
193 XdgShellPopup *s =
new XdgShellPopupUnstableV6(parent);
194 auto popup = zxdg_surface_v6_get_popup(ss, parentSurface, p);
198 queue->addProxy(popup);
202 zxdg_positioner_v6_destroy(p);
207 XdgShellUnstableV6::XdgShellUnstableV6(
QObject *parent)
208 : XdgShell(new Private, parent)
212 XdgShellUnstableV6::~XdgShellUnstableV6() =
default;
215 class XdgTopLevelUnstableV6::Private :
public XdgShellSurface::Private
218 Private(XdgShellSurface *q);
219 WaylandPointer<zxdg_toplevel_v6, zxdg_toplevel_v6_destroy> xdgtoplevelv6;
220 WaylandPointer<zxdg_surface_v6, zxdg_surface_v6_destroy> xdgsurfacev6;
222 void setupV6(zxdg_surface_v6 *surface, zxdg_toplevel_v6 *toplevel)
override;
224 void destroy()
override;
227 using XdgShellSurface::Private::operator xdg_surface *;
228 using XdgShellSurface::Private::operator xdg_toplevel *;
229 operator zxdg_surface_v6 *()
override
233 operator zxdg_surface_v6 *()
const override
237 operator zxdg_toplevel_v6 *()
override
239 return xdgtoplevelv6;
241 operator zxdg_toplevel_v6 *()
const override
243 return xdgtoplevelv6;
246 void setTransientFor(XdgShellSurface *parent)
override;
247 void setTitle(
const QString &title)
override;
248 void setAppId(
const QByteArray &appId)
override;
249 void showWindowMenu(Seat *seat, quint32 serial, qint32 x, qint32 y)
override;
250 void move(Seat *seat, quint32 serial)
override;
251 void resize(Seat *seat, quint32 serial,
Qt::Edges edges)
override;
252 void ackConfigure(quint32 serial)
override;
253 void setMaximized()
override;
254 void unsetMaximized()
override;
255 void setFullscreen(Output *output)
override;
256 void unsetFullscreen()
override;
257 void setMinimized()
override;
258 void setMaxSize(
const QSize &size)
override;
259 void setMinSize(
const QSize &size)
override;
265 static void configureCallback(
void *data,
struct zxdg_toplevel_v6 *xdg_toplevel, int32_t width, int32_t height,
struct wl_array *state);
266 static void closeCallback(
void *data, zxdg_toplevel_v6 *xdg_toplevel);
267 static void surfaceConfigureCallback(
void *data, zxdg_surface_v6 *xdg_surface, uint32_t serial);
269 static const struct zxdg_toplevel_v6_listener s_toplevelListener;
270 static const struct zxdg_surface_v6_listener s_surfaceListener;
273 const struct zxdg_toplevel_v6_listener XdgTopLevelUnstableV6::Private::s_toplevelListener = {configureCallback, closeCallback};
275 const struct zxdg_surface_v6_listener XdgTopLevelUnstableV6::Private::s_surfaceListener = {surfaceConfigureCallback};
277 void XdgTopLevelUnstableV6::Private::surfaceConfigureCallback(
void *data,
struct zxdg_surface_v6 *surface, uint32_t serial)
280 auto s =
reinterpret_cast<Private *
>(data);
281 s->q->configureRequested(s->pendingSize, s->pendingState, serial);
282 if (!s->pendingSize.isNull()) {
283 s->q->setSize(s->pendingSize);
284 s->pendingSize =
QSize();
286 s->pendingState = {};
289 void XdgTopLevelUnstableV6::Private::configureCallback(
void *data,
struct zxdg_toplevel_v6 *xdg_toplevel, int32_t width, int32_t height,
struct wl_array *state)
291 Q_UNUSED(xdg_toplevel)
292 auto s =
reinterpret_cast<Private *
>(data);
295 uint32_t *statePtr =
reinterpret_cast<uint32_t *
>(state->data);
296 for (
size_t i = 0; i < state->size /
sizeof(uint32_t); i++) {
297 switch (statePtr[i]) {
298 case ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED:
299 states = states | XdgShellSurface::State::Maximized;
301 case ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN:
302 states = states | XdgShellSurface::State::Fullscreen;
304 case ZXDG_TOPLEVEL_V6_STATE_RESIZING:
305 states = states | XdgShellSurface::State::Resizing;
307 case ZXDG_TOPLEVEL_V6_STATE_ACTIVATED:
308 states = states | XdgShellSurface::State::Activated;
312 s->pendingSize =
QSize(width, height);
313 s->pendingState = states;
316 void XdgTopLevelUnstableV6::Private::closeCallback(
void *data, zxdg_toplevel_v6 *xdg_toplevel)
318 auto s =
reinterpret_cast<XdgTopLevelUnstableV6::Private *
>(data);
319 Q_ASSERT(s->xdgtoplevelv6 == xdg_toplevel);
320 Q_EMIT s->q->closeRequested();
323 XdgTopLevelUnstableV6::Private::Private(XdgShellSurface *q)
324 : XdgShellSurface::Private(q)
328 void XdgTopLevelUnstableV6::Private::setupV6(zxdg_surface_v6 *surface, zxdg_toplevel_v6 *topLevel)
331 Q_ASSERT(!xdgtoplevelv6);
332 xdgsurfacev6.setup(surface);
333 xdgtoplevelv6.setup(topLevel);
334 zxdg_surface_v6_add_listener(xdgsurfacev6, &s_surfaceListener,
this);
335 zxdg_toplevel_v6_add_listener(xdgtoplevelv6, &s_toplevelListener,
this);
340 xdgtoplevelv6.release();
341 xdgsurfacev6.release();
344 void XdgTopLevelUnstableV6::Private::destroy()
346 xdgtoplevelv6.destroy();
347 xdgsurfacev6.destroy();
350 bool XdgTopLevelUnstableV6::Private::isValid()
const
352 return xdgtoplevelv6.isValid() && xdgsurfacev6.isValid();
355 void XdgTopLevelUnstableV6::Private::setTransientFor(XdgShellSurface *parent)
357 zxdg_toplevel_v6 *parentSurface =
nullptr;
359 parentSurface = *parent;
361 zxdg_toplevel_v6_set_parent(xdgtoplevelv6, parentSurface);
364 void XdgTopLevelUnstableV6::Private::setTitle(
const QString &title)
369 void XdgTopLevelUnstableV6::Private::setAppId(
const QByteArray &appId)
371 zxdg_toplevel_v6_set_app_id(xdgtoplevelv6, appId.
constData());
374 void XdgTopLevelUnstableV6::Private::showWindowMenu(Seat *seat, quint32 serial, qint32 x, qint32 y)
376 zxdg_toplevel_v6_show_window_menu(xdgtoplevelv6, *seat, serial, x, y);
379 void XdgTopLevelUnstableV6::Private::move(Seat *seat, quint32 serial)
381 zxdg_toplevel_v6_move(xdgtoplevelv6, *seat, serial);
384 void XdgTopLevelUnstableV6::Private::resize(Seat *seat, quint32 serial,
Qt::Edges edges)
386 uint wlEdge = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_NONE;
389 wlEdge = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_TOP_LEFT;
391 wlEdge = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_TOP_RIGHT;
393 wlEdge = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_TOP;
397 wlEdge = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_BOTTOM_LEFT;
399 wlEdge = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_BOTTOM_RIGHT;
401 wlEdge = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_BOTTOM;
404 wlEdge = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_RIGHT;
406 wlEdge = ZXDG_TOPLEVEL_V6_RESIZE_EDGE_LEFT;
408 zxdg_toplevel_v6_resize(xdgtoplevelv6, *seat, serial, wlEdge);
411 void XdgTopLevelUnstableV6::Private::ackConfigure(quint32 serial)
413 zxdg_surface_v6_ack_configure(xdgsurfacev6, serial);
416 void XdgTopLevelUnstableV6::Private::setMaximized()
418 zxdg_toplevel_v6_set_maximized(xdgtoplevelv6);
421 void XdgTopLevelUnstableV6::Private::unsetMaximized()
423 zxdg_toplevel_v6_unset_maximized(xdgtoplevelv6);
426 void XdgTopLevelUnstableV6::Private::setFullscreen(Output *output)
428 wl_output *o =
nullptr;
432 zxdg_toplevel_v6_set_fullscreen(xdgtoplevelv6, o);
435 void XdgTopLevelUnstableV6::Private::unsetFullscreen()
437 zxdg_toplevel_v6_unset_fullscreen(xdgtoplevelv6);
440 void XdgTopLevelUnstableV6::Private::setMinimized()
442 zxdg_toplevel_v6_set_minimized(xdgtoplevelv6);
445 void XdgTopLevelUnstableV6::Private::setMaxSize(
const QSize &size)
447 zxdg_toplevel_v6_set_max_size(xdgtoplevelv6, size.
width(), size.
height());
450 void XdgTopLevelUnstableV6::Private::setMinSize(
const QSize &size)
452 zxdg_toplevel_v6_set_min_size(xdgtoplevelv6, size.
width(), size.
height());
455 XdgTopLevelUnstableV6::XdgTopLevelUnstableV6(
QObject *parent)
456 : XdgShellSurface(new Private(this), parent)
460 XdgTopLevelUnstableV6::~XdgTopLevelUnstableV6() =
default;
462 class XdgShellPopupUnstableV6::Private :
public XdgShellPopup::Private
465 Private(XdgShellPopup *q);
467 void setupV6(zxdg_surface_v6 *s, zxdg_popup_v6 *p)
override;
469 void destroy()
override;
471 void requestGrab(Seat *seat, quint32 serial)
override;
472 void ackConfigure(quint32 serial)
override;
474 using XdgShellPopup::Private::operator xdg_popup *;
475 using XdgShellPopup::Private::operator xdg_surface *;
476 operator zxdg_surface_v6 *()
override
480 operator zxdg_surface_v6 *()
const override
484 operator zxdg_popup_v6 *()
override
488 operator zxdg_popup_v6 *()
const override
492 WaylandPointer<zxdg_surface_v6, zxdg_surface_v6_destroy> xdgsurfacev6;
493 WaylandPointer<zxdg_popup_v6, zxdg_popup_v6_destroy> xdgpopupv6;
498 static void configureCallback(
void *data, zxdg_popup_v6 *xdg_popup, int32_t x, int32_t y, int32_t width, int32_t height);
499 static void popupDoneCallback(
void *data, zxdg_popup_v6 *xdg_popup);
500 static void surfaceConfigureCallback(
void *data, zxdg_surface_v6 *xdg_surface, uint32_t serial);
502 static const struct zxdg_popup_v6_listener s_popupListener;
503 static const struct zxdg_surface_v6_listener s_surfaceListener;
506 const struct zxdg_popup_v6_listener XdgShellPopupUnstableV6::Private::s_popupListener = {configureCallback, popupDoneCallback};
508 const struct zxdg_surface_v6_listener XdgShellPopupUnstableV6::Private::s_surfaceListener = {
509 surfaceConfigureCallback,
512 void XdgShellPopupUnstableV6::Private::configureCallback(
void *data, zxdg_popup_v6 *xdg_popup, int32_t x, int32_t y, int32_t width, int32_t height)
515 auto s =
reinterpret_cast<Private *
>(data);
516 s->pendingRect =
QRect(x, y, width, height);
519 void XdgShellPopupUnstableV6::Private::surfaceConfigureCallback(
void *data,
struct zxdg_surface_v6 *surface, uint32_t serial)
522 auto s =
reinterpret_cast<Private *
>(data);
523 s->q->configureRequested(s->pendingRect, serial);
524 s->pendingRect =
QRect();
527 void XdgShellPopupUnstableV6::Private::popupDoneCallback(
void *data, zxdg_popup_v6 *xdg_popup)
529 auto s =
reinterpret_cast<XdgShellPopupUnstableV6::Private *
>(data);
530 Q_ASSERT(s->xdgpopupv6 == xdg_popup);
531 Q_EMIT s->q->popupDone();
534 XdgShellPopupUnstableV6::Private::Private(XdgShellPopup *q)
535 : XdgShellPopup::Private(q)
539 void XdgShellPopupUnstableV6::Private::setupV6(zxdg_surface_v6 *s, zxdg_popup_v6 *p)
542 Q_ASSERT(!xdgsurfacev6);
543 Q_ASSERT(!xdgpopupv6);
545 xdgsurfacev6.setup(s);
547 zxdg_surface_v6_add_listener(xdgsurfacev6, &s_surfaceListener,
this);
548 zxdg_popup_v6_add_listener(xdgpopupv6, &s_popupListener,
this);
553 xdgpopupv6.release();
556 void XdgShellPopupUnstableV6::Private::destroy()
558 xdgpopupv6.destroy();
561 bool XdgShellPopupUnstableV6::Private::isValid()
const
563 return xdgpopupv6.isValid();
566 void XdgShellPopupUnstableV6::Private::requestGrab(Seat *seat, quint32 serial)
568 zxdg_popup_v6_grab(xdgpopupv6, *seat, serial);
571 void XdgShellPopupUnstableV6::Private::ackConfigure(quint32 serial)
573 zxdg_surface_v6_ack_configure(xdgsurfacev6, serial);
576 XdgShellPopupUnstableV6::XdgShellPopupUnstableV6(
QObject *parent)
577 : XdgShellPopup(new Private(this), parent)
581 XdgShellPopupUnstableV6::~XdgShellPopupUnstableV6() =
default;