From e82200cb0ca4389ea75f8ae0c2096358a985c14e Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Mon, 7 Dec 2015 02:04:45 +0000 Subject: Fix for zombie windows on El Capitan/OS X 10.11; thanks to Marc Culler for patch --- macosx/tkMacOSXDialog.c | 2 +- macosx/tkMacOSXDraw.c | 16 ++++++++++++---- macosx/tkMacOSXInit.c | 6 +----- macosx/tkMacOSXNotify.c | 2 ++ macosx/tkMacOSXSubwindows.c | 3 ++- macosx/tkMacOSXWm.c | 46 ++++++++++++++++++++++++++++++++++++++++----- macosx/tkMacOSXXStubs.c | 6 +++--- 7 files changed, 62 insertions(+), 19 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 9cd9cf3..eebff3c 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -1158,7 +1158,7 @@ Tk_MessageBoxObjCmd( [NSApp tkAlertDidEnd:alert returnCode:modalReturnCode contextInfo:callbackInfo]; } - result = (modalReturnCode < 1) ? TCL_OK : TCL_ERROR; + result = (modalReturnCode >= NSAlertFirstButtonReturn) ? TCL_OK : TCL_ERROR; end: [alert release]; return result; diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index 45a07c7..b3c2499 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -138,6 +138,7 @@ BitmapRepFromDrawableRect( CGImageRef cg_image=NULL, sub_cg_image=NULL; NSBitmapImageRep *bitmap_rep=NULL; NSView *view=NULL; + NSAutoreleasePool *pool = [NSAutoreleasePool new]; if ( mac_drawable->flags & TK_IS_PIXMAP ) { /* This means that the MacDrawable is functioning as a Tk Pixmap, so its view @@ -174,6 +175,7 @@ BitmapRepFromDrawableRect( } else { TkMacOSXDbgMsg("Invalid source drawable"); } + [pool drain]; return bitmap_rep; } @@ -1568,7 +1570,6 @@ TkScrollWindow( /* Belt and suspenders: make the AppKit request a redraw when it gets control again. */ - [view setNeedsDisplay:YES]; } } else { dmgRgn = HIShapeCreateEmpty(); @@ -1635,6 +1636,7 @@ TkMacOSXSetupDrawingContext( int dontDraw = 0, isWin = 0; TkMacOSXDrawingContext dc = {}; CGRect clipBounds; + NSAutoreleasePool *pool = [NSAutoreleasePool new]; dc.clipRgn = TkMacOSXGetClipRgn(d); if (!dontDraw) { @@ -1765,6 +1767,7 @@ end: dc.clipRgn = NULL; } *dcPtr = dc; + [pool drain]; return !dontDraw; } @@ -1788,6 +1791,7 @@ void TkMacOSXRestoreDrawingContext( TkMacOSXDrawingContext *dcPtr) { + NSAutoreleasePool *pool = [NSAutoreleasePool new]; if (dcPtr->context) { CGContextSynchronize(dcPtr->context); [[dcPtr->view window] setViewsNeedDisplay:YES]; @@ -1804,6 +1808,7 @@ TkMacOSXRestoreDrawingContext( #ifdef TK_MAC_DEBUG bzero(dcPtr, sizeof(TkMacOSXDrawingContext)); #endif /* TK_MAC_DEBUG */ + [pool drain]; } /* @@ -1829,7 +1834,8 @@ TkMacOSXGetClipRgn( { MacDrawable *macDraw = (MacDrawable *) drawable; HIShapeRef clipRgn = NULL; - + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) { TkMacOSXUpdateClipRgn(macDraw->winPtr); #ifdef TK_MAC_DEBUG_DRAWING @@ -1854,7 +1860,7 @@ TkMacOSXGetClipRgn( } else if (macDraw->visRgn) { clipRgn = HIShapeCreateCopy(macDraw->visRgn); } - + [pool drain]; return clipRgn; } @@ -1907,7 +1913,8 @@ TkpClipDrawableToRect( { MacDrawable *macDraw = (MacDrawable *) d; NSView *view = TkMacOSXDrawableView(macDraw); - + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + if (macDraw->drawRgn) { CFRelease(macDraw->drawRgn); macDraw->drawRgn = NULL; @@ -1940,6 +1947,7 @@ TkpClipDrawableToRect( macDraw->flags &= ~TK_FOCUSED_VIEW; } } + [pool drain]; } /* diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index 6ba726d..8e5479e 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -242,10 +242,7 @@ TkpInit( } #endif - static NSAutoreleasePool *pool = nil; - if (!pool) { - pool = [NSAutoreleasePool new]; - } + NSAutoreleasePool *pool = [NSAutoreleasePool new]; [[NSUserDefaults standardUserDefaults] registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], @@ -316,7 +313,6 @@ TkpInit( TkMacOSXUseAntialiasedText(interp, -1); TkMacOSXInitCGDrawing(interp, TRUE, 0); [pool drain]; - pool = [NSAutoreleasePool new]; /* * FIXME: Close stdin & stdout for remote debugging otherwise we will diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c index 4cfb5a9..c703297 100644 --- a/macosx/tkMacOSXNotify.c +++ b/macosx/tkMacOSXNotify.c @@ -215,6 +215,7 @@ TkMacOSXEventsSetupProc( if (flags & TCL_WINDOW_EVENTS && ![[NSRunLoop currentRunLoop] currentMode]) { static Tcl_Time zeroBlockTime = { 0, 0 }; + NSAutoreleasePool *pool = [NSAutoreleasePool new]; /* Call this with dequeue=NO -- just checking if the queue is empty. */ NSEvent *currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] @@ -223,6 +224,7 @@ TkMacOSXEventsSetupProc( if (currentEvent && currentEvent.type > 0) { Tcl_SetMaxBlockTime(&zeroBlockTime); } + [pool drain]; } } diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index a601c50..b985e5d 100644 --- a/macosx/tkMacOSXSubwindows.c +++ b/macosx/tkMacOSXSubwindows.c @@ -318,7 +318,7 @@ XResizeWindow( unsigned int height) { MacDrawable *macWin = (MacDrawable *) window; - + NSAutoreleasePool *pool= [NSAutoreleasePool new]; display->request++; if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { NSWindow *w = macWin->winPtr->wmInfoPtr->window; @@ -333,6 +333,7 @@ XResizeWindow( } else { MoveResizeWindow(macWin); } + [pool drain]; } /* diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index 69d3cfb..4ce2206 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -390,6 +390,7 @@ static void RemapWindows(TkWindow *winPtr, @end @implementation TKWindow(TKWm) + - (BOOL) canBecomeKeyWindow { TkWindow *winPtr = TkMacOSXGetTkWindow(self); @@ -399,16 +400,38 @@ static void RemapWindows(TkWindow *winPtr, kWindowNoActivatesAttribute)) ? NO : YES; } +#if DEBUG_ZOMBIES - (id) retain { -#if DEBUG_ZOMBIES + id result = [super retain]; const char *title = [[self title] UTF8String]; - if (title != NULL) { - printf("Retaining %s with count %lu\n", title, [self retainCount]); + if (title == nil) { + title = "unnamed window"; } -#endif - return [super retain]; + printf("Retained <%s>. Count is: %lu\n", title, [self retainCount]); + return result; +} + +- (id) autorelease +{ + id result = [super autorelease]; + const char *title = [[self title] UTF8String]; + if (title == nil) { + title = "unnamed window"; + } + printf("Autoreleased <%s>. Count is %lu\n", title, [self retainCount]); + return result; +} + +- (oneway void) release { + const char *title = [[self title] UTF8String]; + if (title == nil) { + title = "unnamed window"; + } + printf("Releasing <%s>. Count is %lu\n", title, [self retainCount]); + [super release]; } +#endif @end #pragma mark - @@ -847,6 +870,15 @@ TkWmDeadWindow( if (winPtr->window) { ((MacDrawable *) winPtr->window)->view = nil; } +#if DEBUG_ZOMBIES + { + const char *title = [[window title] UTF8String]; + if (title == nil) { + title = "unnamed window"; + } + printf("Closing <%s>. Count is: %lu\n", title, [window retainCount]); + } +#endif [window release]; wmPtr->window = NULL; /* Activate the highest window left on the screen. */ @@ -5447,6 +5479,8 @@ TkMacOSXMakeRealWindowExist( */ } + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + WindowClass macClass = wmPtr->macClass; wmPtr->attributes &= (tkAlwaysValidAttributes | macClassAttrs[macClass].validAttrs); @@ -5530,6 +5564,8 @@ TkMacOSXMakeRealWindowExist( TkMacOSXRegisterOffScreenWindow((Window) macWin, window); macWin->flags |= TK_HOST_EXISTS; + + [pool drain]; } /* diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c index f8adf1e..4bdd1c4 100644 --- a/macosx/tkMacOSXXStubs.c +++ b/macosx/tkMacOSXXStubs.c @@ -142,7 +142,6 @@ TkpOpenDisplay( static NSRect maxBounds = {{0, 0}, {0, 0}}; static char vendor[25] = ""; NSArray *cgVers; - NSAutoreleasePool *pool; if (gMacDisplay != NULL) { if (strcmp(gMacDisplay->display->display_name, display_name) == 0) { @@ -152,6 +151,8 @@ TkpOpenDisplay( } } + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + display = (Display *) ckalloc(sizeof(Display)); screen = (Screen *) ckalloc(sizeof(Screen)); bzero(display, sizeof(Display)); @@ -166,7 +167,6 @@ TkpOpenDisplay( display->default_screen = 0; display->display_name = (char *) macScreenName; - pool = [NSAutoreleasePool new]; cgVers = [[[NSBundle bundleWithIdentifier:@"com.apple.CoreGraphics"] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] componentsSeparatedByString:@"."]; @@ -184,7 +184,7 @@ TkpOpenDisplay( { int major, minor, patch; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 10100 Gestalt(gestaltSystemVersionMajor, (SInt32*)&major); Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor); Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch); -- cgit v0.12