summaryrefslogtreecommitdiff
path: root/tk/mac/tkMacWindowMgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'tk/mac/tkMacWindowMgr.c')
-rw-r--r--tk/mac/tkMacWindowMgr.c223
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);
+
+}
+
+