Debugging this a little bit further (I like tricky bugs) shows a number of 
surprising facts.

1) One undo step sometimes calls Segment::notifyRemove more than once.

This is because BasicCommand::unexecute() calls copyFrom() which does

m_segment->erase(m_segment->findTime(m_modifiedEventsStart), 
   m_segment->findTime(m_modifiedEventsEnd));

As the comment in BasicCommand.cpp:302 says, surely this copyFrom() should be 
done without firing notifications?

Note however that this isn't the actual problem. It's just rather confusing 
while debugging ;)
But even if MatrixScene::handleEventRemoved() is called multiple times,
the update() in there has no effect after the first call.
The first call sets d->updateAll to true (in QGraphicsScene), the following 
calls return immediately because updateAll is true. It gets set to false 
whenever actual drawing happens (QGraphicsScene::drawItems, called by 
QGraphicsView::paintEvent).

2) While debugging deep within Qt, I found out that the "dirty" region of the 
graphicsview's viewport is only 4 pixels wide, because 
Panned::showPositionPointer calls viewport()->update(oldRect) which is a 4 
pixels wide rectangle. Normally the graphicsview is repainted via the scene's 
update() mechanism (which stores a dirtyRegion in QGraphicsView itself). I 
think the heart of the bug is a collision between the two update mechanisms. 
The scene thinks it's going to trigger a repaint of the whole view, but the 
view has stored only a tiny update region.

I think it can be fixed by using scene()->update() instead.
Patch attached, please test (I have of course reverted the commit that removes 
the update() call from MatrixScene::handleEventRemoved).

But this makes me wonder, why is the "pointer" drawn in drawForeground, after 
these complex manual updates, instead of making the pointer a graphics item
and letting QGraphicsScene/QGraphicsView take care of updating correctly for 
that item?

-- 
David Faure, fa...@kde.org, http://www.davidfaure.fr
Working on KDE Frameworks 5
diff --git c/src/gui/widgets/Panned.cpp i/src/gui/widgets/Panned.cpp
index 9ade8f1c2..c9ee21904 100644
--- c/src/gui/widgets/Panned.cpp
+++ i/src/gui/widgets/Panned.cpp
@@ -152,21 +152,19 @@ void
 Panned::showPositionPointer(float x) // scene coord; full height
 {
     if (m_pointerVisible) {
-        QRect oldRect = QRect(mapFromScene(m_pointerTop),
-                              QSize(4, viewport()->height()));
+        QRectF oldRect(m_pointerTop, QSizeF(4, height()));
         oldRect.moveTop(0);
         oldRect.moveLeft(oldRect.left() - 1);
-        viewport()->update(oldRect);
+        scene()->update(oldRect);
 //        RG_DEBUG << "Panned::slotShowPositionPointer: old rect " << oldRect;
     }
     m_pointerVisible = true;
     m_pointerTop = QPointF(x, 0);
     m_pointerHeight = 0;
-    QRect newRect = QRect(mapFromScene(m_pointerTop),
-                          QSize(4, viewport()->height()));
+    QRectF newRect(m_pointerTop, QSizeF(4, height()));
     newRect.moveTop(0);
     newRect.moveLeft(newRect.left() - 1);
-    viewport()->update(newRect);
+    scene()->update(newRect);
 //    RG_DEBUG << "Panned::slotShowPositionPointer: new rect " << newRect;
 }
 
@@ -176,7 +174,7 @@ Panned::showPositionPointer(QPointF top, float height) // scene coords
     m_pointerVisible = true;
     m_pointerTop = top;
     m_pointerHeight = height;
-    viewport()->update(); //!!! should update old and new pointer areas only, as in the previous function
+    scene()->update(); //!!! should update old and new pointer areas only, as in the previous function
 }
 
 void
@@ -290,7 +288,7 @@ void
 Panned::hidePositionPointer()
 {
     m_pointerVisible = false;
-    viewport()->update(); //!!! should update old pointer area only, really
+    scene()->update(); //!!! should update old pointer area only, really
 }
 
 void
_______________________________________________
Rosegarden-devel mailing list
Rosegarden-devel@lists.sourceforge.net - use the link below to unsubscribe
https://lists.sourceforge.net/lists/listinfo/rosegarden-devel

Reply via email to