commit ad80d13026a80f649aec1932a503ca9c44ad70de
Author: Jean-Marc Lasgouttes <[email protected]>
Date: Sun Sep 21 00:07:44 2025 +0200
Fix preview drawing after mouse selection is finished
In order to fix #8951, commit 22030781 was backported from gadmm's
lyx-unstable branch. What this does is record when one is selecting,
and block the the switch to preview when the cursor tip leaves the
previewable inset.
The problem is that there is no notification given when the selection
action is finished (mouse release) and therefore metrics are not
recomputed. So the equation is correctly shown as a preview but relies
on the old no-preview metrics.
This commit implements such a notification:
- Add virtual method notifyMouseSelectionDone() to Inset, InsetMathHull,
InsetPreview and InsetIPA.
- Add function notifyMouseSelectionDone() to Cursor.cpp.
- In BufferView::mouseEventDispatch, call the function above when
needed. Note that the code has been changed to preserve the cursor's
anchor. There might be code that does not expect that.
Fixes bug #13222.
---
src/BufferView.cpp | 17 ++++++++++++-----
src/Cursor.cpp | 20 ++++++++++++++++++++
src/Cursor.h | 3 +++
src/insets/Inset.h | 7 +++++++
src/insets/InsetIPA.cpp | 8 ++++++++
src/insets/InsetIPA.h | 2 ++
src/insets/InsetPreview.cpp | 8 ++++++++
src/insets/InsetPreview.h | 2 ++
src/mathed/InsetMathHull.cpp | 17 +++++++++++++++++
src/mathed/InsetMathHull.h | 3 +++
10 files changed, 82 insertions(+), 5 deletions(-)
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 8e7186db03..20d7b0bbfe 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -2912,8 +2912,13 @@ void BufferView::mouseEventDispatch(FuncRequest const &
cmd0)
d->mouse_position_cache_.x = cmd.x();
d->mouse_position_cache_.y = cmd.y();
- d->mouse_selecting_ =
- cmd.action() == LFUN_MOUSE_MOTION && cmd.button() ==
mouse_button::button1;
+ bool mouse_selection_done = false;
+ if (cmd.action() == LFUN_MOUSE_MOTION && cmd.button() ==
mouse_button::button1)
+ d->mouse_selecting_ = true;
+ else if (d->mouse_selecting_) {
+ mouse_selection_done = true;
+ d->mouse_selecting_ = false;
+ }
if (cmd.action() == LFUN_MOUSE_MOTION && cmd.button() ==
mouse_button::none) {
updateHoveredInset();
@@ -2922,6 +2927,7 @@ void BufferView::mouseEventDispatch(FuncRequest const &
cmd0)
Cursor old = cursor();
Cursor cur(*this);
+ cur.realAnchor() = cursor().realAnchor();
cur.push(buffer_.inset());
cur.selection(d->cursor_.selection());
@@ -2942,9 +2948,6 @@ void BufferView::mouseEventDispatch(FuncRequest const &
cmd0)
cur.posBackward();
}
- // Put anchor at the same position.
- cur.resetAnchor();
-
old.beginUndoGroup();
// Try to dispatch to an non-editable inset near this position
@@ -2970,6 +2973,10 @@ void BufferView::mouseEventDispatch(FuncRequest const &
cmd0)
old.endUndoGroup();
+ // Notify end of selection
+ if (mouse_selection_done)
+ notifyMouseSelectionDone(cur);
+
// Do we have a selection?
theSelection().haveSelection(cursor().selection());
diff --git a/src/Cursor.cpp b/src/Cursor.cpp
index 656ee90dce..b5daf9c860 100644
--- a/src/Cursor.cpp
+++ b/src/Cursor.cpp
@@ -2483,6 +2483,26 @@ bool notifyCursorLeavesOrEnters(Cursor const & old,
Cursor & cur)
}
+void notifyMouseSelectionDone(Cursor & cur)
+{
+ // find inset in common
+ size_type i;
+ DocIterator const & anchor = cur.realAnchor();
+ for (i = 0; i < cur.depth() && i < anchor.depth(); ++i) {
+ if (&anchor[i].inset() != &cur[i].inset())
+ break;
+ }
+
+ // notify everything on top of the common part in old cursor
+ for (size_type j = i; j < anchor.depth(); ++j) {
+ Cursor tmpcur = cur;
+ tmpcur.realAnchor().resize(j + 1);
+ anchor[j].inset().notifyMouseSelectionDone(tmpcur);
+ cur.screenUpdateFlags(cur.result().screenUpdate() |
tmpcur.result().screenUpdate());
+ }
+}
+
+
void Cursor::setLanguageFromInput()
{
if (!lyxrc.respect_os_kbd_language
diff --git a/src/Cursor.h b/src/Cursor.h
index c9cc9738ab..c2fcf63135 100644
--- a/src/Cursor.h
+++ b/src/Cursor.h
@@ -563,6 +563,9 @@ public:
bool notifyCursorLeavesOrEnters(Cursor const & old, Cursor & cur);
+ // Notifies all insets which appear in \c cur anchor, but not in \c cur tip.
+void notifyMouseSelectionDone(Cursor & cur);
+
} // namespace lyx
#endif // CURSOR_H
diff --git a/src/insets/Inset.h b/src/insets/Inset.h
index 653fffa729..75489d2d98 100644
--- a/src/insets/Inset.h
+++ b/src/insets/Inset.h
@@ -327,6 +327,13 @@ public:
/// flags to cause a redraw.
virtual bool notifyCursorEnters(Cursor const & /*old*/, Cursor &
/*cur*/)
{ return false; }
+ // Is called when a mouse selection ends by a mouse release event.
+ // Previews of inset that have been left by the cursor are delayed
+ // until this point, so it is an occasion for insets to ask for
+ // metrics recomputation.
+ // \c cur is the cursor position that contains the final selection.
+ virtual void notifyMouseSelectionDone(Cursor & /*cur*/) {}
+
/// is called when the mouse enters or leaves this inset
/// return true if this inset needs a repaint
virtual bool setMouseHover(BufferView const *, bool) const
diff --git a/src/insets/InsetIPA.cpp b/src/insets/InsetIPA.cpp
index 14bafc109d..ee5acfb27b 100644
--- a/src/insets/InsetIPA.cpp
+++ b/src/insets/InsetIPA.cpp
@@ -223,6 +223,14 @@ bool InsetIPA::notifyCursorLeaves(Cursor const & old,
Cursor & cur)
}
+void InsetIPA::notifyMouseSelectionDone(Cursor & cur)
+{
+ reloadPreview(cur.realAnchor());
+ cur.screenUpdateFlags(Update::Force);
+ return InsetText::notifyMouseSelectionDone(cur);
+}
+
+
void InsetIPA::validate(LaTeXFeatures & features) const
{
features.require("tipa");
diff --git a/src/insets/InsetIPA.h b/src/insets/InsetIPA.h
index c7a5fd44e4..2e2cb8f65f 100644
--- a/src/insets/InsetIPA.h
+++ b/src/insets/InsetIPA.h
@@ -70,6 +70,8 @@ public:
bool notifyCursorLeaves(Cursor const & old, Cursor & cur) override;
+ void notifyMouseSelectionDone(Cursor & cur) override;
+
void write(std::ostream & os) const override;
void edit(Cursor & cur, bool front, EntryDirection entry_from) override;
diff --git a/src/insets/InsetPreview.cpp b/src/insets/InsetPreview.cpp
index 9f3f7d1a15..c978414c18 100644
--- a/src/insets/InsetPreview.cpp
+++ b/src/insets/InsetPreview.cpp
@@ -230,4 +230,12 @@ bool InsetPreview::notifyCursorLeaves(Cursor const & old,
Cursor & cur)
}
+void InsetPreview::notifyMouseSelectionDone(Cursor & cur)
+{
+ reloadPreview(cur.realAnchor());
+ cur.screenUpdateFlags(Update::Force);
+ return InsetText::notifyMouseSelectionDone(cur);
+}
+
+
} // namespace lyx
diff --git a/src/insets/InsetPreview.h b/src/insets/InsetPreview.h
index 6bd30f2217..1dea8e1c56 100644
--- a/src/insets/InsetPreview.h
+++ b/src/insets/InsetPreview.h
@@ -71,6 +71,8 @@ public:
bool notifyCursorLeaves(Cursor const & old, Cursor & cur) override;
+ void notifyMouseSelectionDone(Cursor & cur) override;
+
void write(std::ostream & os) const override;
//@}
diff --git a/src/mathed/InsetMathHull.cpp b/src/mathed/InsetMathHull.cpp
index 230de78a6f..b9d76279af 100644
--- a/src/mathed/InsetMathHull.cpp
+++ b/src/mathed/InsetMathHull.cpp
@@ -960,6 +960,23 @@ bool InsetMathHull::notifyCursorEnters(Cursor const & old,
Cursor & cur)
}
+void InsetMathHull::notifyMouseSelectionDone(Cursor & cur)
+{
+ if (RenderPreview::previewMath()) {
+ reloadPreview(cur.realAnchor());
+ /** FIXME: currently, SinglePar operates on the current
+ * paragraph at processUpdateFlags time (here cur) and not the
+ * paragraph where the change happened (old). When this is
+ * fixed, the following test will become useless.
+ */
+ if (&cur.innerParagraph() == &cur.realAnchor().innerParagraph())
+ cur.screenUpdateFlags(Update::SinglePar);
+ else
+ cur.screenUpdateFlags(Update::Force);
+ }
+}
+
+
bool InsetMathHull::insetAllowed(InsetCode code) const
{
switch (code) {
diff --git a/src/mathed/InsetMathHull.h b/src/mathed/InsetMathHull.h
index 1a4eeec8d4..e25e516e0c 100644
--- a/src/mathed/InsetMathHull.h
+++ b/src/mathed/InsetMathHull.h
@@ -161,6 +161,9 @@ public:
bool notifyCursorEnters(Cursor const & old, Cursor & cur) override;
/// get notification when the cursor leaves this inset
bool notifyCursorLeaves(Cursor const & old, Cursor & cur) override;
+ /// get notification when mouse selection has ended and anchor is
+ /// in this inset but not the cursor tip.
+ void notifyMouseSelectionDone(Cursor & cur) override;
///
bool insetAllowed(InsetCode code) const override;
///
--
lyx-cvs mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-cvs