1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-15 08:07:41 +02:00

Do NOT generate keyup, use the system one

David has been trying to beat it into my thick skull that the
command manager should use the system created key up event rather
than generating it, but I just wasn't getting it.

Actually, the documentation for the OSX method I needed to use
to get at the key event before the menus did said that a key up
event couldn't be captured on 10.6 (the oldest we support).  But,
testing showed that it can be, so I was able to do what David was
suggesting.
This commit is contained in:
Leland Lucius 2015-08-12 18:05:50 -05:00
parent 0f79a77baa
commit e119ffcd78
3 changed files with 60 additions and 38 deletions

View File

@ -1193,7 +1193,7 @@ void AudacityProject::CreateMenusAndCommands()
c->AddCommand(wxT("TrackGain"), _("Change gain on focused track"), FN(OnTrackGain), wxT("Shift+G")); c->AddCommand(wxT("TrackGain"), _("Change gain on focused track"), FN(OnTrackGain), wxT("Shift+G"));
c->AddCommand(wxT("TrackGainInc"), _("Increase gain on focused track"), FN(OnTrackGainInc), wxT("Alt+Shift+Up")); c->AddCommand(wxT("TrackGainInc"), _("Increase gain on focused track"), FN(OnTrackGainInc), wxT("Alt+Shift+Up"));
c->AddCommand(wxT("TrackGainDec"), _("Decrease gain on focused track"), FN(OnTrackGainDec), wxT("Alt+Shift+Down")); c->AddCommand(wxT("TrackGainDec"), _("Decrease gain on focused track"), FN(OnTrackGainDec), wxT("Alt+Shift+Down"));
c->AddCommand(wxT("TrackMenu"), _("Open menu on focused track"), FN(OnTrackMenu), wxT("Shift+M")); c->AddCommand(wxT("TrackMenu"), _("Open menu on focused track"), FN(OnTrackMenu), wxT("Shift+M\tskipKeydown"));
c->AddCommand(wxT("TrackMute"), _("Mute/Unmute focused track"), FN(OnTrackMute), wxT("Shift+U")); c->AddCommand(wxT("TrackMute"), _("Mute/Unmute focused track"), FN(OnTrackMute), wxT("Shift+U"));
c->AddCommand(wxT("TrackSolo"), _("Solo/Unsolo focused track"), FN(OnTrackSolo), wxT("Shift+S")); c->AddCommand(wxT("TrackSolo"), _("Solo/Unsolo focused track"), FN(OnTrackSolo), wxT("Shift+S"));
c->AddCommand(wxT("TrackClose"), _("Close focused track"), FN(OnTrackClose), wxT("Shift+C")); c->AddCommand(wxT("TrackClose"), _("Close focused track"), FN(OnTrackClose), wxT("Shift+C"));

View File

