diff options
-rw-r--r-- | macosx/tkMacOSXBitmap.c | 2 | ||||
-rw-r--r-- | macosx/tkMacOSXConstants.h | 95 | ||||
-rw-r--r-- | macosx/tkMacOSXDialog.c | 5 | ||||
-rw-r--r-- | macosx/tkMacOSXEvent.c | 1 | ||||
-rw-r--r-- | macosx/tkMacOSXInit.c | 24 | ||||
-rw-r--r-- | macosx/tkMacOSXKeyEvent.c | 1 | ||||
-rw-r--r-- | macosx/tkMacOSXKeyboard.c | 2 | ||||
-rw-r--r-- | macosx/tkMacOSXMenu.c | 1 | ||||
-rw-r--r-- | macosx/tkMacOSXMenus.c | 1 | ||||
-rw-r--r-- | macosx/tkMacOSXMouseEvent.c | 1 | ||||
-rw-r--r-- | macosx/tkMacOSXNotify.c | 35 | ||||
-rw-r--r-- | macosx/tkMacOSXPrivate.h | 7 | ||||
-rw-r--r-- | macosx/tkMacOSXWindowEvent.c | 5 | ||||
-rw-r--r-- | macosx/tkMacOSXWm.c | 42 | ||||
-rw-r--r-- | macosx/tkMacOSXXStubs.c | 11 |
15 files changed, 192 insertions, 41 deletions
diff --git a/macosx/tkMacOSXBitmap.c b/macosx/tkMacOSXBitmap.c index 52768c6..6e3c1a5 100644 --- a/macosx/tkMacOSXBitmap.c +++ b/macosx/tkMacOSXBitmap.c @@ -12,7 +12,7 @@ */ #include "tkMacOSXPrivate.h" - +#include "tkMacOSXConstants.h" /* * This structure holds information about native bitmaps. */ diff --git a/macosx/tkMacOSXConstants.h b/macosx/tkMacOSXConstants.h new file mode 100644 index 0000000..1ee85a6 --- /dev/null +++ b/macosx/tkMacOSXConstants.h @@ -0,0 +1,95 @@ +/* + * tkMacOSXConstants.h -- + * + * Macros which map the names of NS constants used in the Tk code to + * the new name that Apple came up with for subsequent versions of the + * operating system. (Each new OS release seems to come with a new + * naming convention for the same old constants.) + * + * Copyright (c) 2017 Marc Culler + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TKMACCONSTANTS +#define _TKMACCONSTANTS + +/* + * Let's raise a glass for the project manager who improves our lives by + * generating deprecation warnings about pointless changes of the names + * of constants. + */ + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 +#define NSOKButton NSModalResponseOK +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 +#define NSAppKitDefined NSEventTypeAppKitDefined +#define NSApplicationActivatedEventType NSEventSubtypeApplicationActivated +#define NSApplicationDeactivatedEventType NSEventSubtypeApplicationDeactivated +#define NSWindowExposedEventType NSEventSubtypeWindowExposed +#define NSScreenChangedEventType NSEventSubtypeScreenChanged +#define NSWindowMovedEventType NSEventSubtypeWindowMoved +#define NSKeyUp NSEventTypeKeyUp +#define NSKeyDown NSEventTypeKeyDown +#define NSFlagsChanged NSEventTypeFlagsChanged +#define NSLeftMouseDown NSEventTypeLeftMouseDown +#define NSLeftMouseUp NSEventTypeLeftMouseUp +#define NSRightMouseDown NSEventTypeRightMouseDown +#define NSRightMouseUp NSEventTypeRightMouseUp +#define NSLeftMouseDragged NSEventTypeLeftMouseDragged +#define NSRightMouseDragged NSEventTypeRightMouseDragged +#define NSMouseMoved NSEventTypeMouseMoved +#define NSMouseEntered NSEventTypeMouseEntered +#define NSMouseExited NSEventTypeMouseExited +#define NSScrollWheel NSEventTypeScrollWheel +#define NSOtherMouseDown NSEventTypeOtherMouseDown +#define NSOtherMouseUp NSEventTypeOtherMouseUp +#define NSOtherMouseDragged NSEventTypeOtherMouseDragged +#define NSTabletPoint NSEventTypeTabletPoint +#define NSTabletProximity NSEventTypeTabletProximity +#define NSDeviceIndependentModifierFlagsMask NSEventModifierFlagDeviceIndependentFlagsMask +#define NSCommandKeyMask NSEventModifierFlagCommand +#define NSShiftKeyMask NSEventModifierFlagShift +#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock +#define NSAlternateKeyMask NSEventModifierFlagOption +#define NSControlKeyMask NSEventModifierFlagControl +#define NSNumericPadKeyMask NSEventModifierFlagNumericPad +#define NSFunctionKeyMask NSEventModifierFlagFunction +#define NSCursorUpdate NSEventTypeCursorUpdate +#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground +#define NSCompositeCopy NSCompositingOperationCopy +#define NSWarningAlertStyle NSAlertStyleWarning +#define NSInformationalAlertStyle NSAlertStyleInformational +#define NSCriticalAlertStyle NSAlertStyleCritical +#define NSCenterTextAlignment NSTextAlignmentCenter +#define NSDeviceIndependentModifierFlagsMask NSEventModifierFlagDeviceIndependentFlagsMask +#define NSCommandKeyMask NSEventModifierFlagCommand +#define NSShiftKeyMask NSEventModifierFlagShift +#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock +#define NSAlternateKeyMask NSEventModifierFlagOption +#define NSControlKeyMask NSEventModifierFlagControl +#define NSNumericPadKeyMask NSEventModifierFlagNumericPad +#define NSFunctionKeyMask NSEventModifierFlagFunction +#define NSKeyUp NSEventTypeKeyUp +#define NSKeyDown NSEventTypeKeyDown +#define NSFlagsChanged NSEventTypeFlagsChanged +#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock +#define NSShiftKeyMask NSEventModifierFlagShift +#define NSAnyEventMask NSEventMaskAny +#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground +#define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow +#define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel +#define NSDocModalWindowMask NSWindowStyleMaskDocModalWindow +#define NSHUDWindowMask NSWindowStyleMaskHUDWindow +#define NSTitledWindowMask NSWindowStyleMaskTitled +#define NSClosableWindowMask NSWindowStyleMaskClosable +#define NSResizableWindowMask NSWindowStyleMaskResizable +#define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar +#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable +#define NSBorderlessWindowMask NSWindowStyleMaskBorderless +#endif + +#endif diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 1383225..c1f1491 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -14,6 +14,7 @@ #include "tkMacOSXPrivate.h" #include "tkFileFilter.h" +#include "tkMacOSXConstants.h" #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 #define modalOK NSOKButton @@ -190,7 +191,7 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { { FilePanelCallbackInfo *callbackInfo = contextInfo; - if (returnCode == NSFileHandlingPanelOKButton) { + if (returnCode == modalOK) { Tcl_Obj *resultObj; if (callbackInfo->multiple) { @@ -218,7 +219,7 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { } else { Tcl_SetObjResult(callbackInfo->interp, resultObj); } - } else if (returnCode == NSFileHandlingPanelCancelButton) { + } else if (returnCode == modalCancel) { Tcl_ResetResult(callbackInfo->interp); } if (panel == [NSApp modalWindow]) { diff --git a/macosx/tkMacOSXEvent.c b/macosx/tkMacOSXEvent.c index 7f3357f..de57008 100644 --- a/macosx/tkMacOSXEvent.c +++ b/macosx/tkMacOSXEvent.c @@ -14,6 +14,7 @@ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" +#include "tkMacOSXConstants.h" #pragma mark TKApplication(TKEvent) diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index 33a60f2..a8b4e9d 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -57,17 +57,35 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt @end @implementation TKApplication -@synthesize poolProtected = _poolProtected; +@synthesize poolLock = _poolLock; @end +/* + * #define this to see a message on stderr whenever _resetAutoreleasePool is + * called while the pool is locked. + */ +#undef DEBUG_LOCK + @implementation TKApplication(TKInit) - (void) _resetAutoreleasePool { - if(![self poolProtected]) { + if([self poolLock] == 0) { [_mainPool drain]; _mainPool = [NSAutoreleasePool new]; + } else { +#ifdef DEBUG_LOCK + fprintf(stderr, "Pool is locked with count %d!!!!\n", [self poolLock]); +#endif } } +- (void) _lockAutoreleasePool +{ + [self setPoolLock:[self poolLock] + 1]; +} +- (void) _unlockAutoreleasePool +{ + [self setPoolLock:[self poolLock] - 1]; +} #ifdef TK_MAC_DEBUG_NOTIFICATIONS - (void) _postedNotification: (NSNotification *) notification { @@ -104,7 +122,7 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt { _eventInterp = interp; _mainPool = [NSAutoreleasePool new]; - [NSApp setPoolProtected:NO]; + [NSApp setPoolLock:0]; _defaultMainMenu = nil; [self _setupMenus]; [self setDelegate:self]; diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c index 151b4f2..958f960 100644 --- a/macosx/tkMacOSXKeyEvent.c +++ b/macosx/tkMacOSXKeyEvent.c @@ -15,6 +15,7 @@ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" +#include "tkMacOSXConstants.h" /* #ifdef TK_MAC_DEBUG diff --git a/macosx/tkMacOSXKeyboard.c b/macosx/tkMacOSXKeyboard.c index 7ac087d..bbbbf96 100644 --- a/macosx/tkMacOSXKeyboard.c +++ b/macosx/tkMacOSXKeyboard.c @@ -13,7 +13,7 @@ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" - +#include "tkMacOSXConstants.h" /* * A couple of simple definitions to make code a bit more self-explaining. * diff --git a/macosx/tkMacOSXMenu.c b/macosx/tkMacOSXMenu.c index c7e3a78..d21cd11 100644 --- a/macosx/tkMacOSXMenu.c +++ b/macosx/tkMacOSXMenu.c @@ -19,6 +19,7 @@ #include "tkFont.h" #include "tkMacOSXWm.h" #include "tkMacOSXDebug.h" +#include "tkMacOSXConstants.h" /* #ifdef TK_MAC_DEBUG diff --git a/macosx/tkMacOSXMenus.c b/macosx/tkMacOSXMenus.c index 68b2c00..f8f00a6 100644 --- a/macosx/tkMacOSXMenus.c +++ b/macosx/tkMacOSXMenus.c @@ -13,6 +13,7 @@ #include "tkMacOSXPrivate.h" #include "tkMenu.h" +#include "tkMacOSXConstants.h" static void GenerateEditEvent(const char *name); static Tcl_Obj * GetWidgetDemoPath(Tcl_Interp *interp); diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c index c4197f7..010023f 100644 --- a/macosx/tkMacOSXMouseEvent.c +++ b/macosx/tkMacOSXMouseEvent.c @@ -15,6 +15,7 @@ #include "tkMacOSXWm.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" +#include "tkMacOSXConstants.h" typedef struct { unsigned int state; diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c index f14e1b8..7bb0b0d 100644 --- a/macosx/tkMacOSXNotify.c +++ b/macosx/tkMacOSXNotify.c @@ -15,8 +15,8 @@ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" +#include "tkMacOSXConstants.h" #include <tclInt.h> -#include <pthread.h> #import <objc/objc-auto.h> /* This is not used for anything at the moment. */ @@ -140,7 +140,7 @@ Tk_MacOSXSetupTkNotifier(void) */ if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) { - if (!pthread_main_np()) { + if (![NSThread isMainThread]) { /* * Panic if main runloop is not on the main application thread. */ @@ -150,7 +150,7 @@ Tk_MacOSXSetupTkNotifier(void) } Tcl_CreateEventSource(TkMacOSXEventsSetupProc, TkMacOSXEventsCheckProc, - GetMainEventQueue()); + NULL); TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL); Tcl_SetServiceMode(TCL_SERVICE_ALL); TclMacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode); @@ -184,7 +184,7 @@ TkMacOSXNotifyExitHandler( Tcl_DeleteEventSource(TkMacOSXEventsSetupProc, TkMacOSXEventsCheckProc, - GetMainEventQueue()); + NULL); tsdPtr->initialized = 0; } @@ -216,9 +216,11 @@ TkMacOSXEventsSetupProc( int flags) { NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode]; + // fprintf(stderr, "SetupProc (%s)", [runloopMode UTF8String]); /* runloopMode will be nil if we are in the Tcl event loop. */ if (flags & TCL_WINDOW_EVENTS && !runloopMode) { static const Tcl_Time zeroBlockTime = { 0, 0 }; + [NSApp _resetAutoreleasePool]; /* Call this with dequeue=NO -- just checking if the queue is empty. */ NSEvent *currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] @@ -259,26 +261,15 @@ TkMacOSXEventsCheckProc( /* runloopMode will be nil if we are in the Tcl event loop. */ if (flags & TCL_WINDOW_EVENTS && !runloopMode) { NSEvent *currentEvent = nil; - NSEvent *testEvent = nil; NSModalSession modalSession; - + /* It is possible for the SetupProc to be called before this function + * returns. This happens, for example, when we process an event which + * opens a modal windows. To prevent premature release of our + * application-wide autorelease pool, we must lock it here. + */ + [NSApp _lockAutoreleasePool]; do { - [NSApp _resetAutoreleasePool]; modalSession = TkMacOSXGetModalSession(); - testEvent = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantPast] - inMode:GetRunLoopMode(modalSession) - dequeue:NO]; - /* We must not steal any events during LiveResize. */ -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 - if (testEvent && [[testEvent window] inLiveResize]) { - break; - } -#else - if (testEvent && [[[testEvent window] contentView] inLiveResize]) { - break; - } -#endif currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:GetRunLoopMode(modalSession) @@ -303,6 +294,8 @@ TkMacOSXEventsCheckProc( break; } } while (1); + /* Now we can unlock the pool. */ + [NSApp _unlockAutoreleasePool]; } } diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h index 65d60ce..6248c5a 100644 --- a/macosx/tkMacOSXPrivate.h +++ b/macosx/tkMacOSXPrivate.h @@ -278,14 +278,17 @@ VISIBILITY_HIDDEN NSAutoreleasePool *_mainPool; #ifdef __i386__ /* The Objective C runtime used on i386 requires this. */ - BOOL _poolProtected; + int _poolLock; #endif } -@property BOOL poolProtected; +@property BOOL poolLock; + @end @interface TKApplication(TKInit) - (NSString *)tkFrameworkImagePath:(NSString*)image; - (void)_resetAutoreleasePool; +- (void)_lockAutoreleasePool; +- (void)_unlockAutoreleasePool; @end @interface TKApplication(TKEvent) - (NSEvent *)tkProcessEvent:(NSEvent *)theEvent; diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c index 4672586..df1b138 100644 --- a/macosx/tkMacOSXWindowEvent.c +++ b/macosx/tkMacOSXWindowEvent.c @@ -17,6 +17,7 @@ #include "tkMacOSXWm.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" +#include "tkMacOSXConstants.h" /* #ifdef TK_MAC_DEBUG @@ -858,7 +859,7 @@ ConfigureRestrictProc( * Since it calls Tcl_DoOneEvent, we need to make sure we * don't clobber the AutoreleasePool set up by the caller. */ - [NSApp setPoolProtected:YES]; + [NSApp _lockAutoreleasePool]; /* * Try to prevent flickers and flashes. @@ -889,7 +890,7 @@ ConfigureRestrictProc( [w enableFlushWindow]; [w flushWindowIfNeeded]; NSEnableScreenUpdates(); - [NSApp setPoolProtected:NO]; + [NSApp _unlockAutoreleasePool]; } } diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index 75473bf..63ec362 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -20,6 +20,7 @@ #include "tkMacOSXWm.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" +#include "tkMacOSXConstants.h" #define DEBUG_ZOMBIES 0 @@ -56,6 +57,8 @@ /*Objects for use in setting background color and opacity of window.*/ NSColor *colorName = NULL; BOOL opaqueTag = FALSE; +extern CGImageRef CreateCGImageWithXImage( + XImage *image); static const struct { const UInt64 validAttrs, defaultAttrs, forceOnAttrs, forceOffAttrs; @@ -232,9 +235,28 @@ static int windowHashInit = false; pointrect.size.height = 0; return [self convertRectFromScreen:pointrect].origin; } -@end #endif +/*Override automatic fullscreen button on 10.13 because system fullscreen API +confuses Tk window geometry. +*/ +#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_12 +- (void)toggleFullScreen:(id)sender +{ + TkWindow *winPtr = TkMacOSXGetTkWindow(self); + Tk_Window win_Ptr=(Tk_Window) winPtr; + Tcl_Interp *interp = Tk_Interp(win_Ptr); + if ([self isZoomed]) { + TkMacOSXZoomToplevel(self, inZoomIn); + } else { + TkMacOSXZoomToplevel(self, inZoomOut); + } +} + +#endif +@end + + #pragma mark - @@ -5092,8 +5114,8 @@ TkMacOSXGetTkWindow( * * TkMacOSXIsWindowZoomed -- * - * Ask Carbon if the given window is in the zoomed out state. Because - * dragging & growing a window can change the Carbon zoom state, we + * Ask Cocoa if the given window is in the zoomed out state. Because + * dragging & growing a window can change the Cocoa zoom state, we * cannot rely on wmInfoPtr->hints.initial_state for this information. * * Results: @@ -5111,6 +5133,7 @@ TkMacOSXIsWindowZoomed( { return [TkMacOSXDrawableWindow(winPtr->window) isZoomed]; } + /* *---------------------------------------------------------------------- @@ -5153,12 +5176,13 @@ TkMacOSXZoomToplevel( * Do nothing if already in desired zoom state. */ - if (![window isZoomed] == (zoomPart == inZoomIn)) { + if ((![window isZoomed] == (zoomPart == inZoomIn))) { return false; } - [window zoom:NSApp]; - wmPtr->hints.initial_state = - (zoomPart == inZoomIn ? NormalState : ZoomState); + [window zoom:NSApp]; + + wmPtr->hints.initial_state = + (zoomPart == inZoomIn ? NormalState : ZoomState); return true; } @@ -6501,6 +6525,7 @@ TkMacOSXMakeFullscreen( result = TCL_ERROR; wmPtr->flags &= ~WM_FULLSCREEN; } else { + Tk_UnmapWindow((Tk_Window) winPtr); NSRect bounds = [window contentRectForFrameRect:[window frame]]; NSRect screenBounds = NSMakeRect(0, 0, screenWidth, screenHeight); @@ -6532,6 +6557,7 @@ TkMacOSXMakeFullscreen( [window setStyleMask: NSBorderlessWindowMask]; [NSApp setPresentationOptions: NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar]; + Tk_MapWindow((Tk_Window) winPtr); #endif /*TK_GOT_AT_LEAST_SNOW_LEOPARD*/ } else { wmPtr->flags &= ~WM_FULLSCREEN; @@ -6543,6 +6569,7 @@ TkMacOSXMakeFullscreen( } if (wasFullscreen && !(wmPtr->flags & WM_FULLSCREEN)) { + Tk_UnmapWindow((Tk_Window) winPtr); UInt64 oldAttributes = wmPtr->attributes; NSRect bounds = NSMakeRect(wmPtr->configX, tkMacOSXZeroScreenHeight - (wmPtr->configY + wmPtr->yInParent + wmPtr->configHeight), @@ -6556,6 +6583,7 @@ TkMacOSXMakeFullscreen( wmPtr->flags |= WM_SYNC_PENDING; [window setFrame:[window frameRectForContentRect:bounds] display:YES]; wmPtr->flags &= ~WM_SYNC_PENDING; + Tk_MapWindow((Tk_Window) winPtr); } return result; } diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c index 004ac1b..00940b5 100644 --- a/macosx/tkMacOSXXStubs.c +++ b/macosx/tkMacOSXXStubs.c @@ -681,6 +681,14 @@ XForceScreenSaver( display->request++; } +void +Tk_FreeXId( + Display *display, + XID xid) +{ + /* no-op function needed for stubs implementation. */ +} + int XSync( Display *display, @@ -882,7 +890,6 @@ XGetImage( int bitmap_pad = 0; int bytes_per_row = 4*width; int size; - MacDrawable *macDraw = (MacDrawable *) d; // Where is this variable used? May it be removed? int scalefactor = 1; #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 NSWindow *win = TkMacOSXDrawableWindow(d); @@ -1361,7 +1368,7 @@ void Tk_ResetUserInactiveTime( Display *dpy) { - IOGPoint loc; + IOGPoint loc = {0, 0}; kern_return_t kr; NXEvent nullEvent = {NX_NULLEVENT, {0, 0}, 0, -1, 0}; enum { kNULLEventPostThrottle = 10 }; |