From 02b248d2708a412ac855b73925a676eb9f0c3b20 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 ++-- status.22x | 3 +++ 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/BufferList.cpp b/src/BufferList.cpp index bcdec59d87..d28a342041 100644 --- a/src/BufferList.cpp +++ b/src/BufferList.cpp @@ -271,7 +271,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; @@ -281,6 +281,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 d4ae186a90..68f22ef830 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 f473176725..734ef367f6 100644 --- a/src/frontends/qt4/GuiApplication.cpp +++ b/src/frontends/qt4/GuiApplication.cpp @@ -1388,7 +1388,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; @@ -1863,7 +1863,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; } diff --git a/status.22x b/status.22x index b5af1fea1d..7fc5405ad8 100644 --- a/status.22x +++ b/status.22x @@ -100,6 +100,9 @@ What's new - Fix crash with undo and child documents (bug 10643). +- Fix completely broken undo in Advanced Find & Replace edit areas + (bug 10847). + - Fix crash when changing preview preferences while previewable external inset is open (bug 10785). -- 2.39.5