Le 13/04/2024 à 08:10, Jürgen Spitzmüller a écrit :
Note that this is not specific to this particularly inset. I can
reproduce with any other (text) inset, e.g.:

1. Start a new document.
2. Insert a Note inset
3. Save the (new) file (cursor still being in the Note inset).

=> Kaboom.

What happens is that Save As... reloads the buffer (for a reason that is not very clear at this point), which means that all cursors hold bad pointers. It seems that, before the biginset branch removed a few full metrics updates, we could get away with it (presumably some code somewhere fixes the cursors). Now, we have to fix it at the right place.

I propose the following patch. Can you check that it works?

JMarc


From 3b51ab67228f1014432b99ac2037871bc45e1feb Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date: Tue, 16 Apr 2024 11:45:09 +0200
Subject: [PATCH] Sanitize cursors after a buffer has been reloaded

When a buffer is reloaded, its content may remain the same, but the
memory allocation is new, so that the inset pointers in cursors are
now wrong. This requires to sanitize the cursors held by the buffer
views.

Before the biginset branch, some full metrics computation call that is
now removed probably did that as a side effect. Now we have to be more
precise.

To this effect, introduce WorkAreaManager::sanitizeCursors() and use
it in Buffer::reload().
---
 src/Buffer.cpp                    |  2 ++
 src/frontends/WorkArea.h          |  7 +++++++
 src/frontends/WorkAreaManager.cpp | 10 ++++++++++
 src/frontends/WorkAreaManager.h   |  2 ++
 src/frontends/qt/GuiWorkArea.h    |  4 ++--
 5 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index bbe4d80589..c9d6818df6 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -5562,6 +5562,8 @@ Buffer::ReadStatus Buffer::reload()
 	Buffer const * oldparent = d->parent();
 	d->setParent(nullptr);
 	ReadStatus const status = loadLyXFile();
+	// The inset members in cursors held by buffer views are now wrong.
+	workAreaManager().sanitizeCursors();
 	setBusy(false);
 	if (status == ReadSuccess) {
 		updateBuffer();
diff --git a/src/frontends/WorkArea.h b/src/frontends/WorkArea.h
index d6912fc7fa..c0e673554a 100644
--- a/src/frontends/WorkArea.h
+++ b/src/frontends/WorkArea.h
@@ -18,6 +18,8 @@
 
 namespace lyx {
 
+class BufferView;
+
 namespace frontend {
 
 /**
@@ -40,6 +42,11 @@ public:
 
 	/// Update window titles of all users.
 	virtual void updateWindowTitle() = 0;
+
+	///
+	virtual BufferView & bufferView() = 0;
+	///
+	virtual BufferView const & bufferView() const = 0;
 };
 
 } // namespace frontend
diff --git a/src/frontends/WorkAreaManager.cpp b/src/frontends/WorkAreaManager.cpp
index 8d32c6b6d8..ed01be8997 100644
--- a/src/frontends/WorkAreaManager.cpp
+++ b/src/frontends/WorkAreaManager.cpp
@@ -13,6 +13,9 @@
 
 #include "WorkAreaManager.h"
 
+#include "BufferView.h"
+#include "Cursor.h"
+
 #include "Application.h"
 #include "WorkArea.h"
 
@@ -69,6 +72,13 @@ void WorkAreaManager::scheduleRedraw()
 }
 
 
+void WorkAreaManager::sanitizeCursors()
+{
+	for (WorkArea * wa : work_areas_)
+		wa->bufferView().cursor().sanitize();
+}
+
+
 } // namespace frontend
 } // namespace lyx
 
diff --git a/src/frontends/WorkAreaManager.h b/src/frontends/WorkAreaManager.h
index 94c528b3a6..73548592fa 100644
--- a/src/frontends/WorkAreaManager.h
+++ b/src/frontends/WorkAreaManager.h
@@ -49,6 +49,8 @@ public:
 	/// If there is no work area, create a new one in the current view using the
 	/// buffer buf. Returns false if not possible.
 	bool unhide(Buffer * buf) const;
+	/// Fix cursors in all buffer views held by work areas.
+	void sanitizeCursors();
 
 private:
 	typedef std::list<WorkArea *>::iterator iterator;
diff --git a/src/frontends/qt/GuiWorkArea.h b/src/frontends/qt/GuiWorkArea.h
index 148b79b73a..86bbfda939 100644
--- a/src/frontends/qt/GuiWorkArea.h
+++ b/src/frontends/qt/GuiWorkArea.h
@@ -59,9 +59,9 @@ public:
 	/// is GuiView in fullscreen mode?
 	bool isFullScreen() const;
 	///
-	BufferView & bufferView();
+	BufferView & bufferView() override;
 	///
-	BufferView const & bufferView() const;
+	BufferView const & bufferView() const override;
 	///
 	void scheduleRedraw(bool update_metrics) override;
 
-- 
2.40.1

-- 
lyx-devel mailing list
lyx-devel@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to