diff options
author | Kevin Walzer <kw@codebykevin.com> | 2015-02-19 02:27:03 (GMT) |
---|---|---|
committer | Kevin Walzer <kw@codebykevin.com> | 2015-02-19 02:27:03 (GMT) |
commit | 677891bbd4da362beec2afb9f93af915600182dd (patch) | |
tree | 870dad095fffba59e3e26a3858c2e74e1d95a0a7 | |
parent | 5ed292ea4607b62a48f55c5a6be3ffa103971664 (diff) | |
download | tk-677891bbd4da362beec2afb9f93af915600182dd.zip tk-677891bbd4da362beec2afb9f93af915600182dd.tar.gz tk-677891bbd4da362beec2afb9f93af915600182dd.tar.bz2 |
Restore live resize to Cocoa with reduced flickering; addresses most serious issue of Cocoa drawing while preserving user expectations for display during window resize; thanks to Marc Culler for extensive patch
-rw-r--r-- | macosx/tkMacOSXDraw.c | 18 | ||||
-rw-r--r-- | macosx/tkMacOSXWindowEvent.c | 81 |
2 files changed, 40 insertions, 59 deletions
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index 2f65517..fa99b14 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -1510,14 +1510,6 @@ TkScrollWindow( /* Scroll the rectangle. */ [view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)]; - - /* Redisplay the scrolled area; hide to reduce flicker after removal of private API calls. */ - [view setHidden:YES]; - [view displayRect:scrollDst]; - [view setHidden:NO]; - - - } } @@ -1862,9 +1854,9 @@ TkpClipDrawableToRect( macDraw->drawRgn = NULL; } if (width >= 0 && height >= 0) { - CGRect drawRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff, + CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff, width, height); - HIShapeRef drawRgn = HIShapeCreateWithRect(&drawRect); + HIShapeRef drawRgn = HIShapeCreateWithRect(&clipRect); if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) { TkMacOSXUpdateClipRgn(macDraw->winPtr); @@ -1877,9 +1869,9 @@ TkpClipDrawableToRect( macDraw->drawRgn = drawRgn; } if (view && view != [NSView focusView] && [view lockFocusIfCanDraw]) { - drawRect.origin.y = [view bounds].size.height - - (drawRect.origin.y + drawRect.size.height); - NSRectClip(NSRectFromCGRect(drawRect)); + clipRect.origin.y = [view bounds].size.height - + (clipRect.origin.y + clipRect.size.height); + NSRectClip(NSRectFromCGRect(clipRect)); macDraw->flags |= TK_FOCUSED_VIEW; } } else { diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c index 5556464..5d89105 100644 --- a/macosx/tkMacOSXWindowEvent.c +++ b/macosx/tkMacOSXWindowEvent.c @@ -6,6 +6,8 @@ * * Copyright 2001-2009, Apple Inc. * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net> + * Copyright (c) 2015 Kevin Walzer/WordTech Communications LLC. + * Copyright (c) 2015 Marc Culler. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -760,19 +762,29 @@ Tk_MacOSXIsAppInFront(void) #import <ApplicationServices/ApplicationServices.h> /* - * Custom content view for Tk NSWindows, containing standard NSView subviews. - * The goal is to emulate X11-style drawing in response to Expose events: - * during the normal AppKit drawing cycle, we supress drawing of all subviews - * and instead send Expose events about the subviews that would be redrawn. + * Custom content view for use in Tk NSWindows. + * + * Since Tk handles all drawing of widgets, we only use the AppKit event loop + * as a source of input events. To do this, we overload the NSView drawRect + * method with a method which generates Expose events for Tk but does no + * drawing. The redrawing operations are then done when Tk processes these + * events. + * + * Earlier versions of Mac Tk used subclasses of NSView, e.g. NSButton, as the + * basis for Tk widgets. These would then appear as subviews of the + * TKContentView. To prevent the AppKit from redrawing and corrupting the Tk + * Widgets it was necessary to use Apple private API calls. In order to avoid + * using private API calls, the NSView-based widgets have been replaced with + * normal Tk widgets which draw themselves as native widgets by using the + * HITheme API. + * */ @interface TKContentView(TKWindowEvent) - (void) drawRect: (NSRect) rect; - (void) generateExposeEvents: (HIMutableShapeRef) shape; -- (BOOL) preservesContentDuringLiveResize; -- (void) viewWillStartLiveResize; - (void) viewDidEndLiveResize; -- (void) viewWillDraw; +- (void) tkToolbarButton: (id) sender; - (BOOL) isOpaque; - (BOOL) wantsDefaultClipping; - (BOOL) acceptsFirstResponder; @@ -793,12 +805,10 @@ ExposeRestrictProc( ? TK_PROCESS_EVENT : TK_DEFER_EVENT); } - @implementation TKContentView(TKWindowEvent) - (void) drawRect: (NSRect) rect { - const NSRect *rectsBeingDrawn; NSInteger rectsBeingDrawnCount; @@ -811,7 +821,6 @@ ExposeRestrictProc( NSCompositeSourceOver); #endif - CGFloat height = [self bounds].size.height; HIMutableShapeRef drawShape = HIShapeCreateMutable(); @@ -831,37 +840,18 @@ ExposeRestrictProc( } CFRelease(drawShape); - -} - - -/*Provide more fine-grained control over resizing of content to reduce flicker after removal of private API's.*/ - --(void) viewWillDraw -{ - [super viewWillDraw]; -} - -- (BOOL) preservesContentDuringLiveResize -{ - return NO; -} - -- (void)viewWillStartLiveResize -{ - [super viewWillStartLiveResize]; - [self setNeedsDisplay:NO]; - [self setHidden:YES]; } +/* + * As insurance against bugs that might cause layout glitches during a live + * resize, we redraw the window at the end of the resize operation. + */ - (void)viewDidEndLiveResize { - - [self setHidden:NO]; - [self setNeedsDisplay:YES]; - [super setNeedsDisplay:YES]; - [super viewDidEndLiveResize]; + NSRect bounds = NSRectFromCGRect([self bounds]); + HIShapeRef shape = HIShapeCreateWithRect(&bounds); + [self generateExposeEvents: shape]; } @@ -884,15 +874,16 @@ ExposeRestrictProc( ![[NSRunLoop currentRunLoop] currentMode] && Tcl_GetServiceMode() != TCL_SERVICE_NONE) { /* - * Ensure there are no pending idle-time redraws that could prevent the - * just posted Expose events from generating new redraws. + * Ensure there are no pending idle-time redraws that could + * prevent the just posted Expose events from generating + * new redraws. */ while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {} /* - * For smoother drawing, process Expose events and resulting redraws - * immediately instead of at idle time. + * For smoother drawing, process Expose events and resulting + * redraws immediately instead of at idle time. */ ClientData oldArg; @@ -909,7 +900,10 @@ ExposeRestrictProc( } -/*This is no-op on 10.7 and up because Apple has removed this widget, but leaving here for backwards compatibility.*/ +/* + * This is no-op on 10.7 and up because Apple has removed this widget, + * but we are leaving it here for backwards compatibility. + */ - (void) tkToolbarButton: (id) sender { #ifdef TK_MAC_DEBUG_EVENTS @@ -937,11 +931,6 @@ ExposeRestrictProc( Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); } -- (void) setFrameSize: (NSSize) newSize -{ - [super setFrameSize:newSize]; -} - - (BOOL) isOpaque { NSWindow *w = [self window]; |