commit 5271cdb9e8d66539829b263710278ea7737a9705
Author: Jean-Marc Lasgouttes <[email protected]>
Date:   Tue Jun 16 17:15:54 2026 +0200

    Fix notifyCursorLeavesOrEnters with selections
    
    It may happen that cursor "old" points deeper inside an inset than the
    anchor when doing a selection. This can happens for example when
    selecting with the mouse, where BufferView::mouseEventDispatch() will
    first put the main DocIterator inside a nested inset and later will
    correct that to have a depth compatible with the anchor.
    
    When this happens, notifyCursorLeavesOrEnters could notify a `leave'
    to the selected insets, which is not desirable.
    
    This commit fixes the function so that, when selecting, it only
    considers slices that are compatible with the anchors of both old and
    new cursor.
    
    Fixes bug #13338 (see #13305 for a discussion).
    
    (cherry picked from commit 4dd20ebe45f3f8b1e6880edcee7e49cde29d392f)
---
 src/Cursor.cpp | 27 +++++++++++++++++++++++----
 status.25x     |  2 ++
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/src/Cursor.cpp b/src/Cursor.cpp
index 52c8bf2821..6d55ae86c7 100644
--- a/src/Cursor.cpp
+++ b/src/Cursor.cpp
@@ -2453,15 +2453,34 @@ void Cursor::sanitize()
 
 bool notifyCursorLeavesOrEnters(Cursor const & old, Cursor & cur)
 {
+       // handle selections: the real depth is the deepest element shared
+       // by cursor and anchor.
+       // First the new cursor...
+       size_type real_cur_depth = cur.depth();
+       if (cur.selection())
+               for (size_type i = 0 ; i < min(cur.depth(), 
cur.realAnchor().depth()) ; ++i)
+                       if (&cur[i].inset() != &cur.realAnchor()[i].inset()) {
+                               real_cur_depth = i;
+                               break;
+                       }
+       // ... and then the old one.
+       size_type real_old_depth = old.depth();
+       if (old.selection())
+               for (size_type i = 0 ; i < min(old.depth(), 
old.realAnchor().depth()) ; ++i)
+                       if (&old[i].inset() != &old.realAnchor()[i].inset()) {
+                               real_old_depth = i;
+                               break;
+                       }
+
        // find inset in common
        size_type i;
-       for (i = 0; i < old.depth() && i < cur.depth(); ++i) {
+       for (i = 0; i < real_old_depth && i < real_cur_depth; ++i) {
                if (&old[i].inset() != &cur[i].inset())
                        break;
        }
 
        // update words if we just moved to another paragraph
-       if (i == old.depth() && i == cur.depth()
+       if (i == real_old_depth && i == real_cur_depth
            && !cur.buffer()->isClean()
            && cur.inTexted() && old.inTexted()
            && cur.pit() != old.pit()) {
@@ -2470,7 +2489,7 @@ bool notifyCursorLeavesOrEnters(Cursor const & old, 
Cursor & cur)
 
        // notify everything on top of the common part in old cursor,
        // but stop if the inset claims the cursor to be invalid now
-       for (size_type j = i; j < old.depth(); ++j) {
+       for (size_type j = i; j < real_old_depth; ++j) {
                Cursor inset_pos = old;
                inset_pos.resize(j + 1);
                if (old[j].inset().notifyCursorLeaves(inset_pos, cur))
@@ -2479,7 +2498,7 @@ bool notifyCursorLeavesOrEnters(Cursor const & old, 
Cursor & cur)
 
        // notify everything on top of the common part in new cursor,
        // but stop if the inset claims the cursor to be invalid now
-       for (; i < cur.depth(); ++i) {
+       for (; i < real_cur_depth; ++i) {
                if (cur[i].inset().notifyCursorEnters(old, cur))
                        return true;
        }
diff --git a/status.25x b/status.25x
index c36fd7d0cf..cd8097914d 100644
--- a/status.25x
+++ b/status.25x
@@ -35,6 +35,8 @@ What's new
 - improve performance of code panel with a document with many math
   macros (bug 13321).
 
+- Avoid big delays when selecting a macro definition (bug 13338).
+
 
 * DOCUMENTATION AND LOCALIZATION
 
-- 
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs

Reply via email to