Le 23/10/2017 à 22:26, Pavel Sanda a écrit :
And I have reproducible crash:
1. start new document
2. write "ambititious ", spellcheck correctly underlies text.
3. try to fix spelling via context menu, choose "ambitious"
4. kaboom

Here is a patch, that raises as many question as is solves. The issue is that lyxreplace uses Buffer::update, which does an update in the middle of a dispatch operation (it is necessary to look at the full backtrace to see what happens). This is of course terribly dangerous.

The patch does the right thing by using Cursor::message instead (so that the message is set at the end), but I am sure that there are other places where this may happen. I'd be grateful for ideas that would make buffer::message and BufferView::message safer. It might be enough to just delay the setting of the message in GuiView.

JMarc

PS: I will be in vacation for the next week, so don't expect more than replying to some mail during this time.
diff --git a/src/BufferView.cpp b/src/BufferView.cpp
index 4e2428d7d7..c6c0cf17f7 100644
--- a/src/BufferView.cpp
+++ b/src/BufferView.cpp
@@ -82,6 +82,7 @@
 #include "support/lassert.h"
 #include "support/lstrings.h"
 #include "support/Package.h"
+#include "support/RefChanger.h"
 #include "support/types.h"
 
 #include <cerrno>
@@ -2763,6 +2764,7 @@ void BufferView::updatePosCache()
 	// this is the "nodraw" drawing stage: only set the positions of the
 	// insets in metrics cache.
 	frontend::NullPainter np;
+	Changer chg = make_change(d->update_strategy_, FullScreenUpdate);
 	draw(np, false);
 }
 
diff --git a/src/Cursor.h b/src/Cursor.h
index 6c5e5e6783..955c702655 100644
--- a/src/Cursor.h
+++ b/src/Cursor.h
@@ -274,9 +274,9 @@ public:
 	bool getStatus(FuncRequest const & cmd, FuncStatus & flag) const;
 	/// dispatch from innermost inset upwards
 	void dispatch(FuncRequest const & cmd);
-	/// display a message
+	/// set a message to display after getStatus/dispatch
 	void message(docstring const & msg) const;
-	/// display an error message
+	/// set an error  message to display after getStatus/dispatch
 	void errorMessage(docstring const & msg) const;
 	/// get the resut of the last dispatch
 	DispatchResult const & result() const;
diff --git a/src/lyxfind.cpp b/src/lyxfind.cpp
index 4b8da77ac0..b5b3b7d921 100644
--- a/src/lyxfind.cpp
+++ b/src/lyxfind.cpp
@@ -391,19 +391,19 @@ bool lyxreplace(BufferView * bv,
 			replace_count = rv.second;
 		}
 
-		Buffer const & buf = bv->buffer();
+		Cursor & cur = bv->cursor();
 		if (!update) {
 			// emit message signal.
-			buf.message(_("String not found."));
+			cur.message(_("String not found."));
 		} else {
 			if (replace_count == 0) {
-				buf.message(_("String found."));
+				cur.message(_("String found."));
 			} else if (replace_count == 1) {
-				buf.message(_("String has been replaced."));
+				cur.message(_("String has been replaced."));
 			} else {
 				docstring const str =
 					bformat(_("%1$d strings have been replaced."), replace_count);
-				buf.message(str);
+				cur.message(str);
 			}
 		}
 	} else if (findnext) {
@@ -412,7 +412,7 @@ bool lyxreplace(BufferView * bv,
 		if (findOne(bv, search, casesensitive, matchword, forward, true, findnext))
 			update = true;
 		else
-			bv->message(_("String not found."));
+			bv->cursor().message(_("String not found."));
 	}
 	return update;
 }

Reply via email to