Fix crash handling layers of multiple docs with the timeline (fix #2397)

If we were handling several documents, and merging/flatting/deleting
layers in one of those documents, it could be a problem for the
timeline range when we switched to another doc and undo/redo (because
the DocRange might be holding a pointer to an invalid/deleted layer of
the other document).
This commit is contained in:
David Capello 2020-06-09 17:30:02 -03:00
parent b879fc855a
commit 0ba2a8922b
2 changed files with 23 additions and 2 deletions

View File

@ -50,6 +50,12 @@ void DocRange::clearRange()
m_flags = kNone;
m_selectedLayers.clear();
m_selectedFrames.clear();
// Reset the starting point of a previous startRange/endRange(), we
// don't want to store a pointer to an invalid
// "m_selectingFromLayer" layer.
m_selectingFromLayer = nullptr;
m_selectingFromFrame = -1;
}
void DocRange::startRange(Layer* fromLayer, frame_t fromFrame, Type type)
@ -100,6 +106,14 @@ void DocRange::eraseAndAdjust(const Layer* layer)
if (!enabled())
return;
// Check that the sprite of m_selectingFromLayer is the same than
// the given layer. In the past if we stored an invalid
// "m_selectingFromLayer" for too much time this could fail (even
// more, "m_selectingFromLayer" could be pointing to an already
// closed/deleted sprite).
ASSERT(!m_selectingFromLayer || !layer ||
m_selectingFromLayer->sprite() == layer->sprite());
if (m_selectingFromLayer)
m_selectingFromLayer = candidate_if_layer_is_deleted(m_selectingFromLayer, layer);

View File

@ -393,10 +393,17 @@ void Timeline::detachDocument()
m_thumbnailsPrefConn.disconnect();
m_document->remove_observer(this);
m_document = nullptr;
m_sprite = nullptr;
m_layer = nullptr;
}
// Reset all pointers to this document, even DocRanges, we don't
// want to store a pointer to a layer of a document that we are not
// observing anymore (because the document might be deleted soon).
m_sprite = nullptr;
m_layer = nullptr;
m_range.clearRange();
m_startRange.clearRange();
m_dropRange.clearRange();
if (m_editor) {
m_editor->remove_observer(this);
m_editor = nullptr;