12QWaylandQuickShellSurfaceItem *QWaylandQuickShellSurfaceItemPrivate::maybeCreateAutoPopup(QWaylandShellSurface* shellSurface)
14 if (!m_autoCreatePopupItems)
17 Q_Q(QWaylandQuickShellSurfaceItem);
18 auto *popupItem =
new QWaylandQuickShellSurfaceItem(q);
19 popupItem->setShellSurface(shellSurface);
20 popupItem->setAutoCreatePopupItems(
true);
21 QObject::connect(popupItem, &QWaylandQuickShellSurfaceItem::surfaceDestroyed,
22 popupItem, &QObject::deleteLater);
60QWaylandQuickShellSurfaceItem::~QWaylandQuickShellSurfaceItem()
62 Q_D(QWaylandQuickShellSurfaceItem);
64 if (d->m_shellSurface)
65 disconnect(d->m_shellSurface, &QWaylandShellSurface::modalChanged,
this,
nullptr);
67 if (d->m_shellIntegration) {
68 removeEventFilter(d->m_shellIntegration);
69 delete d->m_shellIntegration;
102void QWaylandQuickShellSurfaceItem::setShellSurface(QWaylandShellSurface *shellSurface)
104 Q_D(QWaylandQuickShellSurfaceItem);
105 if (d->m_shellSurface == shellSurface)
108 if (Q_UNLIKELY(d->m_shellSurface))
109 disconnect(d->m_shellSurface, &QWaylandShellSurface::modalChanged,
this,
nullptr);
111 if (d->m_shellIntegration) {
112 removeEventFilter(d->m_shellIntegration);
113 delete d->m_shellIntegration;
114 d->m_shellIntegration =
nullptr;
117 d->m_shellSurface = shellSurface;
120 d->m_shellIntegration = shellSurface->createIntegration(
this);
121 installEventFilter(d->m_shellIntegration);
123 connect(shellSurface, &QWaylandShellSurface::modalChanged,
this,
124 [d](){
if (d->m_shellSurface->isModal()) d->raise(); });
127 emit shellSurfaceChanged();
151void QWaylandQuickShellSurfaceItem::setMoveItem(QQuickItem *moveItem)
153 Q_D(QWaylandQuickShellSurfaceItem);
154 moveItem = moveItem ? moveItem :
this;
155 if (
this->moveItem() == moveItem)
157 d->m_moveItem = moveItem;
180void QWaylandQuickShellSurfaceItem::setAutoCreatePopupItems(
bool enabled)
182 Q_D(QWaylandQuickShellSurfaceItem);
184 if (enabled == d->m_autoCreatePopupItems)
187 d->m_autoCreatePopupItems = enabled;
188 emit autoCreatePopupItemsChanged();
197void QWaylandQuickShellEventFilter::startFilter(QWaylandClient *client, CallbackFunction closePopups)
200 self =
new QWaylandQuickShellEventFilter(qGuiApp);
201 if (!self->eventFilterInstalled) {
202 qGuiApp->installEventFilter(self);
203 self->eventFilterInstalled =
true;
204 self->client = client;
205 self->closePopups = closePopups;
231bool QWaylandQuickShellEventFilter::eventFilter(QObject *receiver, QEvent *e)
233 if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease) {
234 bool press = e->type() == QEvent::MouseButtonPress;
235 if (press && !waitForRelease) {
237 if (!mousePressTimeout.isActive())
238 mousePressTimeout.start(0,
this);
241 QQuickItem *item = qobject_cast<QQuickItem*>(receiver);
245 QMouseEvent *event =
static_cast<QMouseEvent*>(e);
246 QWaylandQuickShellSurfaceItem *shellSurfaceItem = qobject_cast<QWaylandQuickShellSurfaceItem*>(item);
247 bool finalRelease = (event->type() == QEvent::MouseButtonRelease) && (event->buttons() == Qt::NoButton);
248 bool popupClient = shellSurfaceItem && shellSurfaceItem->surface() && shellSurfaceItem->surface()->client() == client;
250 if (waitForRelease) {
253 waitForRelease =
false;
259 if (finalRelease && mousePressTimeout.isActive()) {
261 qWarning(
"Badly written autotest detected");
262 mousePressTimeout.stop();
266 if (press && !shellSurfaceItem && !QQmlProperty(item, QStringLiteral(
"qtwayland_blocking_overlay")).isValid()) {
272 mousePressTimeout.stop();
274 if (press && !popupClient) {
278 waitForRelease =
true;
328void QWaylandQuickShellSurfaceItemPrivate::raise()
330 Q_Q(QWaylandQuickShellSurfaceItem);
331 auto *moveItem = q->moveItem();
332 QQuickItem *parent = moveItem->parentItem();
335 const bool putOnTop = staysOnTop || m_shellSurface->isModal();
336 const bool putOnBottom = staysOnBottom && !m_shellSurface->isModal();
338 auto it = parent->childItems().crbegin();
339 auto skip = [=](QQuickItem *item) {
340 if (
auto *surf = findSurfaceItemFromMoveItem(item))
341 return (!putOnTop && onTop(surf)) || (putOnBottom && !onBottom(surf));
344 auto end = parent->childItems().crend();
345 while (it != end && skip(*it))
348 QQuickItem *top = *it;
350 moveItem->stackAfter(top);
361void QWaylandQuickShellSurfaceItemPrivate::lower()
363 Q_Q(QWaylandQuickShellSurfaceItem);
364 auto *moveItem = q->moveItem();
365 QQuickItem *parent = moveItem->parentItem();
368 const bool putOnTop = staysOnTop || m_shellSurface->isModal();
369 const bool putOnBottom = staysOnBottom && !m_shellSurface->isModal();
371 auto it = parent->childItems().cbegin();
372 auto skip = [=](QQuickItem *item) {
373 if (
auto *surf = findSurfaceItemFromMoveItem(item))
374 return (!putOnBottom && onBottom(surf)) || (putOnTop && !onTop(surf));
380 QQuickItem *bottom = *it;
381 if (moveItem != bottom)
382 moveItem->stackBefore(bottom);
396void QWaylandQuickShellSurfaceItem::setStaysOnTop(
bool onTop)
398 Q_D(QWaylandQuickShellSurfaceItem);
399 if (d->staysOnTop == onTop)
401 d->staysOnTop = onTop;
402 if (d->staysOnBottom) {
403 d->staysOnBottom =
false;
404 emit staysOnBottomChanged();
409 emit staysOnTopChanged();
410 Q_ASSERT(!(d->staysOnTop && d->staysOnBottom));
424void QWaylandQuickShellSurfaceItem::setStaysOnBottom(
bool onBottom)
426 Q_D(QWaylandQuickShellSurfaceItem);
427 if (d->staysOnBottom == onBottom)
429 d->staysOnBottom = onBottom;
431 d->staysOnTop =
false;
432 emit staysOnTopChanged();
437 emit staysOnBottomChanged();
438 Q_ASSERT(!(d->staysOnTop && d->staysOnBottom));