commit f4abcc5674c77b0166fc7c44325afea45ea8bad8
Author: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date:   Thu Jan 9 12:00:04 2025 +0100

    Check that paragraph has a position when computing cursor position
    
    Rename BufferView::paragraphVisible to BufferView::hasPosition to
    reflect better its semantics. Add a check on the validity of paragraph
    position in metrics.
    
    In Cursor::saveBeforeDispatchPosXY, check BufferView::hasPosition
    before computing position.
    
    Finally, use caretInView in GuiCompleter::updatePopup, since this is
    what is really needed here.
    
    There still remains cases where getPos() is called without a proper
    check of the metrics beforehand. Time will tell whether they are a problem.
    
    (cherry picked from commit 0fa3aba5c6ebf40738abfd3fa480c046f787766b)
---
 src/BufferView.cpp                | 8 ++++----
 src/BufferView.h                  | 4 ++--
 src/Cursor.cpp                    | 6 +++++-
 src/frontends/qt/GuiCompleter.cpp | 3 +--
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index ff62bd2af5..8194271d29 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -3464,7 +3464,7 @@ Point BufferView::coordOffset(DocIterator const & dit) 
const
 
 Point BufferView::getPos(DocIterator const & dit) const
 {
-       if (!paragraphVisible(dit))
+       if (!hasPosition(dit))
                return Point(-1, -1);
 
        CursorSlice const & bot = dit.bottom();
@@ -3477,12 +3477,12 @@ Point BufferView::getPos(DocIterator const & dit) const
 }
 
 
-bool BufferView::paragraphVisible(DocIterator const & dit) const
+bool BufferView::hasPosition(DocIterator const & dit) const
 {
        CursorSlice const & bot = dit.bottom();
        TextMetrics const & tm = textMetrics(bot.text());
 
-       return tm.contains(bot.pit());
+       return tm.contains(bot.pit()) && tm.parMetrics(bot.pit()).hasPosition();
 }
 
 
@@ -3594,7 +3594,7 @@ frontend::CaretGeometry const &  
BufferView::caretGeometry() const
 
 bool BufferView::caretInView() const
 {
-       if (!paragraphVisible(cursor()))
+       if (!hasPosition(cursor()))
                return false;
        Point p;
        Dimension dim;
diff --git a/src/BufferView.h b/src/BufferView.h
index ca2d7bee77..6f61394429 100644
--- a/src/BufferView.h
+++ b/src/BufferView.h
@@ -336,8 +336,8 @@ public:
 
        ///
        Point getPos(DocIterator const & dit) const;
-       /// is the paragraph of the cursor visible ?
-       bool paragraphVisible(DocIterator const & dit) const;
+       /// is there enough metrics information to compute iterator position?
+       bool hasPosition(DocIterator const & dit) const;
        /// is the caret currently visible in the view
        bool caretInView() const;
        /// get the position and height of the caret
diff --git a/src/Cursor.cpp b/src/Cursor.cpp
index b235200db9..13c99ca0bb 100644
--- a/src/Cursor.cpp
+++ b/src/Cursor.cpp
@@ -772,7 +772,11 @@ bool Cursor::getStatus(FuncRequest const & cmd, FuncStatus 
& status) const
 
 void Cursor::saveBeforeDispatchPosXY()
 {
-       getPos(beforeDispatchPosX_, beforeDispatchPosY_);
+       // FIXME: it is known that the case where the position is not
+       // known exist, in particular with previews. The question is
+       // whether not saving the cursor position is bad in these cases.
+       if (bv().hasPosition(*this))
+               getPos(beforeDispatchPosX_, beforeDispatchPosY_);
 }
 
 
diff --git a/src/frontends/qt/GuiCompleter.cpp 
b/src/frontends/qt/GuiCompleter.cpp
index 01ae3ccec8..3fe4946336 100644
--- a/src/frontends/qt/GuiCompleter.cpp
+++ b/src/frontends/qt/GuiCompleter.cpp
@@ -431,8 +431,7 @@ void GuiCompleter::updatePopup(Cursor const & cur)
 void GuiCompleter::asyncUpdatePopup()
 {
        Cursor cur = gui_->bufferView().cursor();
-       if (!cur.inset().completionSupported(cur)
-                 || !cur.bv().paragraphVisible(cur)) {
+       if (!cur.inset().completionSupported(cur) || !cur.bv().caretInView()) {
                popupVisible_ = false;
                return;
        }
-- 
lyx-cvs mailing list
lyx-cvs@lists.lyx.org
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to