From 64a51bdf01b7ffa1a184f1c8e32a4ccd00443c93 Mon Sep 17 00:00:00 2001 From: wolfsuit Date: Wed, 17 Mar 2004 19:01:45 +0000 Subject: Get the "Command-H" -> hide binding working. Also remove the spurious Quit menu item from the File command. --- ChangeLog | 14 +++++++++ macosx/tkMacOSXHLEvents.c | 68 +++++++++++++++++++++++++++++++++++++++-- macosx/tkMacOSXKeyEvent.c | 77 ++++++++++++++++++++++------------------------- macosx/tkMacOSXMenus.c | 10 ++++-- 4 files changed, 123 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index c23d6c2..8ad99f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2004-03-17 Jim Ingham + + * macosx/tkMacOSXHLEvents.c (ApplicationCarbonEventsHandler): New + function. + (tkMacOSXInitAppleEvents): Init the Application Event handler as + well. + * macosx/tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): Grab + the Command-H & Command-Shift-H keys and use them for Hide and + Hide Others before passing keystrokes on to the generic keyboard + event processing. There isn't any other good way to get the + Hide command to work, and the Apple HIG explicitly reserves them. + * macosx/tkMacOSXMenus.c (TkMacOSXInitMenus): Stop putting a Quit + menu item in the File menu. It doesn't belong there. + 2004-03-01 Don Porter *** 8.4.6 TAGGED FOR RELEASE *** diff --git a/macosx/tkMacOSXHLEvents.c b/macosx/tkMacOSXHLEvents.c index 47907fd..e986eab 100644 --- a/macosx/tkMacOSXHLEvents.c +++ b/macosx/tkMacOSXHLEvents.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXHLEvents.c,v 1.5.2.2 2004/02/16 00:42:34 wolfsuit Exp $ + * RCS: @(#) $Id: tkMacOSXHLEvents.c,v 1.5.2.3 2004/03/17 19:01:46 wolfsuit Exp $ */ #include "tkMacOSXPort.h" @@ -45,7 +45,58 @@ static OSErr PrefsHandler (const AppleEvent * event, AppleEvent * reply, long ha static int MissedAnyParameters _ANSI_ARGS_((const AppleEvent *theEvent)); static int ReallyKillMe _ANSI_ARGS_((Tcl_Event *eventPtr, int flags)); static OSErr FSRefToDString _ANSI_ARGS_((const FSRef *fsref, Tcl_DString *ds)); - + +OSStatus ApplicationCarbonEventsHandler (EventHandlerCallRef inHandlerCallRef, + EventRef inEvent, + void *inUserData); +OSStatus ApplicationCarbonEventsHandler (EventHandlerCallRef inHandlerCallRef, + EventRef inEvent, + void *inUserData) +{ + Tcl_CmdInfo dummy; + Tcl_Interp *interp = (Tcl_Interp *) inUserData; + + /* + * This is a bit of a hack. We get "show" events both when we come back + * from being hidden, and whenever we are activated. I only want to run the + * "show" proc when we have been hidden already, not as a substitute for + * . So I use this toggle... + */ + + static int toggleHide = 0; + + switch(GetEventKind (inEvent)) + { + case kEventAppHidden: + /* + * Don't bother if we don't have an interp or + * the show preferences procedure doesn't exist. + */ + + if ((interp == NULL) || + (Tcl_GetCommandInfo(interp, + "::tk::mac::OnHide", &dummy)) == 0) { + return eventNotHandledErr; + } + Tcl_GlobalEval(interp, "::tk::mac::OnHide"); + toggleHide = 1; + break; + case kEventAppShown: + if (toggleHide == 1) { + toggleHide = 0; + if ((interp == NULL) || + (Tcl_GetCommandInfo(interp, + "::tk::mac::OnShow", &dummy)) == 0) { + return eventNotHandledErr; + } + Tcl_GlobalEval(interp, "::tk::mac::OnShow"); + } + break; + default: + break; + } + return eventNotHandledErr; +} /* *---------------------------------------------------------------------- * @@ -71,7 +122,11 @@ TkMacOSXInitAppleEvents( AEEventHandlerUPP OappHandlerUPP, RappHandlerUPP, OdocHandlerUPP, PrintHandlerUPP, QuitHandlerUPP, ScriptHandlerUPP, PrefsHandlerUPP; - + const EventTypeSpec inAppEventTypes[] = { + {kEventClassApplication, kEventAppHidden}, + {kEventClassApplication, kEventAppShown}}; + UInt32 inNumTypes = 2; + /* * Install event handlers for the core apple events. */ @@ -104,6 +159,13 @@ TkMacOSXInitAppleEvents( err = AEInstallEventHandler(kAEMiscStandards, kAEDoScript, ScriptHandlerUPP, (long) interp, false); } + + InstallEventHandler(GetApplicationEventTarget(), + NewEventHandlerUPP (ApplicationCarbonEventsHandler), + inNumTypes, + inAppEventTypes, + (void *) interp, + NULL); } /* diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c index 05f4c3e..fcb5432 100644 --- a/macosx/tkMacOSXKeyEvent.c +++ b/macosx/tkMacOSXKeyEvent.c @@ -138,10 +138,8 @@ int TkMacOSXProcessKeyboardEvent( static UniChar savedChar = 0; OSStatus status; KeyEventData keyEventData; -#if 0 MenuRef menuRef; MenuItemIndex menuItemIndex; -#endif int eventGenerated; UniChar uniChars[5]; /* make this larger, if needed */ UInt32 uniCharsLen = 0; @@ -150,51 +148,44 @@ int TkMacOSXProcessKeyboardEvent( statusPtr->err = 1; return false; } - -#if 0 + /* - * This block of code seems like a good idea, to trap - * key-bindings which point directly to menus, but it - * has a number of problems: - * (1) when grabs are present we definitely don't want - * to do this. - * (2) Tk's semantics define accelerator keystrings in - * menus as a purely visual adornment, and require that - * the developer create separate bindings to trigger - * them. This breaks those semantics. (i.e. Tk will - * behave differently on Aqua to the behaviour on Unix/Win). - * (3) Tk's bindings depend on the current window's bindtags, - * which may be completely different to what happens to be - * in some global menu (agreed, it shouldn't be that different, - * but it often is). + * Because of the way that Tk operates, we can't in general funnel menu + * accelerators through IsMenuKeyEvent. Tk treats accelerators as mere + * decoration, and the user has to install bindings to get them to fire. + * + * However, the only way to trigger the Hide & Hide Others functions + * is by invoking the Menu command for Hide. So there is no nice way to + * provide a Tk command to hide the app which would be available for a + * binding. So I am going to hijack Command-H and Command-Shift-H + * here, and run the menu commands. Since the HI Guidelines explicitly + * reserve these for Hide, this isn't such a bad thing. Also, if you do + * rebind Command-H to another menu item, Hide will lose its binding. * - * While a better middleground might be possible, the best, most - * compatible, approach at present is to disable this block. + * Note that I don't really do anything at this point, + * I just mark stopProcessing as 0 and return, and then the + * RecieveAndProcessEvent code will dispatch the event to the default + * handler. */ + if (IsMenuKeyEvent(NULL, eventPtr->eventRef, - kNilOptions, &menuRef, &menuItemIndex)) { - int oldMode; - MenuID menuID; - KeyMap theKeys; - int selection; + kMenuEventQueryOnly, &menuRef, &menuItemIndex)) { + MenuCommand menuCmd; - menuID = GetMenuID(menuRef); - selection = (menuID << 16) | menuItemIndex; - - GetKeys(theKeys); - oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - TkMacOSXClearMenubarActive(); - - /* - * Handle -postcommand - */ - - TkMacOSXPreprocessMenu(); - TkMacOSXHandleMenuSelect(selection, theKeys[1] & 4); - Tcl_SetServiceMode(oldMode); - return 0; /* TODO: may not be on event on queue. */ + GetMenuItemCommandID (menuRef, menuItemIndex, &menuCmd); + + switch (menuCmd) { + case kHICommandHide: + case kHICommandHideOthers: + case kHICommandShowAll: + case kHICommandPreferences: + statusPtr->stopProcessing = 0; + return 0; /* TODO: may not be on event on queue. */ + break; + default: + break; + } } -#endif status = GetEventParameter(eventPtr->eventRef, kEventParamKeyMacCharCodes, @@ -506,13 +497,17 @@ InitKeyEvent( tkwin = Tk_IdToWindow(dispPtr->display, window); if (tkwin == NULL) { +#ifdef TK_MAC_DEBUG fprintf(stderr,"tkwin == NULL, %d\n", __LINE__); +#endif return -1; } tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr; if (tkwin == NULL) { +#ifdef TK_MAC_DEBUG fprintf(stderr,"tkwin == NULL, %d\n", __LINE__); +#endif return -1; } diff --git a/macosx/tkMacOSXMenus.c b/macosx/tkMacOSXMenus.c index 6eed023..892ef8a 100644 --- a/macosx/tkMacOSXMenus.c +++ b/macosx/tkMacOSXMenus.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXMenus.c,v 1.2.2.1 2003/05/13 02:42:57 das Exp $ + * RCS: @(#) $Id: tkMacOSXMenus.c,v 1.2.2.2 2004/03/17 19:01:47 wolfsuit Exp $ */ #include "tk.h" @@ -189,9 +189,15 @@ TkMacOSXInitMenus( InsertMenu(tkFileMenu, 0); AppendMenu(tkFileMenu, "\pSourceÉ"); AppendMenu(tkFileMenu, "\pClose/W"); + + /* + * These don't belong in the File menu on Mac OS X. + */ + +#if 0 AppendMenu(tkFileMenu, "\p(-"); AppendMenu(tkFileMenu, "\pQuit/Q"); - +#endif if (TkMacOSXUseMenuID(kEditMenu) != TCL_OK) { panic("Menu ID %d is already in use!", kEditMenu); } -- cgit v0.12