sirjuddington/SLADE — pull request #128 by eevee (2014-02-17 22:05:55+00:00)
Title: Fix crashing when closing an archive with open child archives.

...maybe.

I bumped into this playing with my last branch, but found it was pre-existing. I still don't entirely understand why it was happening, but beating several possible causes with a stick seems to have fixed it. I wish I had more closure on this, but the crashes are happening way down in the muck of wxWidgets.

I get a trace like the following from a copy of beta 3 by opening a PK3, opening a WAD inside it, switching back to the PK3 tab, and clicking the X:

```
Stack Trace:
0: [unknown location] [unknown:54754748]
1: [unknown location] [unknown:3343360]
2: [unknown location] ArchiveTreeNode::getEntry(unsigned int)
3: [unknown location] ArchiveEntryList::updateItemAttr(long) const
4: [unknown location] VirtualListView::OnGetItemAttr(long) const
5: [unknown location] [unknown:60674628]
6: [unknown location] [unknown:60731829]
7: [unknown location] [unknown:60722832]
8: [unknown location] wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const
9: [unknown location] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&)
10: [unknown location] wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*)
11: [unknown location] wxEvtHandler::TryHereOnly(wxEvent&)
12: [unknown location] wxEvtHandler::ProcessEventLocally(wxEvent&)
13: [unknown location] wxEvtHandler::ProcessEvent(wxEvent&)
14: [unknown location] wxEvtHandler::SafelyProcessEvent(wxEvent&)
15: [unknown location] wxWindow::GTKSendPaintEvents(_GdkRegion const*)
16: [unknown location] [unknown:60574356]
17: [unknown location] [unknown:21859717]
18: [unknown location] g_closure_invoke
19: [unknown location] [unknown:-1994691]
20: [unknown location] g_signal_emit_valist
21: [unknown location] g_signal_emit
22: [unknown location] [unknown:22973108]
23: [unknown location] gtk_main_do_event
24: [unknown location] [unknown:563439]
25: [unknown location] [unknown:563349]
26: [unknown location] [unknown:563349]
27: [unknown location] [unknown:563349]
28: [unknown location] [unknown:563349]
29: [unknown location] [unknown:563349]
30: [unknown location] [unknown:550190]
31: [unknown location] gdk_window_process_updates
32: [unknown location] wxWindow::Update()
33: [unknown location] SToolBarButton::onFocus(wxFocusEvent&)
34: [unknown location] wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const
35: [unknown location] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&)
36: [unknown location] wxEvtHandler::SearchDynamicEventTable(wxEvent&)
37: [unknown location] wxEvtHandler::TryHereOnly(wxEvent&)
38: [unknown location] wxEvtHandler::ProcessEventLocally(wxEvent&)
39: [unknown location] wxEvtHandler::ProcessEvent(wxEvent&)
40: [unknown location] wxEvtHandler::SafelyProcessEvent(wxEvent&)
41: [unknown location] wxWindow::GTKHandleFocusOutNoDeferring()
42: [unknown location] wxWindow::GTKHandleFocusOut()
43: [unknown location] [unknown:60558508]
44: [unknown location] [unknown:21859717]
45: [unknown location] g_closure_invoke
46: [unknown location] [unknown:-1994691]
47: [unknown location] g_signal_emit_valist
48: [unknown location] g_signal_emit
49: [unknown location] [unknown:22973108]
50: [unknown location] gtk_widget_send_focus_change
51: [unknown location] [unknown:23023251]
52: [unknown location] [unknown:23023666]
53: [unknown location] g_cclosure_marshal_VOID__OBJECTv
54: [unknown location] [unknown:-2066217]
55: [unknown location] g_signal_emit_valist
56: [unknown location] g_signal_emit
57: [unknown location] [unknown:23053245]
58: [unknown location] gtk_widget_hide
59: [unknown location] wxWindow::Show(bool)
60: [unknown location] wxAuiNotebook::DeletePage(unsigned long)
61: [unknown location] wxAuiNotebook::OnTabButton(wxAuiNotebookEvent&)
62: [unknown location] wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const
63: [unknown location] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&)
64: [unknown location] wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*)
65: [unknown location] wxEvtHandler::TryHereOnly(wxEvent&)
66: [unknown location] wxEvtHandler::DoTryChain(wxEvent&)
67: [unknown location] wxEvtHandler::ProcessEvent(wxEvent&)
68: [unknown location] wxWindowBase::TryAfter(wxEvent&)
69: [unknown location] wxAuiTabCtrl::OnLeftUp(wxMouseEvent&)
70: [unknown location] wxAppConsoleBase::CallEventHandler(wxEvtHandler*, wxEventFunctor&, wxEvent&) const
71: [unknown location] wxEvtHandler::ProcessEventIfMatchesId(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&)
72: [unknown location] wxEventHashTable::HandleEvent(wxEvent&, wxEvtHandler*)
73: [unknown location] wxEvtHandler::TryHereOnly(wxEvent&)
74: [unknown location] wxEvtHandler::ProcessEventLocally(wxEvent&)
75: [unknown location] wxEvtHandler::ProcessEvent(wxEvent&)
76: [unknown location] wxEvtHandler::SafelyProcessEvent(wxEvent&)
77: [unknown location] [unknown:60548573]
78: [unknown location] [unknown:21859717]
79: [unknown location] g_closure_invoke
80: [unknown location] [unknown:-1994691]
81: [unknown location] g_signal_emit_valist
82: [unknown location] g_signal_emit
83: [unknown location] [unknown:22973108]
84: [unknown location] gtk_propagate_event
85: [unknown location] gtk_main_do_event
86: [unknown location] [unknown:662588]
87: [unknown location] g_main_context_dispatch
88: [unknown location] [unknown:-8370712]
89: [unknown location] g_main_loop_run
90: [unknown location] gtk_main
91: [unknown location] wxGUIEventLoop::DoRun()
92: [unknown location] wxEventLoopBase::Run()
93: [unknown location] wxAppConsoleBase::MainLoop()
94: [unknown location] wxEntry(int&, wchar_t**)
95: [unknown location] main
96: [unknown location] __libc_start_main
97: [unknown location] _start
```

Frame 59 (`wxWindow::Show(bool)`) is the `wxAuiNotebook` trying to hide the currently-open page before deleting it. For some reason, this ultimately triggers a _redraw_ of the `ArchiveEntryList` on that very page, which is doomed to crash because the archive is already closed at this point.

That behavior makes absolutely no sense to me; I can only guess it's because the child tab was switched to as part of being closed, and wx wants to redraw the current tab once the child tab is gone.

The solution was ultimately to keep the archives open until _after_ the tabs have been closed.

Commit message has some further commentary.