+#if wxUSE_HOTKEY && wxOSX_USE_COCOA_OR_CARBON
+
+OSStatus
+wxHotKeyHandler(EventHandlerCallRef WXUNUSED(nextHandler),
+ EventRef event,
+ void* WXUNUSED(userData))
+{
+ EventHotKeyID hotKeyId;
+
+ GetEventParameter( event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(hotKeyId), NULL, &hotKeyId);
+
+ for ( unsigned i = 0; i < s_hotkeys.size(); ++i )
+ {
+ if ( s_hotkeys[i].keyId == static_cast<int>(hotKeyId.id) )
+ {
+ unsigned char charCode ;
+ UInt32 keyCode ;
+ UInt32 modifiers ;
+ UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
+
+ GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode );
+ GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
+ GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
+
+ UInt32 keymessage = (keyCode << 8) + charCode;
+
+ wxKeyEvent wxevent(wxEVT_HOTKEY);
+ wxevent.SetId(hotKeyId.id);
+ wxTheApp->MacCreateKeyEvent( wxevent, s_hotkeys[i].window , keymessage ,
+ modifiers , when , 0 ) ;
+
+ s_hotkeys[i].window->HandleWindowEvent(wxevent);
+ }
+ }
+
+ return noErr;
+}
+
+bool wxWindowMac::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
+{
+ for ( unsigned i = 0; i < s_hotkeys.size(); ++i )
+ {
+ if ( s_hotkeys[i].keyId == hotkeyId )
+ {
+ wxLogLastError(wxT("hotkeyId already registered"));
+
+ return false;
+ }
+ }
+
+ static bool installed = false;
+ if ( !installed )
+ {
+ EventTypeSpec eventType;
+ eventType.eventClass=kEventClassKeyboard;
+ eventType.eventKind=kEventHotKeyPressed;
+
+ InstallApplicationEventHandler(&wxHotKeyHandler, 1, &eventType, NULL, NULL);
+ installed = true;
+ }
+
+ UInt32 mac_modifiers=0;
+ if ( modifiers & wxMOD_ALT )
+ mac_modifiers |= optionKey;
+ if ( modifiers & wxMOD_SHIFT )
+ mac_modifiers |= shiftKey;
+ if ( modifiers & wxMOD_RAW_CONTROL )
+ mac_modifiers |= controlKey;
+ if ( modifiers & wxMOD_CONTROL )
+ mac_modifiers |= cmdKey;
+
+ EventHotKeyRef hotKeyRef;
+ EventHotKeyID hotKeyIDmac;
+
+ hotKeyIDmac.signature = 'WXMC';
+ hotKeyIDmac.id = hotkeyId;
+
+ if ( RegisterEventHotKey(wxCharCodeWXToOSX((wxKeyCode)keycode), mac_modifiers, hotKeyIDmac,
+ GetApplicationEventTarget(), 0, &hotKeyRef) != noErr )
+ {
+ wxLogLastError(wxT("RegisterHotKey"));
+
+ return false;
+ }
+ else
+ {
+ wxHotKeyRec v;
+ v.ref = hotKeyRef;
+ v.keyId = hotkeyId;
+ v.window = this;
+
+ s_hotkeys.push_back(v);
+ }
+
+ return true;
+}
+
+bool wxWindowMac::UnregisterHotKey(int hotkeyId)
+{
+ for ( int i = ((int)s_hotkeys.size())-1; i>=0; -- i )
+ {
+ if ( s_hotkeys[i].keyId == hotkeyId )
+ {
+ EventHotKeyRef ref = s_hotkeys[i].ref;
+ s_hotkeys.erase(s_hotkeys.begin() + i);
+ if ( UnregisterEventHotKey(ref) != noErr )
+ {
+ wxLogLastError(wxT("UnregisterHotKey"));
+
+ return false;
+ }
+ else
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#endif // wxUSE_HOTKEY
+
+bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event )
+{
+ bool handled = false;
+
+ // moved the ordinary key event sending AFTER the accel evaluation
+
+#if wxUSE_ACCEL
+ if ( !handled && event.GetEventType() == wxEVT_KEY_DOWN)
+ {
+ wxWindow *ancestor = this;
+ while (ancestor)
+ {
+ int command = ancestor->GetAcceleratorTable()->GetCommand( event );
+ if (command != -1)
+ {
+ wxEvtHandler * const handler = ancestor->GetEventHandler();
+
+ wxCommandEvent command_event( wxEVT_MENU, command );
+ handled = handler->ProcessEvent( command_event );
+
+ if ( !handled )
+ {
+ // accelerators can also be used with buttons, try them too
+ command_event.SetEventType(wxEVT_BUTTON);
+ handled = handler->ProcessEvent( command_event );
+ }
+
+ break;
+ }
+
+ if (ancestor->IsTopLevel())
+ break;
+
+ ancestor = ancestor->GetParent();
+ }
+ }
+#endif // wxUSE_ACCEL
+
+ if ( !handled )
+ {
+ handled = HandleWindowEvent( event ) ;
+ if ( handled && event.GetSkipped() )
+ handled = false ;
+ }
+
+ return handled ;
+}
+