commit 288684356016f5cca7959462735f6153cd1adab2
Author: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date:   Wed Jul 3 00:22:55 2024 +0200

    Make sure paragraph positions are updated when scrolling
    
    Sometimes quick selection-scrolling could cause a crash because the
    position of some paragraphs is not computed. To fix that, in
    BufferView::showCursor, make sure that the metrics are always kept
    clean using updateMetrics(false), which is lighweight.
    
    As a consequence, the 'update' parameter of showCursor and
    scrollDocView is not needed anymore. Its removal is mechanical and
    accounts for most of this commit.
    
    The only other significant change is that, when creating synthetic
    mouse events and relying on scroll() for small moves, the full metrics
    recomputation is replaced by the lighter version.
    
    More work is still to come on this code, but this should be going in
    the right direction.
    
    (cherry picked from commit 6e0ea4269ae792225bb4e0d0f0ffcb3236c3c5c9)
---
 src/BufferView.cpp               | 21 ++++++++++-----------
 src/BufferView.h                 |  5 ++---
 src/frontends/qt/GuiWorkArea.cpp |  6 +++---
 3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index ec77a81c46..428c03299f 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -755,7 +755,7 @@ Inset const * BufferView::mathContextMenu(InsetMathNest 
const * inset,
 }
 
 
-void BufferView::scrollDocView(int const pixels, bool update)
+void BufferView::scrollDocView(int const pixels)
 {
        // The scrollbar values are relative to the top of the screen, 
therefore the
        // offset is equal to the target value.
@@ -778,7 +778,7 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
        // cut off at the top
        if (pixels <= d->scrollbarParameters_.min) {
                DocIterator dit = doc_iterator_begin(&buffer_);
-               showCursor(dit, SCROLL_VISIBLE, update);
+               showCursor(dit, SCROLL_VISIBLE);
                LYXERR(Debug::SCROLLING, "scroll to top");
                return;
        }
@@ -787,7 +787,7 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
        if (pixels >= d->scrollbarParameters_.max) {
                DocIterator dit = doc_iterator_end(&buffer_);
                dit.backwardPos();
-               showCursor(dit, SCROLL_VISIBLE, update);
+               showCursor(dit, SCROLL_VISIBLE);
                LYXERR(Debug::SCROLLING, "scroll to bottom");
                return;
        }
@@ -806,14 +806,14 @@ void BufferView::scrollDocView(int const pixels, bool 
update)
                // It seems we didn't find the correct pit so stay on the safe 
side and
                // scroll to bottom.
                LYXERR0("scrolling position not found!");
-               scrollDocView(d->scrollbarParameters_.max, update);
+               scrollDocView(d->scrollbarParameters_.max);
                return;
        }
 
        DocIterator dit = doc_iterator_begin(&buffer_);
        dit.pit() = i;
        LYXERR(Debug::SCROLLING, "pixels = " << pixels << " -> scroll to pit " 
<< i);
-       showCursor(dit, SCROLL_VISIBLE, update);
+       showCursor(dit, SCROLL_VISIBLE);
 }
 
 
@@ -999,21 +999,20 @@ int BufferView::workWidth() const
 
 void BufferView::recenter()
 {
-       showCursor(d->cursor_, SCROLL_CENTER, true);
+       showCursor(d->cursor_, SCROLL_CENTER);
 }
 
 
 void BufferView::showCursor()
 {
-       showCursor(d->cursor_, SCROLL_VISIBLE, true);
+       showCursor(d->cursor_, SCROLL_VISIBLE);
 }
 
 
-void BufferView::showCursor(DocIterator const & dit, ScrollType how,
-       bool update)
+void BufferView::showCursor(DocIterator const & dit, ScrollType how)
 {
-       if (scrollToCursor(dit, how) && update)
-               processUpdateFlags(Update::Force);
+       if (scrollToCursor(dit, how))
+               processUpdateFlags(Update::ForceDraw);
 }
 
 
diff --git a/src/BufferView.h b/src/BufferView.h
index b5439b7036..ca2d7bee77 100644
--- a/src/BufferView.h
+++ b/src/BufferView.h
@@ -219,8 +219,7 @@ public:
        /// This method will automatically scroll and update the BufferView
        /// (metrics+drawing) if needed.
        /// \param how Use this scroll strategy
-       /// \param force If true, update screen after scrolling
-       void showCursor(DocIterator const & dit, ScrollType how, bool update);
+       void showCursor(DocIterator const & dit, ScrollType how);
        /// Scroll to the cursor.
        /// \param how Use this scroll strategy
        /// \return true if screen was scrolled
@@ -232,7 +231,7 @@ public:
        /// scroll document by the given number of pixels.
        int scroll(int pixels);
        /// Scroll the view by a number of pixels.
-       void scrollDocView(int pixels, bool update);
+       void scrollDocView(int pixels);
        /// Set the cursor position based on the scrollbar one.
        void setCursorFromScrollbar();
 
diff --git a/src/frontends/qt/GuiWorkArea.cpp b/src/frontends/qt/GuiWorkArea.cpp
index 8690b6f4f0..7593d4a0c7 100644
--- a/src/frontends/qt/GuiWorkArea.cpp
+++ b/src/frontends/qt/GuiWorkArea.cpp
@@ -588,7 +588,7 @@ void GuiWorkArea::Private::updateScrollbar()
 void GuiWorkArea::scrollTo(int value)
 {
        stopBlinkingCaret();
-       d->buffer_view_->scrollDocView(value, true);
+       d->buffer_view_->scrollDocView(value);
 
        if (lyxrc.cursor_follows_scrollbar) {
                d->buffer_view_->setCursorFromScrollbar();
@@ -961,9 +961,9 @@ void GuiWorkArea::generateSyntheticMouseEvent()
        // Scroll
        if (step <= 2 * wh) {
                d->buffer_view_->scroll(up ? -step : step);
-               d->buffer_view_->updateMetrics();
+               d->buffer_view_->processUpdateFlags(Update::ForceDraw);
        } else {
-               d->buffer_view_->scrollDocView(value + (up ? -step : step), 
false);
+               d->buffer_view_->scrollDocView(value + (up ? -step : step));
        }
 
        // In which paragraph do we have to set the cursor ?
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to