void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) { Q_Q(QWidget); if (extra) { // any size restrictions? w = qMin(w,extra->maxw); h = qMin(h,extra->maxh); w = qMax(w,extra->minw); h = qMax(h,extra->minh); } QPoint oldp = q->geometry().topLeft(); QSize olds = q->size(); QRect r(x, y, w, h); bool isResize = olds != r.size(); isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter? // We only care about stuff that changes the geometry, or may // cause the window manager to change its state if (r.size() == olds && oldp == r.topLeft()) return; if (!data.in_set_window_state) { q->data->window_state &= ~Qt::WindowMaximized; q->data->window_state &= ~Qt::WindowFullScreen; if (q->isWindow()) topData()->normalGeometry = QRect(0, 0, -1, -1); } QPoint oldPos = q->pos(); data.crect = r; if ((q->windowType() == Qt::Desktop)) return; if (q->isVisible()) { bool toplevelMove = false; QWSWindowSurface *surface = 0; if (q->isWindow()) { //### ConfigPending not implemented, do we need it? //setAttribute(Qt::WA_WState_ConfigPending); const QWidgetBackingStore *bs = maybeBackingStore(); if (bs) surface = static_cast<QWSWindowSurface*>(bs->windowSurface); if (isMove && !isResize && surface) { const QPoint offset(x - oldp.x(), y - oldp.y()); moveSurface(surface, offset); toplevelMove = true; //server moves window, but we must send moveEvent, which might trigger painting #ifdef Q_BACKINGSTORE_SUBSURFACES QList<QWindowSurface*> surfaces = bs->subSurfaces; for (int i = 0; i < surfaces.size(); ++i) moveSurface(surfaces.at(i), offset); #endif } else { updateFrameStrut(); } } if (!toplevelMove) { if (q->isWindow()) { if (surface) surface->setGeometry(q->frameGeometry()); else invalidateBuffer(q->rect()); //### #ifdef Q_BACKINGSTORE_SUBSURFACES // XXX: should not resize subsurfaces. Children within a layout // will be resized automatically while children with a static // geometry should get a new clip region instead. const QRect clipRect = q->geometry(); QWidgetBackingStore *bs = maybeBackingStore(); QList<QWindowSurface*> surfaces = bs->subSurfaces; for (int i = 0; i < surfaces.size(); ++i) { QWSWindowSurface *s = static_cast<QWSWindowSurface*>(surfaces.at(i)); QRect srect = s->geometry(); s->setGeometry(clipRect & srect); } #endif } #ifdef Q_BACKINGSTORE_SUBSURFACES // XXX: merge this case with the isWindow() case else if (maybeTopData() && maybeTopData()->windowSurface) { QWSWindowSurface *surface; surface = static_cast<QWSWindowSurface*>(q->windowSurface()); if (isMove && !isResize) { moveSurface(surface, QPoint(x - oldp.x(), y - oldp.y())); } else { const QPoint p = q->mapToGlobal(QPoint()); surface->setGeometry(QRect(p, QSize(w, h))); } } #endif else { if (isMove && !isResize) moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); else invalidateBuffer_resizeHelper(oldPos, olds); } } //### must have frame geometry correct before sending move/resize events if (isMove) { QMoveEvent e(q->pos(), oldPos); QApplication::sendEvent(q, &e); } if (isResize) { QResizeEvent e(r.size(), olds); QApplication::sendEvent(q, &e); } } else { // not visible if (isMove && q->pos() != oldPos) q->setAttribute(Qt::WA_PendingMoveEvent, true); if (isResize) q->setAttribute(Qt::WA_PendingResizeEvent, true); } }
/*! Invalidates the buffer when the widget is resized. Static areas are never invalidated unless absolutely needed. */ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize) { Q_Q(QWidget); Q_ASSERT(!q->isWindow()); Q_ASSERT(q->parentWidget()); const bool staticContents = q->testAttribute(Qt::WA_StaticContents); const bool sizeDecreased = (data.crect.width() < oldSize.width()) || (data.crect.height() < oldSize.height()); const QPoint offset(data.crect.x() - oldPos.x(), data.crect.y() - oldPos.y()); const bool parentAreaExposed = !offset.isNull() || sizeDecreased; const QRect newWidgetRect(q->rect()); const QRect oldWidgetRect(0, 0, oldSize.width(), oldSize.height()); if (!staticContents || graphicsEffect) { QRegion staticChildren; QWidgetBackingStore *bs = 0; if (offset.isNull() && (bs = maybeBackingStore())) staticChildren = bs->staticContents(q, oldWidgetRect); const bool hasStaticChildren = !staticChildren.isEmpty(); if (hasStaticChildren) { QRegion dirty(newWidgetRect); dirty -= staticChildren; invalidateBuffer(dirty); } else { // Entire widget needs repaint. invalidateBuffer(newWidgetRect); } if (!parentAreaExposed) return; // Invalidate newly exposed area of the parent. if (!graphicsEffect && extra && extra->hasMask) { QRegion parentExpose(extra->mask.translated(oldPos)); parentExpose &= QRect(oldPos, oldSize); if (hasStaticChildren) parentExpose -= data.crect; // Offset is unchanged, safe to do this. q->parentWidget()->d_func()->invalidateBuffer(parentExpose); } else { if (hasStaticChildren && !graphicsEffect) { QRegion parentExpose(QRect(oldPos, oldSize)); parentExpose -= data.crect; // Offset is unchanged, safe to do this. q->parentWidget()->d_func()->invalidateBuffer(parentExpose); } else { q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(QRect(oldPos, oldSize))); } } return; } // Move static content to its new position. if (!offset.isNull()) { if (sizeDecreased) { const QSize minSize(qMin(oldSize.width(), data.crect.width()), qMin(oldSize.height(), data.crect.height())); moveRect(QRect(oldPos, minSize), offset.x(), offset.y()); } else { moveRect(QRect(oldPos, oldSize), offset.x(), offset.y()); } } // Invalidate newly visible area of the widget. if (!sizeDecreased || !oldWidgetRect.contains(newWidgetRect)) { QRegion newVisible(newWidgetRect); newVisible -= oldWidgetRect; invalidateBuffer(newVisible); } if (!parentAreaExposed) return; // Invalidate newly exposed area of the parent. const QRect oldRect(oldPos, oldSize); if (extra && extra->hasMask) { QRegion parentExpose(oldRect); parentExpose &= extra->mask.translated(oldPos); parentExpose -= (extra->mask.translated(data.crect.topLeft()) & data.crect); q->parentWidget()->d_func()->invalidateBuffer(parentExpose); } else { QRegion parentExpose(oldRect); parentExpose -= data.crect; q->parentWidget()->d_func()->invalidateBuffer(parentExpose); } }
void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) { Q_Q(QWidget); Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); if ((q->windowType() == Qt::Desktop)) return; QPoint oldPos(q->pos()); QSize oldSize(q->size()); QRect oldGeom(data.crect); // Lose maximized status if deliberate resize if (w != oldSize.width() || h != oldSize.height()) data.window_state &= ~Qt::WindowMaximized; if (extra) { // any size restrictions? w = qMin(w,extra->maxw); h = qMin(h,extra->maxh); w = qMax(w,extra->minw); h = qMax(h,extra->minh); } if (q->isWindow()) topData()->normalGeometry = QRect(0, 0, -1, -1); else { uint s = data.window_state; s &= ~(Qt::WindowMaximized | Qt::WindowFullScreen); data.window_state = s; } bool isResize = w != oldSize.width() || h != oldSize.height(); if (!isMove && !isResize) return; if (q->isWindow()) { if (w == 0 || h == 0) { q->setAttribute(Qt::WA_OutsideWSRange, true); if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) hide_sys(); data.crect = QRect(x, y, w, h); data.window_state &= ~Qt::WindowFullScreen; } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { q->setAttribute(Qt::WA_OutsideWSRange, false); // put the window in its place and show it q->internalWinId()->SetRect(TRect(TPoint(x, y), TSize(w, h))); data.crect.setRect(x, y, w, h); show_sys(); } else { QRect r = QRect(x, y, w, h); data.crect = r; q->internalWinId()->SetRect(TRect(TPoint(x, y), TSize(w, h))); topData()->normalGeometry = data.crect; } } else { data.crect.setRect(x, y, w, h); QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); const bool inTopLevelResize = tlwExtra ? tlwExtra->inTopLevelResize : false; if (q->isVisible() && (!inTopLevelResize || q->internalWinId())) { // Top-level resize optimization does not work for native child widgets; // disable it for this particular widget. if (inTopLevelResize) tlwExtra->inTopLevelResize = false; if (!isResize && maybeBackingStore()) moveRect(QRect(oldPos, oldSize), x - oldPos.x(), y - oldPos.y()); else invalidateBuffer_resizeHelper(oldPos, oldSize); if (inTopLevelResize) tlwExtra->inTopLevelResize = true; } if (q->testAttribute(Qt::WA_WState_Created)) setWSGeometry(); } if (q->isVisible()) { if (isMove && q->pos() != oldPos) { QMoveEvent e(q->pos(), oldPos); QApplication::sendEvent(q, &e); } if (isResize) { bool slowResize = qgetenv("QT_SLOW_TOPLEVEL_RESIZE").toInt(); const bool setTopLevelResize = !slowResize && q->isWindow() && extra && extra->topextra && !extra->topextra->inTopLevelResize; if (setTopLevelResize) extra->topextra->inTopLevelResize = true; QResizeEvent e(q->size(), oldSize); QApplication::sendEvent(q, &e); if (!q->testAttribute(Qt::WA_StaticContents) && q->internalWinId()) q->internalWinId()->DrawDeferred(); if (setTopLevelResize) extra->topextra->inTopLevelResize = false; } } else { if (isMove && q->pos() != oldPos) q->setAttribute(Qt::WA_PendingMoveEvent, true); if (isResize) q->setAttribute(Qt::WA_PendingResizeEvent, true); } }
void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) { Q_Q(QWidget); if (extra) { // any size restrictions? w = qMin(w,extra->maxw); h = qMin(h,extra->maxh); w = qMax(w,extra->minw); h = qMax(h,extra->minh); } if (q->isWindow() && q->windowHandle()) { QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration(); if (!integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)) { x = 0; y = 0; w = q->windowHandle()->width(); h = q->windowHandle()->height(); } } QPoint oldp = q->geometry().topLeft(); QSize olds = q->size(); QRect r(x, y, w, h); bool isResize = olds != r.size(); isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter? // We only care about stuff that changes the geometry, or may // cause the window manager to change its state if (r.size() == olds && oldp == r.topLeft()) return; if (!data.in_set_window_state) { q->data->window_state &= ~Qt::WindowMaximized; q->data->window_state &= ~Qt::WindowFullScreen; if (q->isWindow()) topData()->normalGeometry = QRect(0, 0, -1, -1); } QPoint oldPos = q->pos(); data.crect = r; bool needsShow = false; if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) { q->setAttribute(Qt::WA_OutsideWSRange, true); if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) hide_sys(); data.crect = QRect(x, y, w, h); } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { q->setAttribute(Qt::WA_OutsideWSRange, false); needsShow = true; } if (q->isVisible()) { if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) { if (q->windowHandle()) { if (q->isWindow()) { q->windowHandle()->setGeometry(q->geometry()); } else { QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint()); q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size())); } const QWidgetBackingStore *bs = maybeBackingStore(); if (bs && bs->store) { if (isResize) bs->store->resize(r.size()); } if (needsShow) show_sys(); } if (!q->isWindow()) { if (isMove && !isResize) moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); else invalidateBuffer_resizeHelper(oldPos, olds); } } if (isMove) { QMoveEvent e(q->pos(), oldPos); QApplication::sendEvent(q, &e); } if (isResize) { QResizeEvent e(r.size(), olds); QApplication::sendEvent(q, &e); if (q->windowHandle()) q->update(); } } else { // not visible if (isMove && q->pos() != oldPos) q->setAttribute(Qt::WA_PendingMoveEvent, true); if (isResize) q->setAttribute(Qt::WA_PendingResizeEvent, true); } }