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.
This commit is contained in:
Jean-Marc Lasgouttes 2017-12-13 10:38:47 +01:00
parent 4d0c1c030c
commit 8b107f0490
4 changed files with 20 additions and 5 deletions

View File

@ -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) bool BufferList::isOthersChild(Buffer * parent, Buffer * child)
{ {
LASSERT(parent, return false); LASSERT(parent, return false);

View File

@ -84,6 +84,9 @@ public:
/// returns true if the buffer is loaded /// returns true if the buffer is loaded
bool isLoaded(Buffer const * b) const; 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 /// \return index of named buffer in buffer list
int bufferNum(support::FileName const & name) const; int bufferNum(support::FileName const & name) const;

View File

@ -569,7 +569,8 @@ void Undo::beginUndoGroup()
if (d->group_level_ == 0) { if (d->group_level_ == 0) {
// create a new group // create a new group
++d->group_id_; ++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_; ++d->group_level_;
} }
@ -593,7 +594,8 @@ void Undo::endUndoGroup()
if (d->group_level_ == 0) { if (d->group_level_ == 0) {
// real end of the group // real end of the group
d->group_cur_before_ = CursorData(); 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_);
} }
} }

View File

@ -1402,7 +1402,7 @@ DispatchResult const & GuiApplication::dispatch(FuncRequest const & cmd)
updateCurrentView(cmd, dr); updateCurrentView(cmd, dr);
// the buffer may have been closed by one action // the buffer may have been closed by one action
if (theBufferList().isLoaded(buffer)) if (theBufferList().isLoaded(buffer) || theBufferList().isInternal(buffer))
buffer->undo().endUndoGroup(); buffer->undo().endUndoGroup();
d->dispatch_result_ = dr; d->dispatch_result_ = dr;
@ -1871,7 +1871,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
dispatch(func); dispatch(func);
} }
// the buffer may have been closed by one action // the buffer may have been closed by one action
if (theBufferList().isLoaded(buffer)) if (theBufferList().isLoaded(buffer) || theBufferList().isInternal(buffer))
buffer->undo().endUndoGroup(); buffer->undo().endUndoGroup();
break; break;
} }