diff options
-rw-r--r-- | src/gui/kernel/qwidget_mac.mm | 7 | ||||
-rw-r--r-- | src/gui/painting/qregion.h | 1 | ||||
-rw-r--r-- | src/gui/painting/qregion_mac.cpp | 38 |
3 files changed, 45 insertions, 1 deletions
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 70eea3a..3bbf5d4 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3100,7 +3100,12 @@ void QWidgetPrivate::update_sys(const QRegion &rgn) return; dirtyOnWidget += rgn; #ifndef QT_MAC_USE_COCOA - HIViewSetNeedsDisplayInRegion(qt_mac_nativeview_for(q), QMacSmartQuickDrawRegion(rgn.toQDRgn()), true); + RgnHandle rgnHandle = rgn.toQDRgnForUpdate_sys(); + if (rgnHandle) + HIViewSetNeedsDisplayInRegion(qt_mac_nativeview_for(q), QMacSmartQuickDrawRegion(rgnHandle), true); + else { + HIViewSetNeedsDisplay(qt_mac_nativeview_for(q), true); // do a complete repaint on overflow. + } #else // Cocoa doesn't do regions, it seems more efficient to just update the bounding rect instead of a potential number of message passes for each rect. const QRect &boundingRect = rgn.boundingRect(); diff --git a/src/gui/painting/qregion.h b/src/gui/painting/qregion.h index 1db07a1..84024ce 100644 --- a/src/gui/painting/qregion.h +++ b/src/gui/painting/qregion.h @@ -148,6 +148,7 @@ public: #elif defined(Q_WS_MAC) #if defined Q_WS_MAC32 RgnHandle toQDRgn() const; + RgnHandle toQDRgnForUpdate_sys() const; static QRegion fromQDRgn(RgnHandle shape); #endif #ifdef QT_MAC_USE_COCOA diff --git a/src/gui/painting/qregion_mac.cpp b/src/gui/painting/qregion_mac.cpp index b57f234..9b0e99f 100644 --- a/src/gui/painting/qregion_mac.cpp +++ b/src/gui/painting/qregion_mac.cpp @@ -155,6 +155,44 @@ RgnHandle QRegion::toQDRgn() const } return rgnHandle; } + +/*! + \internal + Create's a RegionHandle, it's the caller's responsibility to release. + Returns 0 if the QRegion overflows. +*/ +RgnHandle QRegion::toQDRgnForUpdate_sys() const +{ + RgnHandle rgnHandle = qt_mac_get_rgn(); + if(d->qt_rgn && d->qt_rgn->numRects) { + RgnHandle tmp_rgn = qt_mac_get_rgn(); + int n = d->qt_rgn->numRects; + const QRect *qt_r = (n == 1) ? &d->qt_rgn->extents : d->qt_rgn->rects.constData(); + while (n--) { + + // detect overflow. Tested for use with HIViewSetNeedsDisplayInRegion + // in QWidgetPrivate::update_sys(). + enum { HIViewSetNeedsDisplayInRegionOverflow = 10000 }; // empirically determined conservative value + qDebug() << qt_r->x() << qt_r->y() << qt_r->right() << qt_r->bottom(); + if (qt_r->right() > HIViewSetNeedsDisplayInRegionOverflow || qt_r->bottom() > HIViewSetNeedsDisplayInRegionOverflow) { + qt_mac_dispose_rgn(tmp_rgn); + qt_mac_dispose_rgn(rgnHandle); + return 0; + } + + SetRectRgn(tmp_rgn, + qMax(SHRT_MIN, qt_r->x()), + qMax(SHRT_MIN, qt_r->y()), + qMin(SHRT_MAX, qt_r->right() + 1), + qMin(SHRT_MAX, qt_r->bottom() + 1)); + UnionRgn(rgnHandle, tmp_rgn, rgnHandle); + ++qt_r; + } + qt_mac_dispose_rgn(tmp_rgn); + } + return rgnHandle; +} + #endif #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) |