From 999872c21db7113e313c7ba098e6740a0a77dc27 Mon Sep 17 00:00:00 2001 From: Leland Lucius Date: Sat, 2 May 2020 21:03:23 -0500 Subject: [PATCH] Bug 2411 - Mac: Crash on docking/undocking Audacity with un-docked toolbar(s) --- src/ProjectWindow.cpp | 74 +++++++++++++++++++++++++------------------ src/TrackPanel.cpp | 13 -------- 2 files changed, 44 insertions(+), 43 deletions(-) diff --git a/src/ProjectWindow.cpp b/src/ProjectWindow.cpp index 69854910a..620e77292 100644 --- a/src/ProjectWindow.cpp +++ b/src/ProjectWindow.cpp @@ -1233,6 +1233,38 @@ void ProjectWindow::UpdateStatusWidths() statusBar->SetStatusWidths( nWidths, widths ); } +void ProjectWindow::MacShowUndockedToolbars(bool show) +{ + (void)show;//compiler food +#ifdef __WXMAC__ + // Save the focus so we can restore it to whatever had it before since + // showing a previously hidden toolbar will cause the focus to be set to + // its frame. If this is not done it will appear that activation events + // aren't being sent to the project window since they are actually being + // delivered to the last tool frame shown. + wxWindow *focused = FindFocus(); + + // Find all the floating toolbars, and show or hide them + const auto &children = GetChildren(); + for(const auto &child : children) { + if (auto frame = dynamic_cast(child)) { + if (!show) { + frame->Hide(); + } + else if (frame->GetBar() && + frame->GetBar()->IsVisible() ) { + frame->Show(); + } + } + } + + // Restore the focus if needed + if (focused) { + focused->SetFocus(); + } +#endif +} + void ProjectWindow::OnIconize(wxIconizeEvent &event) { //JKC: On Iconizing we get called twice. Don't know @@ -1241,6 +1273,16 @@ void ProjectWindow::OnIconize(wxIconizeEvent &event) // void return? I don't know. mIconized = event.IsIconized(); +#if defined(__WXMAC__) + // Readdresses bug 1431 since a crash could occur when restoring iconized + // floating toolbars due to recursion (bug 2411). + MacShowUndockedToolbars(!mIconized); + if( !mIconized ) + { + Raise(); + } +#endif + // VisibileProjectCount seems to be just a counter for debugging. // It's not used outside this function. auto VisibleProjectCount = std::count_if( @@ -1440,24 +1482,6 @@ void ProjectWindow::OnUpdateUI(wxUpdateUIEvent & WXUNUSED(event)) MenuManager::Get( project ).UpdateMenus(); } -void ProjectWindow::MacShowUndockedToolbars(bool show) -{ - (void)show;//compiler food -#ifdef __WXMAC__ - // Find all the floating toolbars, and show or hide them - const auto &children = GetChildren(); - for(const auto &child : children) { - if (auto frame = dynamic_cast(child)) { - if (!show) - frame->Hide(); - else if (frame->GetBar() && - frame->GetBar()->IsVisible()) - frame->Show(); - } - } -#endif -} - void ProjectWindow::OnActivate(wxActivateEvent & event) { // Activate events can fire during window teardown, so just @@ -1467,7 +1491,7 @@ void ProjectWindow::OnActivate(wxActivateEvent & event) } auto &project = mProject; - + mActive = event.GetActive(); // Under Windows, focus can be "lost" when returning to @@ -1481,21 +1505,11 @@ void ProjectWindow::OnActivate(wxActivateEvent & event) // Then, when we receive the // activate event, we restore that focus to the child or the track // panel if no child had the focus (which probably should never happen). - if (!mActive) { -#ifdef __WXMAC__ - if (IsIconized()) - MacShowUndockedToolbars(false); -#endif - } - else { + if (mActive) { auto &toolManager = ToolManager::Get( project ); SetActiveProject( &project ); if ( ! toolManager.RestoreFocus() ) GetProjectPanel( project ).SetFocus(); - -#ifdef __WXMAC__ - MacShowUndockedToolbars(true); -#endif } event.Skip(); } diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index bf498a4a3..c07a51ce5 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -398,19 +398,6 @@ void TrackPanel::OnIdle(wxIdleEvent& event) /// AS: This gets called on our wx timer events. void TrackPanel::OnTimer(wxTimerEvent& ) { -#ifdef __WXMAC__ - // Unfortunate part of fix for bug 1431 - // Without this, the toolbars hide only every other time that you press - // the yellow title bar button. For some reason, not every press sends - // us a deactivate event for the application. - { - auto project = GetProject(); - auto &window = ProjectWindow::Get( *project ); - if (window.IsIconized()) - window.MacShowUndockedToolbars(false); - } -#endif - mTimeCount++; AudacityProject *const p = GetProject();