diff options
Diffstat (limited to 'tk/mac/tkMacWindowMgr.c')
-rw-r--r-- | tk/mac/tkMacWindowMgr.c | 223 |
1 files changed, 191 insertions, 32 deletions
diff --git a/tk/mac/tkMacWindowMgr.c b/tk/mac/tkMacWindowMgr.c index af12dacad00..58cd4a7ec7d 100644 --- a/tk/mac/tkMacWindowMgr.c +++ b/tk/mac/tkMacWindowMgr.c @@ -3,7 +3,7 @@ * * Implements common window manager functions for the Macintosh. * - * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * Copyright (c) 1995-1998 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -63,7 +63,7 @@ static int GenerateActivateEvents _ANSI_ARGS_((EventRecord *eventPtr, static int GenerateFocusEvent _ANSI_ARGS_((EventRecord *eventPtr, Window window)); static int GenerateKeyEvent _ANSI_ARGS_((EventRecord *eventPtr, - Window window)); + Window window, UInt32 savedCode)); static int GenerateUpdateEvent _ANSI_ARGS_((EventRecord *eventPtr, Window window)); static void GenerateUpdates _ANSI_ARGS_((RgnHandle updateRgn, @@ -99,13 +99,19 @@ WindowManagerMouse( EventRecord *eventPtr, /* Macintosh event record. */ Window window) /* Window pointer. */ { - WindowRef whichWindow, frontWindow; + WindowRef whichWindow, frontWindow, frontNonFloating; Tk_Window tkwin; Point where, where2; int xOffset, yOffset; short windowPart; + TkDisplay *dispPtr; frontWindow = FrontWindow(); + if (TkMacHaveAppearance() >= 0x110) { + frontNonFloating = FrontNonFloatingWindow(); + } else { + frontNonFloating = frontWindow; + } /* * The window manager only needs to know about mouse down events @@ -122,13 +128,14 @@ WindowManagerMouse( } windowPart = FindWindow(eventPtr->where, &whichWindow); - tkwin = Tk_IdToWindow(tkDisplayList->display, window); + dispPtr = TkGetDisplayList(); + tkwin = Tk_IdToWindow(dispPtr->display, window); switch (windowPart) { case inSysWindow: SystemClick(eventPtr, (GrafPort *) whichWindow); return false; case inDrag: - if (whichWindow != frontWindow) { + if (!(TkpIsWindowFloating(whichWindow)) && (whichWindow != frontNonFloating)) { if (!(eventPtr->modifiers & cmdKey)) { if ((gGrabWinPtr != NULL) && (gGrabWinPtr != tkwin)) { SysBeep(1); @@ -162,7 +169,8 @@ WindowManagerMouse( return true; case inGrow: case inContent: - if (whichWindow != frontWindow ) { + if (!(TkpIsWindowFloating(whichWindow)) + && (whichWindow != frontNonFloating)) { /* * This click moves the window forward. We don't want * the corasponding mouse-up to be reported to the application @@ -172,9 +180,9 @@ WindowManagerMouse( SysBeep(1); return false; } - BringWindowForward(whichWindow); gEatButtonUp = true; SetPort((GrafPort *) whichWindow); + BringWindowForward(whichWindow); return false; } else { /* @@ -209,6 +217,10 @@ WindowManagerMouse( GetKeys(theKeys); oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); TkMacClearMenubarActive(); + /* + * Handle -postcommand + */ + TkMacPreprocessMenu(); TkMacHandleMenuSelect(MenuSelect(eventPtr->where), theKeys[1] & 4); Tcl_SetServiceMode(oldMode); @@ -264,7 +276,11 @@ TkAboutDlg() DisposDialog(aboutDlog); aboutDlog = NULL; + if (TkMacHaveAppearance() >= 0x110) { SelectWindow(FrontWindow()); + } else { + SelectWindow(FrontNonFloatingWindow()); + } return; } @@ -293,8 +309,10 @@ GenerateUpdateEvent( { WindowRef macWindow; register TkWindow *winPtr; + TkDisplay *dispPtr; - winPtr = (TkWindow *) Tk_IdToWindow(tkDisplayList->display, window); + dispPtr = TkGetDisplayList(); + winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window); if (winPtr == NULL) { return false; @@ -464,6 +482,7 @@ TkGenerateButtonEvent( Point where; Tk_Window tkwin; int dummy; + TkDisplay *dispPtr; /* * ButtonDown events will always occur in the front @@ -474,13 +493,19 @@ TkGenerateButtonEvent( where.h = x; where.v = y; FindWindow(where, &whichWin); - frontWin = FrontWindow(); - - if ((frontWin == NULL) || (frontWin != whichWin && gGrabWinPtr == NULL)) { + if (TkMacHaveAppearance() >= 0x110) { + frontWin = FrontNonFloatingWindow(); + } else { + frontWin = FrontWindow(); + } + + if ((frontWin == NULL) || ((!(TkpIsWindowFloating(whichWin)) && (frontWin != whichWin)) + && gGrabWinPtr == NULL)) { return false; } - tkwin = Tk_IdToWindow(tkDisplayList->display, window); + dispPtr = TkGetDisplayList(); + tkwin = Tk_IdToWindow(dispPtr->display, window); GlobalToLocal(&where); if (tkwin != NULL) { @@ -517,8 +542,10 @@ GenerateActivateEvents( Window window) /* Root X window for event. */ { TkWindow *winPtr; + TkDisplay *dispPtr; - winPtr = (TkWindow *) Tk_IdToWindow(tkDisplayList->display, window); + dispPtr = TkGetDisplayList(); + winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window); if (winPtr == NULL || winPtr->window == None) { return false; } @@ -629,8 +656,10 @@ GenerateFocusEvent( { XEvent event; Tk_Window tkwin; + TkDisplay *dispPtr; - tkwin = Tk_IdToWindow(tkDisplayList->display, window); + dispPtr = TkGetDisplayList(); + tkwin = Tk_IdToWindow(dispPtr->display, window); if (tkwin == NULL) { return false; } @@ -646,9 +675,9 @@ GenerateFocusEvent( event.xany.type = FocusOut; } - event.xany.serial = tkDisplayList->display->request; + event.xany.serial = dispPtr->display->request; event.xany.send_event = False; - event.xfocus.display = tkDisplayList->display; + event.xfocus.display = dispPtr->display; event.xfocus.window = window; event.xfocus.mode = NotifyNormal; event.xfocus.detail = NotifyDetailNone; @@ -679,23 +708,46 @@ GenerateFocusEvent( static int GenerateKeyEvent( EventRecord *eventPtr, /* Incoming Mac event */ - Window window) /* Root X window for event. */ + Window window, /* Root X window for event. */ + UInt32 savedKeyCode) /* If non-zero, this is a lead byte which + * should be combined with the character + * in this event to form one multi-byte + * character. */ { Point where; Tk_Window tkwin; XEvent event; - + unsigned char byte; + char buf[16]; + TkDisplay *dispPtr; + /* * The focus must be in the FrontWindow on the Macintosh. * We then query Tk to determine the exact Tk window * that owns the focus. */ - tkwin = Tk_IdToWindow(tkDisplayList->display, window); + dispPtr = TkGetDisplayList(); + tkwin = Tk_IdToWindow(dispPtr->display, window); + + if (tkwin == NULL) { + return false; + } tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr; if (tkwin == NULL) { return false; } + byte = (unsigned char) (eventPtr->message & charCodeMask); + if ((savedKeyCode == 0) && + (Tcl_ExternalToUtf(NULL, NULL, (char *) &byte, 1, 0, NULL, + buf, sizeof(buf), NULL, NULL, NULL) != TCL_OK)) { + /* + * This event specifies a lead byte. Wait for the second byte + * to come in before sending the XEvent. + */ + + return false; + } where.v = eventPtr->where.v; where.h = eventPtr->where.h; @@ -710,7 +762,10 @@ GenerateKeyEvent( GlobalToLocal(&where); Tk_TopCoordsToWindow(tkwin, where.h, where.v, &event.xkey.x, &event.xkey.y); - event.xkey.keycode = eventPtr->message; + + event.xkey.keycode = byte | + ((savedKeyCode & charCodeMask) << 8) | + ((eventPtr->message & keyCodeMask) << 8); event.xany.serial = Tk_Display(tkwin)->request; event.xkey.window = Tk_WindowId(tkwin); @@ -764,13 +819,14 @@ GeneratePollingEvents() { Tk_Window tkwin, rootwin; Window window; - WindowRef whichwindow, frontWin; + WindowRef whichWindow, frontWin, frontNonFloating; Point whereLocal, whereGlobal; Boolean inContentRgn; short part; int local_x, local_y; int generatedEvents = false; - + TkDisplay *dispPtr; + /* * First we get the current mouse position and determine * what Tk window the mouse is over (if any). @@ -785,14 +841,33 @@ GeneratePollingEvents() whereGlobal = whereLocal; LocalToGlobal(&whereGlobal); - part = FindWindow(whereGlobal, &whichwindow); + part = FindWindow(whereGlobal, &whichWindow); inContentRgn = (part == inContent || part == inGrow); - if ((frontWin != whichwindow) || !inContentRgn) { + if (TkMacHaveAppearance() >= 0x110) { + /* + * If the mouse is over the front non-floating window, then we + * need to set the local coordinates relative to that window + * rather than a possibly floating window above it. + */ + + frontNonFloating = FrontNonFloatingWindow(); + if (whichWindow == frontNonFloating + && (whichWindow != frontWin)) { + SetPort((GrafPort *) frontNonFloating); + whereLocal = whereGlobal; + GlobalToLocal(&whereLocal); + } + } else { + frontNonFloating = frontWin; + } + + if ((!TkpIsWindowFloating(whichWindow) && (frontNonFloating != whichWindow)) || !inContentRgn) { tkwin = NULL; } else { - window = TkMacGetXWindow(whichwindow); - rootwin = Tk_IdToWindow(tkDisplayList->display, window); + window = TkMacGetXWindow(whichWindow); + dispPtr = TkGetDisplayList(); + rootwin = Tk_IdToWindow(dispPtr->display, window); if (rootwin == NULL) { tkwin = NULL; } else { @@ -859,6 +934,7 @@ GeneratePollingEvents2( int local_x, local_y; int generatedEvents = false; Rect bounds; + TkDisplay *dispPtr; /* * First we get the current mouse position and determine @@ -881,7 +957,8 @@ GeneratePollingEvents2( if (whichwindow != frontWin) { tkwin = NULL; } else { - rootwin = Tk_IdToWindow(tkDisplayList->display, window); + dispPtr = TkGetDisplayList(); + rootwin = Tk_IdToWindow(dispPtr->display, window); TkMacWinBounds((TkWindow *) rootwin, &bounds); if (!PtInRect(whereLocal, &bounds)) { tkwin = NULL; @@ -1110,6 +1187,7 @@ TkMacConvertEvent( WindowRef whichWindow; Window window; int eventFound = false; + static UInt32 savedKeyCode; switch (eventPtr->what) { case nullEvent: @@ -1153,11 +1231,28 @@ TkMacConvertEvent( break; } } + /* fall through */ + case keyUp: - whichWindow = FrontWindow(); + whichWindow = FrontNonFloatingWindow(); + if (whichWindow == NULL) { + /* + * This happens if we get a key event before Tk has had a + * chance to actually create and realize ".", if they type + * when "." is withdrawn(!), or between the time "." is + * destroyed and the app exits. + */ + + return false; + } window = TkMacGetXWindow(whichWindow); - eventFound |= GenerateKeyEvent(eventPtr, window); + if (GenerateKeyEvent(eventPtr, window, savedKeyCode) == 0) { + savedKeyCode = eventPtr->message; + return false; + } + eventFound = true; break; + case activateEvt: window = TkMacGetXWindow((WindowRef) eventPtr->message); eventFound |= GenerateActivateEvents(eventPtr, window); @@ -1192,6 +1287,13 @@ TkMacConvertEvent( TkSuspendClipboard(); } tkMacAppInFront = (eventPtr->message & resumeFlag); + if (TkMacHaveAppearance() >= 0x110) { + if (tkMacAppInFront) { + ShowFloatingWindows(); + } else { + HideFloatingWindows(); + } + } break; } break; @@ -1210,6 +1312,7 @@ TkMacConvertEvent( break; } + savedKeyCode = 0; return eventFound; } @@ -1237,6 +1340,7 @@ TkMacConvertTkEvent( { int eventFound = false; Point where; + static UInt32 savedKeyCode; /* * By default, assume it is legal for us to set the cursor @@ -1292,9 +1396,16 @@ TkMacConvertTkEvent( break; } } + /* fall through. */ + case keyUp: - eventFound |= GenerateKeyEvent(eventPtr, window); + if (GenerateKeyEvent(eventPtr, window, savedKeyCode) == 0) { + savedKeyCode = eventPtr->message; + return false; + } + eventFound = true; break; + case activateEvt: /* * It is probably not legal for us to set the cursor @@ -1341,6 +1452,13 @@ TkMacConvertTkEvent( TkSuspendClipboard(); } tkMacAppInFront = (eventPtr->message & resumeFlag); + if (TkMacHaveAppearance() >= 0x110) { + if (tkMacAppInFront) { + ShowFloatingWindows(); + } else { + HideFloatingWindows(); + } + } break; } break; @@ -1358,7 +1476,7 @@ TkMacConvertTkEvent( } break; } - + savedKeyCode = 0; return eventFound; } @@ -1475,6 +1593,12 @@ TkMacWindowOffset( if (!strucRgn || !contRgn) { err = MemError( ); + + } else if (TkMacHaveAppearance()) { + GetWindowRegion(wRef, kWindowStructureRgn, strucRgn); + GetWindowRegion(wRef, kWindowContentRgn, contRgn); + strucRect = (**strucRgn).rgnBBox; + contRect = (**contRgn).rgnBBox; } else { CopyRgn(wPeek->strucRgn, strucRgn); CopyRgn(wPeek->contRgn, contRgn); @@ -1590,7 +1714,10 @@ static void BringWindowForward( WindowRef wRef) { - SelectWindow(wRef); + if (!TkpIsWindowFloating(wRef)) { + if (IsValidWindowPtr(wRef)) + SelectWindow(wRef); + } } /* @@ -1628,3 +1755,35 @@ TkpGetMS() return (long) *int64Ptr; } +/* + *---------------------------------------------------------------------- + * + * TkpIsWindowFloating -- + * + * Returns 1 if a window is floating, 0 otherwise. + * + * Results: + * 1 or 0 depending on window's floating attribute. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TkpIsWindowFloating(WindowRef wRef) +{ + WindowClass class; + + if (TkMacHaveAppearance() < 0x110) { + return 0; + } + + GetWindowClass(wRef, &class); + + return (class == kFloatingWindowClass); + +} + + |