From d36c64873d9260c26be552905a4c2edb10256f79 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Tue, 6 Aug 2019 19:53:20 +0200 Subject: [PATCH] Fix of a Linux / GTK specific crash on deleting of Layers from the side panel: wxWidgets / GTK internally delays the EnsureVisible() call to Idle processing. If the item is deleted after EnsureVisible() is planned and before the Idle processed, the Idle processing routine works with deleted data --- src/slic3r/GUI/GUI_ObjectList.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 346d4494b..a85ab0609 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -186,7 +186,18 @@ ObjectList::ObjectList(wxWindow* parent) : Bind(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, [this](wxCommandEvent& e) { last_volume_is_deleted(e.GetInt()); }); - Bind(wxEVT_SIZE, ([this](wxSizeEvent &e) { this->EnsureVisible(this->GetCurrentItem()); e.Skip(); })); + Bind(wxEVT_SIZE, ([this](wxSizeEvent &e) { +#ifdef __WXGTK__ + // On GTK, the EnsureVisible call is postponed to Idle processing (see wxDataViewCtrl::m_ensureVisibleDefered). + // So the postponed EnsureVisible() call is planned for an item, which may not exist at the Idle processing time, if this wxEVT_SIZE + // event is succeeded by a delete of the currently active item. We are trying our luck by postponing the wxEVT_SIZE triggered EnsureVisible(), + // which seems to be working as of now. + this->CallAfter([this](){ this->EnsureVisible(this->GetCurrentItem()); }); +#else + this->EnsureVisible(this->GetCurrentItem()); +#endif + e.Skip(); + })); } ObjectList::~ObjectList() @@ -3601,4 +3612,4 @@ ModelObject* ObjectList::object(const int obj_idx) const } } //namespace GUI -} //namespace Slic3r \ No newline at end of file +} //namespace Slic3r