From 21096f696a0de7a95b0a12b1d9530c3b4aa399e7 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes 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(). (cherry picked from commit c1fd622c51752d790576600f5911813ff8dac3fa) --- src/Buffer.cpp | 3 +++ src/frontends/WorkArea.h | 7 +++++++ src/frontends/WorkAreaManager.cpp | 12 ++++++++++++ src/frontends/WorkAreaManager.h | 2 ++ src/frontends/qt/GuiWorkArea.h | 4 ++-- 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index de7f4d217c..38d236964a 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -5562,6 +5562,9 @@ 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(); changed(true); 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..324d5571af 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,15 @@ void WorkAreaManager::scheduleRedraw() } +void WorkAreaManager::sanitizeCursors() +{ + for (WorkArea * wa : work_areas_) { + wa->bufferView().cursor().sanitize(); + wa->bufferView().resetInlineCompletionPos(); + } +} + + } // 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::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;