Le 08/02/2025 à 14:12, Pavel Sanda a écrit :
On Sat, Feb 08, 2025 at 02:01:57PM +0100, Pavel Sanda wrote:
I get the crash like 3x in 5min of trying.
The proper layout to get the crash is to have just tiny little of the table
shown in the window (see attachment) and move over it with mouse.
Then hit the next find button.
I can reproduce this issue. Does the patch here work for you? I am
actually frustrated because I do not really understand why the situation
happens. What the patch does it to make some methods more robust instead
(handle the symptoms).
JMarc
From 8ae346c2a5abfc93c6d68cf147df05fd4d9104e7 Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date: Wed, 14 May 2025 11:38:43 +0200
Subject: [PATCH] Fix crashes related to simple search and metrics update
These crashes are a consequence of commit 7f85024f, which improved
performance by not caching position of insets not visible on screen.
This makes a difference, for example, in the case of a tabular inset
which has only its top visible, not its cells.
To this end, introduce the helper methods Inset::hasDim() and
Inset::hasGeometry(), which rely on CoordCache.
This is used in two places:
- In InsetTabular, the methods hitSelectRow and hitSelectColumn return
false if no geometry information exists for the inset.
- In BufferView, the scrollToCursor method check not only he existence
of the toplevel metrics, but also the existence of metrices for the
tip of the document iterator. Indeed, it may happen that the
top-level paragraph has metrics information, but not som if its
contents.
Finally, when handling word-find* lfuns, use directly showCursor()
rather than setting update flags.
---
src/BufferView.cpp | 8 ++++----
src/insets/Inset.cpp | 24 ++++++++++++++++++------
src/insets/Inset.h | 4 ++++
src/insets/InsetTabular.cpp | 4 ++++
4 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 6b8cfa52df..4d9a4b268f 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -1076,7 +1076,7 @@ bool BufferView::scrollToCursor(DocIterator const & dit, ScrollType how)
else if (bot_pit == tm.last().first + 1)
tm.newParMetricsDown();
- if (tm.contains(bot_pit) && how == SCROLL_VISIBLE) {
+ if (how == SCROLL_VISIBLE && tm.contains(bot_pit) && dit.inset().hasDim(*this)) {
ParagraphMetrics const & pm = tm.parMetrics(bot_pit);
LBUFERR(!pm.rows().empty());
// FIXME: smooth scrolling doesn't work in mathed.
@@ -1118,7 +1118,7 @@ bool BufferView::scrollToCursor(DocIterator const & dit, ScrollType how)
pit_type const old_pit = d->anchor_pit_;
int const old_ypos = d->anchor_ypos_;
- if (!tm.contains(bot_pit))
+ if (!tm.contains(bot_pit) || !dit.inset().hasDim(*this))
tm.redoParagraph(bot_pit);
int const offset = coordOffset(dit).y;
@@ -1884,7 +1884,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
act == LFUN_WORD_FIND_FORWARD, false, false, false);
bool found = lyxfind(this, FuncRequest(LFUN_WORD_FIND, data));
if (found)
- dr.screenUpdate(Update::Force | Update::FitCursor);
+ showCursor();
else
dr.setMessage(_("Search string not found!"));
break;
@@ -1899,7 +1899,7 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
break;
}
if (lyxfind(this, FuncRequest(act, arg)))
- dr.screenUpdate(Update::Force | Update::FitCursor);
+ showCursor();
else
dr.setMessage(_("Search string not found!"));
diff --git a/src/insets/Inset.cpp b/src/insets/Inset.cpp
index 70cef59c47..d60e4a8078 100644
--- a/src/insets/Inset.cpp
+++ b/src/insets/Inset.cpp
@@ -323,12 +323,6 @@ string Inset::contextMenuName() const
}
-Dimension const Inset::dimension(BufferView const & bv) const
-{
- return bv.coordCache().insets().dim(this);
-}
-
-
InsetCode insetCode(string const & name)
{
build_translator();
@@ -613,6 +607,24 @@ bool Inset::editing(BufferView const * bv) const
}
+bool Inset::hasDim(BufferView const & bv) const
+{
+ return bv.coordCache().insets().hasDim(this);
+}
+
+
+bool Inset::hasGeometry(BufferView const & bv) const
+{
+ return bv.coordCache().insets().has(this);
+}
+
+
+Dimension const Inset::dimension(BufferView const & bv) const
+{
+ return bv.coordCache().insets().dim(this);
+}
+
+
int Inset::xo(BufferView const & bv) const
{
return bv.coordCache().insets().x(this);
diff --git a/src/insets/Inset.h b/src/insets/Inset.h
index d41c339ebb..13df0e1306 100644
--- a/src/insets/Inset.h
+++ b/src/insets/Inset.h
@@ -236,6 +236,10 @@ public:
/// This can use \c drawMarkers() for example.
virtual void drawDecoration(PainterInfo &, int, int) const {}
+ /// do we have dimension information for this inset ?
+ bool hasDim(BufferView const & bv) const;
+ /// do we have full geometry information for this inset ?
+ bool hasGeometry(BufferView const & bv) const;
/// last metrics computed for the inset
Dimension const dimension(BufferView const &) const;
/// last drawn position for 'important' insets
diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp
index bbf25bb83e..76140cf508 100644
--- a/src/insets/InsetTabular.cpp
+++ b/src/insets/InsetTabular.cpp
@@ -5556,6 +5556,8 @@ void InsetTabular::addToToc(DocIterator const & cpit, bool output_active,
bool InsetTabular::hitSelectRow(BufferView const & bv, int x) const
{
+ if (!hasGeometry(bv))
+ return false;
int const x0 = xo(bv) + ADD_TO_TABULAR_WIDTH;
return x < x0 || x > x0 + tabular.width();
}
@@ -5563,6 +5565,8 @@ bool InsetTabular::hitSelectRow(BufferView const & bv, int x) const
bool InsetTabular::hitSelectColumn(BufferView const & bv, int y) const
{
+ if (!hasGeometry(bv))
+ return false;
int const y0 = yo(bv) - tabular.rowAscent(0) + tabular.offsetVAlignment();
// FIXME: using ADD_TO_TABULAR_WIDTH is not really correct since
// there is no margin added vertically to tabular insets.
--
2.43.0
--
lyx-devel mailing list
lyx-devel@lists.lyx.org
https://lists.lyx.org/mailman/listinfo/lyx-devel