summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Walzer <kw@codebykevin.com>2014-12-24 04:43:40 (GMT)
committerKevin Walzer <kw@codebykevin.com>2014-12-24 04:43:40 (GMT)
commit6137cff44fac896616e033bcba2aa90cd3d4adf5 (patch)
treea2529d63c5b9744d594aeae79995ce53a48e0d29
parentc72a9f168448e8f6b17aa805d5308b4934cfa4d1 (diff)
downloadtk-6137cff44fac896616e033bcba2aa90cd3d4adf5.zip
tk-6137cff44fac896616e033bcba2aa90cd3d4adf5.tar.gz
tk-6137cff44fac896616e033bcba2aa90cd3d4adf5.tar.bz2
All on Tk/Cocoa: Improve view performance during resizing; implement custom drawing of scroller to remove flickering and ghosted appearance during window operations; reduce flickering of menubutton during resizing, but do not completely eliminate ghosted rendering when widget is unmapped
-rw-r--r--macosx/tkMacOSXButton.c2
-rw-r--r--macosx/tkMacOSXMenubutton.c2
-rw-r--r--macosx/tkMacOSXScrlbr.c117
-rw-r--r--macosx/tkMacOSXWindowEvent.c46
-rw-r--r--macosx/ttkMacOSXTheme.c10
5 files changed, 119 insertions, 58 deletions
diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c
index 720e40d..627565a 100644
--- a/macosx/tkMacOSXButton.c
+++ b/macosx/tkMacOSXButton.c
@@ -38,7 +38,7 @@ static NSRect TkMacOSXGetButtonFrame(TkButton *butPtr);
*/
@interface TkNSButton: NSButton
-
+- (void)drawRect:(NSRect)dirtyRect;
@end
@implementation TkNSButton
diff --git a/macosx/tkMacOSXMenubutton.c b/macosx/tkMacOSXMenubutton.c
index df42763..02a7a38 100644
--- a/macosx/tkMacOSXMenubutton.c
+++ b/macosx/tkMacOSXMenubutton.c
@@ -15,7 +15,7 @@
#include "tkMacOSXPrivate.h"
#include "tkMenubutton.h"
#include "tkMacOSXFont.h"
-#include "tkMacOSXDebug.h"
+#include "tkMacOSXDebug.h"
/*
#ifdef TK_MAC_DEBUG
diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c
index 405558b..bd05df8 100644
--- a/macosx/tkMacOSXScrlbr.c
+++ b/macosx/tkMacOSXScrlbr.c
@@ -7,7 +7,8 @@
* Copyright (c) 1996 by Sun Microsystems, Inc.
* Copyright 2001-2009, Apple Inc.
* Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
- *
+ * Copyright (c) 2014 Marc Culler.
+ * Copyright (c) 2014 Kevin Walzer/WordTech Commununications LLC.
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
@@ -21,6 +22,7 @@
#endif
*/
+
NSRect TkMacOSXGetScrollFrame(TkScrollbar *scrlPtr);
/*
@@ -31,56 +33,103 @@ NSRect TkMacOSXGetScrollFrame(TkScrollbar *scrlPtr);
* aware of the state of its Tk parent. This subclass overrides the drawRect
* method so that it will not draw itself if the widget is completely outside
* of its container.
+ *
+ * Custom drawing of the knob seems to work around the flickering visible after * private API's were removed. Based on technique outlined at
+ * http://stackoverflow.com/questions/1604682/nsscroller-
+ * graphical-glitches-lag. Only supported on 10.7 and above.
*/
@interface TkNSScroller: NSScroller
-(void) drawRect:(NSRect)dirtyRect;
-
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+-(BOOL) isHorizontal;
+-(void) drawKnob;
+- (void)drawArrow:(NSScrollerArrow)arrow highlightPart:(int)flag;
+- (void)drawKnobSlotInRect:(NSRect)rect highlight:(BOOL)highlight;
+#endif
@end
@implementation TkNSScroller
- - (void)drawRect:(NSRect)dirtyRect
- {
- NSInteger tag = [self tag];
- if ( tag != -1) {
- TkScrollbar *scrollPtr = (TkScrollbar *)tag;
- MacDrawable* macWin = (MacDrawable *)scrollPtr;
- Tk_Window tkwin = scrollPtr->tkwin;
- NSRect Tkframe = TkMacOSXGetScrollFrame(scrollPtr);
- /* Do not draw if the widget is misplaced or unmapped. */
- if ( NSIsEmptyRect(Tkframe) ||
- ! macWin->winPtr->flags & TK_MAPPED ||
- ! NSEqualRects(Tkframe, [self frame])
- ) {
+
+- (void)drawRect:(NSRect)dirtyRect
+{
+ NSInteger tag = [self tag];
+ if ( tag != -1) {
+ TkScrollbar *scrollPtr = (TkScrollbar *)tag;
+ MacDrawable* macWin = (MacDrawable *)scrollPtr;
+ Tk_Window tkwin = scrollPtr->tkwin;
+ NSRect Tkframe = TkMacOSXGetScrollFrame(scrollPtr);
+ /* Do not draw if the widget is misplaced or unmapped. */
+ if ( NSIsEmptyRect(Tkframe) ||
+ ! macWin->winPtr->flags & TK_MAPPED ||
+ ! NSEqualRects(Tkframe, [self frame])
+ ) {
+ return;
+ }
+
+ /*
+ * Do not draw if the widget is completely outside of its parent.
+ */
+ if (tkwin) {
+ int parent_height = Tk_Height(Tk_Parent(tkwin));
+ int widget_height = Tk_Height(tkwin);
+ int y = Tk_Y(tkwin);
+ if ( y > parent_height || y + widget_height < 0 ) {
return;
}
- /*
- * Do not draw if the widget is completely outside of its parent.
- */
- if (tkwin) {
- int parent_height = Tk_Height(Tk_Parent(tkwin));
- int widget_height = Tk_Height(tkwin);
- int y = Tk_Y(tkwin);
- if ( y > parent_height || y + widget_height < 0 ) {
- return;
- }
-
- int parent_width = Tk_Width(Tk_Parent(tkwin));
- int widget_width = Tk_Width(tkwin);
- int x = Tk_X(tkwin);
- if (x > parent_width || x + widget_width < 0) {
- return;
- }
+ int parent_width = Tk_Width(Tk_Parent(tkwin));
+ int widget_width = Tk_Width(tkwin);
+ int x = Tk_X(tkwin);
+ if (x > parent_width || x + widget_width < 0) {
+ return;
}
}
- [super drawRect:dirtyRect];
}
+ [super drawRect:dirtyRect];
+}
-@end
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
+- (BOOL)isHorizontal {
+ NSRect bounds = [self bounds];
+ return NSWidth(bounds) < NSHeight (bounds);
+}
+- (void)drawKnob
+{
+ NSRect knobRect = [self rectForPart:NSScrollerKnob];
+
+ if ([self isHorizontal]) {
+ NSRect newRect = NSMakeRect(knobRect.origin.x, knobRect.origin.y, knobRect.size.width - 5, knobRect.size.height);
+ NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:newRect xRadius:7 yRadius:7];
+
+ [[NSColor lightGrayColor] set];
+ [path fill];
+ } else {
+ NSRect newRect = NSMakeRect(knobRect.origin.x, knobRect.origin.y, knobRect.size.width, knobRect.size.height - 5);
+ NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:newRect xRadius:7 yRadius:7];
+
+ [[NSColor lightGrayColor] set];
+ [path fill];
+ }
+
+}
+
+- (void)drawArrow:(NSScrollerArrow)arrow highlightPart:(int)flag
+{
+ // We don't want arrows
+}
+
+- (void)drawKnobSlotInRect:(NSRect)rect highlight:(BOOL)highlight
+{
+
+}
+#endif
+
+@end
+
/*
* Declaration of Mac specific scrollbar structure.
diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c
index 6546070..7207859 100644
--- a/macosx/tkMacOSXWindowEvent.c
+++ b/macosx/tkMacOSXWindowEvent.c
@@ -769,6 +769,8 @@ Tk_MacOSXIsAppInFront(void)
@interface TKContentView(TKWindowEvent)
- (void) drawRect: (NSRect) rect;
- (void) generateExposeEvents: (HIMutableShapeRef) shape;
+- (BOOL) preservesContentDuringLiveResize;
+- (void) viewWillStartLiveResize;
- (void) viewDidEndLiveResize;
- (void) viewWillDraw;
- (BOOL) isOpaque;
@@ -780,15 +782,6 @@ Tk_MacOSXIsAppInFront(void)
@implementation TKContentView
@end
-double drawTime;
-
-/*
- * Set a minimum time for drawing to render. With removal of private NSView API's, default drawing
- * is slower and less responsive. This number, which seems feasible after some experimentatation, skips
- * some drawing to avoid lag.
- */
-
-#define MAX_DYNAMIC_TIME .000000001
/*Restrict event processing to Expose events.*/
static Tk_RestrictAction
@@ -805,10 +798,12 @@ ExposeRestrictProc(
- (void) drawRect: (NSRect) rect
{
+
const NSRect *rectsBeingDrawn;
NSInteger rectsBeingDrawnCount;
[self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount];
+
#ifdef TK_MAC_DEBUG_DRAWING
TKLog(@"-[%@(%p) %s%@]", [self class], self, _cmd, NSStringFromRect(rect));
[[NSColor colorWithDeviceRed:0.0 green:1.0 blue:0.0 alpha:.1] setFill];
@@ -816,11 +811,7 @@ ExposeRestrictProc(
NSCompositeSourceOver);
#endif
- NSDate *beginTime=[NSDate date];
-
- /*Skip drawing during live resize if redraw is too slow.*/
- if([self inLiveResize] && drawTime>MAX_DYNAMIC_TIME) return;
-
+
CGFloat height = [self bounds].size.height;
HIMutableShapeRef drawShape = HIShapeCreateMutable();
@@ -841,24 +832,35 @@ ExposeRestrictProc(
}
CFRelease(drawShape);
- drawTime=-[beginTime timeIntervalSinceNow];
- [super setNeedsDisplayInRect:rect];
}
-/*At conclusion of resize event, send notification and set view for redraw if earlier drawing was skipped because of lagginess.*/
+
+/*Provide more fine-grained control over resizing of content to reduce flicker after removal of private API's.*/
+
+- (BOOL) preservesContentDuringLiveResize
+{
+ return YES;
+}
+
+- (void)viewWillStartLiveResize
+{
+ [super viewWillStartLiveResize];
+ [self setNeedsDisplay:NO];
+}
+
+
- (void)viewDidEndLiveResize
{
- if(drawTime>MAX_DYNAMIC_TIME) {
+
[self setNeedsDisplay:YES];
+ [super setNeedsDisplay:YES];
[super viewDidEndLiveResize];
- }
+
}
--(void) viewWillDraw {
- [self setNeedsDisplay:YES];
- }
+/*Core function of this class, generates expose events for redrawing.*/
- (void) generateExposeEvents: (HIMutableShapeRef) shape
{
diff --git a/macosx/ttkMacOSXTheme.c b/macosx/ttkMacOSXTheme.c
index a4abc7b..c5be354 100644
--- a/macosx/ttkMacOSXTheme.c
+++ b/macosx/ttkMacOSXTheme.c
@@ -528,6 +528,10 @@ static Ttk_ElementSpec ComboboxElementSpec = {
ComboboxElementDraw
};
+
+
+
+
/*----------------------------------------------------------------------
* +++ Spinbuttons.
*
@@ -600,6 +604,11 @@ static TrackElementData ScaleData = {
kThemeSlider, kThemeMetricHSliderHeight
};
+static TrackElementData ScrollData = {
+ kThemeScrollBarMedium
+};
+
+
typedef struct {
Tcl_Obj *fromObj; /* minimum value */
Tcl_Obj *toObj; /* maximum value */
@@ -661,6 +670,7 @@ static void TrackElementDraw(
info.trackInfo.slider.thumbDir = kThemeThumbPlain;
}
+
BEGIN_DRAWING(d)
ChkErr(HIThemeDrawTrack, &info, NULL, dc.context, HIOrientation);
END_DRAWING