From 70074e3ac26b510594d84e1200f827db34a75089 Mon Sep 17 00:00:00 2001 From: wolfsuit Date: Thu, 1 Apr 2004 18:33:29 +0000 Subject: Fixes for bugs 220871 and 917557. Plus remove the Quit menu from the default File menu. --- ChangeLog | 18 ++++++++++ macosx/tkMacOSXCarbonEvents.c | 68 ++++++++++++++++++++++++++++++-------- macosx/tkMacOSXKeyEvent.c | 77 ++++++++++++++++++++----------------------- macosx/tkMacOSXMenu.c | 13 ++++++-- macosx/tkMacOSXMenus.c | 14 ++------ 5 files changed, 121 insertions(+), 69 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad231cc..4121177 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2004-03-31 Jim Ingham + + * tkMacOSXCarbonEvents.c (AppEventHandlerProc): Handle the + kEventAppHidden and kEventAppShown events. + (TkMacOSXInitCarbonEvents): Register for the above events. + * tkMacOSXKeyEvent.c (TkMacOSXProcessKeyboardEvent): Steal + the Command-H menu key event and allow the Application + handler to have it. This is currently the only way to get + the Hide behavior to work. [Bug 917557] + + * tkMacOSMenus.c (TkMacOSXHandleMenuSelect): Remove the Quit menu + handler - this was for the Quit item in the File menu, but it doesn't + belong there. + (TkMacOSXInitMenus): Remove the Quit menu item from the File menu. + + * tkMacOSXMenu.c (EventuallyInvokeMenu): Report errors from invoking + menu commands as background errors. [Bug 220871] + 2004-03-31 Don Porter * generic/tkImgPhoto.c: Removed outdated #include's of the tclMath.h diff --git a/macosx/tkMacOSXCarbonEvents.c b/macosx/tkMacOSXCarbonEvents.c index c80ed61..359aed6 100644 --- a/macosx/tkMacOSXCarbonEvents.c +++ b/macosx/tkMacOSXCarbonEvents.c @@ -2,7 +2,10 @@ * tkMacOSXCarbonEvents.c -- * * This file implements functions that register for and handle - * various Carbon Events. + * various Carbon Events. The reason a separate set of handlers + * is necessary is that not all interesting events get delivered + * directly to the event queue through ReceiveNextEvent. Some only + * get delivered if you register a Carbon Event Handler for the event. * * Copyright 2001, Apple Computer, Inc. * @@ -69,7 +72,8 @@ static OSStatus AppEventHandlerProc ( * AppEventHandlerProc -- * * This procedure is the Application CarbonEvent - * handler. + * handler. Currently, it handles the Hide & Show + * events. * * Results: * None. @@ -84,8 +88,50 @@ static OSStatus AppEventHandlerProc ( EventHandlerCallRef callRef, EventRef inEvent, - void *userData) + 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. + */ + toggleHide = 1; + + if ((interp == NULL) || + (Tcl_GetCommandInfo(interp, + "::tk::mac::OnHide", &dummy)) == 0) { + return eventNotHandledErr; + } + Tcl_GlobalEval(interp, "::tk::mac::OnHide"); + 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; } @@ -110,19 +156,15 @@ void TkMacOSXInitCarbonEvents ( Tcl_Interp *interp) { - EventTypeSpec inList[1]; + const EventTypeSpec inAppEventTypes[] = { + {kEventClassApplication, kEventAppHidden}, + {kEventClassApplication, kEventAppShown}}; + int inNumTypes = sizeof (inAppEventTypes) / sizeof (EventTypeSpec); InstallEventHandler(GetApplicationEventTarget(), NewEventHandlerUPP(AppEventHandlerProc), - 0, NULL, NULL, &ApplicationCarbonEventHandler); - - inList[0].eventClass = kEventClassWindow; - inList[0].eventKind = kEventWindowExpanded; - AddEventTypesToHandler (ApplicationCarbonEventHandler, 1, inList); - - inList[0].eventClass = kEventClassWindow; - inList[0].eventKind = kEventWindowCollapsed; - AddEventTypesToHandler (ApplicationCarbonEventHandler, 1, inList); + inNumTypes, inAppEventTypes, (void *) interp, + &ApplicationCarbonEventHandler); } 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/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c index 0885e40..4521754 100644 --- a/macosx/tkMacOSXMenu.c +++ b/macosx/tkMacOSXMenu.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXMenu.c,v 1.12 2004/02/16 00:19:42 wolfsuit Exp $ + * RCS: @(#) $Id: tkMacOSXMenu.c,v 1.13 2004/04/01 18:33:30 wolfsuit Exp $ */ #include "tkMacOSXInt.h" #include "tkMenuButton.h" @@ -2099,11 +2099,18 @@ EventuallyInvokeMenu (ClientData data) { struct MenuCommandHandlerData *realData = (struct MenuCommandHandlerData *) data; + int code; + code = TkInvokeMenu(realData->menuPtr->interp, realData->menuPtr, + realData->index); + if (code != TCL_OK && code != TCL_CONTINUE + && code != TCL_BREAK) { + Tcl_AddErrorInfo(realData->menuPtr->interp, "\n (menu invoke)"); + Tcl_BackgroundError(realData->menuPtr->interp); + } + Tcl_Release(realData->menuPtr->interp); Tcl_Release(realData->menuPtr); - TkInvokeMenu(realData->menuPtr->interp, realData->menuPtr, - realData->index); } /* diff --git a/macosx/tkMacOSXMenus.c b/macosx/tkMacOSXMenus.c index cf28026..a24f880 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.4 2004/01/13 02:06:01 davygrvy Exp $ + * RCS: @(#) $Id: tkMacOSXMenus.c,v 1.5 2004/04/01 18:33:30 wolfsuit Exp $ */ #include "tk.h" @@ -31,7 +31,6 @@ #define kSourceItem 1 #define kCloseItem 2 -#define kQuitItem 4 #define EDIT_CUT 1 #define EDIT_COPY 2 @@ -110,14 +109,6 @@ TkMacOSXHandleMenuSelect( tkwin = Tk_IdToWindow(dispPtr->display, window); TkGenWMDestroyEvent(tkwin); break; - case kQuitItem: - /* Exit */ - if (optionKeyPressed || gInterp == NULL) { - Tcl_Exit(0); - } else { - Tcl_Eval(gInterp, "exit"); - } - break; } break; case kEditMenu: @@ -189,8 +180,7 @@ TkMacOSXInitMenus( InsertMenu(tkFileMenu, 0); AppendMenu(tkFileMenu, "\pSourceÉ"); AppendMenu(tkFileMenu, "\pClose/W"); - AppendMenu(tkFileMenu, "\p(-"); - AppendMenu(tkFileMenu, "\pQuit/Q"); + if (TkMacOSXUseMenuID(kEditMenu) != TCL_OK) { Tcl_Panic("Menu ID %d is already in use!", kEditMenu); -- cgit v0.12