#include "wx/caret.h"
#endif
-#define MAC_SCROLLBAR_SIZE 15
-#define MAC_SMALL_SCROLLBAR_SIZE 11
+#if wxUSE_DRAG_AND_DROP
+#include "wx/dnd.h"
+#endif
#include "wx/mac/uma.h"
+#define MAC_SCROLLBAR_SIZE 15
+#define MAC_SMALL_SCROLLBAR_SIZE 11
+
#ifndef __DARWIN__
#include <Windows.h>
#include <ToolUtils.h>
#endif
#endif
-#if wxUSE_DRAG_AND_DROP
-#include "wx/dnd.h"
-#endif
-
#include <string.h>
extern wxList wxPendingDelete;
static const EventTypeSpec eventList[] =
{
+ { kEventClassCommand, kEventProcessCommand } ,
+ { kEventClassCommand, kEventCommandUpdateStatus } ,
+
{ kEventClassControl , kEventControlHit } ,
-#if TARGET_API_MAC_OSX
{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
{ kEventClassTextInput, kEventTextInputUpdateActiveInputArea } ,
-
+
{ kEventClassControl , kEventControlDraw } ,
{ kEventClassControl , kEventControlVisibilityChanged } ,
{ kEventClassControl , kEventControlEnabledStateChanged } ,
// { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
// { kEventClassControl , kEventControlBoundsChanged } ,
-#endif
} ;
static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
wxWindowMac* focus = (wxWindowMac*) data ;
-
+
wchar_t* uniChars = NULL ;
UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
-
+
UniChar* charBuf;
UInt32 dataSize = 0 ;
int numChars = 0 ;
{
numChars = dataSize / sizeof( UniChar) ;
charBuf = buf ;
-
+
if ( dataSize > sizeof(buf) )
charBuf = new UniChar[ numChars ] ;
else
charBuf = buf ;
-
+
uniChars = new wchar_t[ numChars ] ;
GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ;
#if SIZEOF_WCHAR_T == 2
numChars = converter.MB2WC( uniChars , (const char*)charBuf , numChars ) ;
#endif
}
-
+
switch ( GetEventKind( event ) )
{
case kEventTextInputUpdateActiveInputArea :
// EVT_CHAR
for (int pos=0 ; pos < numChars ; pos++)
{
-
WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
wxTheApp->MacSetCurrentEvent( event , handler ) ;
-
+
UInt32 message = (0 << 8) + ((char)uniChars[pos] );
if ( wxTheApp->MacSendCharEvent(
focus , message , 0 , when , 0 , 0 , uniChars[pos] ) )
{
result = noErr ;
}
-
+
wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
}
}
GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers );
GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point );
-
+
UInt32 message = (keyCode << 8) + charCode;
- // this is only called when no default handler has jumped in, e.g. a wxControl on a floater window does not
- // get its own kEventTextInputUnicodeForKeyEvent, so we reroute the event back to the control
-
- // NOTE to Stefan: Is this still needed? Shouldn't we be calling SendToEventTarget rather than
- // HandleControlKey? (which, IIRC, is not Unicode friendly?) TODO :: MEMORY LEAK IN uniChar etc.
- /*
- wxControl* control = wxDynamicCast( focus , wxControl ) ;
- if ( control )
- {
- ControlRef macControl = (ControlRef) control->GetHandle() ;
- if ( macControl )
- {
- ::HandleControlKey( macControl , keyCode , charCode , modifiers ) ;
- result = noErr ;
- }
- }
- */
-
+
// An IME input event may return several characters, but we need to send one char at a time to
// EVT_CHAR
for (int pos=0 ; pos < numChars ; pos++)
{
-
WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
wxTheApp->MacSetCurrentEvent( event , handler ) ;
-
+
if ( wxTheApp->MacSendCharEvent(
focus , message , modifiers , when , point.h , point.v , uniChars[pos] ) )
{
result = noErr ;
}
-
+
wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
}
}
default:
break ;
}
-
- delete[] uniChars ;
+
+ delete [] uniChars ;
if ( charBuf != buf )
- delete[] charBuf ;
+ delete [] charBuf ;
return result ;
-
+}
+
+static pascal OSStatus wxMacWindowCommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+ wxWindowMac* focus = (wxWindowMac*) data ;
+
+ HICommand command ;
+
+ wxMacCarbonEvent cEvent( event ) ;
+ cEvent.GetParameter<HICommand>(kEventParamDirectObject,typeHICommand,&command) ;
+
+ wxMenuItem* item = NULL ;
+ wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ;
+ int id = wxMacCommandToId( command.commandID ) ;
+
+ if ( item )
+ {
+ wxASSERT( itemMenu != NULL ) ;
+
+ switch ( cEvent.GetKind() )
+ {
+ case kEventProcessCommand :
+ {
+ if (item->IsCheckable())
+ item->Check( !item->IsChecked() ) ;
+
+ if ( itemMenu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) )
+ result = noErr ;
+ else
+ {
+ wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED , id);
+ event.SetEventObject(focus);
+ event.SetInt(item->IsCheckable() ? item->IsChecked() : -1);
+
+ if ( focus->GetEventHandler()->ProcessEvent(event) )
+ result = noErr ;
+ }
+ }
+ break ;
+
+ case kEventCommandUpdateStatus:
+ {
+ wxUpdateUIEvent event(id);
+ event.SetEventObject( itemMenu );
+
+ bool processed = false;
+
+ // Try the menu's event handler
+ {
+ wxEvtHandler *handler = itemMenu->GetEventHandler();
+ if ( handler )
+ processed = handler->ProcessEvent(event);
+ }
+
+ // Try the window the menu was popped up from
+ // (and up through the hierarchy)
+ if ( !processed )
+ {
+ const wxMenuBase *menu = itemMenu;
+ while ( menu )
+ {
+ wxWindow *win = menu->GetInvokingWindow();
+ if ( win )
+ {
+ processed = win->GetEventHandler()->ProcessEvent(event);
+ break;
+ }
+
+ menu = menu->GetParent();
+ }
+ }
+
+ if ( !processed )
+ {
+ processed = focus->GetEventHandler()->ProcessEvent(event);
+ }
+
+ if ( processed )
+ {
+ // if anything changed, update the changed attribute
+ if (event.GetSetText())
+ itemMenu->SetLabel(id, event.GetText());
+ if (event.GetSetChecked())
+ itemMenu->Check(id, event.GetChecked());
+ if (event.GetSetEnabled())
+ itemMenu->Enable(id, event.GetEnabled());
+
+ result = noErr ;
+ }
+ }
+ break ;
+
+ default :
+ break ;
+ }
+ }
+ return result ;
}
pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
switch ( GetEventClass( event ) )
{
+ case kEventClassCommand :
+ result = wxMacWindowCommandEventHandler( handler , event , data ) ;
+ break ;
+
case kEventClassControl :
result = wxMacWindowControlEventHandler( handler, event, data ) ;
break ;
case kEventClassTextInput :
result = wxMacUnicodeTextEventHandler( handler , event , data ) ;
break ;
+
default :
break ;
}
wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
}
-// Destructor
wxWindowMac::~wxWindowMac()
{
SendDestroyEvent();
break;
}
}
-#endif // __WXUNIVERSAL__
+#endif
// destroy children before destroying this window itself
DestroyChildren();
bool wxWindowMac::MacCanFocus() const
{
- // there is currently no way to determine whether the window is running in full keyboard
- // access mode, therefore we cannot rely on these features, yet the only other way would be
- // to issue a SetKeyboardFocus event and verify after whether it succeeded, this would risk problems
- // in event handlers...
- UInt32 features = 0 ;
- m_peer->GetFeatures( &features ) ;
+ // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
+ // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning, but the value range
+ // is nowhere documented
+ Boolean keyExistsAndHasValidFormat ;
+ CFIndex fullKeyboardAccess = CFPreferencesGetAppIntegerValue ( CFSTR("AppleKeyboardUIMode" ) ,
+ kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat);
+
+ if ( keyExistsAndHasValidFormat && fullKeyboardAccess > 0 )
+ return true ;
+ else
+ {
+ UInt32 features = 0 ;
+ m_peer->GetFeatures( &features ) ;
- return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ;
+ return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ;
+ }
}
void wxWindowMac::SetFocus()
long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() , y, x, 0) ;
if ( HiWord(menuResult) != 0 )
{
- MenuCommand id ;
- GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &id ) ;
+ MenuCommand macid;
+ GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &macid );
+ int id = wxMacCommandToId( macid );
wxMenuItem* item = NULL ;
wxMenu* realmenu ;
item = menu->FindItem( id, &realmenu ) ;
- if (item->IsCheckable())
- item->Check( !item->IsChecked() ) ;
+ if ( item )
+ {
+ if (item->IsCheckable())
+ item->Check( !item->IsChecked() ) ;
- menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
+ menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
+ }
}
menu->MacAfterDisplay( true ) ;