From 87d291ee237cd24419ced6237b52518a53a4f474 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. (cherry picked from commit 8b107f0490e61b4390e925f08d21661ef50d6f49) --- 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 a61b0bfd80..5e83c7b63e 100644 --- a/src/BufferList.cpp +++ b/src/BufferList.cpp @@ -269,7 +269,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; @@ -279,6 +279,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 a479728ebd..f7ee48205f 100644 --- a/src/Undo.cpp +++ b/src/Undo.cpp @@ -562,7 +562,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_; } @@ -586,7 +587,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 1e847464d8..97a60e9b44 100644 --- a/src/frontends/qt4/GuiApplication.cpp +++ b/src/frontends/qt4/GuiApplication.cpp @@ -1407,7 +1407,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; @@ -1883,7 +1883,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; }