Bug 406 - Label creation/other non-dialogue editing and keyboard selection hang on long projects
This is part 1... Provides some relief to the selection "hang" This patch adds the ability for the keyboard based commands (like cursor left, extend selection right, etc.) to know when the key has been released. When the patch is applied the current state is saved only when the key is released and not every time it repeats. Here's an example of the difference it makes. This video show the selection "hang", but also watch the CPU usage. All I'm doing is pressing SHIFT+RIGHT ARROW. http://youtu.be/tdMntDwGSkM This one is the same thing bug with the patch applied. Notice that the selection "hang" no longer occurs and look at the CPU usage! http://youtu.be/EpXNsQ4Cky0
This commit is contained in:
parent
0bee195b0e
commit
03f5088b6a
|
@ -138,6 +138,16 @@ AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *pr
|
|||
{
|
||||
mProject = project;
|
||||
mCommandFunction = commandFunction;
|
||||
mCommandKeyFunction = NULL;
|
||||
mCommandListFunction = NULL;
|
||||
}
|
||||
|
||||
AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *project,
|
||||
audCommandKeyFunction commandFunction)
|
||||
{
|
||||
mProject = project;
|
||||
mCommandFunction = NULL;
|
||||
mCommandKeyFunction = commandFunction;
|
||||
mCommandListFunction = NULL;
|
||||
}
|
||||
|
||||
|
@ -146,6 +156,7 @@ AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *pr
|
|||
{
|
||||
mProject = project;
|
||||
mCommandFunction = NULL;
|
||||
mCommandKeyFunction = NULL;
|
||||
mCommandListFunction = commandFunction;
|
||||
}
|
||||
|
||||
|
@ -155,16 +166,19 @@ AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *pr
|
|||
{
|
||||
mProject = project;
|
||||
mCommandFunction = NULL;
|
||||
mCommandKeyFunction = NULL;
|
||||
mCommandListFunction = commandFunction;
|
||||
mExplicitIndices = explicitIndices;
|
||||
}
|
||||
|
||||
void AudacityProjectCommandFunctor::operator()(int index )
|
||||
void AudacityProjectCommandFunctor::operator()(int index, const wxEvent * evt)
|
||||
{
|
||||
if (mCommandListFunction && mExplicitIndices.GetCount() > 0)
|
||||
(mProject->*(mCommandListFunction)) (mExplicitIndices[index]);
|
||||
else if (mCommandListFunction)
|
||||
(mProject->*(mCommandListFunction)) (index);
|
||||
else if (mCommandKeyFunction)
|
||||
(mProject->*(mCommandKeyFunction)) (evt);
|
||||
else
|
||||
(mProject->*(mCommandFunction)) ();
|
||||
}
|
||||
|
@ -1116,21 +1130,21 @@ void AudacityProject::CreateMenusAndCommands()
|
|||
c->AddCommand(wxT("Toggle"), _("Toggle Focused Track"), FN(OnToggle), wxT("Return"));
|
||||
c->AddCommand(wxT("ToggleAlt"), _("Toggle Focused Track"), FN(OnToggle), wxT("NUMPAD_ENTER"));
|
||||
|
||||
c->AddCommand(wxT("CursorLeft"), _("Cursor Left"), FN(OnCursorLeft), wxT("Left\tallowdup"));
|
||||
c->AddCommand(wxT("CursorRight"), _("Cursor Right"), FN(OnCursorRight), wxT("Right\tallowdup"));
|
||||
c->AddCommand(wxT("CursorLeft"), _("Cursor Left"), FN(OnCursorLeft), wxT("Left\twantevent\tallowdup"));
|
||||
c->AddCommand(wxT("CursorRight"), _("Cursor Right"), FN(OnCursorRight), wxT("Right\twantevent\tallowdup"));
|
||||
c->AddCommand(wxT("CursorShortJumpLeft"), _("Cursor Short Jump Left"), FN(OnCursorShortJumpLeft), wxT(","));
|
||||
c->AddCommand(wxT("CursorShortJumpRight"), _("Cursor Short Jump Right"), FN(OnCursorShortJumpRight), wxT("."));
|
||||
c->AddCommand(wxT("CursorLongJumpLeft"), _("Cursor Long Jump Left"), FN(OnCursorLongJumpLeft), wxT("Shift+,"));
|
||||
c->AddCommand(wxT("CursorLongJumpRight"), _("Cursor Long Jump Right"), FN(OnCursorLongJumpRight), wxT("Shift+."));
|
||||
|
||||
c->AddCommand(wxT("SelExtLeft"), _("Selection Extend Left"), FN(OnSelExtendLeft), wxT("Shift+Left\tallowdup"));
|
||||
c->AddCommand(wxT("SelExtRight"), _("Selection Extend Right"), FN(OnSelExtendRight), wxT("Shift+Right\tallowdup"));
|
||||
c->AddCommand(wxT("SelExtLeft"), _("Selection Extend Left"), FN(OnSelExtendLeft), wxT("Shift+Left\twantevent\tallowdup"));
|
||||
c->AddCommand(wxT("SelExtRight"), _("Selection Extend Right"), FN(OnSelExtendRight), wxT("Shift+Right\twantevent\tallowdup"));
|
||||
|
||||
c->AddCommand(wxT("SelSetExtLeft"), _("Set (or Extend) Left Selection"), FN(OnSelSetExtendLeft));
|
||||
c->AddCommand(wxT("SelSetExtRight"), _("Set (or Extend) Right Selection"), FN(OnSelSetExtendRight));
|
||||
|
||||
c->AddCommand(wxT("SelCntrLeft"), _("Selection Contract Left"), FN(OnSelContractLeft), wxT("Ctrl+Shift+Right"));
|
||||
c->AddCommand(wxT("SelCntrRight"), _("Selection Contract Right"), FN(OnSelContractRight), wxT("Ctrl+Shift+Left"));
|
||||
c->AddCommand(wxT("SelCntrLeft"), _("Selection Contract Left"), FN(OnSelContractLeft), wxT("Ctrl+Shift+Right\twantevent"));
|
||||
c->AddCommand(wxT("SelCntrRight"), _("Selection Contract Right"), FN(OnSelContractRight), wxT("Ctrl+Shift+Left\twantevent"));
|
||||
|
||||
c->AddCommand(wxT("TrackPan"), _("Change pan on focused track"), FN(OnTrackPan), wxT("Shift+P"));
|
||||
c->AddCommand(wxT("TrackPanLeft"), _("Pan left on focused track"), FN(OnTrackPanLeft), wxT("Alt+Shift+Left"));
|
||||
|
@ -2166,14 +2180,14 @@ void AudacityProject::OnToggle()
|
|||
mTrackPanel->OnToggle( );
|
||||
}
|
||||
|
||||
void AudacityProject::OnCursorLeft()
|
||||
void AudacityProject::OnCursorLeft(const wxEvent * evt)
|
||||
{
|
||||
mTrackPanel->OnCursorLeft( false, false );
|
||||
mTrackPanel->OnCursorLeft( false, false, evt->GetEventType() == wxEVT_KEY_UP );
|
||||
}
|
||||
|
||||
void AudacityProject::OnCursorRight()
|
||||
void AudacityProject::OnCursorRight(const wxEvent * evt)
|
||||
{
|
||||
mTrackPanel->OnCursorRight( false, false );
|
||||
mTrackPanel->OnCursorRight( false, false, evt->GetEventType() == wxEVT_KEY_UP );
|
||||
}
|
||||
|
||||
void AudacityProject::OnCursorShortJumpLeft()
|
||||
|
@ -2206,24 +2220,24 @@ void AudacityProject::OnSelSetExtendRight()
|
|||
mTrackPanel->OnBoundaryMove( false, false);
|
||||
}
|
||||
|
||||
void AudacityProject::OnSelExtendLeft()
|
||||
void AudacityProject::OnSelExtendLeft(const wxEvent * evt)
|
||||
{
|
||||
mTrackPanel->OnCursorLeft( true, false );
|
||||
mTrackPanel->OnCursorLeft( true, false, evt->GetEventType() == wxEVT_KEY_UP );
|
||||
}
|
||||
|
||||
void AudacityProject::OnSelExtendRight()
|
||||
void AudacityProject::OnSelExtendRight(const wxEvent * evt)
|
||||
{
|
||||
mTrackPanel->OnCursorRight( true, false );
|
||||
mTrackPanel->OnCursorRight( true, false, evt->GetEventType() == wxEVT_KEY_UP );
|
||||
}
|
||||
|
||||
void AudacityProject::OnSelContractLeft()
|
||||
void AudacityProject::OnSelContractLeft(const wxEvent * evt)
|
||||
{
|
||||
mTrackPanel->OnCursorRight( true, true );
|
||||
mTrackPanel->OnCursorRight( true, true, evt->GetEventType() == wxEVT_KEY_UP );
|
||||
}
|
||||
|
||||
void AudacityProject::OnSelContractRight()
|
||||
void AudacityProject::OnSelContractRight(const wxEvent * evt)
|
||||
{
|
||||
mTrackPanel->OnCursorLeft( true, true );
|
||||
mTrackPanel->OnCursorLeft( true, true, evt->GetEventType() == wxEVT_KEY_UP );
|
||||
}
|
||||
|
||||
//this pops up a dialog which allows the left selection to be set.
|
||||
|
|
12
src/Menus.h
12
src/Menus.h
|
@ -136,12 +136,12 @@ void OnCursorDown();
|
|||
void OnShiftDown();
|
||||
void OnToggle();
|
||||
|
||||
void OnCursorLeft();
|
||||
void OnCursorRight();
|
||||
void OnSelExtendLeft();
|
||||
void OnSelExtendRight();
|
||||
void OnSelContractLeft();
|
||||
void OnSelContractRight();
|
||||
void OnCursorLeft(const wxEvent * evt);
|
||||
void OnCursorRight(const wxEvent * evt);
|
||||
void OnSelExtendLeft(const wxEvent * evt);
|
||||
void OnSelExtendRight(const wxEvent * evt);
|
||||
void OnSelContractLeft(const wxEvent * evt);
|
||||
void OnSelContractRight(const wxEvent * evt);
|
||||
|
||||
void OnCursorShortJumpLeft();
|
||||
void OnCursorShortJumpRight();
|
||||
|
|
|
@ -1707,7 +1707,7 @@ bool AudacityProject::HandleKeyUp(wxKeyEvent & event)
|
|||
if (event.GetKeyCode() == WXK_CONTROL)
|
||||
mTrackPanel->HandleControlKey(false);
|
||||
|
||||
return false;
|
||||
return mCommandManager.HandleKey(event, GetUpdateFlags(), 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void AudacityProject::OnMenuEvent(wxMenuEvent & event)
|
||||
|
|
|
@ -569,6 +569,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame,
|
|||
};
|
||||
|
||||
typedef void (AudacityProject::*audCommandFunction)();
|
||||
typedef void (AudacityProject::*audCommandKeyFunction)(const wxEvent *);
|
||||
typedef void (AudacityProject::*audCommandListFunction)(int);
|
||||
|
||||
// Previously this was in menus.cpp, and the declaration of the
|
||||
|
@ -578,15 +579,18 @@ class AUDACITY_DLL_API AudacityProjectCommandFunctor : public CommandFunctor
|
|||
public:
|
||||
AudacityProjectCommandFunctor(AudacityProject *project,
|
||||
audCommandFunction commandFunction);
|
||||
AudacityProjectCommandFunctor(AudacityProject *project,
|
||||
audCommandKeyFunction commandFunction);
|
||||
AudacityProjectCommandFunctor(AudacityProject *project,
|
||||
audCommandListFunction commandFunction);
|
||||
AudacityProjectCommandFunctor(AudacityProject *project,
|
||||
audCommandListFunction commandFunction,
|
||||
wxArrayInt explicitIndices);
|
||||
virtual void operator()(int index = 0);
|
||||
virtual void operator()(int index = 0, const wxEvent *evt = NULL);
|
||||
private:
|
||||
AudacityProject *mProject;
|
||||
audCommandFunction mCommandFunction;
|
||||
audCommandKeyFunction mCommandKeyFunction;
|
||||
audCommandListFunction mCommandListFunction;
|
||||
wxArrayInt mExplicitIndices;
|
||||
};
|
||||
|
|
|
@ -6479,8 +6479,20 @@ void TrackPanel::ScrollIntoView(int x)
|
|||
ScrollIntoView(PositionToTime(x, GetLeftOffset()));
|
||||
}
|
||||
|
||||
void TrackPanel::OnCursorLeft( bool shift, bool ctrl )
|
||||
void TrackPanel::OnCursorLeft( bool shift, bool ctrl, bool keyup )
|
||||
{
|
||||
if( keyup )
|
||||
{
|
||||
int token = GetProject()->GetAudioIOToken();
|
||||
if( token > 0 && gAudioIO->IsStreamActive( token ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MakeParentModifyState();
|
||||
return;
|
||||
}
|
||||
|
||||
// If the last adjustment was very recent, we are
|
||||
// holding the key down and should move faster.
|
||||
wxLongLong curtime = ::wxGetLocalTimeMillis();
|
||||
|
@ -6579,12 +6591,22 @@ void TrackPanel::OnCursorLeft( bool shift, bool ctrl )
|
|||
// Make sure it's visible
|
||||
ScrollIntoView( mViewInfo->sel0 );
|
||||
}
|
||||
|
||||
MakeParentModifyState();
|
||||
}
|
||||
|
||||
void TrackPanel::OnCursorRight( bool shift, bool ctrl )
|
||||
void TrackPanel::OnCursorRight( bool shift, bool ctrl, bool keyup )
|
||||
{
|
||||
if( keyup )
|
||||
{
|
||||
int token = GetProject()->GetAudioIOToken();
|
||||
if( token > 0 && gAudioIO->IsStreamActive( token ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MakeParentModifyState();
|
||||
return;
|
||||
}
|
||||
|
||||
// If the last adjustment was very recent, we are
|
||||
// holding the key down and should move faster.
|
||||
wxLongLong curtime = ::wxGetLocalTimeMillis();
|
||||
|
@ -6685,8 +6707,6 @@ void TrackPanel::OnCursorRight( bool shift, bool ctrl )
|
|||
// Make sure new position is in view
|
||||
ScrollIntoView( mViewInfo->sel1 );
|
||||
}
|
||||
|
||||
MakeParentModifyState();
|
||||
}
|
||||
|
||||
// Handles moving a selection edge with the keyboard in snap-to-time mode;
|
||||
|
|
|
@ -235,8 +235,8 @@ class AUDACITY_DLL_API TrackPanel:public wxPanel {
|
|||
virtual void OnNextTrack(bool shift = false);
|
||||
virtual void OnToggle();
|
||||
|
||||
virtual void OnCursorLeft(bool shift, bool ctrl);
|
||||
virtual void OnCursorRight(bool shift, bool ctrl);
|
||||
virtual void OnCursorLeft(bool shift, bool ctrl, bool keyup = false);
|
||||
virtual void OnCursorRight(bool shift, bool ctrl, bool keyup = false);
|
||||
virtual void OnCursorMove(bool forward, bool jump, bool longjump);
|
||||
virtual void OnBoundaryMove(bool left, bool boundaryContract);
|
||||
virtual void ScrollIntoView(double pos);
|
||||
|
|
|
@ -695,6 +695,7 @@ int CommandManager::NewIdentifier(wxString name, wxString label, wxMenu *menu,
|
|||
tmpEntry->flags = mDefaultFlags;
|
||||
tmpEntry->mask = mDefaultMask;
|
||||
tmpEntry->enabled = true;
|
||||
tmpEntry->wantevent = (label.Find(wxT("\twantevent")) != wxNOT_FOUND);
|
||||
|
||||
// Key from preferences overridse the default key given
|
||||
gPrefs->SetPath(wxT("/NewKeys"));
|
||||
|
@ -1000,7 +1001,7 @@ void CommandManager::TellUserWhyDisallowed( wxUint32 flagsGot, wxUint32 flagsReq
|
|||
/// returning true iff successful. If you pass any flags,
|
||||
///the command won't be executed unless the flags are compatible
|
||||
///with the command's flags.
|
||||
bool CommandManager::HandleCommandEntry(CommandListEntry * entry, wxUint32 flags, wxUint32 mask)
|
||||
bool CommandManager::HandleCommandEntry(CommandListEntry * entry, wxUint32 flags, wxUint32 mask, const wxEvent * evt)
|
||||
{
|
||||
if (!entry || !entry->enabled)
|
||||
return false;
|
||||
|
@ -1025,7 +1026,7 @@ bool CommandManager::HandleCommandEntry(CommandListEntry * entry, wxUint32 flags
|
|||
}
|
||||
}
|
||||
|
||||
(*(entry->callback))(entry->index);
|
||||
(*(entry->callback))(entry->index, evt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1050,7 +1051,17 @@ bool CommandManager::HandleKey(wxKeyEvent &evt, wxUint32 flags, wxUint32 mask)
|
|||
{
|
||||
wxString keyStr = KeyEventToKeyString(evt);
|
||||
CommandListEntry *entry = mCommandKeyHash[keyStr];
|
||||
return HandleCommandEntry( entry, flags, mask );
|
||||
if (evt.GetEventType() == wxEVT_KEY_DOWN)
|
||||
{
|
||||
return HandleCommandEntry( entry, flags, mask, &evt );
|
||||
}
|
||||
|
||||
if (entry && entry->wantevent)
|
||||
{
|
||||
return HandleCommandEntry( entry, flags, mask, &evt );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// HandleTextualCommand() allows us a limitted version of script/batch
|
||||
|
|
|
@ -25,7 +25,7 @@ class AUDACITY_DLL_API CommandFunctor
|
|||
public:
|
||||
CommandFunctor(){};
|
||||
virtual ~CommandFunctor(){};
|
||||
virtual void operator()(int index = 0) = 0;
|
||||
virtual void operator()(int index = 0, const wxEvent *e = NULL) = 0;
|
||||
};
|
||||
|
||||
struct MenuBarListEntry
|
||||
|
@ -55,6 +55,7 @@ struct CommandListEntry
|
|||
int index;
|
||||
int count;
|
||||
bool enabled;
|
||||
bool wantevent;
|
||||
wxUint32 flags;
|
||||
wxUint32 mask;
|
||||
};
|
||||
|
@ -180,7 +181,7 @@ class AUDACITY_DLL_API CommandManager: public XMLTagHandler
|
|||
//
|
||||
// Executing commands
|
||||
//
|
||||
bool HandleCommandEntry(CommandListEntry * entry, wxUint32 flags, wxUint32 mask);
|
||||
bool HandleCommandEntry(CommandListEntry * entry, wxUint32 flags, wxUint32 mask, const wxEvent * evt = NULL);
|
||||
bool HandleMenuID(int id, wxUint32 flags, wxUint32 mask);
|
||||
bool HandleKey(wxKeyEvent &evt, wxUint32 flags, wxUint32 mask);
|
||||
bool HandleTextualCommand(wxString & Str, wxUint32 flags, wxUint32 mask);
|
||||
|
|
Loading…
Reference in New Issue