summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--macosx/tkMacOSXDraw.c56
-rw-r--r--macosx/tkMacOSXFont.c2
-rw-r--r--macosx/tkMacOSXImage.c74
-rw-r--r--macosx/tkMacOSXNotify.c7
-rw-r--r--macosx/tkMacOSXPrivate.h2
-rw-r--r--macosx/tkMacOSXRegion.c2
-rw-r--r--macosx/tkMacOSXWindowEvent.c34
-rw-r--r--macosx/tkMacOSXWm.c9
-rw-r--r--tests/entry.test1
-rw-r--r--tests/font.test6
-rw-r--r--tests/scale.test2
-rw-r--r--tests/textWind.test28
-rw-r--r--tests/unixEmbed.test1
-rwxr-xr-xunix/configure2
-rw-r--r--unix/configure.in2
15 files changed, 151 insertions, 77 deletions
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index bf6a4a7..d5396eb 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -27,6 +27,7 @@
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_DRAWING
#define TK_MAC_DEBUG_IMAGE_DRAWING
+#define TK_MAC_DEBUG_CG
#endif
*/
@@ -1265,6 +1266,12 @@ TkMacOSXSetupDrawingContext(
Bool canDraw = true;
TKContentView *view = nil;
TkMacOSXDrawingContext dc = {};
+ CGFloat drawingHeight;
+
+#ifdef TK_MAC_DEBUG_CG
+ fprintf(stderr, "TkMacOSXSetupDrawingContext: %s\n",
+ macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
+#endif
/*
* If the drawable is not a pixmap, get the associated NSView.
@@ -1296,13 +1303,10 @@ TkMacOSXSetupDrawingContext(
*/
dc.context = TkMacOSXGetCGContextForDrawable(d);
- if (dc.context) {
- dc.portBounds = CGContextGetClipBoundingBox(dc.context);
- } else {
+ if (!dc.context) {
NSRect drawingBounds, currentBounds;
dc.view = view;
dc.context = GET_CGCONTEXT;
- dc.portBounds = NSRectToCGRect([view bounds]);
if (dc.clipRgn) {
CGRect clipBounds;
CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
@@ -1354,15 +1358,20 @@ TkMacOSXSetupDrawingContext(
* Finish configuring the drawing context.
*/
+ drawingHeight = view ? [view bounds].size.height :
+ CGContextGetClipBoundingBox(dc.context).size.height;
CGAffineTransform t = {
.a = 1, .b = 0,
.c = 0, .d = -1,
.tx = 0,
- .ty = dc.portBounds.size.height
+ .ty = drawingHeight
};
- dc.portBounds.origin.x += macDraw->xOff;
- dc.portBounds.origin.y += macDraw->yOff;
+#ifdef TK_MAC_DEBUG_CG
+ fprintf(stderr, "TkMacOSXSetupDrawingContext: pushing GState for %s\n",
+ macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
+#endif
+
CGContextSaveGState(dc.context);
CGContextSetTextDrawingMode(dc.context, kCGTextFill);
CGContextConcatCTM(dc.context, t);
@@ -1388,11 +1397,26 @@ TkMacOSXSetupDrawingContext(
*/
ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
+
+#ifdef TK_MAC_DEBUG_CG
+ fprintf(stderr, "Setting complex clip for %s to:\n",
+ macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None");
+ TkMacOSXPrintRectsInRegion(dc.clipRgn);
+#endif
+
CGContextEOClip(dc.context);
- }
- else {
+ } else {
CGRect r;
HIShapeGetBounds(dc.clipRgn, &r);
+
+#ifdef TK_MAC_DEBUG_CG
+ fprintf(stderr, "Current clip BBox is %s\n",
+ NSStringFromRect(CGContextGetClipBoundingBox(GET_CGCONTEXT)).UTF8String);
+ fprintf(stderr, "Setting clip for %s to rect %s:\n",
+ macDraw->winPtr ? Tk_PathName(macDraw->winPtr) : "None",
+ NSStringFromRect(r).UTF8String);
+#endif
+
CGContextClipToRect(dc.context, r);
}
}
@@ -1413,8 +1437,8 @@ TkMacOSXSetupDrawingContext(
TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
if (view) {
- CGContextSetPatternPhase(dc.context,
- CGSizeMake(dc.portBounds.size.width, dc.portBounds.size.height));
+ CGSize size = NSSizeToCGSize([view bounds].size);
+ CGContextSetPatternPhase(dc.context, size);
}
if (gc->function != GXcopy) {
TkMacOSXDbgMsg("Logical functions other than GXcopy are "
@@ -1491,13 +1515,21 @@ TkMacOSXRestoreDrawingContext(
if (dcPtr->context) {
CGContextSynchronize(dcPtr->context);
CGContextRestoreGState(dcPtr->context);
+
+#ifdef TK_MAC_DEBUG_CG
+ fprintf(stderr, "TkMacOSXRestoreDrawingContext: popped GState\n");
+#endif
+
}
if (dcPtr->clipRgn) {
CFRelease(dcPtr->clipRgn);
+ dcPtr->clipRgn = NULL;
}
+
#ifdef TK_MAC_DEBUG
bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
-#endif /* TK_MAC_DEBUG */
+#endif
+
}
/*
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index feff3bf..d9c1c01 100644
--- a/macosx/tkMacOSXFont.c
+++ b/macosx/tkMacOSXFont.c
@@ -1219,7 +1219,7 @@ TkpDrawAngledCharsInContext(
(CFAttributedStringRef)attributedString);
textX += (CGFloat) macWin->xOff;
textY += (CGFloat) macWin->yOff;
- height = drawingContext.portBounds.size.height;
+ height = [drawingContext.view bounds].size.height;
textY = height - textY;
t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, height);
if (angle != 0.0) {
diff --git a/macosx/tkMacOSXImage.c b/macosx/tkMacOSXImage.c
index 69967af..6f55171 100644
--- a/macosx/tkMacOSXImage.c
+++ b/macosx/tkMacOSXImage.c
@@ -528,51 +528,43 @@ CreateCGImageFromDrawableRect(
{
MacDrawable *mac_drawable = (MacDrawable *)drawable;
CGContextRef cg_context = NULL;
+ CGRect image_rect = CGRectMake(x, y, width, height);
CGImageRef cg_image = NULL, result = NULL;
- NSBitmapImageRep *bitmapRep = nil;
- NSView *view = nil;
+ unsigned char *imageData = NULL;
if (mac_drawable->flags & TK_IS_PIXMAP) {
- /*
- * This MacDrawable is a bitmap, so its view is NULL.
- */
-
- CGRect image_rect = CGRectMake(x, y, width, height);
-
cg_context = TkMacOSXGetCGContextForDrawable(drawable);
- cg_image = CGBitmapContextCreateImage((CGContextRef) cg_context);
- if (cg_image) {
- result = CGImageCreateWithImageInRect(cg_image, image_rect);
- CGImageRelease(cg_image);
- }
- } else if (TkMacOSXGetNSViewForDrawable(mac_drawable) != nil) {
-
- /*
- * Convert Tk top-left to NSView bottom-left coordinates.
- */
-
- int view_height = [view bounds].size.height;
- NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
- view_height - height - y - mac_drawable->yOff,
- width, height);
-
- /*
- * Attempt to copy from the view to a bitmapImageRep. If the view does
- * not have a valid CGContext, doing this will silently corrupt memory
- * and make a big mess. So, in that case, we just return NULL.
- */
-
- if (view == [NSView focusView]) {
- bitmapRep = [view bitmapImageRepForCachingDisplayInRect: view_rect];
- [view cacheDisplayInRect:view_rect toBitmapImageRep:bitmapRep];
- result = [bitmapRep CGImage];
- CFRelease(bitmapRep);
- } else {
- TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap.");
- result = NULL;
+ if (cg_context) {
+ cg_image = CGBitmapContextCreateImage((CGContextRef) cg_context);
+ CFRelease(cg_context);
}
} else {
- TkMacOSXDbgMsg("Invalid source drawable");
+ NSView *view = TkMacOSXGetNSViewForDrawable(mac_drawable);
+ if (view == nil) {
+ TkMacOSXDbgMsg("Invalid source drawable");
+ return NULL;
+ }
+ NSSize size = view.frame.size;
+ NSUInteger width = size.width, height = size.height;
+ NSUInteger bytesPerPixel = 4,
+ bytesPerRow = bytesPerPixel * width,
+ bitsPerComponent = 8;
+ imageData = ckalloc(height * bytesPerRow);
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ cg_context = CGBitmapContextCreate(imageData, width, height,
+ bitsPerComponent, bytesPerRow, colorSpace,
+ kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
+ CFRelease(colorSpace);
+ [view.layer renderInContext:cg_context];
+ }
+ if (cg_context) {
+ cg_image = CGBitmapContextCreateImage(cg_context);
+ CGContextRelease(cg_context);
+ }
+ if (cg_image) {
+ result = CGImageCreateWithImageInRect(cg_image, image_rect);
+ CGImageRelease(cg_image);
}
+ ckfree(imageData);
return result;
}
@@ -676,11 +668,11 @@ XGetImage(
|| bytes_per_row < 4 * width
|| size != bytes_per_row * height) {
TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
- CFRelease(bitmapRep);
+ [bitmapRep release];
return NULL;
}
memcpy(bitmap, (char *)[bitmapRep bitmapData], size);
- CFRelease(bitmapRep);
+ [bitmapRep release];
/*
* When Apple extracts a bitmap from an NSView, it may be in either
diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c
index f32fa76..0438525 100644
--- a/macosx/tkMacOSXNotify.c
+++ b/macosx/tkMacOSXNotify.c
@@ -340,8 +340,9 @@ TkMacOSXNotifyExitHandler(
* for all views that need display before it returns. We call it with
* deQueue=NO so that it will not change anything on the AppKit event
* queue, because we only want the side effect that it runs drawRect. The
- * only time when any NSViews have the needsDisplay property set to YES
- * is during execution of this function.
+ * only times when any NSViews have the needsDisplay property set to YES
+ * are during execution of this function or in the addDirtyRect method
+ * of TKContentView.
*
* The reason for running this function as an idle task is to try to
* arrange that all widgets will be fully configured before they are
@@ -377,7 +378,7 @@ TkMacOSXDrawAllViews(
if (dirtyCount) {
continue;
}
- [view setNeedsDisplayInRect:[view tkDirtyRect]];
+ [[view layer] setNeedsDisplayInRect:[view tkDirtyRect]];
}
} else {
[window displayIfNeeded];
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index 0bd46c6..be2264f 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -27,6 +27,7 @@
#define TextStyle MacTextStyle
#import <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>
+#import <QuartzCore/QuartzCore.h>
#ifndef NO_CARBON_H
#import <Carbon/Carbon.h>
#endif
@@ -203,7 +204,6 @@ typedef struct TkMacOSXDrawingContext {
CGContextRef context;
NSView *view;
HIShapeRef clipRgn;
- CGRect portBounds;
} TkMacOSXDrawingContext;
/*
diff --git a/macosx/tkMacOSXRegion.c b/macosx/tkMacOSXRegion.c
index 3c168f1..fbb41cb 100644
--- a/macosx/tkMacOSXRegion.c
+++ b/macosx/tkMacOSXRegion.c
@@ -575,7 +575,7 @@ rectPrinter(
void *ref)
{
if (rect) {
- printf(" %s\n", NSStringFromRect(*rect).UTF8String);
+ fprintf(stderr, " %s\n", NSStringFromRect(*rect).UTF8String);
}
return noErr;
}
diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c
index 0075fb8..fe8a983 100644
--- a/macosx/tkMacOSXWindowEvent.c
+++ b/macosx/tkMacOSXWindowEvent.c
@@ -915,11 +915,45 @@ ConfigureRestrictProc(
@implementation TKContentView(TKWindowEvent)
+- (id)initWithFrame:(NSRect)frame
+{
+ self = [super initWithFrame:frame];
+ if (self) {
+ /*
+ * The layer must exist before we set wantsLayer to YES.
+ */
+
+ self.layer = [CALayer layer];
+ self.wantsLayer = YES;
+ self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
+ self.layer.contentsGravity = self.layer.contentsAreFlipped ?
+ kCAGravityTopLeft : kCAGravityBottomLeft;
+
+ /*
+ * Nothing gets drawn at all if the layer does not have a delegate.
+ * Currently, we do not implement any methods of the delegate, however.
+ */
+
+ self.layer.delegate = (id) self;
+ }
+ return self;
+}
+
+/*
+ * We will just use drawRect.
+ */
+
+- (BOOL) wantsUpdateLayer
+{
+ return NO;
+}
+
- (void) addTkDirtyRect: (NSRect) rect
{
_tkNeedsDisplay = YES;
_tkDirtyRect = NSUnionRect(_tkDirtyRect, rect);
[NSApp setNeedsToDraw:YES];
+ [self setNeedsDisplay:YES];
}
- (void) clearTkDirtyRect
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 4f073d8..77f7b09 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -5535,12 +5535,15 @@ Tk_MacOSXGetTkWindow(
void *w)
{
Window window = None;
- TkDisplay *dispPtr = TkGetDisplayList();
if ([(NSWindow *)w respondsToSelector: @selector (tkWindow)]) {
window = [(TKWindow *)w tkWindow];
}
- return (window != None ?
- Tk_IdToWindow(dispPtr->display, window) : NULL);
+ if (window) {
+ TkDisplay *dispPtr = TkGetDisplayList();
+ return Tk_IdToWindow(dispPtr->display, window);
+ } else {
+ return NULL;
+ }
}
/*
diff --git a/tests/entry.test b/tests/entry.test
index ef70a9e..a72d36a 100644
--- a/tests/entry.test
+++ b/tests/entry.test
@@ -2968,6 +2968,7 @@ test entry-17.2 {EntryUpdateScrollbar procedure} -body {
test entry-17.3 {EntryUpdateScrollbar procedure} -body {
entry .e -width 10 -xscrollcommand scroll -font {Courier -12}
pack .e
+ update idletasks
set timeout [after 500 {set scrollInfo {-1000000 -1000000}}]
.e insert 0 abcdefghijklmnopqrs
.e xview 6
diff --git a/tests/font.test b/tests/font.test
index 6995a7b..5af2dbb 100644
--- a/tests/font.test
+++ b/tests/font.test
@@ -523,16 +523,16 @@ test font-12.2 {UpdateDependantFonts procedure: pings the widgets} -setup {
destroy .t.f
catch {font delete xyz}
pack [label .t.f]
- update
+ update idletasks
} -body {
font create xyz -family times -size 20
.t.f config -font xyz -text "abcd" -padx 0 -bd 0 -highlightthickness 0
set a1 [font measure xyz "abcd"]
- update
+ update idletasks
set b1 [winfo reqwidth .t.f]
font configure xyz -family helvetica -size 20
set a2 [font measure xyz "abcd"]
- update
+ update idletasks
set b2 [winfo reqwidth .t.f]
expr {$a1==$b1 && $a2==$b2}
} -cleanup {
diff --git a/tests/scale.test b/tests/scale.test
index 34f2cd9..d7f3a75 100644
--- a/tests/scale.test
+++ b/tests/scale.test
@@ -1522,6 +1522,7 @@ test scale-20.7 {Bug [2262543fff] - Scale widget unexpectedly fires command call
} -body {
scale .s -from 1 -to 50 -command {set commandedVar}
pack .s
+ update idletasks
.s set 10
set timeout [after 500 {set $commandedVar "timeout"}]
vwait commandedVar ; # -command callback shall fire
@@ -1538,6 +1539,7 @@ test scale-20.8 {Bug [2262543fff] - Scale widget unexpectedly fires command call
} -body {
scale .s -from 1 -to 50 -variable scaleVar -command {set commandedVar}
pack .s
+ update idletasks
.s set 10
set timeout [after 500 {set $commandedVar "timeout"}]
vwait commandedVar ; # -command callback shall fire
diff --git a/tests/textWind.test b/tests/textWind.test
index a11a418..1329790 100644
--- a/tests/textWind.test
+++ b/tests/textWind.test
@@ -1541,26 +1541,34 @@ test textWind-17.9 {peer widget window configuration} -setup {
test textWind-17.10 {peer widget window configuration} -setup {
destroy .t .tt
} -body {
+ set res {}
pack [text .t]
.t delete 1.0 end
.t insert 1.0 "Some sample text"
toplevel .tt
pack [.t peer create .tt.t]
+ update idletasks
.t window create 1.2 -window [frame .t.f -width 10 -height 20 -bg blue]
+ update idletasks
+ # There should be a window in the main widget but not in the peer.
+ lappend res [.t window configure 1.2 -window]
+ lappend res [.tt.t window configure 1.2 -window]
.tt.t window create 1.2 -window [frame .tt.t.f -width 25 -height 20 -bg blue]
- update ; update
- .t window configure 1.2 -create \
- {destroy %W.f ; frame %W.f -width 50 -height 7 -bg red}
- .tt.t window configure 1.2 -window {}
+ update idletasks
+ .t window configure 1.2 -create {destroy %W.f ; frame %W.f -width 50 -height 7 -bg red}
+ update idletasks
+ # The main widget should not have changed.
+ lappend res [.t window configure 1.2 -window]
.t window configure 1.2 -window {}
- set res [list [.t window configure 1.2 -window] \
- [.tt.t window configure 1.2 -window]]
- update
- lappend res [.t window configure 1.2 -window] \
- [.tt.t window configure 1.2 -window]
+ .tt.t window configure 1.2 -window {}
+ update idletasks
+ # Nothing should have changed.
+ lappend res [.t window configure 1.2 -window]
+ lappend res [.tt.t window configure 1.2 -window]
} -cleanup {
destroy .tt .t
-} -result {{-window {} {} {} {}} {-window {} {} {} {}} {-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}
+} -result {{-window {} {} {} .t.f} {-window {} {} {} {}} {-window {} {} {} .t.f}\
+{-window {} {} {} .t.f} {-window {} {} {} .tt.t.f}}
test textWind-18.1 {embedded window deletion triggered by a script bound to <Map>} -setup {
catch {destroy .t .f .f2}
diff --git a/tests/unixEmbed.test b/tests/unixEmbed.test
index bb7edc5..d5f6ee3 100644
--- a/tests/unixEmbed.test
+++ b/tests/unixEmbed.test
@@ -1301,6 +1301,7 @@ test unixEmbed-11.2 {mouse coordinates in embedded toplevels} -constraints {
wm geometry .main 200x400+100+100
update idletasks
focus -force .main
+ after 100
set x [expr {[winfo x .main ] + [winfo x .main.b] + 40}]
set y [expr {[winfo y .main ] + [winfo y .main.b] + 38}]
lappend result [winfo containing $x $y]
diff --git a/unix/configure b/unix/configure
index 45c215e..691d43b 100755
--- a/unix/configure
+++ b/unix/configure
@@ -9385,7 +9385,7 @@ cat >>confdefs.h <<\_ACEOF
#define MAC_OSX_TK 1
_ACEOF
- LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit"
+ LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit -framework QuartzCore"
EXTRA_CC_SWITCHES='-std=gnu99 -x objective-c'
TK_WINDOWINGSYSTEM=AQUA
if test -n "${enable_symbols}" -a "${enable_symbols}" != no; then
diff --git a/unix/configure.in b/unix/configure.in
index 78dd688..9720b91 100644
--- a/unix/configure.in
+++ b/unix/configure.in
@@ -354,7 +354,7 @@ fi
if test $tk_aqua = yes; then
AC_DEFINE(MAC_OSX_TK, 1, [Are we building TkAqua?])
- LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit"
+ LIBS="$LIBS -framework Cocoa -framework Carbon -framework IOKit -framework QuartzCore"
EXTRA_CC_SWITCHES='-std=gnu99 -x objective-c'
TK_WINDOWINGSYSTEM=AQUA
if test -n "${enable_symbols}" -a "${enable_symbols}" != no; then