Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | merge trunk, fix conflicts in tkTextDisp.c by propagating [0ffbdfe2] (the fix for [61cb40b01b]) to the revised text widget. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | revised_text | tip-466 |
Files: | files | file ages | folders |
SHA3-256: |
2793972a39e72462b08837641cc44e6f |
User & Date: | fvogel 2025-03-01 10:12:00.267 |
References
2025-03-01
| ||
10:18 | • Ticket [61cb40b0] Scrolling a canvas or text with embedded windows can cause artifacts with tcl/tk 9.0.1 Aqua status still Closed with 4 other changes artifact: b4e89b9c user: fvogel | |
Context
2025-03-09
| ||
17:27 | merge trunk check-in: 8a6f1edf user: fvogel tags: revised_text, tip-466 | |
2025-03-01
| ||
10:12 | merge trunk, fix conflicts in tkTextDisp.c by propagating [0ffbdfe2] (the fix for [61cb40b01b]) to the revised text widget. check-in: 2793972a user: fvogel tags: revised_text, tip-466 | |
09:55 | merge trunk check-in: fa3abf01 user: fvogel tags: revised_text, tip-466 | |
2025-02-28
| ||
15:39 | Remove a couple of comments added as reminders. check-in: b1b79d93 user: culler tags: trunk, main | |
Changes
Changes to generic/tkCanvas.c.
︙ | ︙ | |||
3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 | #else canvasPtr->drawableXOrigin = canvasPtr->xOrigin; canvasPtr->drawableYOrigin = canvasPtr->yOrigin; pixmap = Tk_WindowId(tkwin); Tk_ClipDrawableToRect(Tk_Display(tkwin), pixmap, screenX1 - canvasPtr->xOrigin, screenY1 - canvasPtr->yOrigin, width, height); #endif /* TK_NO_DOUBLE_BUFFERING */ /* * Clear the area to be redrawn. */ XFillRectangle(Tk_Display(tkwin), pixmap, canvasPtr->pixmapGC, | > > > > > > > > > > > > > > > > > > > > > > | 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 | #else canvasPtr->drawableXOrigin = canvasPtr->xOrigin; canvasPtr->drawableYOrigin = canvasPtr->yOrigin; pixmap = Tk_WindowId(tkwin); Tk_ClipDrawableToRect(Tk_Display(tkwin), pixmap, screenX1 - canvasPtr->xOrigin, screenY1 - canvasPtr->yOrigin, width, height); /* * Call ItemDisplay for all window items. This does not redraw the * windows, but sets their position within the canvas, which ensures * for macOS (the only platform which defines TK_NO_DOUBLE_BUFFERING) * that the clipping region for the canvas gets updated before the * background is painted by XFillRectangle. Otherwise, when the * background is filled the old locations of the window items will be * clipped away, rather than the new locations, causing "ghost" * windows to appear at the old locations. Now that updateLayer is * being used for macOS drawing it should be possible to stop * maintaining clipping regions for all widgets. When that happens * this code can probably be removed. */ for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; itemPtr = itemPtr->nextPtr) { if (AlwaysRedraw(itemPtr)) { ItemDisplay(canvasPtr, itemPtr, pixmap, screenX1, screenY1, width, height); } } #endif /* TK_NO_DOUBLE_BUFFERING */ /* * Clear the area to be redrawn. */ XFillRectangle(Tk_Display(tkwin), pixmap, canvasPtr->pixmapGC, |
︙ | ︙ |
Changes to generic/tkTextDisp.c.
︙ | ︙ | |||
96 97 98 99 100 101 102 | * between them, that are on the same line and use the same font and font * size. Allocate the chars of all these chunks, the so-called "stretch", * in a DString in the first chunk, the so-called "base chunk". Use the * base chunk string for measuring and drawing, so that these actions are * always performed with maximum context. * * This is necessary for text rendering engines that provide ligatures | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | * between them, that are on the same line and use the same font and font * size. Allocate the chars of all these chunks, the so-called "stretch", * in a DString in the first chunk, the so-called "base chunk". Use the * base chunk string for measuring and drawing, so that these actions are * always performed with maximum context. * * This is necessary for text rendering engines that provide ligatures * and sub-pixel layout, like ATSU on macOS. If we don't do this, the * measuring will change all the time, leading to an ugly "tremble and * shiver" effect. This is because of the continuous splitting and * re-merging of chunks that goes on in a text widget, when the cursor or * the selection move. * * Side effects: * |
︙ | ︙ | |||
8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 | * Now scroll the lines. This may generate damage which we handle by * calling TextInvalidateRegion to mark the display blocks as stale. */ damageRgn = TkCreateRegion(); if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC, MAX(0, dInfoPtr->x - extent1), oldY, dInfoPtr->maxX - dInfoPtr->x + extent1 + extent2, height, 0, y - oldY, damageRgn)) { TextInvalidateRegion(textPtr, damageRgn); } DEBUG(stats.numCopies += 1); TkDestroyRegion(damageRgn); } /* * Clear the REDRAW_PENDING flag here. This is actually pretty tricky. We want to | > > > | 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 | * Now scroll the lines. This may generate damage which we handle by * calling TextInvalidateRegion to mark the display blocks as stale. */ damageRgn = TkCreateRegion(); if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC, MAX(0, dInfoPtr->x - extent1), oldY, dInfoPtr->maxX - dInfoPtr->x + extent1 + extent2, height, 0, y - oldY, damageRgn)) { #ifndef MACOSX_TK /* No point in doing this on macOS. The DLines get redrawn anyway.*/ TextInvalidateRegion(textPtr, damageRgn); #endif } DEBUG(stats.numCopies += 1); TkDestroyRegion(damageRgn); } /* * Clear the REDRAW_PENDING flag here. This is actually pretty tricky. We want to |
︙ | ︙ | |||
8878 8879 8880 8881 8882 8883 8884 | } else if (dInfoPtr->countWindows > 0 && dlPtr->chunkPtr) { /* * On macOS we need to redisplay all embedded windows which * were moved by the call to TkScrollWindows above. This is * not necessary on Unix or Windows because XScrollWindow will * have included the bounding rectangles of all of these * windows in the damage region. The macosx implementation of | | > | | < < | | < < | < > | | 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 | } else if (dInfoPtr->countWindows > 0 && dlPtr->chunkPtr) { /* * On macOS we need to redisplay all embedded windows which * were moved by the call to TkScrollWindows above. This is * not necessary on Unix or Windows because XScrollWindow will * have included the bounding rectangles of all of these * windows in the damage region. The macosx implementation of * TkScrollWindow is not able to do this because no * information about embedded windows is avaliable to it. So * it simply generates a damage region which is the scroll * source rectangle minus the scroll destination rectangle. * (On Unix this is handled by GraphicsExpose events generated * by XCopyArea and on Windows by ScrollWindowEx. On macOS * the embedded windows are not managed by the window manager, * so there is no analogous technique available.) * * On the other hand, this loop is already iterating through * all embedded windows which could possibly have been moved * by the scrolling. So it is as efficient to redisplay them * here as it would have been if they had been redisplayed by * the call to TextInvalidateRegion above. */ #else } else if (dInfoPtr->countWindows > 0 && dlPtr->chunkPtr && (dlPtr->y < 0 || dlPtr->y + dlPtr->height > dInfoPtr->maxY)) { /* * On platforms other than the macOS: * * It's the first or last DLine which are also overlapping the * top or bottom of the window, but we decided above it wasn't * necessary to display them (we were able to update them by * scrolling). This is fine, except that if the lines contain * any embedded windows, we must still call the display proc * on them because they might need to be unmapped or they |
︙ | ︙ | |||
8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 | } if (tkTextDebug) { char string[TK_POS_CHARS]; TkrTextPrintIndex(textPtr, &dlPtr->index, string); LOG("tk_textEmbWinDisplay", string); } chunkPtr->layoutProcs->displayProc(textPtr, chunkPtr, x, dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, NULL, (Drawable) None, dlPtr->y + dlPtr->spaceAbove); } } } #ifndef TK_NO_DOUBLE_BUFFERING Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap); #endif /* TK_NO_DOUBLE_BUFFERING */ } | > > > > > > > > > | 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 | } if (tkTextDebug) { char string[TK_POS_CHARS]; TkrTextPrintIndex(textPtr, &dlPtr->index, string); LOG("tk_textEmbWinDisplay", string); } #ifdef MAC_OSX_TK /* We need to redisplay the entire DLine so that the * background of the line will not contain artifacts left * by the scrolling. */ DisplayDLine(textPtr, dlPtr, NULL, pixmap); #else chunkPtr->layoutProcs->displayProc(textPtr, chunkPtr, x, dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, NULL, (Drawable) None, dlPtr->y + dlPtr->spaceAbove); #endif } } } #ifndef TK_NO_DOUBLE_BUFFERING Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap); #endif /* TK_NO_DOUBLE_BUFFERING */ } |
︙ | ︙ |
Changes to macosx/tkMacOSXWindowEvent.c.
︙ | ︙ | |||
956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 | - (BOOL) wantsUpdateLayer { return YES; } - (void) updateLayer { CGContextRef context = self.tkLayerBitmapContext; if (context && ![NSApp tkWillExit]) { /* * Create a CGImage by copying (probably using copy-on-write) the * bitmap data of the CGBitmapContext that we have been using for * drawing. Then render that CGImage into the CALayer of this view by * assigning a reference to the CGImage to the contents property of the * layer. This will cause all drawing done since the last call to this * function to become visible. */ CGImageRef newImg = CGBitmapContextCreateImage(context); self.layer.contents = (__bridge id) newImg; CGImageRelease(newImg); // will quickly leak memory if this is missing /* * Run any pending widget display procs as part of the update. * Without this there are black flashes when a window opens. */ | > > | > > | 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 | - (BOOL) wantsUpdateLayer { return YES; } - (void) updateLayer { CGContextRef context = self.tkLayerBitmapContext; static bool initialized = NO; if (context && ![NSApp tkWillExit]) { /* * Create a CGImage by copying (probably using copy-on-write) the * bitmap data of the CGBitmapContext that we have been using for * drawing. Then render that CGImage into the CALayer of this view by * assigning a reference to the CGImage to the contents property of the * layer. This will cause all drawing done since the last call to this * function to become visible. */ CGImageRef newImg = CGBitmapContextCreateImage(context); self.layer.contents = (__bridge id) newImg; CGImageRelease(newImg); // will quickly leak memory if this is missing /* * Run any pending widget display procs as part of the update. * Without this there are black flashes when a window opens. */ if (!initialized) { while(Tcl_DoOneEvent(TCL_IDLE_EVENTS)){} initialized = YES; } } } - (void) viewDidChangeBackingProperties { /* |
︙ | ︙ |
Changes to macosx/tkMacOSXWm.c.
︙ | ︙ | |||
7074 7075 7076 7077 7078 7079 7080 | Tk_MapWindow((Tk_Window)winPtr); [macWin deminiaturize:NSApp]; [macWin orderFront:NSApp]; TkMacOSXZoomToplevel(macWin, state == NormalState ? inZoomIn : inZoomOut); } /* | | > | 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 | Tk_MapWindow((Tk_Window)winPtr); [macWin deminiaturize:NSApp]; [macWin orderFront:NSApp]; TkMacOSXZoomToplevel(macWin, state == NormalState ? inZoomIn : inZoomOut); } /* * Make sure windows are updated after the state change too. This is needed * in order for the event-9.11-20 tests to pass. */ while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)){} setStateEnd: return 1; } |
︙ | ︙ |