From a29e4eaff5889eee632ce93c2e6a313cd9c011a1 Mon Sep 17 00:00:00 2001 From: Tobias Deiminger Date: Thu, 22 Nov 2018 18:50:14 +0100 Subject: [PATCH] Fix inconsistent viewport positioning in PageView Summary: This diff unifies the calculation of the viewport position from a given DocumentViewport. PageView::notifyViewportChanged and PageView::slotRelayoutPages used to handle it differntly, which resulted in viewport jumps for no reason. It happened in various situations, e.g. when jumping to a page using the footer page navigation, or when reloading the document after presentation mode left, or when resizing the main window after presentation mode left. The diff selects the notifyViewportChanged way (align viewport top border with page top margin) as golden behavior in case of rePos.enabled == false. BUGS: 357958 CCBUG: 341939 CCBUG: 400890 341939 and 400890 are fixed partially. These two still suffer from a minor displacement that happens when finished signal arrives from pixmap generation thread. Test Plan: - When using the footer page navigation to jump to different pages, new page top is always algined with viewport top. - After changing page with footer page navigation, press F5 to reload. Page top stays aligned with viewport top. - When exiting presentation mode, and touching the file, page top stays aligned with viewport top. - When exiting presentation mode, and changing main window size, page top stays aligned with viewport top. Reviewers: #okular, sander Reviewed By: sander Subscribers: ngraham, sander, aacid, okular-devel Tags: #okular Differential Revision: https://phabricator.kde.org/D16941 --- autotests/data/simple-multipage.pdf | Bin 0 -> 18473 bytes autotests/data/simple-multipage.tex | 82 ++++++++++++++++++++++++++++ autotests/parttest.cpp | 30 ++++++++++ ui/pageview.cpp | 67 +++++++++++++---------- ui/pageview.h | 1 + 5 files changed, 150 insertions(+), 30 deletions(-) create mode 100755 autotests/data/simple-multipage.pdf create mode 100755 autotests/data/simple-multipage.tex diff --git a/autotests/data/simple-multipage.pdf b/autotests/data/simple-multipage.pdf new file mode 100755 index 0000000000000000000000000000000000000000..eff96927de2e0b7b00047dd22a9fbff79281a5b6 GIT binary patch literal 18473 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, 600); + part.widget()->show(); + QVERIFY( QTest::qWaitForWindowExposed( part.widget() ) ); + + part.m_document->pages(); + part.m_document->setViewportPage( targetPage ); + + /* Document::setViewportPage triggers pixmap rendering in another thread. + * We want to test how things look AFTER finished signal arrives back, + * because PageView::slotRelayoutPages may displace the viewport again. + */ + QTRY_VERIFY( part.m_document->page( targetPage )->hasPixmap( part.m_pageView ) ); + + const int contentAreaHeight = part.m_pageView->verticalScrollBar()->maximum() + part.m_pageView->viewport()->height(); + const int pageWithSpaceTop = contentAreaHeight / part.m_document->pages() * targetPage; + + /* + * This is a test for a "known by trial" displacement. + * We'd need access to part.m_pageView->d->items[targetPage]->croppedGeometry().top(), + * to determine the expected viewport position, but we don't have access. + */ + QCOMPARE(part.m_pageView->verticalScrollBar()->value(), pageWithSpaceTop - 4); +} + } // namespace Okular int main(int argc, char *argv[]) diff --git a/ui/pageview.cpp b/ui/pageview.cpp index a23aa5293..ee3a03ed4 100644 --- a/ui/pageview.cpp +++ b/ui/pageview.cpp @@ -1331,36 +1331,15 @@ void PageView::slotRealNotifyViewportChanged( bool smoothMove ) slotRelayoutPages(); // restore viewport center or use default {x-center,v-top} alignment - const QRect & r = item->croppedGeometry(); - int newCenterX = r.left(), - newCenterY = r.top(); - if ( vp.rePos.enabled ) - { - if ( vp.rePos.pos == Okular::DocumentViewport::Center ) - { - newCenterX += (int)( normClamp( vp.rePos.normalizedX, 0.5 ) * (double)r.width() ); - newCenterY += (int)( normClamp( vp.rePos.normalizedY, 0.0 ) * (double)r.height() ); - } - else - { - // TopLeft - newCenterX += (int)( normClamp( vp.rePos.normalizedX, 0.0 ) * (double)r.width() + viewport()->width() / 2 ); - newCenterY += (int)( normClamp( vp.rePos.normalizedY, 0.0 ) * (double)r.height() + viewport()->height() / 2 ); - } - } - else - { - newCenterX += r.width() / 2; - newCenterY += viewport()->height() / 2 - 10; - } + const QPoint centerCoord = viewportToContentArea( vp ); // if smooth movement requested, setup parameters and start it if ( smoothMove ) { d->viewportMoveActive = true; d->viewportMoveTime.start(); - d->viewportMoveDest.setX( newCenterX ); - d->viewportMoveDest.setY( newCenterY ); + d->viewportMoveDest.setX( centerCoord.x() ); + d->viewportMoveDest.setY( centerCoord.y() ); if ( !d->viewportMoveTimer ) { d->viewportMoveTimer = new QTimer( this ); @@ -1372,7 +1351,7 @@ void PageView::slotRealNotifyViewportChanged( bool smoothMove ) horizontalScrollBar()->setEnabled( false ); } else - center( newCenterX, newCenterY ); + center( centerCoord.x(), centerCoord.y() ); d->blockPixmapsRequest = false; // request visible pixmaps in the current viewport and recompute it @@ -3805,6 +3784,35 @@ void PageView::scrollPosIntoView( const QPoint & pos ) else d->dragScrollTimer.stop(); } +QPoint PageView::viewportToContentArea( const Okular::DocumentViewport & vp ) const { + Q_ASSERT( vp.pageNumber >= 0 ); + + const QRect & r = d->items[ vp.pageNumber ]->croppedGeometry(); + QPoint c { r.left(), r.top() }; + + if ( vp.rePos.enabled ) + { + if ( vp.rePos.pos == Okular::DocumentViewport::Center ) + { + c.rx() += qRound( normClamp( vp.rePos.normalizedX, 0.5 ) * (double)r.width() ); + c.ry() += qRound( normClamp( vp.rePos.normalizedY, 0.0 ) * (double)r.height() ); + } + else + { + // TopLeft + c.rx() += qRound( normClamp( vp.rePos.normalizedX, 0.0 ) * (double)r.width() + viewport()->width() / 2 ); + c.ry() += qRound( normClamp( vp.rePos.normalizedY, 0.0 ) * (double)r.height() + viewport()->height() / 2 ); + } + } + else + { + // exact repositioning disabled, align page top margin with viewport top border by default + c.rx() += r.width() / 2; + c.ry() += viewport()->height() / 2 - 10; + } + return c; +} + void PageView::updateSelection( const QPoint & pos ) { if ( d->mouseSelecting ) @@ -4644,11 +4652,10 @@ void PageView::slotRelayoutPages() { int prevX = horizontalScrollBar()->value(), prevY = verticalScrollBar()->value(); - const QRect & geometry = d->items[ vp.pageNumber ]->croppedGeometry(); - double nX = vp.rePos.enabled ? normClamp( vp.rePos.normalizedX, 0.5 ) : 0.5, - nY = vp.rePos.enabled ? normClamp( vp.rePos.normalizedY, 0.0 ) : 0.0; - center( geometry.left() + qRound( nX * (double)geometry.width() ), - geometry.top() + qRound( nY * (double)geometry.height() ) ); + + const QPoint centerPos = viewportToContentArea( vp ); + center( centerPos.x(), centerPos.y() ); + // center() usually moves the viewport, that requests pixmaps too. // if that doesn't happen we have to request them by hand if ( prevX == horizontalScrollBar()->value() && prevY == verticalScrollBar()->value() ) diff --git a/ui/pageview.h b/ui/pageview.h index b995c6123..637f8054a 100644 --- a/ui/pageview.h +++ b/ui/pageview.h @@ -198,6 +198,7 @@ Q_OBJECT QMenu* createProcessLinkMenu( PageViewItem *item, const QPoint & eventPos ); // used when selecting stuff, makes the view scroll as necessary to keep the mouse inside the view void scrollPosIntoView( const QPoint & pos ); + QPoint viewportToContentArea( const Okular::DocumentViewport & vp ) const; // called from slots to turn off trim modes mutually exclusive to id void updateTrimMode( int except_id );