void QWaylandWindow::setVisible(bool visible) { if (visible) { if (window()->type() == Qt::Popup && transientParent()) { QWaylandWindow *parent = transientParent(); mMouseDevice = parent->mMouseDevice; mMouseSerial = parent->mMouseSerial; QWaylandWlShellSurface *wlshellSurface = dynamic_cast<QWaylandWlShellSurface*>(mShellSurface); if (mMouseDevice && wlshellSurface) { wlshellSurface->setPopup(transientParent(), mMouseDevice, mMouseSerial); } } setGeometry(window()->geometry()); // Don't flush the events here, or else the newly visible window may start drawing, but since // there was no frame before it will be stuck at the waitForFrameSync() in // QWaylandShmBackingStore::beginPaint(). } else { QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // when flushing the event queue, it could contain a close event, in which // case 'this' will be deleted. When that happens, we must abort right away. QPointer<QWaylandWindow> deleteGuard(this); QWindowSystemInterface::flushWindowSystemEvents(); if (!deleteGuard.isNull()) { attach(static_cast<QWaylandBuffer *>(0), 0, 0); commit(); if (mBackingStore) { mBackingStore->hidden(); } } } }
void QQuickMenuPopupWindow::setGeometry(int posx, int posy, int w, int h) { QWindow *pw = transientParent(); if (!pw && parentItem()) pw = parentItem()->window(); if (!pw) pw = this; QRect g = pw->screen()->availableVirtualGeometry(); if (posx + w > g.right()) { if (qobject_cast<QQuickMenuPopupWindow *>(transientParent())) { // reposition submenu window on the parent menu's left side int submenuOverlap = pw->x() + pw->width() - posx; posx -= pw->width() + w - 2 * submenuOverlap; } else { posx = g.right() - w; } } else { posx = qMax(posx, g.left()); } posy = qBound(g.top(), posy, g.bottom() - h); QQuickWindow::setGeometry(posx, posy, w, h); }
void QQuickWindowQmlImpl::setVisible(bool visible) { Q_D(QQuickWindowQmlImpl); if (!d->complete) d->visible = visible; else if (!transientParent() || transientParent()->isVisible()) QQuickWindow::setVisible(visible); }
void componentComplete() { m_complete = true; if (transientParent() && !transientParent()->isVisible()) { connect(transientParent(), &QQuickWindow::visibleChanged, this, &QQuickWindowQmlImpl::setWindowVisibility, Qt::QueuedConnection); } else { setWindowVisibility(); } }
void QQuickPopupWindow::forwardEventToTransientParent(QMouseEvent *e) { if (!qobject_cast<QQuickPopupWindow*>(transientParent()) && ((m_mouseMoved && e->type() == QEvent::MouseButtonRelease) || e->type() == QEvent::MouseButtonPress)) { // Clicked outside any popup dismissPopup(); } else if (transientParent()) { QPoint parentPos = transientParent()->mapFromGlobal(mapToGlobal(e->pos())); QMouseEvent pe = QMouseEvent(e->type(), parentPos, e->button(), e->buttons(), e->modifiers()); QGuiApplication::sendEvent(transientParent(), &pe); } }
void QQuickPopupWindow::show() { qreal posx = x(); qreal posy = y(); // transientParent may not be a QQuickWindow when embedding into widgets if (QWindow *tp = transientParent()) { if (m_parentItem) { QPointF pos = m_parentItem->mapToItem(m_parentItem->window()->contentItem(), QPointF(posx, posy)); posx = pos.x(); posy = pos.y(); } QPoint tlwOffset = tp->mapToGlobal(QPoint()); posx += tlwOffset.x(); posy += tlwOffset.y(); } else if (m_parentItem && m_parentItem->window()) { QPoint offset; QQuickWindow *quickWindow = m_parentItem->window(); QWindow *renderWindow = QQuickRenderControl::renderWindowFor(quickWindow, &offset); QPointF pos = m_parentItem->mapToItem(quickWindow->contentItem(), QPointF(posx, posy)); posx = pos.x(); posy = pos.y(); QPoint parentWindowOffset = (renderWindow ? renderWindow : quickWindow)->mapToGlobal(QPoint()); posx += offset.x() + parentWindowOffset.x(); posy += offset.y() + parentWindowOffset.y(); } if (m_contentItem) { qreal initialWidth = qMax(qreal(1), m_contentItem->width()); qreal initialHeight = qMax(qreal(1), m_contentItem->height()); setGeometry(posx, posy, initialWidth, initialHeight); } else { setPosition(posx, posy); } emit geometryChanged(); if (!qobject_cast<QQuickPopupWindow *>(transientParent())) { // No need for parent menu windows if (QQuickWindow *w = qobject_cast<QQuickWindow *>(transientParent())) { if (QQuickItem *mg = w->mouseGrabberItem()) mg->ungrabMouse(); } else if (m_parentItem && m_parentItem->window()) { if (QQuickItem *mg = m_parentItem->window()->mouseGrabberItem()) mg->ungrabMouse(); } } QQuickWindow::show(); setMouseGrabEnabled(true); // Needs to be done after calling show() setKeyboardGrabEnabled(true); }
void QQuickPopupWindow::hideEvent(QHideEvent *e) { if (QWindow *tp = !m_needsActivatedEvent ? transientParent() : 0) { m_needsActivatedEvent = true; QWindowSystemInterface::handleWindowActivated(tp); } QQuickWindow::hideEvent(e); }
void QQuickWindowQmlImpl::setWindowVisibility() { Q_D(QQuickWindowQmlImpl); if (transientParent() && !transientParent()->isVisible()) return; if (sender()) { disconnect(transientParent(), &QWindow::visibleChanged, this, &QQuickWindowQmlImpl::setWindowVisibility); } // We have deferred window creation until we have the full picture of what // the user wanted in terms of window state, geometry, visibility, etc. if ((d->visibility == Hidden && d->visible) || (d->visibility > AutomaticVisibility && !d->visible)) { QQmlData *data = QQmlData::get(this); Q_ASSERT(data && data->context); QQmlError error; error.setObject(this); const QQmlContextData* urlContext = data->context; while (urlContext && urlContext->url().isEmpty()) urlContext = urlContext->parent; error.setUrl(urlContext ? urlContext->url() : QUrl()); QString objectId = data->context->findObjectId(this); if (!objectId.isEmpty()) error.setDescription(QCoreApplication::translate("QQuickWindowQmlImpl", "Conflicting properties 'visible' and 'visibility' for Window '%1'").arg(objectId)); else error.setDescription(QCoreApplication::translate("QQuickWindowQmlImpl", "Conflicting properties 'visible' and 'visibility'")); QQmlEnginePrivate::get(data->context->engine)->warning(error); } if (d->visibility == AutomaticVisibility) { setWindowState(QGuiApplicationPrivate::platformIntegration()->defaultWindowState(flags())); setVisible(d->visible); } else { setVisibility(d->visibility); } }
void QQuickMenuPopupWindow::setParentWindow(QQuickWindow *parentWindow) { if (transientParent() != parentWindow) setTransientParent(parentWindow); if (parentWindow) { connect(parentWindow, SIGNAL(destroyed()), this, SLOT(dismissPopup())); if (QQuickMenuPopupWindow *pw = qobject_cast<QQuickMenuPopupWindow *>(parentWindow)) connect(pw, SIGNAL(popupDismissed()), this, SLOT(dismissPopup())); } }
void QQuickPopupWindow::exposeEvent(QExposeEvent *e) { if (isExposed() && m_needsActivatedEvent) { m_needsActivatedEvent = false; QWindowSystemInterface::handleWindowActivated(this); } else if (!isExposed() && !m_needsActivatedEvent) { m_needsActivatedEvent = true; if (QWindow *tp = transientParent()) QWindowSystemInterface::handleWindowActivated(tp); } QQuickWindow::exposeEvent(e); }
void QQuickPopupWindow::show() { qreal posx = x(); qreal posy = y(); if (QQuickWindow *parentWindow = qobject_cast<QQuickWindow *>(transientParent())) { if (m_parentItem) { QPointF pos = m_parentItem->mapToItem(parentWindow->contentItem(), QPointF(posx, posy)); posx = pos.x(); posy = pos.y(); } if (parentWindow->parent()) { // If the parent window is embedded in another window, the offset needs to be relative to // its top-level window container, or to global coordinates, which is the same in the end. QPoint parentWindowOffset = parentWindow->mapToGlobal(QPoint()); posx += parentWindowOffset.x(); posy += parentWindowOffset.y(); } else { posx += parentWindow->geometry().left(); posy += parentWindow->geometry().top(); } } if (m_contentItem) { qreal initialWidth = qMax(qreal(1), m_contentItem->width()); qreal initialHeight = qMax(qreal(1), m_contentItem->height()); setGeometry(posx, posy, initialWidth, initialHeight); } else { setPosition(posx, posy); } if (!qobject_cast<QQuickPopupWindow *>(transientParent())) // No need for parent menu windows if (QQuickWindow *w = qobject_cast<QQuickWindow *>(transientParent())) if (QQuickItem *mg = w->mouseGrabberItem()) mg->ungrabMouse(); QQuickWindow::show(); setMouseGrabEnabled(true); // Needs to be done after calling show() setKeyboardGrabEnabled(true); }
void popupWindow::show() { qreal posx = x(); qreal posy = y(); // transientParent may not be a QQuickWindow when embedding into widgets if (QWindow *tp = transientParent()) { if (m_pParentItem) { QPointF pos = m_pParentItem->mapToItem(m_pParentItem->window()->contentItem(), QPointF()); posx = pos.x(); posy = pos.y(); } QPoint tlwOffset = tp->mapToGlobal(QPoint()); posx += tlwOffset.x(); posy += tlwOffset.y(); } else if (m_pParentItem && m_pParentItem->window()) { QPoint offset; QQuickWindow *quickWindow = m_pParentItem->window(); QWindow *renderWindow = QQuickRenderControl::renderWindowFor(quickWindow, &offset); QPointF pos = m_pParentItem->mapToItem(quickWindow->contentItem(), QPointF(posx, posy)); posx = pos.x(); posy = pos.y(); QPoint parentWindowOffset = (renderWindow ? renderWindow : quickWindow)->mapToGlobal(QPoint()); posx += offset.x() + parentWindowOffset.x(); posy += offset.y() + parentWindowOffset.y(); } setGeometry(posx + m_xOffset, posy + m_yOffset, width(), height()); emit geometryChanged(); m_mouseMoved = false; QQuickWindow::show(); setMouseGrabEnabled(true); // Needs to be done after calling show() //setKeyboardGrabEnabled(true); }
void QWaylandWindow::setVisible(bool visible) { if (visible) { if (window()->type() == Qt::Popup) { QWaylandWindow *parent = transientParent(); if (!parent) { // Try with the current focus window. It should be the right one and anyway // better than having no parent at all. parent = mDisplay->lastInputWindow(); } if (parent) { QWaylandWlShellSurface *wlshellSurface = qobject_cast<QWaylandWlShellSurface*>(mShellSurface); if (wlshellSurface) wlshellSurface->setPopup(parent, mDisplay->lastInputDevice(), mDisplay->lastInputSerial()); } } setGeometry(window()->geometry()); // Don't flush the events here, or else the newly visible window may start drawing, but since // there was no frame before it will be stuck at the waitForFrameSync() in // QWaylandShmBackingStore::beginPaint(). } else { QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // when flushing the event queue, it could contain a close event, in which // case 'this' will be deleted. When that happens, we must abort right away. QPointer<QWaylandWindow> deleteGuard(this); QWindowSystemInterface::flushWindowSystemEvents(); if (!deleteGuard.isNull()) { attach(static_cast<QWaylandBuffer *>(0), 0, 0); commit(); if (mBackingStore) { mBackingStore->hidden(); } } } }