Bug 547577 - nsWindow::Scroll must be updated for widget QT port. r=dougt

This commit is contained in:
Oleg Romashin
2010-02-25 22:45:37 +02:00
parent fc5c3afffb
commit 09a099e466
3 changed files with 58 additions and 18 deletions

View File

@@ -231,8 +231,15 @@ UpdateOffScreenBuffers(QSize aSize, int aDepth)
if (!gBufferPixmap)
return false;
if (gfxQtPlatform::GetPlatform()->GetRenderMode() == gfxQtPlatform::RENDER_XLIB)
if (gfxQtPlatform::GetPlatform()->GetRenderMode() == gfxQtPlatform::RENDER_XLIB) {
if (!gBufferPixmap->handle()) {
NS_ERROR("XDrawable must be available for QPixmap in RENDER_XLIB mode");
delete gBufferPixmap;
gBufferPixmap = nsnull;
return false;
}
return true;
}
// Check if system depth has related gfxImage format
gfxASurface::gfxImageFormat format =
@@ -653,7 +660,10 @@ nsWindow::Update()
if (!mWidget)
return NS_OK;
mWidget->update(); // FIXME This call cause update for whole window on each scroll event
// Just proceed all pending paints
if (GetViewWidget())
GetViewWidget()->repaint();
return NS_OK;
}
@@ -688,9 +698,21 @@ nsWindow::Scroll(const nsIntPoint& aDelta,
for (BlitRectIter iter(aDelta, aDestRects); !iter.IsDone(); ++iter) {
const nsIntRect & r = iter.Rect();
QRect rect(r.x - aDelta.x, r.y - aDelta.y, r.width, r.height);
mWidget->scroll(aDelta.x, aDelta.y, rect);
QRegion goodReg(QRect(r.x, r.y, r.width, r.height));
goodReg = goodReg.subtracted(mDirtyScrollArea);
const QVector<QRect> myRects = goodReg.rects();
for (QVector<QRect>::const_iterator it = myRects.constBegin(); it < myRects.constEnd(); ++it) {
QRect rect(*it);
mWidget->scroll(aDelta.x, aDelta.y, rect);
// Calculate dirty area which is need to be updated
QRegion dirtyReg(rect);
rect.translate(aDelta.x, aDelta.y);
dirtyReg = dirtyReg.subtracted(rect);
mDirtyScrollArea = mDirtyScrollArea.united(dirtyReg);
}
}
ConfigureChildren(aConfigurations);
// Show windows again...
@@ -961,20 +983,13 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
if (!mWidget)
return nsEventStatus_eIgnore;
static NS_DEFINE_CID(kRegionCID, NS_REGION_CID);
nsCOMPtr<nsIRegion> updateRegion = do_CreateInstance(kRegionCID);
if (!updateRegion)
return nsEventStatus_eIgnore;
QRectF r;
if (aOption)
r = aOption->exposedRect;
else
r = mWidget->boundingRect();
updateRegion->SetTo( (int)r.x(), (int)r.y(), (int)r.width(), (int)r.height() );
mDirtyScrollArea = QRegion();
gfxQtPlatform::RenderMode renderMode = gfxQtPlatform::GetPlatform()->GetRenderMode();
// Prepare offscreen buffers if RenderMode Xlib or Image
@@ -1009,8 +1024,8 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
nsIntRect rect(r.x(), r.y(), r.width(), r.height());
event.refPoint.x = r.x();
event.refPoint.y = r.y();
event.rect = nsnull;
event.region = updateRegion;
event.rect = &rect;
event.region = nsnull;
event.renderingContext = rc;
nsEventStatus status = DispatchEvent(&event);
@@ -1025,7 +1040,10 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
LOGDRAW(("[%p] draw done\n", this));
if (renderMode == gfxQtPlatform::RENDER_SHARED_IMAGE) {
// If handle not available for QPixmap it means that we are using
// "-graphicssystem raster" rendering backend
// in raster mode we can just wrap gBufferImage as QImage and paint directly
if (renderMode == gfxQtPlatform::RENDER_SHARED_IMAGE && gBufferPixmap->handle()) {
if (gNeedColorConversion) {
pixman_image_t *src_image = NULL;
pixman_image_t *dst_image = NULL;
@@ -1057,13 +1075,25 @@ nsWindow::DoPaint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption)
gcv.graphics_exposures = False;
GC gc = XCreateGC (disp, gBufferPixmap->handle(), GCGraphicsExposures, &gcv);
XShmPutImage(disp, gBufferPixmap->handle(), gc, gBufferImage->image(),
0, 0, 0, 0, gBufferImage->GetSize().width, gBufferImage->GetSize().height,
rect.x, rect.y, rect.x, rect.y, rect.width, rect.height,
False);
XFreeGC (disp, gc);
}
if (renderMode != gfxQtPlatform::RENDER_QPAINTER)
aPainter->drawPixmap(QPoint(0, 0), *gBufferPixmap);
if (renderMode != gfxQtPlatform::RENDER_QPAINTER) {
if (gBufferPixmap->handle())
aPainter->drawPixmap(QPoint(rect.x, rect.y), *gBufferPixmap,
QRect(rect.x, rect.y, rect.width, rect.height));
else {
QImage img(gBufferImage->Data(),
gBufferImage->Width(),
gBufferImage->Height(),
gBufferImage->Stride(),
QImage::Format_RGB32);
aPainter->drawImage(QPoint(rect.x, rect.y), img,
QRect(rect.x, rect.y, rect.width, rect.height));
}
}
ctx = nsnull;
targetSurface = nsnull;
@@ -1964,6 +1994,10 @@ nsWindow::createQWidget(MozQWidget *parent, nsWidgetInitData *aInitData)
if (mScene && newView) {
mScene->addItem(widget);
newView->setTopLevel(widget);
#if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
// Top level widget is just container, and should not be painted
widget->setFlag(QGraphicsItem::ItemHasNoContents);
#endif
}
if (mWindowType == eWindowType_popup) {