[LyX/master] Fix notifyCursorLeavesOrEnters with selections
Jean-Marc Lasgouttes <[email protected]> Fri, 26 Jun 2026 17:52:04 +0000
| Newsgroups | gmane.editors.lyx.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 4dd20ebe45f3f8b1e6880edcee7e49cde29d392f 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). --- src/Cursor.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Cursor.cpp b/src/Cursor.cpp index 3141660515..2b713a80f5 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].realInset() != cur[i].realInset()) 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].realInset()->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].realInset()->notifyCursorEnters(old, cur)) return true; } -- lyx-cvs mailing list [email protected] https://lists.lyx.org/mailman/listinfo/lyx-cvs