From 8b107f0490e61b4390e925f08d21661ef50d6f49 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Wed, 13 Dec 2017 10:38:47 +0100 Subject: [PATCH] Handle properly undo groups in embedded work areas When a buffer is in an embedded work area (adv. find&replace), it is not found by BufferList:::exists(), and therefore the undo group created in GuiApplication::dispatch and in the handling of LFUN_COMMAND_SEQUENCE will not be closed.. Crashes can ensue, as described in Ubuntu bug: https://bugs.launchpad.net/bugs/1737429 The solution is to introduce BufferList::isInternal and act on it. Fixes bug #10847. --- src/BufferList.cpp | 12 +++++++++++- src/BufferList.h | 3 +++ src/Undo.cpp | 6 ++++-- src/frontends/qt4/GuiApplication.cpp | 4 ++-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/BufferList.cpp b/src/BufferList.cpp index 2bbb8b93a4..538df77a1d 100644 --- a/src/BufferList.cpp +++ b/src/BufferList.cpp @@ -268,7 +268,7 @@ bool BufferList::exists(FileName const & fname) const } - bool BufferList::isLoaded(Buffer const * b) const +bool BufferList::isLoaded(Buffer const * b) const { if (!b) return false; @@ -278,6 +278,16 @@ bool BufferList::exists(FileName const & fname) const } +bool BufferList::isInternal(Buffer const * b) const +{ + if (!b) + return false; + BufferStorage::const_iterator cit = + find(binternal.begin(), binternal.end(), b); + return cit != binternal.end(); +} + + bool BufferList::isOthersChild(Buffer * parent, Buffer * child) { LASSERT(parent, return false); diff --git a/src/BufferList.h b/src/BufferList.h index 01698af4bb..ca55abe8c9 100644 --- a/src/BufferList.h +++ b/src/BufferList.h @@ -84,6 +84,9 @@ public: /// returns true if the buffer is loaded bool isLoaded(Buffer const * b) const; + /// returns true if the buffer is known as internal buffer + bool isInternal(Buffer const * b) const; + /// \return index of named buffer in buffer list int bufferNum(support::FileName const & name) const; diff --git a/src/Undo.cpp b/src/Undo.cpp index 2eb35a29d0..b388b9cd59 100644 --- a/src/Undo.cpp +++ b/src/Undo.cpp @@ -569,7 +569,8 @@ void Undo::beginUndoGroup() if (d->group_level_ == 0) { // create a new group ++d->group_id_; - LYXERR(Debug::UNDO, "+++++++Creating new group " << d->group_id_); + LYXERR(Debug::UNDO, "+++++++ Creating new group " << d->group_id_ + << " for buffer " << &d->buffer_); } ++d->group_level_; } @@ -593,7 +594,8 @@ void Undo::endUndoGroup() if (d->group_level_ == 0) { // real end of the group d->group_cur_before_ = CursorData(); - LYXERR(Debug::UNDO, "-------End of group " << d->group_id_); + LYXERR(Debug::UNDO, "------- End of group " << d->group_id_ + << " of buffer " << &d->buffer_); } } diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp index b579f62a2b..5d7f559b57 100644 --- a/src/frontends/qt4/GuiApplication.cpp +++ b/src/frontends/qt4/GuiApplication.cpp @@ -1402,7 +1402,7 @@ DispatchResult const & GuiApplication::dispatch(FuncRequest const & cmd) updateCurrentView(cmd, dr); // the buffer may have been closed by one action - if (theBufferList().isLoaded(buffer)) + if (theBufferList().isLoaded(buffer) || theBufferList().isInternal(buffer)) buffer->undo().endUndoGroup(); d->dispatch_result_ = dr; @@ -1871,7 +1871,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr) dispatch(func); } // the buffer may have been closed by one action - if (theBufferList().isLoaded(buffer)) + if (theBufferList().isLoaded(buffer) || theBufferList().isInternal(buffer)) buffer->undo().endUndoGroup(); break; } -- 2.39.5