summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@nokia.com>2011-01-21 08:10:24 (GMT)
committerRichard Moe Gustavsen <richard.gustavsen@nokia.com>2011-01-21 10:39:40 (GMT)
commit0a1e41a7192f0ac92cba16a82369a6fef633ac3d (patch)
tree88e3448eb9e89f148a8822a9cae570745085dd56 /src/gui
parent5e5e16fd7107334e10939592170fc322cfa86da9 (diff)
downloadQt-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.mm87
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
}