diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-02-20 01:01:00 +0100 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2019-02-20 09:51:12 +0100 |
commit | 035f934d7a798e97bf0213a5d42a3d511132f03d (patch) | |
tree | 89aa6efdc86864ce479cddca6b9c4ba523c2754a /src/widgets/kernel | |
parent | f4cc23cffbe3005f0a522cac938695e87ecd6407 (diff) | |
parent | da4ab444ffac37514435364d4d3f0ad59d4f9bc3 (diff) |
Merge remote-tracking branch 'origin/5.13' into dev
Conflicts:
tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
Added tests/auto/testlib/selftests/expected_crashes_5.txt to work
round the output of the crashes test (which exercises UB, see
QTBUG-73903) being truncated on one test platform.
Change-Id: I9cd3f2639b4e50c3c4513e14629a40bdca8f8273
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qdesktopwidget.cpp | 24 | ||||
-rw-r--r-- | src/widgets/kernel/qdesktopwidget.h | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout.cpp | 18 | ||||
-rw-r--r-- | src/widgets/kernel/qlayout.h | 8 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 138 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 15 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetbackingstore.cpp | 270 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetbackingstore_p.h | 6 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 2 |
10 files changed, 212 insertions, 273 deletions
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index e189e5ba50..9e784b41c6 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1239,6 +1239,7 @@ QStyle* QApplication::setStyle(const QString& style) return s; } +#if QT_DEPRECATED_SINCE(5, 8) /*! Returns the color specification. \obsolete @@ -1313,6 +1314,7 @@ void QApplication::setColorSpec(int spec) { Q_UNUSED(spec) } +#endif /*! \property QApplication::globalStrut diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index 5fb7882932..d17c7eb36c 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -176,26 +176,32 @@ void QDesktopWidgetPrivate::_q_updateScreens() // Notice that we trigger screenCountChanged even if a screen was removed and another one added, // in which case the total number of screens did not change. This is the only way for applications // to notice that a screen was swapped out against another one. +#if QT_DEPRECATED_SINCE(5, 11) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED emit q->screenCountChanged(targetLength); QT_WARNING_POP +#endif } +#if QT_DEPRECATED_SINCE(5, 11) foreach (int changedScreen, changedScreens) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED emit q->resized(changedScreen); QT_WARNING_POP +#endif } void QDesktopWidgetPrivate::_q_availableGeometryChanged() { +#if QT_DEPRECATED_SINCE(5, 11) Q_Q(QDesktopWidget); if (QScreen *screen = qobject_cast<QScreen *>(q->sender())) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED emit q->workAreaResized(QGuiApplication::screens().indexOf(screen)); QT_WARNING_POP +#endif } QDesktopWidget::QDesktopWidget() @@ -212,10 +218,12 @@ QDesktopWidget::~QDesktopWidget() { } +#if QT_DEPRECATED_SINCE(5, 11) bool QDesktopWidget::isVirtualDesktop() const { return QDesktopWidgetPrivate::isVirtualDesktop(); } +#endif bool QDesktopWidgetPrivate::isVirtualDesktop() { @@ -242,24 +250,27 @@ int QDesktopWidgetPrivate::height() return geometry().height(); } +#if QT_DEPRECATED_SINCE(5, 11) int QDesktopWidget::primaryScreen() const { return QDesktopWidgetPrivate::primaryScreen(); } +#endif int QDesktopWidgetPrivate::primaryScreen() { return 0; } -int QDesktopWidget::numScreens() const +int QDesktopWidgetPrivate::numScreens() { - return QDesktopWidgetPrivate::numScreens(); + return qMax(QGuiApplication::screens().size(), 1); } -int QDesktopWidgetPrivate::numScreens() +#if QT_DEPRECATED_SINCE(5, 11) +int QDesktopWidget::numScreens() const { - return qMax(QGuiApplication::screens().size(), 1); + return QDesktopWidgetPrivate::numScreens(); } QWidget *QDesktopWidget::screen(int screen) @@ -274,6 +285,7 @@ const QRect QDesktopWidget::availableGeometry(int screenNo) const { return QDesktopWidgetPrivate::availableGeometry(screenNo); } +#endif const QRect QDesktopWidgetPrivate::availableGeometry(int screenNo) { @@ -281,10 +293,12 @@ const QRect QDesktopWidgetPrivate::availableGeometry(int screenNo) return screen ? screen->availableGeometry() : QRect(); } +#if QT_DEPRECATED_SINCE(5, 11) const QRect QDesktopWidget::screenGeometry(int screenNo) const { return QDesktopWidgetPrivate::screenGeometry(screenNo); } +#endif const QRect QDesktopWidgetPrivate::screenGeometry(int screenNo) { @@ -344,10 +358,12 @@ int QDesktopWidgetPrivate::screenNumber(const QWidget *w) return allScreens.indexOf(widgetScreen); } +#if QT_DEPRECATED_SINCE(5, 11) int QDesktopWidget::screenNumber(const QPoint &p) const { return QDesktopWidgetPrivate::screenNumber(p); } +#endif int QDesktopWidgetPrivate::screenNumber(const QPoint &p) { diff --git a/src/widgets/kernel/qdesktopwidget.h b/src/widgets/kernel/qdesktopwidget.h index f986f0db20..e5c587984f 100644 --- a/src/widgets/kernel/qdesktopwidget.h +++ b/src/widgets/kernel/qdesktopwidget.h @@ -52,9 +52,11 @@ class QDesktopWidgetPrivate; class Q_WIDGETS_EXPORT QDesktopWidget : public QWidget { Q_OBJECT +#if QT_DEPRECATED_SINCE(5, 11) Q_PROPERTY(bool virtualDesktop READ isVirtualDesktop) Q_PROPERTY(int screenCount READ screenCount NOTIFY screenCountChanged) Q_PROPERTY(int primaryScreen READ primaryScreen NOTIFY primaryScreenChanged) +#endif public: QDesktopWidget(); ~QDesktopWidget(); diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index 090abc883d..f27851c7bb 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -282,6 +282,7 @@ bool QLayout::setAlignment(QLayout *l, Qt::Alignment alignment) return false; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \property QLayout::margin \brief the width of the outside border of the layout @@ -307,6 +308,15 @@ int QLayout::margin() const } /*! + \obsolete +*/ +void QLayout::setMargin(int margin) +{ + setContentsMargins(margin, margin, margin, margin); +} + +#endif +/*! \property QLayout::spacing \brief the spacing between widgets inside the layout @@ -344,14 +354,6 @@ int QLayout::spacing() const } } -/*! - \obsolete -*/ -void QLayout::setMargin(int margin) -{ - setContentsMargins(margin, margin, margin, margin); -} - void QLayout::setSpacing(int spacing) { if (QBoxLayout* boxlayout = qobject_cast<QBoxLayout*>(this)) { diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h index 616f4e7164..35a04a35b2 100644 --- a/src/widgets/kernel/qlayout.h +++ b/src/widgets/kernel/qlayout.h @@ -63,7 +63,9 @@ class Q_WIDGETS_EXPORT QLayout : public QObject, public QLayoutItem Q_OBJECT Q_DECLARE_PRIVATE(QLayout) +#if QT_DEPRECATED_SINCE(5, 13) Q_PROPERTY(int margin READ margin WRITE setMargin) +#endif Q_PROPERTY(int spacing READ spacing WRITE setSpacing) Q_PROPERTY(SizeConstraint sizeConstraint READ sizeConstraint WRITE setSizeConstraint) public: @@ -81,10 +83,12 @@ public: QLayout(); ~QLayout(); +#if QT_DEPRECATED_SINCE(5, 13) int margin() const; - int spacing() const; - void setMargin(int); +#endif + + int spacing() const; void setSpacing(int); void setContentsMargins(int left, int top, int right, int bottom); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index e1ce731418..51b2bf8b5f 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -4508,8 +4508,7 @@ void QWidget::setForegroundRole(QPalette::ColorRole role) style, depend on third party APIs to render the content of widgets, and these styles typically do not follow the palette. Because of this, assigning roles to a widget's palette is not guaranteed to change the - appearance of the widget. Instead, you may choose to apply a \l - styleSheet. + appearance of the widget. Instead, you may choose to apply a \l {styleSheet}. \warning Do not use this function in conjunction with \l{Qt Style Sheets}. When using style sheets, the palette of a widget can be customized using @@ -5313,7 +5312,7 @@ void QWidget::setGraphicsEffect(QGraphicsEffect *effect) return; if (d->graphicsEffect) { - d->invalidateBuffer(rect()); + d->invalidateBackingStore(rect()); delete d->graphicsEffect; d->graphicsEffect = 0; } @@ -7330,11 +7329,11 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) if (renderToTexture) { QRegion updateRegion(q->geometry()); updateRegion += QRect(oldPos, olds); - q->parentWidget()->d_func()->invalidateBuffer(updateRegion); + q->parentWidget()->d_func()->invalidateBackingStore(updateRegion); } else if (isMove && !isResize) { moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); } else { - invalidateBuffer_resizeHelper(oldPos, olds); + invalidateBackingStore_resizeHelper(oldPos, olds); } } } @@ -8096,7 +8095,7 @@ void QWidgetPrivate::show_sys() QWidgetWindow *window = windowHandle(); if (q->testAttribute(Qt::WA_DontShowOnScreen)) { - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); q->setAttribute(Qt::WA_Mapped); // add our window the modal window list (native dialogs) if (window && q->isWindow() @@ -8139,7 +8138,7 @@ void QWidgetPrivate::show_sys() #ifndef QT_NO_CURSOR qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show #endif - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); window->setNativeWindowVisibility(true); // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ? if (window->isTopLevel()) { @@ -8253,12 +8252,12 @@ void QWidgetPrivate::hide_sys() QWidget *p = q->parentWidget(); if (p &&p->isVisible()) { if (renderToTexture) - p->d_func()->invalidateBuffer(q->geometry()); + p->d_func()->invalidateBackingStore(q->geometry()); else - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); } } else { - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); } if (window) @@ -8288,49 +8287,57 @@ void QWidgetPrivate::hide_sys() \endlist */ - void QWidget::setVisible(bool visible) { - if (visible) { // show - if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden)) - return; + if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden) == !visible) + return; - Q_D(QWidget); + // Remember that setVisible was called explicitly + setAttribute(Qt::WA_WState_ExplicitShowHide); + + Q_D(QWidget); + d->setVisible(visible); +} +// This method is called from QWidgetWindow in response to QWindow::setVisible, +// and should match the semantics of QWindow::setVisible. QWidget::setVisible on +// the other hand keeps track of WA_WState_ExplicitShowHide in addition. +void QWidgetPrivate::setVisible(bool visible) +{ + Q_Q(QWidget); + if (visible) { // show // Designer uses a trick to make grabWidget work without showing - if (!isWindow() && parentWidget() && parentWidget()->isVisible() - && !parentWidget()->testAttribute(Qt::WA_WState_Created)) - parentWidget()->window()->d_func()->createRecursively(); + if (!q->isWindow() && q->parentWidget() && q->parentWidget()->isVisible() + && !q->parentWidget()->testAttribute(Qt::WA_WState_Created)) + q->parentWidget()->window()->d_func()->createRecursively(); //create toplevels but not children of non-visible parents - QWidget *pw = parentWidget(); - if (!testAttribute(Qt::WA_WState_Created) - && (isWindow() || pw->testAttribute(Qt::WA_WState_Created))) { - create(); + QWidget *pw = q->parentWidget(); + if (!q->testAttribute(Qt::WA_WState_Created) + && (q->isWindow() || pw->testAttribute(Qt::WA_WState_Created))) { + q->create(); } - bool wasResized = testAttribute(Qt::WA_Resized); - Qt::WindowStates initialWindowState = windowState(); + bool wasResized = q->testAttribute(Qt::WA_Resized); + Qt::WindowStates initialWindowState = q->windowState(); // polish if necessary - ensurePolished(); + q->ensurePolished(); - // remember that show was called explicitly - setAttribute(Qt::WA_WState_ExplicitShowHide); // whether we need to inform the parent widget immediately - bool needUpdateGeometry = !isWindow() && testAttribute(Qt::WA_WState_Hidden); + bool needUpdateGeometry = !q->isWindow() && q->testAttribute(Qt::WA_WState_Hidden); // we are no longer hidden - setAttribute(Qt::WA_WState_Hidden, false); + q->setAttribute(Qt::WA_WState_Hidden, false); if (needUpdateGeometry) - d->updateGeometry_helper(true); + updateGeometry_helper(true); // activate our layout before we and our children become visible - if (d->layout) - d->layout->activate(); + if (layout) + layout->activate(); - if (!isWindow()) { - QWidget *parent = parentWidget(); + if (!q->isWindow()) { + QWidget *parent = q->parentWidget(); while (parent && parent->isVisible() && parent->d_func()->layout && !parent->data->in_show) { parent->d_func()->layout->activate(); if (parent->isWindow()) @@ -8343,30 +8350,28 @@ void QWidget::setVisible(bool visible) // adjust size if necessary if (!wasResized - && (isWindow() || !parentWidget()->d_func()->layout)) { - if (isWindow()) { - adjustSize(); - if (windowState() != initialWindowState) - setWindowState(initialWindowState); + && (q->isWindow() || !q->parentWidget()->d_func()->layout)) { + if (q->isWindow()) { + q->adjustSize(); + if (q->windowState() != initialWindowState) + q->setWindowState(initialWindowState); } else { - adjustSize(); + q->adjustSize(); } - setAttribute(Qt::WA_Resized, false); + q->setAttribute(Qt::WA_Resized, false); } - setAttribute(Qt::WA_KeyboardFocusChange, false); + q->setAttribute(Qt::WA_KeyboardFocusChange, false); - if (isWindow() || parentWidget()->isVisible()) { - d->show_helper(); + if (q->isWindow() || q->parentWidget()->isVisible()) { + show_helper(); - qApp->d_func()->sendSyntheticEnterLeave(this); + qApp->d_func()->sendSyntheticEnterLeave(q); } QEvent showToParentEvent(QEvent::ShowToParent); - QApplication::sendEvent(this, &showToParentEvent); + QApplication::sendEvent(q, &showToParentEvent); } else { // hide - if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden)) - return; #if 0 // Used to be included in Qt4 for Q_WS_WIN // reset WS_DISABLED style in a Blocked window if(isWindow() && testAttribute(Qt::WA_WState_Created) @@ -8377,33 +8382,30 @@ void QWidget::setVisible(bool visible) SetWindowLong(winId(), GWL_STYLE, dwStyle); } #endif - if (QApplicationPrivate::hidden_focus_widget == this) + if (QApplicationPrivate::hidden_focus_widget == q) QApplicationPrivate::hidden_focus_widget = 0; - Q_D(QWidget); - // hw: The test on getOpaqueRegion() needs to be more intelligent // currently it doesn't work if the widget is hidden (the region will // be clipped). The real check should be testing the cached region // (and dirty flag) directly. - if (!isWindow() && parentWidget()) // && !d->getOpaqueRegion().isEmpty()) - parentWidget()->d_func()->setDirtyOpaqueRegion(); + if (!q->isWindow() && q->parentWidget()) // && !d->getOpaqueRegion().isEmpty()) + q->parentWidget()->d_func()->setDirtyOpaqueRegion(); - setAttribute(Qt::WA_WState_Hidden); - setAttribute(Qt::WA_WState_ExplicitShowHide); - if (testAttribute(Qt::WA_WState_Created)) - d->hide_helper(); + q->setAttribute(Qt::WA_WState_Hidden); + if (q->testAttribute(Qt::WA_WState_Created)) + hide_helper(); // invalidate layout similar to updateGeometry() - if (!isWindow() && parentWidget()) { - if (parentWidget()->d_func()->layout) - parentWidget()->d_func()->layout->invalidate(); - else if (parentWidget()->isVisible()) - QApplication::postEvent(parentWidget(), new QEvent(QEvent::LayoutRequest)); + if (!q->isWindow() && q->parentWidget()) { + if (q->parentWidget()->d_func()->layout) + q->parentWidget()->d_func()->layout->invalidate(); + else if (q->parentWidget()->isVisible()) + QApplication::postEvent(q->parentWidget(), new QEvent(QEvent::LayoutRequest)); } QEvent hideToParentEvent(QEvent::HideToParent); - QApplication::sendEvent(this, &hideToParentEvent); + QApplication::sendEvent(q, &hideToParentEvent); } } @@ -11891,7 +11893,7 @@ void QWidget::raise() QRegion region(rect()); d->subtractOpaqueSiblings(region); - d->invalidateBuffer(region); + d->invalidateBackingStore(region); } if (testAttribute(Qt::WA_WState_Created)) d->raise_sys(); @@ -11911,7 +11913,7 @@ void QWidgetPrivate::raise_sys() } else if (renderToTexture) { if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry())); } } } @@ -11961,7 +11963,7 @@ void QWidgetPrivate::lower_sys() q->windowHandle()->lower(); } else if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry())); } } @@ -12005,7 +12007,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget*) Q_Q(QWidget); if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry())); } } @@ -12447,7 +12449,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) d->aboutToDestroy(); if (!isWindow() && parentWidget()) - parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); + parentWidget()->d_func()->invalidateBackingStore(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); if ((windowType() == Qt::Popup) && qApp) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index ab5dc6bfba..797963b931 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -452,10 +452,11 @@ public: void scrollChildren(int dx, int dy); void moveRect(const QRect &, int dx, int dy); void scrollRect(const QRect &, int dx, int dy); - void invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize); - // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). - void invalidateBuffer(const QRegion &); - void invalidateBuffer(const QRect &); + void invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize); + + template <class T> + void invalidateBackingStore(const T &); + QRegion overlappedRegion(const QRect &rect, bool breakAfterFirst = false) const; void syncBackingStore(); void syncBackingStore(const QRegion ®ion); @@ -484,6 +485,7 @@ public: void hide_sys(); void hide_helper(); void _q_showIfNotHidden(); + void setVisible(bool); void setEnabled_helper(bool); static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = 0); @@ -606,6 +608,11 @@ public: return extra ? extra->nativeChildrenForced : false; } + inline QRect effectiveRectFor(const QRegion ®ion) const + { + return effectiveRectFor(region.boundingRect()); + } + inline QRect effectiveRectFor(const QRect &rect) const { #if QT_CONFIG(graphicseffect) diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 69460bcd54..595beeaf47 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -501,6 +501,9 @@ void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, UpdateTime updateTi } } +static inline QRect widgetRectFor(QWidget *, const QRect &r) { return r; } +static inline QRect widgetRectFor(QWidget *widget, const QRegion &) { return widget->rect(); } + /*! Marks the region of the widget as dirty (if not already marked as dirty) and posts an UpdateRequest event to the top-level widget (if not already posted). @@ -511,42 +514,44 @@ void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, UpdateTime updateTi If the widget paints directly on screen, the event is sent to the widget instead of the top-level widget, and bufferState is completely ignored. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). */ -void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, - UpdateTime updateTime, BufferState bufferState) +template <class T> +void QWidgetBackingStore::markDirty(const T &r, QWidget *widget, UpdateTime updateTime, BufferState bufferState) { Q_ASSERT(tlw->d_func()->extra); Q_ASSERT(tlw->d_func()->extra->topextra); Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize); Q_ASSERT(widget->isVisible() && widget->updatesEnabled()); Q_ASSERT(widget->window() == tlw); - Q_ASSERT(!rgn.isEmpty()); + Q_ASSERT(!r.isEmpty()); #if QT_CONFIG(graphicseffect) widget->d_func()->invalidateGraphicsEffectsRecursively(); -#endif // QT_CONFIG(graphicseffect) +#endif + + QRect widgetRect = widgetRectFor(widget, r); + + // --------------------------------------------------------------------------- if (widget->d_func()->paintOnScreen()) { if (widget->d_func()->dirty.isEmpty()) { - widget->d_func()->dirty = rgn; + widget->d_func()->dirty = r; sendUpdateRequest(widget, updateTime); return; - } else if (qt_region_strictContains(widget->d_func()->dirty, widget->rect())) { + } else if (qt_region_strictContains(widget->d_func()->dirty, widgetRect)) { if (updateTime == UpdateNow) sendUpdateRequest(widget, updateTime); - return; // Already dirty. + return; // Already dirty } const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty(); - widget->d_func()->dirty += rgn; + widget->d_func()->dirty += r; if (!eventAlreadyPosted || updateTime == UpdateNow) sendUpdateRequest(widget, updateTime); return; } - const QPoint offset = widget->mapTo(tlw, QPoint()); + // --------------------------------------------------------------------------- if (QWidgetPrivate::get(widget)->renderToTexture) { if (!widget->d_func()->inDirtyList) @@ -556,133 +561,67 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, return; } - const QRect widgetRect = widget->d_func()->effectiveRectFor(widget->rect()); - if (qt_region_strictContains(dirty, widgetRect.translated(offset))) { + // --------------------------------------------------------------------------- + + QRect effectiveWidgetRect = widget->d_func()->effectiveRectFor(widgetRect); + const QPoint offset = widget->mapTo(tlw, QPoint()); + QRect translatedRect = effectiveWidgetRect.translated(offset); +#if QT_CONFIG(graphicseffect) + // Graphics effects may exceed window size, clamp + translatedRect = translatedRect.intersected(QRect(QPoint(), tlw->size())); +#endif + if (qt_region_strictContains(dirty, translatedRect)) { if (updateTime == UpdateNow) sendUpdateRequest(tlw, updateTime); - return; // Already dirty. + return; // Already dirty } + // --------------------------------------------------------------------------- + if (bufferState == BufferInvalid) { const bool eventAlreadyPosted = !dirty.isEmpty() || updateRequestSent; #if QT_CONFIG(graphicseffect) if (widget->d_func()->graphicsEffect) - dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset); + dirty += widget->d_func()->effectiveRectFor(r).translated(offset); else -#endif // QT_CONFIG(graphicseffect) - dirty += rgn.translated(offset); +#endif + dirty += r.translated(offset); + if (!eventAlreadyPosted || updateTime == UpdateNow) sendUpdateRequest(tlw, updateTime); return; } + // --------------------------------------------------------------------------- + if (dirtyWidgets.isEmpty()) { - addDirtyWidget(widget, rgn); + addDirtyWidget(widget, r); sendUpdateRequest(tlw, updateTime); return; } + // --------------------------------------------------------------------------- + if (widget->d_func()->inDirtyList) { - if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) { + if (!qt_region_strictContains(widget->d_func()->dirty, effectiveWidgetRect)) { #if QT_CONFIG(graphicseffect) if (widget->d_func()->graphicsEffect) - widget->d_func()->dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()); + widget->d_func()->dirty += widget->d_func()->effectiveRectFor(r); else -#endif // QT_CONFIG(graphicseffect) - widget->d_func()->dirty += rgn; +#endif + widget->d_func()->dirty += r; } } else { - addDirtyWidget(widget, rgn); - } - - if (updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); -} - -/*! - This function is equivalent to calling markDirty(QRegion(rect), ...), but - is more efficient as it eliminates QRegion operations/allocations and can - use the rect more precisely for additional cut-offs. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). -*/ -void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, - UpdateTime updateTime, BufferState bufferState) -{ - Q_ASSERT(tlw->d_func()->extra); - Q_ASSERT(tlw->d_func()->extra->topextra); - Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize); - Q_ASSERT(widget->isVisible() && widget->updatesEnabled()); - Q_ASSERT(widget->window() == tlw); - Q_ASSERT(!rect.isEmpty()); - -#if QT_CONFIG(graphicseffect) - widget->d_func()->invalidateGraphicsEffectsRecursively(); -#endif // QT_CONFIG(graphicseffect) - - if (widget->d_func()->paintOnScreen()) { - if (widget->d_func()->dirty.isEmpty()) { - widget->d_func()->dirty = QRegion(rect); - sendUpdateRequest(widget, updateTime); - return; - } else if (qt_region_strictContains(widget->d_func()->dirty, rect)) { - if (updateTime == UpdateNow) - sendUpdateRequest(widget, updateTime); - return; // Already dirty. - } - - const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty(); - widget->d_func()->dirty += rect; - if (!eventAlreadyPosted || updateTime == UpdateNow) - sendUpdateRequest(widget, updateTime); - return; - } - - if (QWidgetPrivate::get(widget)->renderToTexture) { - if (!widget->d_func()->inDirtyList) - addDirtyRenderToTextureWidget(widget); - if (!updateRequestSent || updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); - return; + addDirtyWidget(widget, r); } - - const QRect widgetRect = widget->d_func()->effectiveRectFor(rect); - QRect translatedRect = widgetRect; - if (widget != tlw) - translatedRect.translate(widget->mapTo(tlw, QPoint())); - // Graphics effects may exceed window size, clamp. - translatedRect = translatedRect.intersected(QRect(QPoint(), tlw->size())); - if (qt_region_strictContains(dirty, translatedRect)) { - if (updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); - return; // Already dirty - } - - if (bufferState == BufferInvalid) { - const bool eventAlreadyPosted = !dirty.isEmpty(); - dirty += translatedRect; - if (!eventAlreadyPosted || updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); - return; - } - - if (dirtyWidgets.isEmpty()) { - addDirtyWidget(widget, rect); - sendUpdateRequest(tlw, updateTime); - return; - } - - if (widget->d_func()->inDirtyList) { - if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) - widget->d_func()->dirty += widgetRect; - } else { - addDirtyWidget(widget, rect); - } + // --------------------------------------------------------------------------- if (updateTime == UpdateNow) sendUpdateRequest(tlw, updateTime); } +template void QWidgetBackingStore::markDirty<QRect>(const QRect &, QWidget *, UpdateTime, BufferState); +template void QWidgetBackingStore::markDirty<QRegion>(const QRegion &, QWidget *, UpdateTime, BufferState); /*! Marks the \a region of the \a widget as dirty on screen. The \a region will be copied from @@ -853,11 +792,11 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) if (!extra || !extra->hasMask) { parentR -= newRect; } else { - // invalidateBuffer() excludes anything outside the mask + // invalidateBackingStore() excludes anything outside the mask parentR += newRect & clipR; } - pd->invalidateBuffer(parentR); - invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft())); + pd->invalidateBackingStore(parentR); + invalidateBackingStore((newRect & clipR).translated(-data.crect.topLeft())); } else { QWidgetBackingStore *wbs = x->backingStoreTracker.data(); @@ -888,7 +827,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) if (childUpdatesEnabled) { if (!overlappedExpose.isEmpty()) { overlappedExpose.translate(-data.crect.topLeft()); - invalidateBuffer(overlappedExpose); + invalidateBackingStore(overlappedExpose); } if (!childExpose.isEmpty()) { childExpose.translate(-data.crect.topLeft()); @@ -938,9 +877,9 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) if (!overlappedRegion(scrollRect.translated(data.crect.topLeft()), true).isEmpty()) { QRegion region(scrollRect); subtractOpaqueSiblings(region); - invalidateBuffer(region); + invalidateBackingStore(region); }else { - invalidateBuffer(scrollRect); + invalidateBackingStore(scrollRect); } } else { const QPoint toplevelOffset = q->mapTo(tlw, QPoint()); @@ -981,7 +920,7 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) return; if (!overlappedExpose.isEmpty()) - invalidateBuffer(overlappedExpose); + invalidateBackingStore(overlappedExpose); if (!childExpose.isEmpty()) { wbs->markDirty(childExpose, q); isScrolled = true; @@ -1465,26 +1404,11 @@ void QWidgetBackingStore::flush(QWidget *widget) dirtyOnScreenWidgets->clear(); } -static inline bool discardInvalidateBufferRequest(QWidget *widget, QTLWExtra *tlwExtra) -{ - Q_ASSERT(widget); - if (QApplication::closingDown()) - return true; - - if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore) - return true; - - if (!widget->isVisible() || !widget->updatesEnabled()) - return true; - - return false; -} - /*! - Invalidates the buffer when the widget is resized. + Invalidates the backing store when the widget is resized. Static areas are never invalidated unless absolutely needed. */ -void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize) +void QWidgetPrivate::invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize) { Q_Q(QWidget); Q_ASSERT(!q->isWindow()); @@ -1509,10 +1433,10 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q if (hasStaticChildren) { QRegion dirty(newWidgetRect); dirty -= staticChildren; - invalidateBuffer(dirty); + invalidateBackingStore(dirty); } else { // Entire widget needs repaint. - invalidateBuffer(newWidgetRect); + invalidateBackingStore(newWidgetRect); } if (!parentAreaExposed) @@ -1524,14 +1448,14 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q parentExpose &= QRect(oldPos, oldSize); if (hasStaticChildren) parentExpose -= data.crect; // Offset is unchanged, safe to do this. - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(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); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } else { - q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(QRect(oldPos, oldSize))); + q->parentWidget()->d_func()->invalidateBackingStore(effectiveRectFor(QRect(oldPos, oldSize))); } } return; @@ -1552,7 +1476,7 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q if (!sizeDecreased || !oldWidgetRect.contains(newWidgetRect)) { QRegion newVisible(newWidgetRect); newVisible -= oldWidgetRect; - invalidateBuffer(newVisible); + invalidateBackingStore(newVisible); } if (!parentAreaExposed) @@ -1564,74 +1488,56 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q QRegion parentExpose(oldRect); parentExpose &= extra->mask.translated(oldPos); parentExpose -= (extra->mask.translated(data.crect.topLeft()) & data.crect); - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } else { QRegion parentExpose(oldRect); parentExpose -= data.crect; - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } } /*! - Invalidates the \a rgn (in widget's coordinates) of the backing store, i.e. - all widgets intersecting with the region will be repainted when the backing store - is synced. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). + Invalidates the \a r (in widget's coordinates) of the backing store, i.e. + all widgets intersecting with the region will be repainted when the backing + store is synced. */ -void QWidgetPrivate::invalidateBuffer(const QRegion &rgn) +template <class T> +void QWidgetPrivate::invalidateBackingStore(const T &r) { - Q_Q(QWidget); - - QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); - if (discardInvalidateBufferRequest(q, tlwExtra) || rgn.isEmpty()) + if (r.isEmpty()) return; - QRegion wrgn(rgn); - wrgn &= clipRect(); - if (!graphicsEffect && extra && extra->hasMask) - wrgn &= extra->mask; - if (wrgn.isEmpty()) + if (QApplication::closingDown()) return; - tlwExtra->backingStoreTracker->markDirty(wrgn, q, - QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); -} - -/*! - This function is equivalent to calling invalidateBuffer(QRegion(rect), ...), but - is more efficient as it eliminates QRegion operations/allocations and can - use the rect more precisely for additional cut-offs. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). -*/ -void QWidgetPrivate::invalidateBuffer(const QRect &rect) -{ Q_Q(QWidget); - - QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); - if (discardInvalidateBufferRequest(q, tlwExtra) || rect.isEmpty()) + if (!q->isVisible() || !q->updatesEnabled()) return; - QRect wRect(rect); - wRect &= clipRect(); - if (wRect.isEmpty()) + QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); + if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore) return; - if (graphicsEffect || !extra || !extra->hasMask) { - tlwExtra->backingStoreTracker->markDirty(wRect, q, - QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); + T clipped(r); + clipped &= clipRect(); + if (clipped.isEmpty()) return; - } - QRegion wRgn(extra->mask); - wRgn &= wRect; - if (wRgn.isEmpty()) - return; + if (!graphicsEffect && extra && extra->hasMask) { + QRegion masked(extra->mask); + masked &= clipped; + if (masked.isEmpty()) + return; - tlwExtra->backingStoreTracker->markDirty(wRgn, q, + tlwExtra->backingStoreTracker->markDirty(masked, q, QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); + } else { + tlwExtra->backingStoreTracker->markDirty(clipped, q, + QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); + } } +// Needed by tst_QWidget +template Q_AUTOTEST_EXPORT void QWidgetPrivate::invalidateBackingStore<QRect>(const QRect &r); void QWidgetPrivate::repaint_sys(const QRegion &rgn) { diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index a1846da44e..e7a2bca33a 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -118,10 +118,8 @@ public: return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && dirtyRenderToTextureWidgets.isEmpty()); } - // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). - void markDirty(const QRegion &rgn, QWidget *widget, UpdateTime updateTime = UpdateLater, - BufferState bufferState = BufferValid); - void markDirty(const QRect &rect, QWidget *widget, UpdateTime updateTime = UpdateLater, + template <class T> + void markDirty(const T &r, QWidget *widget, UpdateTime updateTime = UpdateLater, BufferState bufferState = BufferValid); private: diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 991a05fa02..e9b749d7c2 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -73,7 +73,7 @@ public: { Q_Q(QWidgetWindow); if (QWidget *widget = q->widget()) - widget->setVisible(visible); + QWidgetPrivate::get(widget)->setVisible(visible); else QWindowPrivate::setVisible(visible); } |