From ce92dce8562e2b407853f047ca4578b48ab66f73 Mon Sep 17 00:00:00 2001 From: Darrell Walisser Date: Sun, 28 Aug 2016 13:00:44 -0400 Subject: [PATCH 01/14] improved OpenMP SpecCache::Populate --- src/WaveClip.cpp | 78 +++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 44 deletions(-) diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index 47913e04d..f993a91a2 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -43,7 +43,6 @@ #include "Experimental.h" -//#undef _OPENMP #ifdef _OPENMP #include #else @@ -930,8 +929,18 @@ bool SpecCache::CalculateOneSpectrum int correctedX = (floor(0.5 + xx + timeCorrection * pixelsPerSecond / rate)); if (correctedX >= lowerBoundX && correctedX < upperBoundX) - result = true, - out[half * correctedX + bin] += power; + { + result = true; + + int index = half * correctedX + bin; +#ifdef _OPENMP + // This assignment can race if index reaches into another thread's bins. + // The probability of a race very low, so this carries little overhead, + // about 5% slower vs allowing it to race. + #pragma omp atomic +#endif + out[index] += power; + } } } } @@ -990,29 +999,6 @@ void SpecCache::Populate if (!autocorrelation) ComputeSpectrogramGainFactors(fftLen, rate, frequencyGain, gainFactors); -#ifdef _OPENMP - // todo: query # of threads or make it a setting - const int numThreads = 8; - omp_set_num_threads(numThreads); - - // We need certain per-thread data for thread safety - // Assumes WaveTrackCache is reentrant since it takes a const* to WaveTrack - struct { - WaveTrackCache* cache; - float* scratch; - } threadLocalStorage[numThreads]; - - // May as well use existing data for one of the threads - assert(numThreads > 0); - threadLocalStorage[0].cache = &waveTrackCache; - threadLocalStorage[0].scratch = &scratch[0]; - - for (int i = 1; i < numThreads; i++) { - threadLocalStorage[i].cache = new WaveTrackCache( waveTrackCache.GetTrack() ); - threadLocalStorage[i].scratch = new float[scratchSize]; - } -#endif - // Loop over the ranges before and after the copied portion and compute anew. // One of the ranges may be empty. for (int jj = 0; jj < 2; ++jj) { @@ -1020,24 +1006,36 @@ void SpecCache::Populate const int upperBoundX = jj == 0 ? copyBegin : numPixels; #ifdef _OPENMP - #pragma omp parallel for + // Storage for mutable per-thread data. + // private clause ensures one copy per thread + struct ThreadLocalStorage { + ThreadLocalStorage() { cache = nullptr; } + ~ThreadLocalStorage() { delete cache; } + + void init(WaveTrackCache &waveTrackCache, size_t scratchSize) { + if (!cache) { + cache = new WaveTrackCache(waveTrackCache.GetTrack()); + scratch.reserve(scratchSize); + } + } + WaveTrackCache* cache; + std::vector scratch; + } tls; + + #pragma omp parallel for private(tls) #endif for (auto xx = lowerBoundX; xx < upperBoundX; ++xx) { #ifdef _OPENMP - int threadNum = omp_get_thread_num(); - - assert(threadNum >=0 && threadNum < numThreads); - - WaveTrackCache* cache = threadLocalStorage[threadNum].cache; - float* buffer = threadLocalStorage[threadNum].scratch; + tls.init(waveTrackCache, scratchSize); + WaveTrackCache& cache = *tls.cache; + float* buffer = &tls.scratch[0]; #else - WaveTrackCache* cache = &waveTrackCache; + WaveTrackCache& cache = waveTrackCache; float* buffer = &scratch[0]; #endif - CalculateOneSpectrum( - settings, *cache, xx, numSamples, + settings, cache, xx, numSamples, offset, rate, pixelsPerSecond, lowerBoundX, upperBoundX, gainFactors, buffer, &freq[0]); @@ -1098,14 +1096,6 @@ void SpecCache::Populate } } } - -#ifdef _OPENMP - for (int i = 1; i < numThreads; i++) - { - delete[] threadLocalStorage[i].scratch; - delete threadLocalStorage[i].cache; - } -#endif } bool WaveClip::GetSpectrogram(WaveTrackCache &waveTrackCache, From c580009063ab0baf7f3fdb9387f69bb05eeb0275 Mon Sep 17 00:00:00 2001 From: James Crook Date: Tue, 30 Aug 2016 00:33:58 +0100 Subject: [PATCH 02/14] Effects grouped on Windows and Mac too. Makes the very long effects menu manageable. --- src/Menus.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Menus.cpp b/src/Menus.cpp index b9418cc23..206eaec29 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -1480,11 +1480,7 @@ void AudacityProject::AddEffectMenuItemGroup(CommandManager *c, int namesCnt = (int) names.GetCount(); int perGroup; -#if defined(__WXGTK__) gPrefs->Read(wxT("/Effects/MaxPerGroup"), &perGroup, 15); -#else - gPrefs->Read(wxT("/Effects/MaxPerGroup"), &perGroup, 0); -#endif int groupCnt = namesCnt; for (int i = 0; i < namesCnt; i++) From beeb0c790ce6f805e5524c2ea9a60521a1559807 Mon Sep 17 00:00:00 2001 From: James Crook Date: Tue, 30 Aug 2016 09:08:24 +0100 Subject: [PATCH 03/14] Bug 1484 - (Residual) Shift click on Wave/Label to extend (once again) It turns out that having fixed the behaviour of Shift-Click on the Track Control Panel, I'd also fixed the behaviour of Shift-Click on the wave. But then I blew it by over riding the Shift-Click behaviour on wave to use the version that does NOT horizontally extend. This change comments out the 'bShift' and so gives us the original Shift-Click behaviour on wave, without undoing the other fixes. --- src/TrackPanel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index cbc07845a..9e558640a 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -6208,7 +6208,7 @@ bool TrackPanel::HandleTrackLocationMouseEvent(WaveTrack * track, wxRect &rect, bool bCtrlDown = event.ControlDown(); bool unsafe = IsUnsafe(); - if( bShift || bCtrlDown ){ + if( /*bShift ||*/ bCtrlDown ){ HandleListSelection(track, bShift, bCtrlDown, !unsafe); return true; @@ -6284,7 +6284,7 @@ bool TrackPanel::HandleLabelTrackClick(LabelTrack * lTrack, wxRect &rect, wxMous bool bCtrlDown = event.ControlDown(); bool unsafe = IsUnsafe(); - if( bShift || bCtrlDown ){ + if( /*bShift ||*/ bCtrlDown ){ HandleListSelection(lTrack, bShift, bCtrlDown, !unsafe); return true; From 576020f203e692ccddc065268c6607bdc26b0b72 Mon Sep 17 00:00:00 2001 From: James Crook Date: Tue, 30 Aug 2016 22:13:33 +0100 Subject: [PATCH 04/14] Bug 1505 - Window size not restored on launch (using virtual desktop) Fixed by being more tolerant of window being (slightly) off screen. Windows 10 appears to mis-report the window size by 6 pixels. This fix allows the user to restore a window that is (slightly) off screen. That's OK and helps those users who position and size the window very precisely. --- src/Project.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/Project.cpp b/src/Project.cpp index 356252520..1a2463ec5 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -692,6 +692,7 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized) windowRect = defaultRect; } + // The 'screen' is the area minus the task bar. wxRect screenRect = wxGetClientDisplayRect(); #if defined(__WXMAC__) @@ -705,16 +706,16 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized) } #endif - - // Make sure initial sizes fit within the display bounds + // We don't mind being 32 pixels off the screen in any direction. + // Make sure initial sizes (pretty much) fit within the display bounds // We used to trim the sizes which could result in ridiculously small windows. // contributing to bug 1243. - // Now instead if the window doesn't fit the screen, we use the default + // Now instead if the window significantly doesn't fit the screen, we use the default // window instead, which we know does. - if (!screenRect.Contains( normalRect )) { + if (!screenRect.Contains( wxRect(normalRect).Deflate( 32, 32 ))) { normalRect = defaultRect; } - if (!screenRect.Contains( windowRect )) { + if (!screenRect.Contains( wxRect(windowRect).Deflate( 32, 32 ) )) { windowRect = defaultRect; } @@ -754,10 +755,16 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized) nextRect->y += inc; } + // Windows can say that we are off screen when actually we are not. + // On Windows 10 I am seeing miscalculation by about 6 pixels. + // To fix this we allow some sloppiness on the edge being counted as off screen. + // This matters most when restoring very carefully sized windows that are maximised + // in one dimension (height or width) but not both. + const int edgeSlop = 10; //Have we hit the right side of the screen? wxPoint bottomRight = nextRect->GetBottomRight(); - if (bottomRight.x > screenRect.GetRight()) { + if (bottomRight.x > (screenRect.GetRight()+edgeSlop)) { int newWidth = screenRect.GetWidth() - nextRect->GetLeft(); if (newWidth < defaultRect.GetWidth()) { nextRect->x = windowRect.x; @@ -771,10 +778,10 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized) //Have we hit the bottom of the screen? bottomRight = nextRect->GetBottomRight(); - if (bottomRight.y > screenRect.GetBottom()) { + if (bottomRight.y > (screenRect.GetBottom()+edgeSlop)) { nextRect->y -= inc; bottomRight = nextRect->GetBottomRight(); - if (bottomRight.y > screenRect.GetBottom()) { + if (bottomRight.y > (screenRect.GetBottom()+edgeSlop)) { nextRect->SetBottom(screenRect.GetBottom()); } } From 9d059bf13ba5645f58a5294b46200def2ee8480c Mon Sep 17 00:00:00 2001 From: James Crook Date: Tue, 30 Aug 2016 22:16:39 +0100 Subject: [PATCH 05/14] Ungroup Effects on Windows and Mac. --- src/Menus.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Menus.cpp b/src/Menus.cpp index 206eaec29..b9418cc23 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -1480,7 +1480,11 @@ void AudacityProject::AddEffectMenuItemGroup(CommandManager *c, int namesCnt = (int) names.GetCount(); int perGroup; +#if defined(__WXGTK__) gPrefs->Read(wxT("/Effects/MaxPerGroup"), &perGroup, 15); +#else + gPrefs->Read(wxT("/Effects/MaxPerGroup"), &perGroup, 0); +#endif int groupCnt = namesCnt; for (int i = 0; i < namesCnt; i++) From c57f8292003cb0a9fba715ef969fd85d6b24c70e Mon Sep 17 00:00:00 2001 From: James Crook Date: Tue, 30 Aug 2016 23:46:12 +0100 Subject: [PATCH 06/14] Bug 1484 - (Residual) Shift-Click calculates start/end for itself. Smarter logic, which extends down from the first or up from the last. --- src/TrackPanel.cpp | 47 ++++++++++++++++++++++++++++++++++++++++------ src/TrackPanel.h | 1 + 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 9e558640a..6abb332d3 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -1888,6 +1888,44 @@ void TrackPanel::SelectRangeOfTracks(Track *sTrack, Track *eTrack) } } +void TrackPanel::ChangeSelectionOnShiftClick(Track * pTrack){ + + // Optional: Track already selected? Nothing to do. + // If we enable this, Shift-Click behaves like click in this case. + //if( pTrack->GetSelected() ) + // return; + + // Find first and last selected track. + Track* pFirst = nullptr; + Track* pLast = nullptr; + // We will either extend from the first or from the last. + Track* pExtendFrom= nullptr; + + TrackListIterator iter(GetTracks()); + for (Track *t = iter.First(); t; t = iter.Next()) { + const bool isSelected = t->GetSelected(); + // If our track is after the first, extend from the first. + if( t == pTrack ){ + pExtendFrom = pFirst; + } + // Record first and last selected. + if( isSelected ){ + if( !pFirst ) + pFirst = t; + pLast = t; + } + } + // Our track was the first or earlier. Extend from the last. + if( !pExtendFrom ) + pExtendFrom = pLast; + + SelectNone(); + if( pExtendFrom ) + SelectRangeOfTracks(pTrack, pExtendFrom); + else + SelectTrack( pTrack, true ); +} + /// This method gets called when we're handling selection /// and the mouse was just clicked. void TrackPanel::SelectionHandleClick(wxMouseEvent & event, @@ -1929,11 +1967,8 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, && !stretch #endif ) { - SelectNone(); - if (mLastPickedTrack && event.ShiftDown()) - SelectRangeOfTracks(pTrack, mLastPickedTrack); - else - SelectTrack(pTrack, true); + + ChangeSelectionOnShiftClick( pTrack ); double value; // Shift-click, choose closest boundary @@ -4977,7 +5012,7 @@ void TrackPanel::HandleListSelection(Track *t, bool shift, bool ctrl, } else { if (shift && mLastPickedTrack) - SelectRangeOfTracks(t, mLastPickedTrack); + ChangeSelectionOnShiftClick( t ); else{ SelectNone(); SelectTrack(t, true); diff --git a/src/TrackPanel.h b/src/TrackPanel.h index 78e19a9fa..dc010a7e2 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -296,6 +296,7 @@ class AUDACITY_DLL_API TrackPanel final : public OverlayPanel { protected: + virtual void ChangeSelectionOnShiftClick(Track * pTrack); virtual void SelectionHandleClick(wxMouseEvent &event, Track* pTrack, wxRect rect); virtual void StartSelection (int mouseXCoordinate, int trackLeftEdge); From 180da5a7696281832e84e88d898d1c12f97b6f5c Mon Sep 17 00:00:00 2001 From: Darrell Walisser Date: Wed, 31 Aug 2016 11:22:29 -0400 Subject: [PATCH 07/14] change reserve to resize, clarify what omp atomic is used --- src/WaveClip.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index f993a91a2..ccd1c1771 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -937,7 +937,7 @@ bool SpecCache::CalculateOneSpectrum // This assignment can race if index reaches into another thread's bins. // The probability of a race very low, so this carries little overhead, // about 5% slower vs allowing it to race. - #pragma omp atomic + #pragma omp atomic update #endif out[index] += power; } @@ -1015,7 +1015,7 @@ void SpecCache::Populate void init(WaveTrackCache &waveTrackCache, size_t scratchSize) { if (!cache) { cache = new WaveTrackCache(waveTrackCache.GetTrack()); - scratch.reserve(scratchSize); + scratch.resize(scratchSize); } } WaveTrackCache* cache; From 09e6d20dbc351170bd9edf4845be7c645b572f3a Mon Sep 17 00:00:00 2001 From: James Crook Date: Wed, 31 Aug 2016 22:43:39 +0100 Subject: [PATCH 08/14] Credits for Darrell Walisser (OpenMP for Spectrum Display) --- src/AboutDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AboutDialog.cpp b/src/AboutDialog.cpp index c158302a8..7b63e60e5 100644 --- a/src/AboutDialog.cpp +++ b/src/AboutDialog.cpp @@ -117,6 +117,7 @@ void AboutDialog::CreateCreditsList() AddCredit(wxString(wxT("Mike Underwood, ")) + _("developer"), roleContributor); AddCredit(wxString(wxT("Philip Van Baren, ")) + _("developer"), roleContributor); AddCredit(wxString(wxT("Salvo Ventura, ")) + _("developer"), roleContributor); + AddCredit(wxString(wxT("Darrell Walisser, ")) + _("developer"), roleContributor); AddCredit(wxString(wxT("Jun Wan, ")) + _("developer"), roleContributor); AddCredit(wxString(wxT("Daniel Winzen, ")) + _("developer"), roleContributor); AddCredit(wxString(wxT("Tom Woodhams, ")) + _("developer"), roleContributor); From 6881163129c35852012bb6651cc7c88aed2465ca Mon Sep 17 00:00:00 2001 From: James Crook Date: Wed, 31 Aug 2016 23:38:54 +0100 Subject: [PATCH 09/14] Bug 1484 - (Residual) Alternative Ctrl-Click behaviour on Wave Previously Ctrl Click on Wave behaved exactly as Ctrl Click on Track Control Panel. With this change on wave it (a) No longer toggles. It only adds. (b) It will extend and can be drag extended. It is possible to change (a) to be toggle if that is desired. This should ease the creation and extension of discontinuous track selections. --- src/TrackPanel.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 6abb332d3..6def028ec 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -1961,14 +1961,24 @@ void TrackPanel::SelectionHandleClick(wxMouseEvent & event, bool stretch = HitTestStretch(pTrack, rect, event); #endif - if (event.ShiftDown() + bool bShiftDown = event.ShiftDown(); + bool bCtrlDown = event.ControlDown(); + if (bShiftDown || bCtrlDown #ifdef USE_MIDI && !stretch #endif ) { - ChangeSelectionOnShiftClick( pTrack ); + if( bShiftDown ) + ChangeSelectionOnShiftClick( pTrack ); + if( bCtrlDown ){ + //bool bIsSelected = pTrack->GetSelected(); + bool bIsSelected = false; + // could set bIsSelected true here, but toggling is more technically correct. + // if we want to match behaviour in Track Control Panel. + SelectTrack( pTrack, !bIsSelected, false ); + } double value; // Shift-click, choose closest boundary @@ -2757,7 +2767,8 @@ void TrackPanel::SelectionHandleDrag(wxMouseEvent & event, Track *clickedTrack) if (event.CmdDown()) { // Ctrl-drag has no meaning, fuhggeddaboudit - return; + // JKC YES it has meaning. + //return; } wxRect rect = mCapturedRect; @@ -6242,7 +6253,7 @@ bool TrackPanel::HandleTrackLocationMouseEvent(WaveTrack * track, wxRect &rect, bool bShift = event.ShiftDown(); bool bCtrlDown = event.ControlDown(); bool unsafe = IsUnsafe(); - + bCtrlDown = false; if( /*bShift ||*/ bCtrlDown ){ HandleListSelection(track, bShift, bCtrlDown, !unsafe); From 9787bf7978f7e901dc8f9a6955a360e036270d79 Mon Sep 17 00:00:00 2001 From: James Crook Date: Thu, 1 Sep 2016 22:09:37 +0100 Subject: [PATCH 10/14] Bug 1220 - (Residual) OS X: Audacity's temp dir defaults to location that is cleaned up on reboot. --- src/AudacityApp.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index df3fd429a..1687da323 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -1590,7 +1590,13 @@ bool AudacityApp::IsTempDirectoryNameOK( const wxString & Name ){ // use Long Path to expand out any abbreviated long substrings. wxString BadPath = tmpFile.GetLongPath(); ::wxRemoveFile(tmpFile.GetFullPath()); + #ifdef __WXMAC__ + // This test is to fix bug 1220 on a 1.x to 2.x to 2.1.3 upgrade. + // It is very slightly less permissive than we could be as it stops a path + // with this string ANYWHERE within it. + if( Name.Contains( "/tmp/audacity1.") ) + return false; BadPath = BadPath.BeforeLast( '/' ) + "/"; wxFileName cmpFile( Name ); wxString NameCanonical = cmpFile.GetLongPath( ) + "/"; From 8d55ab9afd44ee6e5cd2476e4992c534c5216fdb Mon Sep 17 00:00:00 2001 From: James Crook Date: Thu, 1 Sep 2016 23:27:44 +0100 Subject: [PATCH 11/14] Bug 1314 - Audacity always launches in middle of first monitor after quit on any part of second monitor. Splash screen still always appears on first screen (intentional). Also I fixed issue where new project windows would appear on first screen, even if Audacity on second. --- src/Project.cpp | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/Project.cpp b/src/Project.cpp index 1a2463ec5..b18d820f3 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -636,16 +636,21 @@ void GetDefaultWindowRect(wxRect *defRect) } } +// true iff we have enough of the top bar to be able to reposition the window. bool IsWindowAccessible(wxRect *requestedRect) { wxDisplay display; wxRect targetTitleRect(requestedRect->GetLeftTop(), requestedRect->GetBottomRight()); + // Hackery to approximate a window top bar size from a window size. + // and exclude the open/close and borders. targetTitleRect.x += 15; targetTitleRect.width -= 100; if (targetTitleRect.width < 165) targetTitleRect.width = 165; targetTitleRect.height = 15; int targetBottom = targetTitleRect.GetBottom(); int targetRight = targetTitleRect.GetRight(); + // This looks like overkill to check each and every pixel in the ranges. + // and decide that if any is visible on screen we are OK. for (int i = targetTitleRect.GetLeft(); i < targetRight; i++) { for (int j = targetTitleRect.GetTop(); j < targetBottom; j++) { int monitor = display.GetFromPoint(wxPoint(i, j)); @@ -657,6 +662,18 @@ bool IsWindowAccessible(wxRect *requestedRect) return FALSE; } +// Returns the screen containing a rectangle, or -1 if none does. +int ScreenContaining( wxRect & r ){ + unsigned int n = wxDisplay::GetCount(); + for(unsigned int i = 0;iy += inc; } + // defaultrect is a rectangle on the first screen. It's the right fallback to + // use most of the time if things are not working out right with sizing. + // windowRect is a saved rectangle size. + // normalRect seems to be a substitute for windowRect when iconized or maximised. + // Windows can say that we are off screen when actually we are not. // On Windows 10 I am seeing miscalculation by about 6 pixels. // To fix this we allow some sloppiness on the edge being counted as off screen. @@ -762,7 +782,15 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized) // in one dimension (height or width) but not both. const int edgeSlop = 10; - //Have we hit the right side of the screen? + // Next four lines are getting the rectangle for the screen that contains the + // top left corner of nextRect (and defaulting to rect of screen 0 otherwise). + wxPoint p = nextRect->GetLeftTop(); + int scr = std::max( 0, wxDisplay::GetFromPoint( p )); + wxDisplay d( scr ); + wxRect screenRect = d.GetClientArea(); + + // Now we (possibly) start trimming our rectangle down. + // Have we hit the right side of the screen? wxPoint bottomRight = nextRect->GetBottomRight(); if (bottomRight.x > (screenRect.GetRight()+edgeSlop)) { int newWidth = screenRect.GetWidth() - nextRect->GetLeft(); @@ -776,7 +804,7 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized) } } - //Have we hit the bottom of the screen? + // Have we hit the bottom of the screen? bottomRight = nextRect->GetBottomRight(); if (bottomRight.y > (screenRect.GetBottom()+edgeSlop)) { nextRect->y -= inc; @@ -786,6 +814,9 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized) } } + // After all that we could have a window that does not have a visible + // top bar. [It is unlikely, but something might have gone wrong] + // If so, use the safe fallback size. if (!IsWindowAccessible(nextRect)) { *nextRect = defaultRect; } From f6870896a1c0906511af56b92b814f6c03ea7765 Mon Sep 17 00:00:00 2001 From: James Crook Date: Fri, 2 Sep 2016 18:25:59 +0100 Subject: [PATCH 12/14] Fix Mac build breaker. Caused by declaring a variable later than a conditionally compiled piece of code. Net result is that Mac will be less tolerant of a window partly off the top of the screen than Windows will be, and will reset it to the default. --- src/Project.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Project.cpp b/src/Project.cpp index b18d820f3..78f9f24f7 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -710,7 +710,9 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized) } + wxRect screenRect( wxGetClientDisplayRect()); #if defined(__WXMAC__) + // On OSX, the top of the window should never be less than the menu height, // so something is amiss if it is if (normalRect.y < screenRect.y) { @@ -787,7 +789,7 @@ void GetNextWindowPlacement(wxRect *nextRect, bool *pMaximized, bool *pIconized) wxPoint p = nextRect->GetLeftTop(); int scr = std::max( 0, wxDisplay::GetFromPoint( p )); wxDisplay d( scr ); - wxRect screenRect = d.GetClientArea(); + screenRect = d.GetClientArea(); // Now we (possibly) start trimming our rectangle down. // Have we hit the right side of the screen? From 06b623bbb1e511c7f8e4ecefe15258b897fc6713 Mon Sep 17 00:00:00 2001 From: James Crook Date: Sat, 3 Sep 2016 17:49:57 +0100 Subject: [PATCH 13/14] Bug 1220 - (Residual) OS X: Exclude directories with substring /tmp/ in them. --- src/AudacityApp.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index 1687da323..c0a67b7e8 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -1593,9 +1593,10 @@ bool AudacityApp::IsTempDirectoryNameOK( const wxString & Name ){ #ifdef __WXMAC__ // This test is to fix bug 1220 on a 1.x to 2.x to 2.1.3 upgrade. - // It is very slightly less permissive than we could be as it stops a path - // with this string ANYWHERE within it. - if( Name.Contains( "/tmp/audacity1.") ) + // It is less permissive than we could be as it stops a path + // with this string ANYWHERE within it rather than excluding just + // the paths that the earlier Audacities used to create. + if( Name.Contains( "/tmp/") ) return false; BadPath = BadPath.BeforeLast( '/' ) + "/"; wxFileName cmpFile( Name ); From 2fb18e8961a09aa9a144f1fb057f300a9fea8d00 Mon Sep 17 00:00:00 2001 From: James Crook Date: Sat, 3 Sep 2016 20:19:34 +0100 Subject: [PATCH 14/14] Bug 1496 - Mouse down while undoing in Envelope Tool corrupts Undo stack The Ctrl-Z was interrupting the enveloping, making it finish, but it then got asked to finish again on a mouse up. This change stops the second finish from happening. --- src/TrackPanel.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 6def028ec..4825f35ec 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -1167,8 +1167,12 @@ void TrackPanel::HandleInterruptedDrag() WasOverCutLine, IsStretching */ - + // The bogus id isn't used anywhere, but may help with debugging. + // as this is sending a bogus mouse up. The mouse button is still actually down + // and may go up again. + const int idBogusUp = 2; wxMouseEvent evt { wxEVT_LEFT_UP }; + evt.SetId( idBogusUp ); evt.SetPosition(this->ScreenToClient(::wxGetMousePosition())); this->ProcessEvent(evt); } @@ -3068,7 +3072,10 @@ void TrackPanel::HandleEnvelope(wxMouseEvent & event) if (mCapturedTrack) ForwardEventToEnvelope(event); - if (event.LeftUp()) { + // We test for IsEnveloping, because we could have had our action stopped already, + // and already recorded and the second mouse up is bogus. + // e.g could be stopped by some key press. Bug 1496. + if ((mMouseCapture == IsEnveloping ) && event.LeftUp()) { SetCapturedTrack( NULL ); MakeParentPushState( /* i18n-hint: (verb) Audacity has just adjusted the envelope .*/