diff options
Diffstat (limited to 'macosx')
-rw-r--r-- | macosx/tkMacOSXCarbonEvents.c | 154 |
1 files changed, 95 insertions, 59 deletions
diff --git a/macosx/tkMacOSXCarbonEvents.c b/macosx/tkMacOSXCarbonEvents.c index 6b28cf3..65b792e 100644 --- a/macosx/tkMacOSXCarbonEvents.c +++ b/macosx/tkMacOSXCarbonEvents.c @@ -60,7 +60,7 @@ * software in accordance with the terms specified in this * license. * - * RCS: @(#) $Id: tkMacOSXCarbonEvents.c,v 1.17 2007/06/29 03:20:00 das Exp $ + * RCS: @(#) $Id: tkMacOSXCarbonEvents.c,v 1.18 2007/11/08 14:26:50 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -80,21 +80,28 @@ static OSStatus CarbonEventHandlerProc(EventHandlerCallRef callRef, EventRef event, void *userData); static OSStatus InstallStandardApplicationEventHandler(void); -static void ExitRaelEventHandlerProc(EventHandlerCallRef callRef, - EventRef event, void *userData) __attribute__ ((__noreturn__)); static void CarbonTimerProc(EventLoopTimerRef timer, void *userData); /* * Static data used by several functions in this file: */ -static jmp_buf exitRaelJmpBuf; static EventLoopTimerRef carbonTimer = NULL; static int carbonTimerEnabled = 0; static EventHandlerUPP carbonEventHandlerUPP = NULL; static Tcl_Interp *carbonEventInterp = NULL; static int inTrackingLoop = 0; +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 +/* + * For InstallStandardApplicationEventHandler(): + */ + +static jmp_buf exitRaelJmpBuf; +static void ExitRaelEventHandlerProc(EventHandlerCallRef callRef, + EventRef event, void *userData) __attribute__ ((__noreturn__)); +#endif + /* *---------------------------------------------------------------------- @@ -130,8 +137,9 @@ CarbonEventHandlerProc( bzero(&eventStatus, sizeof(eventStatus)); #ifdef TK_MAC_DEBUG_CARBON_EVENTS - if (macEvent.eKind != kEventMouseMoved && - macEvent.eKind != kEventMouseDragged) { + if (!(macEvent.eClass == kEventClassMouse && ( + macEvent.eKind == kEventMouseMoved || + macEvent.eKind == kEventMouseDragged))) { TkMacOSXDbgMsg("Started handling %s", TkMacOSXCarbonEventToAscii(event)); TkMacOSXInitNamedDebugSymbol(HIToolbox, void, _DebugPrintEvent, @@ -249,7 +257,7 @@ TkMacOSXInitCarbonEvents( _TraceEventByName(CFSTR("kEventWindowActivated")); _TraceEventByName(CFSTR("kEventWindowDeactivated")); _TraceEventByName(CFSTR("kEventWindowUpdate")); - _TraceEventByName(CFSTR("kEventWindowExpanded")); + _TraceEventByName(CFSTR("kEventWindowExpanding")); _TraceEventByName(CFSTR("kEventWindowBoundsChanged")); _TraceEventByName(CFSTR("kEventWindowDragStarted")); _TraceEventByName(CFSTR("kEventWindowDragCompleted")); @@ -289,7 +297,7 @@ TkMacOSXInstallWindowCarbonEventHandler( {kEventClassWindow, kEventWindowActivated}, {kEventClassWindow, kEventWindowDeactivated}, {kEventClassWindow, kEventWindowUpdate}, - {kEventClassWindow, kEventWindowExpanded}, + {kEventClassWindow, kEventWindowExpanding}, {kEventClassWindow, kEventWindowBoundsChanged}, {kEventClassWindow, kEventWindowDragStarted}, {kEventClassWindow, kEventWindowDragCompleted}, @@ -324,65 +332,92 @@ TkMacOSXInstallWindowCarbonEventHandler( static OSStatus InstallStandardApplicationEventHandler(void) { - /* - * This is a hack to workaround missing Carbon API to install the standard - * application event handler (InstallStandardEventHandler() does not work - * on the application target). The only way to install the standard app - * handler is to call RunApplicationEventLoop(), but since we are running - * our own event loop, we'll immediately need to break out of RAEL again: - * we do this via longjmp out of the ExitRaelEventHandlerProc event handler - * called first off from RAEL by posting a high priority dummy event. - * This workaround is derived from a similar approach in Technical Q&A 1061. - */ - enum { - kExitRaelEvent = 'ExiT' - }; - const EventTypeSpec exitRaelEventType = { - kExitRaelEvent, kExitRaelEvent - }; - EventHandlerUPP exitRaelEventHandler; - EventHandlerRef exitRaelEventHandlerRef = NULL; - EventRef exitRaelEvent = NULL; OSStatus err = memFullErr; - exitRaelEventHandler = NewEventHandlerUPP( - (EventHandlerProcPtr) ExitRaelEventHandlerProc); - if (exitRaelEventHandler) { - err = ChkErr(InstallEventHandler, GetEventDispatcherTarget(), - exitRaelEventHandler, 1, &exitRaelEventType, NULL, - &exitRaelEventHandlerRef); - } - if (err == noErr) { - err = ChkErr(CreateEvent, NULL, kExitRaelEvent, kExitRaelEvent, - GetCurrentEventTime(), kEventAttributeNone, &exitRaelEvent); - } - if (err == noErr) { - err = ChkErr(PostEventToQueue, GetMainEventQueue(), exitRaelEvent, - kEventPriorityHigh); - } - if (err == noErr) { - if (!setjmp(exitRaelJmpBuf)) { - RunApplicationEventLoop(); + TK_IF_HI_TOOLBOX(5, + /* + * The approach below does not work correctly in Leopard, it leads to + * crashes in [NSView unlockFocus] whenever HIToolbox uses Cocoa (Help + * menu, Nav Services, Color Picker). While it is now possible to + * install the standard app handler with InstallStandardEventHandler(), + * to fully replicate RAEL the standard menubar event handler also needs + * to be installed. Unfortunately there appears to be no public API to + * obtain the menubar event target. As a workaround, for now we resort + * to calling the HIToolbox-internal GetMenuBarEventTarget() directly + * (symbol acquired via TkMacOSXInitNamedDebugSymbol() from HIToolbox + * version 343, may not exist in later versions). + */ + err = ChkErr(InstallStandardEventHandler, GetApplicationEventTarget()); + TkMacOSXInitNamedDebugSymbol(HIToolbox, EventTargetRef, + GetMenuBarEventTarget, void); + if (GetMenuBarEventTarget) { + ChkErr(InstallStandardEventHandler, GetMenuBarEventTarget()); + } else { + TkMacOSXDbgMsg("Unable to install standard menubar event handler"); + } + ) TK_ELSE_HI_TOOLBOX (5, + /* + * This is a hack to workaround missing Carbon API to install the + * standard application event handler (InstallStandardEventHandler() + * does not work on the application target). The only way to install the + * standard app handler is to call RunApplicationEventLoop(), but since + * we are running our own event loop, we'll immediately need to break + * out of RAEL again: we do this via longjmp out of the + * ExitRaelEventHandlerProc event handler called first off from RAEL by + * posting a high priority dummy event. This workaround is derived from + * a similar approach in Technical Q&A 1061. + */ + enum { + kExitRaelEvent = 'ExiT' + }; + const EventTypeSpec exitRaelEventType = { + kExitRaelEvent, kExitRaelEvent + }; + EventHandlerUPP exitRaelEventHandler; + EventHandlerRef exitRaelEventHandlerRef = NULL; + EventRef exitRaelEvent = NULL; + + exitRaelEventHandler = NewEventHandlerUPP( + (EventHandlerProcPtr) ExitRaelEventHandlerProc); + if (exitRaelEventHandler) { + err = ChkErr(InstallEventHandler, GetEventDispatcherTarget(), + exitRaelEventHandler, 1, &exitRaelEventType, NULL, + &exitRaelEventHandlerRef); + } + if (err == noErr) { + err = ChkErr(CreateEvent, NULL, kExitRaelEvent, kExitRaelEvent, + GetCurrentEventTime(), kEventAttributeNone, + &exitRaelEvent); + } + if (err == noErr) { + err = ChkErr(PostEventToQueue, GetMainEventQueue(), exitRaelEvent, + kEventPriorityHigh); + } + if (err == noErr) { + if (!setjmp(exitRaelJmpBuf)) { + RunApplicationEventLoop(); - /* - * This point should never be reached! - */ + /* + * This point should never be reached! + */ - Tcl_Panic("RunApplicationEventLoop exited !"); + Tcl_Panic("RunApplicationEventLoop exited !"); + } } - } - if (exitRaelEvent) { - ReleaseEvent(exitRaelEvent); - } - if (exitRaelEventHandlerRef) { - RemoveEventHandler(exitRaelEventHandlerRef); - } - if (exitRaelEventHandler) { - DisposeEventHandlerUPP(exitRaelEventHandler); - } + if (exitRaelEvent) { + ReleaseEvent(exitRaelEvent); + } + if (exitRaelEventHandlerRef) { + RemoveEventHandler(exitRaelEventHandlerRef); + } + if (exitRaelEventHandler) { + DisposeEventHandlerUPP(exitRaelEventHandler); + } + ) TK_ENDIF return err; } +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 /* *---------------------------------------------------------------------- * @@ -409,6 +444,7 @@ ExitRaelEventHandlerProc( { longjmp(exitRaelJmpBuf, 1); } +#endif /* *---------------------------------------------------------------------- |