diff options
author | Richard Moe Gustavsen <richard.gustavsen@nokia.com> | 2011-01-21 08:10:24 (GMT) |
---|---|---|
committer | Richard Moe Gustavsen <richard.gustavsen@nokia.com> | 2011-01-21 10:39:40 (GMT) |
commit | 0a1e41a7192f0ac92cba16a82369a6fef633ac3d (patch) | |
tree | 88e3448eb9e89f148a8822a9cae570745085dd56 /src/gui | |
parent | 5e5e16fd7107334e10939592170fc322cfa86da9 (diff) | |
download | Qt-0a1e41a7192f0ac92cba16a82369a6fef633ac3d.zip Qt-0a1e41a7192f0ac92cba16a82369a6fef633ac3d.tar.gz Qt-0a1e41a7192f0ac92cba16a82369a6fef633ac3d.tar.bz2 |
Cocoa/Alien: bugfix scrolling, dirty region issue
When scrolling a widget we also need to scroll the already
marked dirty regions on the widget along with the scroll.
Since we might end up scrolling several time before a drawRect
is called (normal with inertia scrolling), we need to mark exposed
areas during scrolling as dirty as well, so they get handled
correctly on subsequent scrolls.
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qwidget_mac.mm | 87 |
1 files changed, 42 insertions, 45 deletions
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 8d6c09c..4e488bf 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -4772,6 +4772,34 @@ void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &qscrollRect) if (!view) return; + // Calculate the rectangles that needs to be redrawn + // after the scroll. This will be source rect minus destination rect: + QRect deltaXRect; + if (dx != 0) { + deltaXRect.setY(validScrollRect.y()); + deltaXRect.setHeight(validScrollRect.height()); + if (dx > 0) { + deltaXRect.setX(validScrollRect.x()); + deltaXRect.setWidth(dx); + } else { + deltaXRect.setX(validScrollRect.x() + validScrollRect.width() + dx); + deltaXRect.setWidth(-dx); + } + } + + QRect deltaYRect; + if (dy != 0) { + deltaYRect.setX(validScrollRect.x()); + deltaYRect.setWidth(validScrollRect.width()); + if (dy > 0) { + deltaYRect.setY(validScrollRect.y()); + deltaYRect.setHeight(dy); + } else { + deltaYRect.setY(validScrollRect.y() + validScrollRect.height() + dy); + deltaYRect.setHeight(-dy); + } + } + if (isAlien) { // Since q is alien, we need to translate the scroll rect: QPoint widgetTopLeftInsideNative = nativeWidget->mapFromGlobal(q->mapToGlobal(QPoint())); @@ -4805,44 +4833,12 @@ void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &qscrollRect) } } + // Now, scroll the pixels: NSRect nsscrollRect = NSMakeRect( validScrollRect.x(), validScrollRect.y(), validScrollRect.width(), validScrollRect.height()); - - // Calculate the rectangles that needs to be redrawn - // after the scroll. This will be source rect minus destination rect: - - NSRect deltaXRect = { {0, 0}, {0, 0} }; - NSRect deltaYRect = { {0, 0}, {0, 0} }; - - if (dy != 0) { - deltaYRect.size.width = nsscrollRect.size.width; - deltaYRect.origin.x = nsscrollRect.origin.x; - if (dy > 0) { - deltaYRect.size.height = dy; - deltaYRect.origin.y = nsscrollRect.origin.y; - } else { - deltaYRect.size.height = -dy; - deltaYRect.origin.y = nsscrollRect.origin.y + nsscrollRect.size.height + dy; - } - } - - if (dx != 0) { - deltaXRect.size.height = nsscrollRect.size.height; - deltaXRect.origin.y = nsscrollRect.origin.y; - if (dx > 0) { - deltaXRect.size.width = dx; - deltaXRect.origin.x = nsscrollRect.origin.x; - } else { - deltaXRect.size.width = -dx; - deltaXRect.origin.x = nsscrollRect.origin.x + nsscrollRect.size.width + dx; - } - } - NSSize deltaSize = NSMakeSize(dx, dy); [view scrollRect:nsscrollRect by:deltaSize]; - [view setNeedsDisplayInRect:deltaXRect]; - [view setNeedsDisplayInRect:deltaYRect]; // Some areas inside the scroll rect might have been marked as dirty from before, which // means that they are scheduled to be redrawn. But as we now scroll, those dirty rects @@ -4851,19 +4847,20 @@ void QWidgetPrivate::scroll_sys(int dx, int dy, const QRect &qscrollRect) // rect, the old calls to setNeedsDisplay still makes sense. // NB: Using [view translateRectsNeedingDisplayInRect:nsscrollRect by:deltaSize] have // so far not been proven fruitful to solve this problem. - const QVector<QRect> &rects = dirtyOnWidget.rects(); - const QVector<QRect>::const_iterator end = rects.end(); - QVector<QRect>::const_iterator it = rects.begin(); - while (it != end) { - QRect qdirtyRect = *it; - if (isAlien) { - const QPoint dirtyTopLeftInsideNative = nativeWidget->mapFromGlobal(q->mapToGlobal(qdirtyRect.topLeft())); - qdirtyRect.moveTo(dirtyTopLeftInsideNative); - } - const NSRect nsdirtyRect = NSMakeRect(qdirtyRect.x() + dx, qdirtyRect.y() + dy, qdirtyRect.width(), qdirtyRect.height()); - [view setNeedsDisplayInRect:nsdirtyRect]; - ++it; + const QVector<QRect> &dirtyRectsToScroll = dirtyOnWidget.rects(); + for (int i=0; i<dirtyRectsToScroll.size(); ++i) { + QRect qdirtyRect = dirtyRectsToScroll[i]; + qdirtyRect.moveBy(dx, dy); + update_sys(qdirtyRect); } + + // Update newly exposed areas. This will generate new dirty areas on + // q, and therefore, we do it after updating the old dirty rects above: + if (dx != 0) + update_sys(deltaXRect); + if (dy != 0) + update_sys(deltaYRect); + #endif // QT_MAC_USE_COCOA } |