Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix for shimmering of buttons embedded when scrolled in text and canvas widgets; improvements in scrolling smoothness in text widget. Thanks to Marc Culler for patches. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
a8d82409cd315302189fd747f5e9b6f6 |
User & Date: | kevin_walzer 2014-08-16 00:52:12 |
Context
2014-08-18
| ||
20:21 | merge mark check-in: d9afbc28 user: dgp tags: trunk | |
2014-08-16
| ||
00:52 | Fix for shimmering of buttons embedded when scrolled in text and canvas widgets; improvements in scrolling smoothness in text widget. Thanks to Marc Culler for patches. check-in: a8d82409 user: kevin_walzer tags: trunk | |
2014-08-14
| ||
02:41 | Allow Tk to post popup menus when Tk app is not frontmost check-in: 51268e7b user: kevin_walzer tags: trunk | |
Changes
Changes to generic/tkTextDisp.c.
︙ | ︙ | |||
3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 | /* * First recompute what's supposed to be displayed. */ UpdateDisplayInfo(textPtr); dInfoPtr->dLinesInvalidated = 0; /* * See if it's possible to bring some parts of the screen up-to-date by * scrolling (copying from other parts of the screen). We have to be * particularly careful with the top and bottom lines of the display, * since these may only be partially visible and therefore not helpful for * some scrolling purposes. */ | > > > > > > > > > | 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 | /* * First recompute what's supposed to be displayed. */ UpdateDisplayInfo(textPtr); dInfoPtr->dLinesInvalidated = 0; #ifdef MAC_OSX_TK /* * Make sure that unmapped subwindows really have been unmapped. * If the unmap request is pending as an idle request, the window * can get redrawn on top of the widget. */ while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {} #endif /* * See if it's possible to bring some parts of the screen up-to-date by * scrolling (copying from other parts of the screen). We have to be * particularly careful with the top and bottom lines of the display, * since these may only be partially visible and therefore not helpful for * some scrolling purposes. */ |
︙ | ︙ | |||
4031 4032 4033 4034 4035 4036 4037 | /* * Reduce the height of the area being copied if necessary to avoid * overwriting the border area. */ if ((y + height) > dInfoPtr->maxY) { | | | 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 | /* * Reduce the height of the area being copied if necessary to avoid * overwriting the border area. */ if ((y + height) > dInfoPtr->maxY) { height = dInfoPtr->maxY - y; } oldY = dlPtr->oldY; if (y < dInfoPtr->y) { /* * Adjust if the area being copied is going to overwrite the top * border of the window (so the top line is only half onscreen). */ |
︙ | ︙ |
Changes to macosx/tkMacOSXButton.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /* * tkMacOSXButton.c -- * * This file implements the Macintosh specific portion of the * button widgets. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]> * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkButton.h" #include "tkMacOSXFont.h" #include "tkMacOSXDebug.h" /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_BUTTON #endif */ typedef struct MacButton { TkButton info; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | /* * tkMacOSXButton.c -- * * This file implements the Macintosh specific portion of the * button widgets. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]> * Copyright 2014 Marc Culler. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkButton.h" #include "tkMacOSXFont.h" #include "tkMacOSXDebug.h" /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_BUTTON #endif */ static NSRect TkMacOSXGetButtonFrame(TkButton *butPtr); /* * A subclass of NSButton with sanity checking: * NSButtons created by Tk will have their tag set to a pointer to the TkButton * which manages the NSButton. This allows a TkNSButton to be aware of the * state of its Tk parent. This subclass overrides the drawRect method * so that it will not draw itself unless the NSButton frame matches * the frame which was installed by DisplayButton, and the TkButton is * mapped. Also, it will not draw anything if the widget is completely * outside of its container. */ @interface TkNSButton: NSButton @end @implementation TkNSButton - (void)drawRect:(NSRect)dirtyRect { NSInteger tag = [self tag]; if ( tag != -1) { TkButton *butPtr = (TkButton *)tag; MacDrawable* macWin = (MacDrawable *)butPtr; NSRect Tkframe = TkMacOSXGetButtonFrame(butPtr); Tk_Window tkwin = butPtr->tkwin; /* 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, or within 20 pixels of the lower border; this prevents buttons from being drawn on peer widgets as scrolling occurs. */ 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 - 20 || y + widget_height < 0 ) { return; } } [super drawRect:dirtyRect]; } } @end typedef struct MacButton { TkButton info; TkNSButton *button; NSImage *image, *selectImage, *tristateImage; #if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS int fix; #endif } MacButton; #if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS |
︙ | ︙ | |||
182 183 184 185 186 187 188 189 190 191 192 193 194 195 | break; } } /* *---------------------------------------------------------------------- * * TkpComputeButtonGeometry -- * * After changes in a button's text or bitmap, this procedure * recomputes the button's geometry and passes this information * along to the geometry manager for the window. * * Results: | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | break; } } /* *---------------------------------------------------------------------- * * TkpShiftButton -- * * Moves the frame of an NSButton (or TkNSButton) and in case the tag is * set, also adjusts the xOff and yOff of the controlling TkButton's * MacDrawable. This is used to avoid jitter when scrolling. * * Results: * None * * Side effects: * Moves the NSbutton after adjusting the associated MacDrawable. * *---------------------------------------------------------------------- */ void TkpShiftButton( NSButton *button, NSPoint delta ) { NSPoint origin = [button frame].origin; NSInteger tag = [button tag]; if ( tag != -1) { TkButton* butPtr = (TkButton *)tag; TkWindow *winPtr = (TkWindow *) (butPtr->tkwin); if (winPtr) { MacDrawable *macWin = (MacDrawable *) winPtr->window; macWin->xOff += delta.x; macWin->yOff += delta.y; } } origin.x += delta.x; origin.y -= delta.y; [button setFrameOrigin:origin]; } /* *---------------------------------------------------------------------- * * TkpComputeButtonGeometry -- * * After changes in a button's text or bitmap, this procedure * recomputes the button's geometry and passes this information * along to the geometry manager for the window. * * Results: |
︙ | ︙ | |||
214 215 216 217 218 219 220 | } ComputeUnixButtonGeometry(butPtr); break; case TYPE_BUTTON: case TYPE_CHECK_BUTTON: case TYPE_RADIO_BUTTON: if (!macButtonPtr->button) { | | > | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 | } ComputeUnixButtonGeometry(butPtr); break; case TYPE_BUTTON: case TYPE_CHECK_BUTTON: case TYPE_RADIO_BUTTON: if (!macButtonPtr->button) { TkNSButton *button = [[TkNSButton alloc] initWithFrame:NSZeroRect]; [button setTag:(NSInteger)butPtr]; macButtonPtr->button = TkMacOSXMakeUncollectable(button); } ComputeNativeButtonGeometry(butPtr); break; } } |
︙ | ︙ | |||
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | #pragma mark - #pragma mark Native Buttons: /* *---------------------------------------------------------------------- * * DisplayNativeButton -- * * This procedure is invoked to display a button widget. It is * normally invoked as an idle handler. * * Results: * None. * * Side effects: * Commands are output to X to display the button in its * current mode. The REDRAW_PENDING flag is cleared. * *---------------------------------------------------------------------- */ static void DisplayNativeButton( TkButton *butPtr) { MacButton *macButtonPtr = (MacButton *) butPtr; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | #pragma mark - #pragma mark Native Buttons: /* *---------------------------------------------------------------------- * * TkMacOSXGetButtonFrame -- * * Computes a frame for an NSButton that will correspond to where * Tk thinks the button is located. * * Results: * Returns an NSRect describing a frame for an NSButton. * * Side effects: * None * *---------------------------------------------------------------------- */ NSRect TkMacOSXGetButtonFrame( TkButton *butPtr) { MacButton *macButtonPtr = (MacButton *) butPtr; Tk_Window tkwin = butPtr->tkwin; TkWindow *winPtr = (TkWindow *) tkwin; if (tkwin) { MacDrawable *macWin = (MacDrawable *) winPtr->window; NSView *view = TkMacOSXDrawableView(macWin); CGFloat viewHeight = [view bounds].size.height; NSRect frame = NSMakeRect(macWin->xOff, macWin->yOff, Tk_Width(tkwin), Tk_Height(tkwin)); #if TK_MAC_BUTTON_USE_COMPATIBILITY_METRICS if (tkMacOSXUseCompatibilityMetrics) { BoundsFix boundsFix = boundsFixes[macButtonPtr->fix]; frame = NSOffsetRect(frame, boundsFix.offsetX, boundsFix.offsetY); frame.size.height -= boundsFix.shrinkH + NATIVE_BUTTON_EXTRA_H; frame = NSInsetRect(frame, boundsFix.inset + NATIVE_BUTTON_INSET, boundsFix.inset + NATIVE_BUTTON_INSET); } #endif frame.origin.y = viewHeight - (frame.origin.y + frame.size.height); return frame; } else { return NSZeroRect; } } /* *---------------------------------------------------------------------- * * DisplayNativeButton -- * * This procedure is invoked to display a button widget. It is * normally invoked as an idle handler. * * Results: * None. * * Side effects: * Commands are output to X to display the button in its * current mode. The REDRAW_PENDING flag is cleared. * *---------------------------------------------------------------------- */ static void DisplayNativeButton( TkButton *butPtr) { MacButton *macButtonPtr = (MacButton *) butPtr; TkNSButton *button = macButtonPtr->button; Tk_Window tkwin = butPtr->tkwin; TkWindow *winPtr = (TkWindow *) tkwin; MacDrawable *macWin = (MacDrawable *) winPtr->window; TkMacOSXDrawingContext dc; NSView *view = TkMacOSXDrawableView(macWin); CGFloat viewHeight = [view bounds].size.height; CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0, |
︙ | ︙ | |||
345 346 347 348 349 350 351 | } if (butPtr->type == TYPE_BUTTON && butPtr->defaultState == STATE_ACTIVE) { //[[view window] setDefaultButtonCell:cell]; [button setKeyEquivalent:@"\r"]; } else { [button setKeyEquivalent:@""]; } | < < < | < < < < < < < < < | < | 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 | } if (butPtr->type == TYPE_BUTTON && butPtr->defaultState == STATE_ACTIVE) { //[[view window] setDefaultButtonCell:cell]; [button setKeyEquivalent:@"\r"]; } else { [button setKeyEquivalent:@""]; } frame = TkMacOSXGetButtonFrame(butPtr); [button setFrame:frame]; [button displayRectIgnoringOpacity:[button bounds]]; TkMacOSXRestoreDrawingContext(&dc); #ifdef TK_MAC_DEBUG_BUTTON TKLog(@"button %s frame %@ width %d height %d", ((TkWindow *)butPtr->tkwin)->pathName, NSStringFromRect(frame), Tk_Width(tkwin), Tk_Height(tkwin)); #endif |
︙ | ︙ | |||
392 393 394 395 396 397 398 | */ static void ComputeNativeButtonGeometry( TkButton *butPtr) /* Button whose geometry may have changed. */ { MacButton *macButtonPtr = (MacButton *) butPtr; | | | 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 | */ static void ComputeNativeButtonGeometry( TkButton *butPtr) /* Button whose geometry may have changed. */ { MacButton *macButtonPtr = (MacButton *) butPtr; TkNSButton *button = macButtonPtr->button; NSButtonCell *cell = [button cell]; NSButtonType type = -1; NSBezelStyle style = 0; NSInteger highlightsBy = 0, showsStateBy = 0; NSFont *font; NSRect bounds = NSZeroRect, titleRect = NSZeroRect; int haveImage = (butPtr->image || butPtr->bitmap != None), haveText = 0; |
︙ | ︙ | |||
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 | height += 2*butPtr->padY; } Tk_GeometryRequest(butPtr->tkwin, (int) (width + 2*butPtr->inset), (int) (height + 2*butPtr->inset)); Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset); } /* * Local Variables: * mode: objc * c-basic-offset: 4 * fill-column: 79 * coding: utf-8 * End: */ | > | 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 | height += 2*butPtr->padY; } Tk_GeometryRequest(butPtr->tkwin, (int) (width + 2*butPtr->inset), (int) (height + 2*butPtr->inset)); Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset); } /* * Local Variables: * mode: objc * c-basic-offset: 4 * fill-column: 79 * coding: utf-8 * End: */ |
Changes to macosx/tkMacOSXDraw.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkMacOSXDebug.h" #include "xbytes.h" /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_DRAWING #define TK_MAC_DEBUG_IMAGE_DRAWING #endif */ | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkMacOSXDebug.h" #include "xbytes.h" #include "tkButton.h" /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_DRAWING #define TK_MAC_DEBUG_IMAGE_DRAWING #endif */ |
︙ | ︙ | |||
1475 1476 1477 1478 1479 1480 1481 | GC gc, /* GC for window to be scrolled. */ int x, int y, /* Position rectangle to be scrolled. */ int width, int height, int dx, int dy, /* Distance rectangle should be moved. */ TkRegion damageRgn) /* Region to accumulate damage in. */ { Drawable drawable = Tk_WindowId(tkwin); | | | | | > | | | | | | | | | | | | | | | | | | | | | < | | | | | < < < < < < < < < < < < | < | | < | | | < | | | | > | < | < | < < | | < < < < < | | | > > | | > > | | 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 | GC gc, /* GC for window to be scrolled. */ int x, int y, /* Position rectangle to be scrolled. */ int width, int height, int dx, int dy, /* Distance rectangle should be moved. */ TkRegion damageRgn) /* Region to accumulate damage in. */ { Drawable drawable = Tk_WindowId(tkwin); MacDrawable *macDraw = (MacDrawable *) drawable; NSView *view = TkMacOSXDrawableView(macDraw); CGRect srcRect, dstRect; HIShapeRef dmgRgn = NULL, extraRgn; NSRect bounds, visRect, scrollSrc, scrollDst; NSPoint delta = NSMakePoint(dx, dy); int result; if ( view ) { /* Get the scroll area in NSView coordinates (origin at bottom left). */ bounds = [view bounds]; scrollSrc = NSMakeRect( macDraw->xOff + x, bounds.size.height - height - (macDraw->yOff + y), width, height); scrollDst = NSOffsetRect(scrollSrc, dx, -dy); /* Limit scrolling to the window content area. */ visRect = [view visibleRect]; scrollSrc = NSIntersectionRect(scrollSrc, visRect); scrollDst = NSIntersectionRect(scrollDst, visRect); if ( !NSIsEmptyRect(scrollSrc) && !NSIsEmptyRect(scrollDst) ) { /* * Mark the difference between source and destination as damaged. * This region is described in the Tk coordinate system. */ srcRect = CGRectMake(x, y, width, height); dstRect = CGRectOffset(srcRect, dx, dy); dmgRgn = HIShapeCreateMutableWithRect(&srcRect); extraRgn = HIShapeCreateWithRect(&dstRect); ChkErr(HIShapeDifference, dmgRgn, extraRgn, (HIMutableShapeRef) dmgRgn); CFRelease(extraRgn); /* Scroll the rectangle. */ [view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)]; /* * Adjust the positions of the button subwindows that meet the scroll * area. */ for (NSView *subview in [view subviews] ) { if ( [subview isKindOfClass:[NSButton class]] == YES ) { NSRect subframe = [subview frame]; if ( NSIntersectsRect(scrollSrc, subframe) || NSIntersectsRect(scrollDst, subframe) ) { TkpShiftButton((NSButton *)subview, delta ); } } } /* Redisplay the scrolled area. */ [view displayRect:scrollDst]; } } if ( dmgRgn == NULL ) { dmgRgn = HIShapeCreateEmpty(); } TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn); result = HIShapeIsEmpty(dmgRgn) ? 0 : 1; CFRelease(dmgRgn); return result; } |
︙ | ︙ |
Changes to macosx/tkMacOSXInt.h.
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | /* * Include platform specific public interfaces. */ #ifndef _TKMAC #include "tkMacOSX.h" #endif /* * Define compatibility platform types used in the structures below so that * this header can be included without pulling in the platform headers. */ | > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /* * Include platform specific public interfaces. */ #ifndef _TKMAC #include "tkMacOSX.h" #import <Cocoa/Cocoa.h> #endif /* * Define compatibility platform types used in the structures below so that * this header can be included without pulling in the platform headers. */ |
︙ | ︙ | |||
192 193 194 195 196 197 198 | MODULE_SCOPE int XSetClipRectangles(Display *d, GC gc, int clip_x_origin, int clip_y_origin, XRectangle* rectangles, int n, int ordering); #endif MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x, int y, int width, int height); MODULE_SCOPE void TkpRetainRegion(TkRegion r); MODULE_SCOPE void TkpReleaseRegion(TkRegion r); | | | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | MODULE_SCOPE int XSetClipRectangles(Display *d, GC gc, int clip_x_origin, int clip_y_origin, XRectangle* rectangles, int n, int ordering); #endif MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x, int y, int width, int height); MODULE_SCOPE void TkpRetainRegion(TkRegion r); MODULE_SCOPE void TkpReleaseRegion(TkRegion r); MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta); /* * Include the stubbed internal platform-specific API. */ #include "tkIntPlatDecls.h" #endif /* _TKMACINT */ |