summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXCarbonEvents.c
diff options
context:
space:
mode:
authordas <das>2007-11-08 14:26:50 (GMT)
committerdas <das>2007-11-08 14:26:50 (GMT)
commitb70b015d8e93070f8cfb10b42f444ed478c185a8 (patch)
tree080f695b63822ed8caa1ba792aaed96578512c4a /macosx/tkMacOSXCarbonEvents.c
parentad2bc9bc277cdb6120447f7d81e512eaa39f85b9 (diff)
downloadtk-b70b015d8e93070f8cfb10b42f444ed478c185a8.zip
tk-b70b015d8e93070f8cfb10b42f444ed478c185a8.tar.gz
tk-b70b015d8e93070f8cfb10b42f444ed478c185a8.tar.bz2
* macosx/tkMacOSXCarbonEvents.c
(InstallStandardApplicationEventHandler): on Mac OS X Leopard, replace the 2005-11-27 approach of installing the standard application handler by calling RAEL and immediately longjmping out of it from an event handler, as that now leads to crashes in -[NSView unlockFocus] whenever HIToolbox uses Cocoa in Leopard (Help menu, Nav Services, Color Picker). Instead call InstallStandardEventHandler() on the application and menubar event targets, as Leopard ISEH finally handles these correctly. Unfortunately need a HIToolbox-internal SPI to retrieve the menubar event target, no public API appears have that functionality.
Diffstat (limited to 'macosx/tkMacOSXCarbonEvents.c')
-rw-r--r--macosx/tkMacOSXCarbonEvents.c154
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
/*
*----------------------------------------------------------------------