@ -123,7 +123,14 @@ public:
: wxEventFilter() : wxEventFilter()
{ {
#if defined(__WXMAC__) #if defined(__WXMAC__)
NSEventMask mask = NSKeyDownMask; // In wx3, the menu accelerators take precendence over key event processing
// so we won't get wxEVT_CHAR_HOOK events for combinations assigned to menus.
// Since we only support OS X 10.6 or greater, we can use an event monitor
// to capture the key event before it gets to the normal wx3 processing.
// The documentation for addLocalMonitorForEventsMatchingMask implies that
// NSKeyUpMask can't be used in 10.6, but testing shows that it can.
NSEventMask mask = NSKeyDownMask | NSKeyUpMask;
mHandler = mHandler =
[ [
@ -138,11 +145,18 @@ public:
{ {
mEvent = event; mEvent = event;
wxKeyEvent wxevent(wxEVT_KEY_DOWN); wxKeyEvent wxevent([event type] == NSKeyDown ? wxEVT_KEY_DOWN : wxEVT_KEY_UP);
impl->SetupKeyEvent(wxevent, event); impl->SetupKeyEvent(wxevent, event);
wxKeyEvent eventHook(wxEVT_CHAR_HOOK, wxevent); if ([event type] == NSKeyDown)
return FilterEvent(eventHook) == Event_Processed ? nil : event; {
wxKeyEvent eventHook(wxEVT_CHAR_HOOK, wxevent);
return FilterEvent(eventHook) == Event_Processed ? nil : event;
}
else
{
return FilterEvent(wxevent) == Event_Processed ? nil : event;
}
} }
} }
@ -166,25 +180,31 @@ public:
int FilterEvent(wxEvent& event) int FilterEvent(wxEvent& event)
{ {
wxEventType type = event.GetEventType(); wxEventType type = event.GetEventType();
if (type != wxEVT_CHAR_HOOK) if (type != wxEVT_CHAR_HOOK && type != wxEVT_KEY_UP)
{ {
return Event_Skip; return Event_Skip;
} }
AudacityProject *project = GetActiveProject(); AudacityProject *project = GetActiveProject();
if (!project || !project->IsEnabled()) if (!project || !project->IsEnabled())
{ {
return Event_Skip; return Event_Skip;
} }
wxKeyEvent key = (wxKeyEvent &) event;
if (type == wxEVT_CHAR_HOOK)
{
key.SetEventType(wxEVT_KEY_DOWN);
}
wxWindow *handler = project->GetKeyboardCaptureHandler(); wxWindow *handler = project->GetKeyboardCaptureHandler();
if (handler && HandleCapture(handler, (wxKeyEvent &) event)) if (handler && HandleCapture(handler, key))
{ {
return Event_Processed; return Event_Processed;
} }
CommandManager *manager = project->GetCommandManager(); CommandManager *manager = project->GetCommandManager();
if (manager && manager->FilterKeyEvent(project, (wxKeyEvent &) event)) if (manager && manager->FilterKeyEvent(project, key))
{ {
return Event_Processed; return Event_Processed;
} }
@ -195,7 +215,7 @@ public:
private: private:
// Returns true if the event was captured and processed // Returns true if the event was captured and processed
bool HandleCapture(wxWindow *target, wxKeyEvent & event) bool HandleCapture(wxWindow *target, const wxKeyEvent & event)
{ {
if (wxGetTopLevelParent(target) != wxGetTopLevelParent(wxWindow::FindFocus())) if (wxGetTopLevelParent(target) != wxGetTopLevelParent(wxWindow::FindFocus()))
{ {
@ -203,8 +223,7 @@ private:
} }
wxEvtHandler *handler = target->GetEventHandler(); wxEvtHandler *handler = target->GetEventHandler();
wxKeyEvent temp = (wxKeyEvent &) event; wxKeyEvent temp = event;
temp.SetEventType(wxEVT_KEY_DOWN);
#if defined(__WXGTK__) #if defined(__WXGTK__)
// wxGTK uses the control and alt modifiers to represent ALTGR, // wxGTK uses the control and alt modifiers to represent ALTGR,
@ -233,24 +252,20 @@ private:
return false; return false;
} }
wxString chars = GetUnicodeString(temp); if (temp.GetEventType() == wxEVT_KEY_DOWN)
for (size_t i = 0, cnt = chars.Length(); i < cnt; i++)
{ {
temp = (wxKeyEvent &) event; wxString chars = GetUnicodeString(temp);
temp.SetEventType(wxEVT_CHAR); for (size_t i = 0, cnt = chars.Length(); i < cnt; i++)
temp.WasProcessed(); {
temp.StopPropagation(); temp = event;
temp.m_uniChar = chars[i]; temp.SetEventType(wxEVT_CHAR);
wxEventProcessInHandlerOnly onlyChar(temp, handler); temp.WasProcessed();
handler->ProcessEvent(temp); temp.StopPropagation();
temp.m_uniChar = chars[i];
wxEventProcessInHandlerOnly onlyChar(temp, handler);
handler->ProcessEvent(temp);
}
} }
temp = (wxKeyEvent &) event;
temp.SetEventType(wxEVT_KEY_UP);
temp.WasProcessed();
temp.StopPropagation();
wxEventProcessInHandlerOnly onlyUp(temp, handler);
handler->ProcessEvent(temp);
return true; return true;
} }
@ -834,7 +849,8 @@ CommandListEntry *CommandManager::NewIdentifier(const wxString & name,
entry->flags = mDefaultFlags; entry->flags = mDefaultFlags;
entry->mask = mDefaultMask; entry->mask = mDefaultMask;
entry->enabled = true; entry->enabled = true;
entry->wantKeyup = (accel.Find(wxT("\twantKeyup")) != wxNOT_FOUND); entry->skipKeydown = (accel.Find(wxT("\tskipKeydown")) != wxNOT_FOUND);
entry->wantKeyup = (accel.Find(wxT("\twantKeyup")) != wxNOT_FOUND) || entry->skipKeydown;
entry->isGlobal = false; entry->isGlobal = false;
// For key bindings for commands with a list, such as effects, // For key bindings for commands with a list, such as effects,
@ -1049,12 +1065,13 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent &
return false; return false;
} }
// Global commands are tied to any specific project // Global commands aren't tied to any specific project
if (entry->isGlobal) if (entry->isGlobal)
{ {
// Global commands are always disabled so they do not interfere with the // Global commands are always disabled so they do not interfere with the
// rest of the command handling. But, to use the common handler, we // rest of the command handling. But, to use the common handler, we
// enable it temporarily and then disable it again after handling. // enable them temporarily and then disable them again after handling.
// LL: Why do they need to be disabled???
entry->enabled = true; entry->enabled = true;
bool ret = HandleCommandEntry(entry, 0xffffffff, 0xffffffff, &evt); bool ret = HandleCommandEntry(entry, 0xffffffff, 0xffffffff, &evt);
entry->enabled = false; entry->enabled = false;
@ -1073,16 +1090,20 @@ bool CommandManager::FilterKeyEvent(AudacityProject *project, const wxKeyEvent &
wxUint32 flags = project->GetUpdateFlags(); wxUint32 flags = project->GetUpdateFlags();
wxKeyEvent temp = evt; wxKeyEvent temp = evt;
temp.SetEventType(wxEVT_KEY_DOWN);
if (HandleCommandEntry(entry, flags, 0xffffffff, &temp)) if (temp.GetEventType() == wxEVT_KEY_DOWN)
{ {
if (entry->wantKeyup) if (entry->skipKeydown)
{ {
temp.SetEventType(wxEVT_KEY_UP); return true;
HandleCommandEntry(entry, flags, 0xffffffff, &temp);
} }
return true; return HandleCommandEntry(entry, flags, 0xffffffff, &temp);
}
if (temp.GetEventType() == wxEVT_KEY_UP && entry->wantKeyup)
{
return HandleCommandEntry(entry, flags, 0xffffffff, &temp);
} }
return false; return false;

View File

@ -57,6 +57,7 @@ struct CommandListEntry
int index; int index;
int count; int count;
bool enabled; bool enabled;
bool skipKeydown;
bool wantKeyup; bool wantKeyup;
bool isGlobal; bool isGlobal;
wxUint32 flags; wxUint32 flags;