summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwolfsuit <wolfsuit>2004-04-01 18:33:29 (GMT)
committerwolfsuit <wolfsuit>2004-04-01 18:33:29 (GMT)
commit70074e3ac26b510594d84e1200f827db34a75089 (patch)
tree1d90d3f2090d5341ddc0c5d009b3cbb4f1b530ef
parent6320df04ec1f7454632285dcfc34f22a38122b0f (diff)
downloadtk-70074e3ac26b510594d84e1200f827db34a75089.zip
tk-70074e3ac26b510594d84e1200f827db34a75089.tar.gz
tk-70074e3ac26b510594d84e1200f827db34a75089.tar.bz2
Fixes for bugs 220871 and 917557. Plus remove the Quit menu from the default
File menu.
-rw-r--r--ChangeLog18
-rw-r--r--macosx/tkMacOSXCarbonEvents.c68
-rw-r--r--macosx/tkMacOSXKeyEvent.c77
-rw-r--r--macosx/tkMacOSXMenu.c13
-rw-r--r--macosx/tkMacOSXMenus.c14
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 <jingham@apple.com>
+
+ * 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 <dgp@users.sourceforge.net>
* 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
+ * <Activate>. 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);