From 8b87e18c6d752f4f86c556515fd3be4ca80cfd97 Mon Sep 17 00:00:00 2001 From: David Bailes Date: Tue, 26 Jun 2018 09:13:29 +0100 Subject: [PATCH] Accessibility: clean up track focus events after an effect is applied. Problem. When an effect is applied, whatever track is the original focus, there is a focus event for track one. This causes NVDA to read out the track name of track 1, which is unnecessary noise. The reason for this is that the execution of the Progress dialog destructor causes AudacityProject::OnActivate() to be called which causes a set focus on the TrackPanel. When this happens, the pointers to the selected tracks have changed, but the final focus has not been set (at the end of AudacityProject::DoEffect()). So TrackPanelAx::GetFocus returns the first track. Fix: Modify TrackPanelAx::GetFocus so that if the existing pointer to the focused track is null, then use the track at the same position, if it exists. --- src/TrackPanelAx.cpp | 34 +++++++++++++++++++++++----------- src/TrackPanelAx.h | 1 + 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/TrackPanelAx.cpp b/src/TrackPanelAx.cpp index 91985c9ec..07ab3f3a9 100644 --- a/src/TrackPanelAx.cpp +++ b/src/TrackPanelAx.cpp @@ -40,23 +40,36 @@ TrackPanelAx::TrackPanelAx( wxWindow *window ) mTrackName = true; mMessageCount = 0; + mNumFocusedTrack = 0; } TrackPanelAx::~TrackPanelAx() { } -// Returns currently focused track or first one if none focused +// Returns currently focused track +// if that track no longer exists, if there is a track at +// the same position, use that, else if there is a first +// track, use that. std::shared_ptr TrackPanelAx::GetFocus() { auto focusedTrack = mFocusedTrack.lock(); if( !focusedTrack ) { - TrackListIterator iter( mTrackPanel->GetTracks() ); - focusedTrack = Track::Pointer( iter.First() ); - // only call SetFocus if the focus has changed to avoid - // unnecessary focus events - if (focusedTrack) - focusedTrack = SetFocus(); + if (mNumFocusedTrack >=1) { + // This prevents the focus from being unnecessarily set to track 1 + // when effects are applied. (Applying an effect can change + // the pointers of the selected tracks.) + focusedTrack = FindTrack(mNumFocusedTrack); + } + if (!focusedTrack) { + + TrackListIterator iter( mTrackPanel->GetTracks() ); + focusedTrack = Track::Pointer( iter.First() ); + // only call SetFocus if the focus has changed to avoid + // unnecessary focus events + if (focusedTrack) + focusedTrack = SetFocus(); + } } if( !TrackNum( focusedTrack ) ) @@ -92,23 +105,22 @@ std::shared_ptr TrackPanelAx::SetFocus( std::shared_ptr track ) } mFocusedTrack = track; + mNumFocusedTrack = TrackNum(track); #if wxUSE_ACCESSIBILITY if( track ) { - int num = TrackNum( track ); - NotifyEvent( wxACC_EVENT_OBJECT_FOCUS, mTrackPanel, wxOBJID_CLIENT, - num ); + mNumFocusedTrack ); if( track->GetSelected() ) { NotifyEvent( wxACC_EVENT_OBJECT_SELECTION, mTrackPanel, wxOBJID_CLIENT, - num ); + mNumFocusedTrack ); } } else diff --git a/src/TrackPanelAx.h b/src/TrackPanelAx.h index f61b5e7dd..a932e7893 100644 --- a/src/TrackPanelAx.h +++ b/src/TrackPanelAx.h @@ -121,6 +121,7 @@ private: TrackPanel *mTrackPanel; std::weak_ptr mFocusedTrack; + int mNumFocusedTrack; wxString mMessage; bool mTrackName;