summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarc_culler <marc.culler@gmail.com>2020-09-07 19:21:30 (GMT)
committermarc_culler <marc.culler@gmail.com>2020-09-07 19:21:30 (GMT)
commitaa6bf77b41864232f8ca997436e72cdd6fabb32b (patch)
treeb5f33519606af41f0e39b8dde7cd718a0ead6e64
parented825e13f3d05988eacdfaf8e978377149b9302b (diff)
parentc504b8fc55ded70a21166e2d2c8ee960c4cef962 (diff)
downloadtk-aa6bf77b41864232f8ca997436e72cdd6fabb32b.zip
tk-aa6bf77b41864232f8ca997436e72cdd6fabb32b.tar.gz
tk-aa6bf77b41864232f8ca997436e72cdd6fabb32b.tar.bz2
Merge 8.6
-rw-r--r--generic/tkInt.decls14
-rw-r--r--generic/tkIntPlatDecls.h17
-rw-r--r--generic/tkStubInit.c4
-rw-r--r--macosx/tkMacOSXColor.c12
-rw-r--r--macosx/tkMacOSXMouseEvent.c293
-rw-r--r--macosx/tkMacOSXPrivate.h26
-rw-r--r--macosx/tkMacOSXTest.c14
-rw-r--r--macosx/tkMacOSXWm.c150
8 files changed, 266 insertions, 264 deletions
diff --git a/generic/tkInt.decls b/generic/tkInt.decls
index 03dfd91..73854c8 100644
--- a/generic/tkInt.decls
+++ b/generic/tkInt.decls
@@ -963,9 +963,10 @@ declare 24 aqua {
declare 25 aqua {
void TkMacOSXMenuClick(void)
}
-declare 26 aqua {
- void TkMacOSXRegisterOffScreenWindow(Window window, void *portPtr)
-}
+# The corresponding Unregister was not a stub, and this should be static.
+#declare 26 aqua {
+# void TkMacOSXRegisterOffScreenWindow(Window window, void *portPtr)
+#}
declare 27 aqua {
int TkMacOSXResizable(TkWindow *winPtr)
}
@@ -984,9 +985,10 @@ declare 31 aqua {
declare 32 aqua {
void TkMacOSXUpdateClipRgn(TkWindow *winPtr)
}
-declare 33 aqua {
- void TkMacOSXUnregisterMacWindow(void *portPtr)
-}
+# This was not implemented. Perhaps meant to be OffScreen ?
+#declare 33 aqua {
+# void TkMacOSXUnregisterMacWindow(void *portPtr)
+#}
declare 34 aqua {
int TkMacOSXUseMenuID(short macID)
}
diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h
index bd1df36..88b36ce 100644
--- a/generic/tkIntPlatDecls.h
+++ b/generic/tkIntPlatDecls.h
@@ -198,9 +198,7 @@ EXTERN void TkMacOSXMakeRealWindowExist(TkWindow *winPtr);
EXTERN void * TkMacOSXMakeStippleMap(Drawable d1, Drawable d2);
/* 25 */
EXTERN void TkMacOSXMenuClick(void);
-/* 26 */
-EXTERN void TkMacOSXRegisterOffScreenWindow(Window window,
- void *portPtr);
+/* Slot 26 is reserved */
/* 27 */
EXTERN int TkMacOSXResizable(TkWindow *winPtr);
/* 28 */
@@ -213,8 +211,7 @@ EXTERN void TkMacOSXSetUpClippingRgn(Drawable drawable);
EXTERN void TkMacOSXSetUpGraphicsPort(GC gc, void *destPort);
/* 32 */
EXTERN void TkMacOSXUpdateClipRgn(TkWindow *winPtr);
-/* 33 */
-EXTERN void TkMacOSXUnregisterMacWindow(void *portPtr);
+/* Slot 33 is reserved */
/* 34 */
EXTERN int TkMacOSXUseMenuID(short macID);
/* 35 */
@@ -419,14 +416,14 @@ typedef struct TkIntPlatStubs {
void (*tkMacOSXMakeRealWindowExist) (TkWindow *winPtr); /* 23 */
void * (*tkMacOSXMakeStippleMap) (Drawable d1, Drawable d2); /* 24 */
void (*tkMacOSXMenuClick) (void); /* 25 */
- void (*tkMacOSXRegisterOffScreenWindow) (Window window, void *portPtr); /* 26 */
+ void (*reserved26)(void);
int (*tkMacOSXResizable) (TkWindow *winPtr); /* 27 */
void (*tkMacOSXSetHelpMenuItemCount) (void); /* 28 */
void (*tkMacOSXSetScrollbarGrow) (TkWindow *winPtr, int flag); /* 29 */
void (*tkMacOSXSetUpClippingRgn) (Drawable drawable); /* 30 */
void (*tkMacOSXSetUpGraphicsPort) (GC gc, void *destPort); /* 31 */
void (*tkMacOSXUpdateClipRgn) (TkWindow *winPtr); /* 32 */
- void (*tkMacOSXUnregisterMacWindow) (void *portPtr); /* 33 */
+ void (*reserved33)(void);
int (*tkMacOSXUseMenuID) (short macID); /* 34 */
Region (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */
void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */
@@ -655,8 +652,7 @@ extern const TkIntPlatStubs *tkIntPlatStubsPtr;
(tkIntPlatStubsPtr->tkMacOSXMakeStippleMap) /* 24 */
#define TkMacOSXMenuClick \
(tkIntPlatStubsPtr->tkMacOSXMenuClick) /* 25 */
-#define TkMacOSXRegisterOffScreenWindow \
- (tkIntPlatStubsPtr->tkMacOSXRegisterOffScreenWindow) /* 26 */
+/* Slot 26 is reserved */
#define TkMacOSXResizable \
(tkIntPlatStubsPtr->tkMacOSXResizable) /* 27 */
#define TkMacOSXSetHelpMenuItemCount \
@@ -669,8 +665,7 @@ extern const TkIntPlatStubs *tkIntPlatStubsPtr;
(tkIntPlatStubsPtr->tkMacOSXSetUpGraphicsPort) /* 31 */
#define TkMacOSXUpdateClipRgn \
(tkIntPlatStubsPtr->tkMacOSXUpdateClipRgn) /* 32 */
-#define TkMacOSXUnregisterMacWindow \
- (tkIntPlatStubsPtr->tkMacOSXUnregisterMacWindow) /* 33 */
+/* Slot 33 is reserved */
#define TkMacOSXUseMenuID \
(tkIntPlatStubsPtr->tkMacOSXUseMenuID) /* 34 */
#define TkMacOSXVisableClipRgn \
diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c
index 9c8a1d8..e0c4c93 100644
--- a/generic/tkStubInit.c
+++ b/generic/tkStubInit.c
@@ -601,14 +601,14 @@ static const TkIntPlatStubs tkIntPlatStubs = {
TkMacOSXMakeRealWindowExist, /* 23 */
TkMacOSXMakeStippleMap, /* 24 */
TkMacOSXMenuClick, /* 25 */
- TkMacOSXRegisterOffScreenWindow, /* 26 */
+ 0, /* 26 */
TkMacOSXResizable, /* 27 */
TkMacOSXSetHelpMenuItemCount, /* 28 */
TkMacOSXSetScrollbarGrow, /* 29 */
TkMacOSXSetUpClippingRgn, /* 30 */
TkMacOSXSetUpGraphicsPort, /* 31 */
TkMacOSXUpdateClipRgn, /* 32 */
- TkMacOSXUnregisterMacWindow, /* 33 */
+ 0, /* 33 */
TkMacOSXUseMenuID, /* 34 */
TkMacOSXVisableClipRgn, /* 35 */
TkMacOSXWinBounds, /* 36 */
diff --git a/macosx/tkMacOSXColor.c b/macosx/tkMacOSXColor.c
index 813f59b..ab28fbf 100644
--- a/macosx/tkMacOSXColor.c
+++ b/macosx/tkMacOSXColor.c
@@ -318,19 +318,15 @@ GetRGBA(
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
color = [[NSColor colorForControlTint: [NSColor currentControlTint]]
colorUsingColorSpace:sRGB];
- [color getComponents: rgba];
#endif
- break;
- }
- if (entry->index == selectedTabTextIndex) {
+ } else if (entry->index == selectedTabTextIndex) {
int OSVersion = [NSApp macOSVersion];
if (OSVersion > 100600 && OSVersion < 110000) {
- color = [NSColor whiteColor];
- [color getComponents: rgba];
- break;
+ color = [[NSColor whiteColor] colorUsingColorSpace:sRGB];
}
+ } else {
+ color = [[NSColor valueForKey:entry->selector] colorUsingColorSpace:sRGB];
}
- color = [[NSColor valueForKey:entry->selector] colorUsingColorSpace:sRGB];
[color getComponents: rgba];
break;
case clearColor:
diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c
index 9b623be..050f4fd 100644
--- a/macosx/tkMacOSXMouseEvent.c
+++ b/macosx/tkMacOSXMouseEvent.c
@@ -24,6 +24,7 @@ typedef struct {
Point global;
Point local;
} MouseEventData;
+
static Tk_Window captureWinPtr = NULL; /* Current capture window; may be
* NULL. */
@@ -42,9 +43,9 @@ enum {
* window attribute pointing to the active window. As of 10.8 this behavior
* had changed. The new behavior was that if the mouse were ever moved outside
* of a window, all subsequent NSMouseMoved NSEvents would have a Nil window
- * attribute. To work around this the TKApplication remembers the last non-Nil
- * window that it received in a mouse event. If it receives an NSEvent with a
- * Nil window attribute then the saved window is used.
+ * attribute until the mouse returned to the window. In 11.1 it changed again.
+ * The window attribute can be non-nil, but referencing a window which does not
+ * belong to the application.
*/
@implementation TKApplication(TKMouseEvent)
@@ -52,147 +53,160 @@ enum {
{
NSWindow *eventWindow = [theEvent window];
NSEventType eventType = [theEvent type];
+ NSRect viewFrame = [[eventWindow contentView] frame];
TkWindow *winPtr = NULL, *grabWinPtr;
- Tk_Window tkwin;
+ Tk_Window tkwin = NULL, capture, target;
NSPoint local, global;
- NSInteger button = -1;
- [NSEvent stopPeriodicEvents];
+ NSInteger button;
+ Bool inTitleBar = NO;
+ int win_x, win_y;
+ unsigned int buttonState = 0;
+ static int validPresses = 0, ignoredPresses = 0;
#ifdef TK_MAC_DEBUG_EVENTS
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, theEvent);
#endif
+
+ /*
+ * If this event is not for a Tk toplevel, it should just be passed up the
+ * responder chain. However, there is an exception for synthesized events,
+ * which are used in testing. Those events are recognized by having their
+ * (unused) pressure field set to the impossible value -1.0.
+ */
+
+ if (![eventWindow isMemberOfClass:[TKWindow class]]) {
+ if (eventWindow && [theEvent pressure] != -1.0) {
+ return theEvent;
+ }
+ }
+
+ /*
+ * Check if the event is located in the titlebar.
+ */
+
+ if (eventWindow) {
+ inTitleBar = viewFrame.size.height < [theEvent locationInWindow].y;
+ }
+ button = [theEvent buttonNumber] + Button1;
switch (eventType) {
- case NSLeftMouseDown:
- case NSRightMouseDown:
- case NSOtherMouseDown:
+ case NSRightMouseUp:
+ case NSOtherMouseUp:
+ buttonState &= ~Tk_GetButtonMask(button);
+ break;
case NSLeftMouseDragged:
case NSRightMouseDragged:
case NSOtherMouseDragged:
- button = [theEvent buttonNumber] + Button1;
+ case NSRightMouseDown:
+ case NSOtherMouseDown:
+ buttonState |= Tk_GetButtonMask(button);
+ break;
case NSMouseEntered:
+ if (!inTitleBar) {
+ [(TKWindow *)eventWindow setMouseInResizeArea:YES];
+ }
+ break;
case NSMouseExited:
- case NSCursorUpdate:
+ [(TKWindow *)eventWindow setMouseInResizeArea:NO];
+ break;
case NSLeftMouseUp:
- case NSRightMouseUp:
- case NSOtherMouseUp:
+ case NSLeftMouseDown:
case NSMouseMoved:
+ case NSScrollWheel:
+#if 0
+ case NSCursorUpdate:
case NSTabletPoint:
case NSTabletProximity:
- case NSScrollWheel:
+#endif
break;
- default: /* Unrecognized mouse event. */
+ default: /* This type of event is ignored. */
return theEvent;
}
/*
- * Compute the mouse position in Tk screen coordinates (global) and in the
- * Tk coordinates of its containing Tk Window (local). If a grab is in effect,
- * the local coordinates should be relative to the grab window.
+ * Update the button state. We ignore left button presses that start a
+ * resize or occur in the title bar. See tickets [d72abe6b54] and
+ * [39cbacb9e8].
*/
- if (eventWindow) {
- local = [theEvent locationInWindow];
+ if (eventType == NSLeftMouseDown) {
+ if ([(TKWindow *)eventWindow mouseInResizeArea] &&
+ ([eventWindow styleMask] & NSResizableWindowMask)) {
- /*
- * Do not send ButtonPress XEvents for MouseDown NSEvents that start a
- * resize. (The MouseUp will be handled during LiveResize.) See
- * ticket [d72abe6b54].
- */
+ /*
+ * When the left button is pressed in the resize area, we receive
+ * NSMouseDown, but when it is released we do not receive
+ * NSMouseUp. So ignore the event and clear the button state but
+ * do not change the ignoredPresses count.
+ */
- if (eventType == NSLeftMouseDown &&
- ([eventWindow styleMask] & NSResizableWindowMask) &&
- [NSApp macOSVersion] > 100600) {
- NSRect frame = [eventWindow frame];
- if (local.x < 3 || local.x > frame.size.width - 3 || local.y < 3) {
- return theEvent;
- }
+ buttonState &= ~Tk_GetButtonMask(Button1);
+ return theEvent;
}
- global = [eventWindow tkConvertPointToScreen: local];
- tkwin = TkpGetCapture();
- if (tkwin) {
- winPtr = (TkWindow *) tkwin;
- eventWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
- if (eventWindow) {
- local = [eventWindow tkConvertPointFromScreen: global];
- } else {
- return theEvent;
- }
+ if (inTitleBar) {
+ ignoredPresses++;
+ return theEvent;
}
- local.y = [eventWindow frame].size.height - local.y;
- global.y = TkMacOSXZeroScreenHeight() - global.y;
- } else {
-
- /*
- * If the event has no NSWindow, the location is in screen coordinates.
- */
-
- global = [theEvent locationInWindow];
- tkwin = TkpGetCapture();
- if (tkwin) {
- winPtr = (TkWindow *) tkwin;
- eventWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
- } else {
- eventWindow = [NSApp mainWindow];
+ validPresses++;
+ buttonState |= Tk_GetButtonMask(Button1);
+ }
+ if (eventType == NSLeftMouseUp) {
+ if (ignoredPresses > 0) {
+ ignoredPresses--;
+ } else if (validPresses > 0) {
+ validPresses--;
}
- if (!eventWindow) {
- return theEvent;
+ if (validPresses == 0) {
+ buttonState &= ~Tk_GetButtonMask(Button1);
}
- local = [eventWindow tkConvertPointFromScreen: global];
- local.y = [eventWindow frame].size.height - local.y;
- global.y = TkMacOSXZeroScreenHeight() - global.y;
}
/*
- * If we still don't have a window, try using the toplevel that
- * manages the NSWindow.
+ * Find an appropriate NSWindow to attach to this event, and its
+ * associated Tk window.
*/
- if (!tkwin) {
- winPtr = TkMacOSXGetTkWindow(eventWindow);
- tkwin = (Tk_Window)winPtr;
+ capture = TkpGetCapture();
+ if (capture) {
+ winPtr = (TkWindow *) capture;
+ eventWindow = TkMacOSXGetNSWindowForDrawable(winPtr->window);
+ if (!eventWindow) {
+ return theEvent;
+ }
+ } else {
+ if (eventWindow) {
+ winPtr = TkMacOSXGetTkWindow(eventWindow);
+ }
+ if (!winPtr) {
+ eventWindow = [NSApp mainWindow];
+ winPtr = TkMacOSXGetTkWindow(eventWindow);
+ }
}
- if (!tkwin) {
+ if (!winPtr) {
/*
- * We can't find a window for this event. We have to ignore it.
+ * We couldn't find a Tk window for this event. We have to ignore it.
*/
#ifdef TK_MAC_DEBUG_EVENTS
- TkMacOSXDbgMsg("tkwin == NULL");
+ TkMacOSXDbgMsg("Event received with no Tk window.");
#endif
return theEvent;
}
+ tkwin = (Tk_Window) winPtr;
/*
- * Ignore the event if a local grab is in effect and the Tk event window is
- * not in the grabber's subtree.
- */
-
- grabWinPtr = winPtr->dispPtr->grabWinPtr;
- if (grabWinPtr && /* There is a grab in effect ... */
- !winPtr->dispPtr->grabFlags && /* and it is a local grab ... */
- grabWinPtr->mainPtr == winPtr->mainPtr){ /* in the same application. */
- Tk_Window tkwin2, tkEventWindow = Tk_CoordsToWindow(global.x, global.y, tkwin);
- if (!tkEventWindow) {
- return theEvent;
- }
- for (tkwin2 = tkEventWindow;
- !Tk_IsTopLevel(tkwin2);
- tkwin2 = Tk_Parent(tkwin2)) {
- if (tkwin2 == (Tk_Window)grabWinPtr) {
- break;
- }
- }
- if (tkwin2 != (Tk_Window)grabWinPtr) {
- return theEvent;
- }
- }
-
- /*
- * Convert local from NSWindow flipped coordinates to the toplevel's
- * coordinates.
+ * Compute the mouse position in local (window) and global (screen)
+ * coordinates. These are Tk coordinates, meaning that the local origin is
+ * at the top left corner of the containing toplevel and the global origin
+ * is at top left corner of the primary screen.
*/
+ global = [NSEvent mouseLocation];
+ local = [eventWindow tkConvertPointFromScreen: global];
+ global.x = floor(global.x);
+ global.y = floor(TkMacOSXZeroScreenHeight() - global.y);
+ local.x = floor(local.x);
+ local.y = floor([eventWindow frame].size.height - local.y);
if (Tk_IsEmbedded(winPtr)) {
TkWindow *contPtr = TkpGetOtherWindow(winPtr);
if (Tk_IsTopLevel(contPtr)) {
@@ -209,25 +223,44 @@ enum {
}
/*
- * Use the toplevel coordinates to find the containing Tk window. Then
- * convert local into the coordinates of that window. (The converted
- * local coordinates are only needed for scrollwheel events.)
+ * Use the local coordinates to find the Tk window which should receive
+ * this event. Also convert local into the coordinates of that window.
+ * (The converted local coordinates are only needed for scrollwheel
+ * events.)
*/
- int win_x, win_y;
- tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
- local.x = win_x;
- local.y = win_y;
+ target = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
/*
- * Generate an XEvent for this mouse event.
+ * Ignore the event if a local grab is in effect and the Tk window is
+ * not in the grabber's subtree.
*/
- unsigned int state = 0;
- if (button > 0) {
- state |= Tk_GetButtonMask(button);
+ grabWinPtr = winPtr->dispPtr->grabWinPtr;
+ if (grabWinPtr && /* There is a grab in effect ... */
+ !winPtr->dispPtr->grabFlags && /* and it is a local grab ... */
+ grabWinPtr->mainPtr == winPtr->mainPtr){ /* in the same application. */
+ Tk_Window tkwin2;
+ if (!target) {
+ return theEvent;
+ }
+ for (tkwin2 = target;
+ !Tk_IsTopLevel(tkwin2);
+ tkwin2 = Tk_Parent(tkwin2)) {
+ if (tkwin2 == (Tk_Window)grabWinPtr) {
+ break;
+ }
+ }
+ if (tkwin2 != (Tk_Window)grabWinPtr) {
+ return theEvent;
+ }
}
+ /*
+ * Generate an XEvent for this mouse event.
+ */
+
+ unsigned int state = buttonState;
NSUInteger modifiers = [theEvent modifierFlags];
if (modifiers & NSAlphaShiftKeyMask) {
@@ -255,32 +288,34 @@ enum {
if (eventType != NSScrollWheel) {
/*
- * For normal mouse events, Tk_UpdatePointer will send the XEvent.
+ * For normal mouse events, Tk_UpdatePointer will send the appropriate
+ * XEvents using its cached state information. Unfortunately, it will
+ * also recompute the local coordinates.
*/
#ifdef TK_MAC_DEBUG_EVENTS
- TKLog(@"UpdatePointer %p x %f.0 y %f.0 %d",
- tkwin, global.x, global.y, state);
+ TKLog(@"UpdatePointer %p x %.1f y %.1f %d",
+ target, global.x, global.y, state);
#endif
- Tk_UpdatePointer(tkwin, global.x, global.y, state);
+
+ Tk_UpdatePointer(target, global.x, global.y, state);
} else {
+ CGFloat delta;
+ int coarseDelta;
+ XEvent xEvent;
/*
* For scroll wheel events we need to send the XEvent here.
*/
- CGFloat delta;
- int coarseDelta;
- XEvent xEvent;
-
xEvent.type = MouseWheelEvent;
- xEvent.xbutton.x = local.x;
- xEvent.xbutton.y = local.y;
+ xEvent.xbutton.x = win_x;
+ xEvent.xbutton.y = win_y;
xEvent.xbutton.x_root = global.x;
xEvent.xbutton.y_root = global.y;
xEvent.xany.send_event = false;
- xEvent.xany.display = Tk_Display(tkwin);
- xEvent.xany.window = Tk_WindowId(tkwin);
+ xEvent.xany.display = Tk_Display(target);
+ xEvent.xany.window = Tk_WindowId(target);
delta = [theEvent deltaY];
if (delta != 0.0) {
@@ -608,6 +643,23 @@ GenerateButtonEvent(
return true;
}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpWarpPointer --
+ *
+ * Move the mouse cursor to the screen location specified by the warpX and
+ * warpY fields of a TkDisplay.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * The mouse cursor is moved.
+ *
+ *----------------------------------------------------------------------
+ */
+
void
TkpWarpPointer(
TkDisplay *dispPtr)
@@ -652,7 +704,6 @@ TkpSetCapture(
while (winPtr && !Tk_IsTopLevel(winPtr)) {
winPtr = winPtr->parentPtr;
}
- [NSEvent stopPeriodicEvents];
captureWinPtr = (Tk_Window)winPtr;
}
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index 498f94c..987ce03 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -437,16 +437,40 @@ VISIBILITY_HIDDEN
VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
+{
+#ifdef __i386__
+ /* The Objective C runtime used on i386 requires this. */
+ Bool _mouseInResizeArea;
+ Window _tkWindow;
+#endif
+}
+@property Bool mouseInResizeArea;
+@property Window tkWindow;
@end
@interface TKWindow(TKWm)
- (void) tkLayoutChanged;
@end
-@interface NSDrawerWindow : NSWindow
+@interface TKDrawerWindow : NSWindow
{
id _i1, _i2;
+#ifdef __i386__
+ /* The Objective C runtime used on i386 requires this. */
+ Window _tkWindow;
+#endif
+}
+@property Window tkWindow;
+@end
+
+@interface TKPanel : NSPanel
+{
+#ifdef __i386__
+ /* The Objective C runtime used on i386 requires this. */
+ Window _tkWindow;
+#endif
}
+@property Window tkWindow;
@end
#pragma mark NSMenu & NSMenuItem Utilities
diff --git a/macosx/tkMacOSXTest.c b/macosx/tkMacOSXTest.c
index 496d9cc..ee31995 100644
--- a/macosx/tkMacOSXTest.c
+++ b/macosx/tkMacOSXTest.c
@@ -175,9 +175,11 @@ TkTestLogDisplay(
* PressButtonObjCmd --
*
* This Tcl command simulates a button press at a specific screen
- * location. It injects NSEvents into the NSApplication event queue,
- * as opposed to adding events to the Tcl queue as event generate
- * would do. One application is for testing the grab command.
+ * location. It injects NSEvents into the NSApplication event queue, as
+ * opposed to adding events to the Tcl queue as event generate would do.
+ * One application is for testing the grab command. These events have
+ * pressure = -1.0 as a signal indicating that they should not be ignored
+ * by [NSApp tkProcessMouseEvent].
*
* Results:
* A standard Tcl result.
@@ -239,7 +241,7 @@ PressButtonObjCmd(
context:nil
eventNumber:0
clickCount:1
- pressure:0.0];
+ pressure:-1.0];
[NSApp postEvent:motion atStart:NO];
press = [NSEvent mouseEventWithType:NSLeftMouseDown
location:loc
@@ -249,7 +251,7 @@ PressButtonObjCmd(
context:nil
eventNumber:1
clickCount:1
- pressure:0.0];
+ pressure:-1.0];
[NSApp postEvent:press atStart:NO];
release = [NSEvent mouseEventWithType:NSLeftMouseUp
location:loc
@@ -259,7 +261,7 @@ PressButtonObjCmd(
context:nil
eventNumber:2
clickCount:1
- pressure:0.0];
+ pressure:-1.0];
[NSApp postEvent:release atStart:NO];
return TCL_OK;
}
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 6eb05f8..14cae08 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -193,13 +193,6 @@ static const Tk_GeomMgr wmMgrType = {
static int tkMacOSXWmAttrNotifyVal = 0;
/*
- * Hash table for Mac Window -> TkWindow mapping.
- */
-
-static Tcl_HashTable windowTable;
-static int windowHashInit = false;
-
-/*
* Forward declarations for procedures defined in this file:
*/
@@ -360,11 +353,21 @@ static void RemoveTransient(TkWindow *winPtr);
#pragma mark -
-#pragma mark TKWindow(TKWm)
+@implementation TKPanel: NSPanel
+@synthesize tkWindow = _tkWindow;
+@end
+
+@implementation TKDrawerWindow: NSWindow
+@synthesize tkWindow = _tkWindow;
+@end
@implementation TKWindow: NSWindow
+@synthesize mouseInResizeArea = _mouseInResizeArea;
+@synthesize tkWindow = _tkWindow;
@end
+#pragma mark TKWindow(TKWm)
+
@implementation TKWindow(TKWm)
/*
@@ -885,7 +888,7 @@ TkWmDeadWindow(
TkWindow *winPtr) /* Top-level window that's being deleted. */
{
WmInfo *wmPtr = winPtr->wmInfoPtr, *wmPtr2;
- NSWindow *ourNSWindow;
+ TKWindow *deadNSWindow;
if (wmPtr == NULL) {
return;
@@ -964,27 +967,27 @@ TkWmDeadWindow(
* the parent. Then close and release the NSWindow.
*/
- ourNSWindow = wmPtr->window;
- if (ourNSWindow && !Tk_IsEmbedded(winPtr)) {
- NSWindow *parent = [ourNSWindow parentWindow];
- TkMacOSXUnregisterMacWindow(ourNSWindow);
+ deadNSWindow = (TKWindow *)wmPtr->window;
+ if (deadNSWindow && !Tk_IsEmbedded(winPtr)) {
+ NSWindow *parent = [deadNSWindow parentWindow];
+ [deadNSWindow setTkWindow:None];
if (winPtr->window) {
((MacDrawable *)winPtr->window)->view = nil;
}
wmPtr->window = NULL;
if (parent) {
- [parent removeChildWindow:ourNSWindow];
+ [parent removeChildWindow:deadNSWindow];
}
#if DEBUG_ZOMBIES > 1
{
- const char *title = [[ourNSWindow title] UTF8String];
+ const char *title = [[deadNSWindow title] UTF8String];
if (title == nil) {
title = "unnamed window";
}
fprintf(stderr, ">>>> Closing <%s>. Count is: %lu\n", title,
- [ourNSWindow retainCount]);
+ [deadNSWindow retainCount]);
}
#endif
@@ -1011,7 +1014,7 @@ TkWmDeadWindow(
wmPtr2 = winPtr2->wmInfoPtr;
isOnScreen = (wmPtr2->hints.initial_state != IconicState &&
wmPtr2->hints.initial_state != WithdrawnState);
- if (w != ourNSWindow && isOnScreen && [w canBecomeKeyWindow]) {
+ if (w != deadNSWindow && isOnScreen && [w canBecomeKeyWindow]) {
[w makeKeyAndOrderFront:NSApp];
break;
}
@@ -1021,12 +1024,12 @@ TkWmDeadWindow(
* Prevent zombies on systems with a TouchBar.
*/
- if (ourNSWindow == [NSApp keyWindow]) {
+ if (deadNSWindow == [NSApp keyWindow]) {
[NSApp _setKeyWindow:nil];
[NSApp _setMainWindow:nil];
}
- [ourNSWindow close];
- [ourNSWindow release];
+ [deadNSWindow close];
+ [deadNSWindow release];
[NSApp _resetAutoreleasePool];
#if DEBUG_ZOMBIES > 1
@@ -5363,7 +5366,8 @@ TkGetTransientMaster(
*
* TkMacOSXGetXWindow --
*
- * Returns the X window Id associated with the given NSWindow*.
+ * Stub function that returns the X window Id associated with the
+ * given NSWindow*.
*
* Results:
* The window id is returned. None is returned if not a Tk window.
@@ -5378,16 +5382,9 @@ Window
TkMacOSXGetXWindow(
void *macWinPtr)
{
- Tcl_HashEntry *hPtr;
-
- if (!macWinPtr || !windowHashInit) {
- return None;
- }
- hPtr = Tcl_FindHashEntry(&windowTable, macWinPtr);
- if (hPtr == NULL) {
- return None;
- }
- return (Window) Tcl_GetHashValue(hPtr);
+ TKWindow *w = (TKWindow *)macWinPtr;
+ Window window = (Window) TkMacOSXGetTkWindow(w);
+ return window ? window : None;
}
/*
@@ -5410,11 +5407,14 @@ TkWindow*
TkMacOSXGetTkWindow(
NSWindow *w)
{
- Window window = TkMacOSXGetXWindow(w);
+ Window window = None;
TkDisplay *dispPtr = TkGetDisplayList();
-
+ if ([w respondsToSelector: @selector (tkWindow)]) {
+ window = [(TKWindow *)w tkWindow];
+ }
return (window != None ?
(TkWindow *)Tk_IdToWindow(dispPtr->display, window) : NULL);
+
}
/*
@@ -5827,7 +5827,8 @@ WmWinTabbingId(
result = Tcl_NewStringObj(idString.UTF8String, [idString length]);
}
if (result == NULL) {
- NSLog(@"Failed to read tabbing identifier; try calling update idletasks before getting/setting the tabbing identifier of the window.");
+ NSLog(@"Failed to read tabbing identifier; try calling update idletasks"
+ " before getting/setting the tabbing identifier of the window.");
return TCL_OK;
}
Tcl_SetObjResult(interp, result);
@@ -6083,16 +6084,16 @@ TkMacOSXMakeRealWindowExist(
NSUnifiedTitleAndToolbarWindowMask : 0) |
((attributes & kWindowSideTitlebarAttribute) ? 1 << 9 : 0) |
(attributes >> WM_NSMASK_SHIFT);
- Class winClass = (macClass == kDrawerWindowClass ? [NSDrawerWindow class] :
+ Class winClass = (macClass == kDrawerWindowClass ? [TKDrawerWindow class] :
(styleMask & (NSUtilityWindowMask|NSDocModalWindowMask|
- NSNonactivatingPanelMask|NSHUDWindowMask)) ? [NSPanel class] :
+ NSNonactivatingPanelMask|NSHUDWindowMask)) ? [TKPanel class] :
[TKWindow class]);
NSRect structureRect = [winClass frameRectForContentRect:NSZeroRect
styleMask:styleMask];
NSRect contentRect = NSMakeRect(5 - structureRect.origin.x,
TkMacOSXZeroScreenHeight() - (TkMacOSXZeroScreenTop() + 5 +
structureRect.origin.y + structureRect.size.height + 200), 200, 200);
- NSWindow *window = [[winClass alloc] initWithContentRect:contentRect
+ TKWindow *window = [[winClass alloc] initWithContentRect:contentRect
styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
if (!window) {
Tcl_Panic("couldn't allocate new Mac window");
@@ -6105,7 +6106,7 @@ TkMacOSXMakeRealWindowExist(
[window setAcceptsMouseMovedEvents:YES];
[window setReleasedWhenClosed:NO];
if (styleMask & NSUtilityWindowMask) {
- [(NSPanel*)window setFloatingPanel:YES];
+ [(TKPanel*)window setFloatingPanel:YES];
}
if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
!(styleMask & NSDocModalWindowMask)) {
@@ -6125,7 +6126,7 @@ TkMacOSXMakeRealWindowExist(
geometry.origin.y = TkMacOSXZeroScreenHeight() - (geometry.origin.y +
geometry.size.height);
[window setFrame:geometry display:YES];
- TkMacOSXRegisterOffScreenWindow((Window) macWin, window);
+ [window setTkWindow: (Window) macWin];
macWin->flags |= TK_HOST_EXISTS;
if (overrideRedirect) {
@@ -6178,75 +6179,6 @@ TkpRedrawWidget(Tk_Window tkwin) {
}
}
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXRegisterOffScreenWindow --
- *
- * This function adds the passed in Off Screen Port to the hash table that
- * maps Mac windows to root X windows.
- *
- * Results:
- * None.
- *
- * Side effects:
- * An entry is added to the windowTable hash table.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkMacOSXRegisterOffScreenWindow(
- Window window, /* Window structure. */
- void *portPtr) /* Pointer to a Mac Window. */
-{
- Tcl_HashEntry *valueHashPtr;
- int isNew;
-
- if (!windowHashInit) {
- Tcl_InitHashTable(&windowTable, TCL_ONE_WORD_KEYS);
- windowHashInit = true;
- }
- valueHashPtr = Tcl_CreateHashEntry(&windowTable, (char *) portPtr, &isNew);
- if (!isNew) {
- Tcl_Panic("Same macintosh window allocated twice!");
- }
- Tcl_SetHashValue(valueHashPtr, window);
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * TkMacOSXUnregisterMacWindow --
- *
- * Given a macintosh port window, this function removes the association
- * between this window and the root X window that Tk cares about.
- *
- * Results:
- * None.
- *
- * Side effects:
- * An entry is removed from the windowTable hash table.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkMacOSXUnregisterMacWindow(
- void *macWinPtr) /* Reference to a Mac Window */
-{
- Tcl_HashEntry *entryPtr;
-
- if (!windowHashInit) {
- Tcl_Panic("TkMacOSXUnregisterMacWindow: unmapping before inited");
- }
- entryPtr = Tcl_FindHashEntry(&windowTable, macWinPtr);
- if (!entryPtr) {
- TkMacOSXDbgMsg("Failed to find window %p", macWinPtr);
- } else {
- Tcl_DeleteHashEntry(entryPtr);
- }
-}
/*
*----------------------------------------------------------------------
@@ -6857,7 +6789,7 @@ ApplyWindowAttributeFlagChanges(
if ((wmPtr->flags & WM_TOPMOST) != (oldFlags & WM_TOPMOST)) {
[macWindow setLevel:(wmPtr->flags & WM_TOPMOST) ?
kCGUtilityWindowLevel : ([macWindow isKindOfClass:
- [NSPanel class]] && [macWindow isFloatingPanel] ?
+ [TKPanel class]] && [macWindow isFloatingPanel] ?
kCGFloatingWindowLevel : kCGNormalWindowLevel)];
}