diff --git a/examples/pdf/multipage/viewer.qml b/examples/pdf/multipage/viewer.qml
index 77c06f80fd9c22a0ea8056626334cf7dc628df23..bbc28cd8dbacd727e8890644661a9c9920064caf 100644
--- a/examples/pdf/multipage/viewer.qml
+++ b/examples/pdf/multipage/viewer.qml
@@ -139,7 +139,7 @@ ApplicationWindow {
                 from: 1
                 to: document.pageCount
                 editable: true
-                onValueChanged: view.currentPage = value - 1
+                onValueModified: view.goToPage(value - 1)
                 Shortcut {
                     sequence: StandardKey.MoveToPreviousPage
                     onActivated: currentPageSB.value--
@@ -256,7 +256,7 @@ ApplicationWindow {
         anchors.fill: parent
         document: root.document
         searchString: searchField.text
-        onCurrentPageReallyChanged: currentPageSB.value = page + 1
+        onCurrentPageChanged: currentPageSB.value = view.currentPage + 1
     }
 
     footer: ToolBar {
diff --git a/src/pdf/quick/qml/PdfMultiPageView.qml b/src/pdf/quick/qml/PdfMultiPageView.qml
index 095081c5da099a2edc7a1d13d489ce66f93b8944..acef9fbea789f593514f28e076c4a85aea5eab74 100644
--- a/src/pdf/quick/qml/PdfMultiPageView.qml
+++ b/src/pdf/quick/qml/PdfMultiPageView.qml
@@ -62,16 +62,19 @@ Item {
     property real pageRotation: 0
     property string searchString
     property string selectedText
-    property alias currentPage: listView.currentIndex
+    property alias currentPage: navigationStack.currentPage
     function copySelectionToClipboard() {
         if (listView.currentItem !== null)
             listView.currentItem.selection.copyToClipboard()
     }
     property alias backEnabled: navigationStack.backAvailable
     property alias forwardEnabled: navigationStack.forwardAvailable
-    function back() { navigationStack.back() }
-    function forward() { navigationStack.forward() }
-    signal currentPageReallyChanged(page: int)
+    function back() {
+        navigationStack.back()
+    }
+    function forward() {
+        navigationStack.forward()
+    }
 
     function resetScale() {
         root.renderScale = 1
@@ -99,6 +102,16 @@ Item {
         }
     }
 
+    function goToPage(page) {
+        goToLocation(page, Qt.point(0, 0), 0)
+    }
+
+    function goToLocation(page, location, zoom) {
+        if (zoom > 0)
+            root.renderScale = zoom
+        navigationStack.push(page, location, zoom)
+    }
+
     id: root
     ListView {
         id: listView
@@ -109,11 +122,7 @@ Item {
         highlightMoveVelocity: 2000 // TODO increase velocity when setting currentIndex somehow, too
         property real rotationModulus: Math.abs(root.pageRotation % 180)
         property bool rot90: rotationModulus > 45 && rotationModulus < 135
-        property size firstPagePointSize: document.pagePointSize(0)
-        onCurrentIndexChanged: {
-            navigationStack.push(currentIndex, Qt.point(0, 0), root.renderScale)
-            root.currentPageReallyChanged(currentIndex)
-        }
+        property size firstPagePointSize: document === undefined ? Qt.size(0, 0) : document.pagePointSize(0)
         delegate: Rectangle {
             id: paper
             implicitWidth: image.width
@@ -233,7 +242,7 @@ Item {
                         cursorShape: Qt.PointingHandCursor
                         onClicked: {
                             if (page >= 0)
-                                listView.currentIndex = page
+                                root.goToLocation(page, location, zoom)
                             else
                                 Qt.openUrlExternally(url)
                         }
@@ -241,11 +250,28 @@ Item {
                 }
             }
         }
-        ScrollBar.vertical: ScrollBar { }
+        ScrollBar.vertical: ScrollBar {
+            property bool moved: false
+            onPositionChanged: moved = true
+            onActiveChanged: {
+                var currentPage = listView.indexAt(0, listView.contentY)
+                var currentItem = listView.itemAtIndex(currentPage)
+                var currentLocation = Qt.point(0, listView.contentY - currentItem.y)
+                if (active) {
+                    moved = false
+                    navigationStack.push(currentPage, currentLocation, root.renderScale);
+                } else if (moved) {
+                    navigationStack.update(currentPage, currentLocation, root.renderScale);
+                }
+            }
+        }
     }
     PdfNavigationStack {
         id: navigationStack
         onJumped: listView.currentIndex = page
-        onCurrentPageChanged: root.currentPageReallyChanged(navigationStack.currentPage)
+        onCurrentPageChanged: listView.positionViewAtIndex(currentPage, ListView.Beginning)
+        onCurrentLocationChanged: listView.contentY += currentLocation.y // currentPageChanged() MUST occur first!
+        onCurrentZoomChanged: root.renderScale = currentZoom
+        // TODO deal with horizontal location (need another Flickable probably)
     }
 }
diff --git a/src/pdf/quick/qquickpdfnavigationstack.cpp b/src/pdf/quick/qquickpdfnavigationstack.cpp
index 57acdc4bc837c03507a8b0c85397d60f21c40de8..51f65f032be54cb004ef4046278ce61f398a0401 100644
--- a/src/pdf/quick/qquickpdfnavigationstack.cpp
+++ b/src/pdf/quick/qquickpdfnavigationstack.cpp
@@ -56,6 +56,7 @@ Q_LOGGING_CATEGORY(qLcNav, "qt.pdf.navigationstack")
 QQuickPdfNavigationStack::QQuickPdfNavigationStack(QObject *parent)
     : QObject(parent)
 {
+    push(0, QPointF(), 1);
 }
 
 /*!