diff options
author | fvogel <fvogelnew1@free.fr> | 2018-10-18 18:59:35 (GMT) |
---|---|---|
committer | fvogel <fvogelnew1@free.fr> | 2018-10-18 18:59:35 (GMT) |
commit | 862b1ce457db872564c56b295c9487f3fe529253 (patch) | |
tree | 6dc8e6a4aff3db5664a64553c797549df1c21ed1 | |
parent | c650f722da03d87c52824306cefeb20c03ebb8b4 (diff) | |
parent | 4e54b1b43919621c5d881e4c61a9ee2b74467ced (diff) | |
download | tk-862b1ce457db872564c56b295c9487f3fe529253.zip tk-862b1ce457db872564c56b295c9487f3fe529253.tar.gz tk-862b1ce457db872564c56b295c9487f3fe529253.tar.bz2 |
merge core-8-6-branch
-rw-r--r-- | generic/tk.h | 2 | ||||
-rw-r--r-- | generic/tkInt.decls | 6 | ||||
-rw-r--r-- | generic/tkIntPlatDecls.h | 8 | ||||
-rw-r--r-- | generic/tkStubInit.c | 2 | ||||
-rw-r--r-- | generic/tkText.c | 18 | ||||
-rw-r--r-- | generic/ttk/ttkTreeview.c | 2 | ||||
-rw-r--r-- | macosx/README | 9 | ||||
-rw-r--r-- | macosx/tkMacOSXClipboard.c | 31 | ||||
-rw-r--r-- | macosx/tkMacOSXConstants.h | 1 | ||||
-rw-r--r-- | macosx/tkMacOSXPrivate.h | 3 | ||||
-rw-r--r-- | macosx/tkMacOSXScrlbr.c | 7 | ||||
-rw-r--r-- | macosx/tkMacOSXSubwindows.c | 20 | ||||
-rw-r--r-- | macosx/tkMacOSXWindowEvent.c | 159 | ||||
-rw-r--r-- | macosx/tkMacOSXWm.c | 9 | ||||
-rw-r--r-- | tests/text.test | 214 |
15 files changed, 384 insertions, 107 deletions
diff --git a/generic/tk.h b/generic/tk.h index 87150e9..633a595 100644 --- a/generic/tk.h +++ b/generic/tk.h @@ -1174,7 +1174,7 @@ typedef struct Tk_TSOffset { } Tk_TSOffset; /* - * Bit fields in Tk_Offset->flags: + * Bit fields in Tk_TSOffset->flags: */ #define TK_OFFSET_INDEX 1 diff --git a/generic/tkInt.decls b/generic/tkInt.decls index a13d8d7..d0b7678 100644 --- a/generic/tkInt.decls +++ b/generic/tkInt.decls @@ -983,9 +983,9 @@ declare 38 aqua { declare 39 aqua { void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid) } -declare 40 aqua { - void TkSuspendClipboard(void) -} +# +# Slot 40 unused (WAS: TkSuspendClipboard) +# declare 41 aqua { int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart) } diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h index e48e803..c666e3d 100644 --- a/generic/tkIntPlatDecls.h +++ b/generic/tkIntPlatDecls.h @@ -224,8 +224,7 @@ EXTERN void TkMacOSXWindowOffset(void *wRef, int *xOffset, EXTERN int TkSetMacColor(unsigned long pixel, void *macColor); /* 39 */ EXTERN void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid); -/* 40 */ -EXTERN void TkSuspendClipboard(void); +/* Slot 40 is reserved */ /* 41 */ EXTERN int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart); @@ -384,7 +383,7 @@ typedef struct TkIntPlatStubs { void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */ int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */ void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */ - void (*tkSuspendClipboard) (void); /* 40 */ + void (*reserved40) (void); int (*tkMacOSXZoomToplevel) (void *whichWindow, short zoomPart); /* 41 */ Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */ MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */ @@ -599,8 +598,7 @@ extern const TkIntPlatStubs *tkIntPlatStubsPtr; (tkIntPlatStubsPtr->tkSetMacColor) /* 38 */ #define TkSetWMName \ (tkIntPlatStubsPtr->tkSetWMName) /* 39 */ -#define TkSuspendClipboard \ - (tkIntPlatStubsPtr->tkSuspendClipboard) /* 40 */ +/* Slot 40 is reserved */ #define TkMacOSXZoomToplevel \ (tkIntPlatStubsPtr->tkMacOSXZoomToplevel) /* 41 */ #define Tk_TopCoordsToWindow \ diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c index 9411c26..7e02302 100644 --- a/generic/tkStubInit.c +++ b/generic/tkStubInit.c @@ -547,7 +547,7 @@ static const TkIntPlatStubs tkIntPlatStubs = { TkMacOSXWindowOffset, /* 37 */ TkSetMacColor, /* 38 */ TkSetWMName, /* 39 */ - TkSuspendClipboard, /* 40 */ + 0, /* 40 */ TkMacOSXZoomToplevel, /* 41 */ Tk_TopCoordsToWindow, /* 42 */ TkMacOSXContainerId, /* 43 */ diff --git a/generic/tkText.c b/generic/tkText.c index d43bef6..4c536a2 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -5823,7 +5823,7 @@ SearchCore( firstOffset = 0; } - if (alreadySearchOffset != -1) { + if (alreadySearchOffset >= 0) { if (searchSpecPtr->backwards) { if (alreadySearchOffset < lastOffset) { lastOffset = alreadySearchOffset; @@ -5912,17 +5912,17 @@ SearchCore( * match. */ - const char c = pattern[0]; + const char c = matchLength ? pattern[0] : '\0'; - if (alreadySearchOffset != -1) { + if (alreadySearchOffset >= 0) { p = startOfLine + alreadySearchOffset; alreadySearchOffset = -1; } else { p = startOfLine + lastOffset -1; } while (p >= startOfLine + firstOffset) { - if (p[0] == c && !strncmp(p, pattern, - (size_t) matchLength)) { + if (matchLength == 0 || (p[0] == c && !strncmp( + p, pattern, (size_t) matchLength))) { goto backwardsMatch; } p--; @@ -6085,10 +6085,14 @@ SearchCore( if (firstNewLine != -1) { break; } else { - alreadySearchOffset -= matchLength; + alreadySearchOffset -= (matchLength ? matchLength : 1); + if (alreadySearchOffset < 0) { + break; + } } } else { - firstOffset = p - startOfLine + matchLength; + firstOffset = matchLength ? p - startOfLine + matchLength + : p - startOfLine + 1; if (firstOffset >= lastOffset) { /* * Now, we have to be careful not to find diff --git a/generic/ttk/ttkTreeview.c b/generic/ttk/ttkTreeview.c index d957ad2..bef84f3 100644 --- a/generic/ttk/ttkTreeview.c +++ b/generic/ttk/ttkTreeview.c @@ -1825,7 +1825,7 @@ static int DrawSubtree( static int DrawForest( Treeview *tv, TreeItem *item, Drawable d, int depth, int row) { - while (item && row <= tv->tree.yscroll.last) { + while (item && row < tv->tree.yscroll.last) { row = DrawSubtree(tv, item, d, depth, row); item = item->next; } diff --git a/macosx/README b/macosx/README index bcd5dce..c63b8ae 100644 --- a/macosx/README +++ b/macosx/README @@ -561,3 +561,12 @@ source and destination rectangles for the scrolling. The embedded windows are redrawn within the DisplayText function by some conditional code which is only used for macOS. +5.0 Virtual events on 10.14 +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +10.14 supports system appearance changes, and has added a "Dark Mode" +that casts all window frames and menus as black. Tk 8.6.9 has added two +virtual events, <<LightAqua>> and <<DarkAqua>>, to allow you to update +your Tk app's appearance when the system appearance changes. Just bind +your appearance-updating code to these virtual events and you will see +it triggered when the system appearance toggles between dark and light. diff --git a/macosx/tkMacOSXClipboard.c b/macosx/tkMacOSXClipboard.c index 07a8419..9b65bc3 100644 --- a/macosx/tkMacOSXClipboard.c +++ b/macosx/tkMacOSXClipboard.c @@ -70,10 +70,8 @@ static Tk_Window clipboardOwner = NULL; if (clipboardOwner && [[NSPasteboard generalPasteboard] changeCount] != changeCount) { TkDisplay *dispPtr = TkGetDisplayList(); - if (dispPtr) { XEvent event; - event.xany.type = SelectionClear; event.xany.serial = NextRequest(Tk_Display(clipboardOwner)); event.xany.send_event = False; @@ -125,8 +123,10 @@ TkSelGetSelection( int result = TCL_ERROR; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - if (dispPtr && selection == dispPtr->clipboardAtom && (target == XA_STRING - || target == dispPtr->utf8Atom)) { + int haveExternalClip = ([[NSPasteboard generalPasteboard] changeCount] != changeCount); + if (dispPtr && (haveExternalClip || dispPtr->clipboardActive) + && selection == dispPtr->clipboardAtom + && (target == XA_STRING || target == dispPtr->utf8Atom)) { NSString *string = nil; NSPasteboard *pb = [NSPasteboard generalPasteboard]; NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject: @@ -176,7 +176,6 @@ XSetSelectionOwner( clipboardOwner = owner ? Tk_IdToWindow(display, owner) : NULL; if (!dispPtr->clipboardActive) { NSPasteboard *pb = [NSPasteboard generalPasteboard]; - changeCount = [pb declareTypes:[NSArray array] owner:NSApp]; } } @@ -290,28 +289,6 @@ TkSelPropProc( } /* - *---------------------------------------------------------------------- - * - * TkSuspendClipboard -- - * - * Handle clipboard conversion as required by the suppend event. - * - * Results: - * None. - * - * Side effects: - * The local scrap is moved to the global scrap. - * - *---------------------------------------------------------------------- - */ - -void -TkSuspendClipboard(void) -{ - changeCount = [[NSPasteboard generalPasteboard] changeCount]; -} - -/* * Local Variables: * mode: objc * c-basic-offset: 4 diff --git a/macosx/tkMacOSXConstants.h b/macosx/tkMacOSXConstants.h index 95983dd..bb2206e 100644 --- a/macosx/tkMacOSXConstants.h +++ b/macosx/tkMacOSXConstants.h @@ -90,6 +90,7 @@ #define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar #define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable #define NSBorderlessWindowMask NSWindowStyleMaskBorderless +#define NSFullScreenWindowMask NSWindowStyleMaskFullScreen #endif #endif diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h index 730ccaa..28597dd 100644 --- a/macosx/tkMacOSXPrivate.h +++ b/macosx/tkMacOSXPrivate.h @@ -330,7 +330,8 @@ VISIBILITY_HIDDEN @interface TKContentView(TKWindowEvent) - (void) drawRect: (NSRect) rect; - (void) generateExposeEvents: (HIShapeRef) shape; -- (void) viewDidEndLiveResize; +- (void) viewDidChangeEffectiveAppearance; +- (void) updateAppearanceEvent; - (void) tkToolbarButton: (id) sender; - (BOOL) isOpaque; - (BOOL) wantsDefaultClipping; diff --git a/macosx/tkMacOSXScrlbr.c b/macosx/tkMacOSXScrlbr.c index 2fb9454..f15146d 100644 --- a/macosx/tkMacOSXScrlbr.c +++ b/macosx/tkMacOSXScrlbr.c @@ -279,7 +279,7 @@ TkpComputeScrollbarGeometry( * window, if any). Then arrange for the window to be redisplayed. */ - if (scrollPtr->vertical) { + if (scrollPtr->vertical) { Tk_GeometryRequest(scrollPtr->tkwin, scrollPtr->width + 2*scrollPtr->inset, 2*(scrollPtr->arrowLength + scrollPtr->borderWidth @@ -377,7 +377,7 @@ TkpScrollbarPosition( int x, int y) /* Coordinates within scrollPtr's window. */ { - /* + /* * Using code from tkUnixScrlbr.c because Unix scroll bindings are * driving the display at the script level. All the Mac scrollbar * has to do is re-draw itself. @@ -412,12 +412,13 @@ TkpScrollbarPosition( if (y < scrollPtr->sliderFirst) { return TOP_GAP; } - if (y < scrollPtr->sliderLast){ + if (y < scrollPtr->sliderLast) { return SLIDER; } if (y >= length - (scrollPtr->arrowLength + inset)) { return BOTTOM_ARROW; } + return BOTTOM_GAP; } diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index 3d5e986..0f9214f 100644 --- a/macosx/tkMacOSXSubwindows.c +++ b/macosx/tkMacOSXSubwindows.c @@ -205,6 +205,13 @@ XMapWindow( event.xvisibility.type = VisibilityNotify; event.xvisibility.state = VisibilityUnobscured; NotifyVisibility(macWin->winPtr, &event); + + /* + * Make sure that subwindows get displayed. + */ + + GenerateConfigureNotify(macWin->winPtr, 1); + } /* @@ -295,10 +302,12 @@ XUnmapWindow( event.xunmap.from_configure = false; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } else { + /* * Rebuild the visRgn clip region for the parent so it will be allowed * to draw in the space from which this subwindow was removed. */ + if (parentPtr && parentPtr->privatePtr->visRgn) { TkMacOSXInvalidateViewRegion(TkMacOSXDrawableView(parentPtr->privatePtr), parentPtr->privatePtr->visRgn); @@ -380,10 +389,12 @@ XMoveResizeWindow( if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { NSWindow *w = macWin->winPtr->wmInfoPtr->window; if (w) { + /* We explicitly convert everything to doubles so we don't get * surprised (again) by what happens when you do arithmetic with * unsigned ints. */ + CGFloat X = (CGFloat)x; CGFloat Y = (CGFloat)y; CGFloat Width = (CGFloat)width; @@ -470,6 +481,7 @@ MoveResizeWindow( if (contWinPtr) { macParent = contWinPtr->privatePtr; } else { + /* * Here we should handle out of process embedding. At this point, * we are assuming that the changes.x,y is not maintained, if you @@ -478,6 +490,7 @@ MoveResizeWindow( */ } } else { + /* * TODO: update all xOff & yOffs */ @@ -569,6 +582,7 @@ XRaiseWindow( if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { TkWmRestackToplevel(macWin->winPtr, Above, NULL); } else { + /* * TODO: this should generate damage */ @@ -603,7 +617,8 @@ XLowerWindow( if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { TkWmRestackToplevel(macWin->winPtr, Below, NULL); } else { - /* + + /* * TODO: this should generate damage */ } @@ -874,6 +889,7 @@ TkMacOSXUpdateClipRgn( } CFRelease(rgn); } else { + /* * An unmapped window has empty clip regions to prevent any * (erroneous) drawing into it or its children from becoming @@ -1134,6 +1150,7 @@ void * TkMacOSXGetRootControl( Drawable drawable) { + /* * will probably need to fix this up for embedding */ @@ -1314,6 +1331,7 @@ UpdateOffsets( TkWindow *childPtr; if (winPtr->privatePtr == NULL) { + /* * We haven't called Tk_MakeWindowExist for this window yet. The offset * information will be postponed and calulated at that time. (This will diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c index bbfe5b7..36fc297 100644 --- a/macosx/tkMacOSXWindowEvent.c +++ b/macosx/tkMacOSXWindowEvent.c @@ -68,11 +68,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification; TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); #endif BOOL movedOnly = [[notification name] - isEqualToString:NSWindowDidMoveNotification]; - - if (movedOnly) { - /* constraining to screen after move not needed with AppKit */ - } + isEqualToString:NSWindowDidMoveNotification]; NSWindow *w = [notification object]; TkWindow *winPtr = TkMacOSXGetTkWindow(w); @@ -96,6 +92,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification; flags |= TK_SIZE_CHANGED; } if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) { + /* * Propagate geometry changes immediately. */ @@ -119,6 +116,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification; TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState; Tk_MapWindow((Tk_Window) winPtr); if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) { + /* * Process all Tk events generated by Tk_MapWindow(). */ @@ -174,6 +172,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification; return (winPtr ? NO : YES); } + #ifdef TK_MAC_DEBUG_NOTIFICATIONS - (void) windowDragStart: (NSNotification *) notification @@ -213,6 +212,8 @@ extern NSString *NSWindowDidOrderOffScreenNotification; //Tk_UnmapWindow((Tk_Window) winPtr); } } + + #endif /* TK_MAC_DEBUG_NOTIFICATIONS */ - (void) _setupWindowNotifications @@ -236,6 +237,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification; observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:); #endif #undef observe + } @end @@ -256,7 +258,6 @@ extern NSString *NSWindowDidOrderOffScreenNotification; #ifdef TK_MAC_DEBUG_NOTIFICATIONS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); #endif - TkSuspendClipboard(); } - (void) applicationShowHide: (NSNotification *) notification @@ -299,7 +300,7 @@ extern NSString *NSWindowDidOrderOffScreenNotification; * GenerateUpdates -- * * Given a Macintosh update region and a Tk window this function geneates - * a X Expose event for the window if it is within the update region. The + * an X Expose event for the window if it meets the update region. The * function will then recursivly have each damaged window generate Expose * events for its child windows. * @@ -579,10 +580,12 @@ TkGenWMConfigureEvent( if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) && ((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) { if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) { + /* * Don't set external width, since the user didn't change it * from what the widgets asked for. */ + } else if (wmPtr->gridWin != NULL) { wmPtr->width = wmPtr->reqGridWidth + (width - winPtr->reqWidth)/wmPtr->widthInc; @@ -594,10 +597,12 @@ TkGenWMConfigureEvent( } if ((wmPtr->height == -1) && (height == winPtr->reqHeight)) { + /* * Don't set external height, since the user didn't change it * from what the widgets asked for. */ + } else if (wmPtr->gridWin != NULL) { wmPtr->height = wmPtr->reqGridHeight + (height - winPtr->reqHeight)/wmPtr->heightInc; @@ -813,17 +818,7 @@ ConfigureRestrictProc( r.origin.y = height - (r.origin.y + r.size.height); HIShapeUnionWithRect(drawShape, &r); } - if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) { - [self generateExposeEvents:(HIShapeRef)drawShape]; - } else { - [self performSelectorOnMainThread:@selector(generateExposeEvents:) - withObject:(id)drawShape waitUntilDone:NO - modes:[NSArray arrayWithObjects:NSRunLoopCommonModes, - - NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, - nil]]; - } - + [self generateExposeEvents:(HIShapeRef)drawShape]; CFRelease(drawShape); } @@ -839,62 +834,56 @@ ConfigureRestrictProc( ClientData oldArg; Tk_RestrictProc *oldProc; - /* This can be called from outside the Tk event loop. + /* + * This can be called from outside the Tk event loop. * Since it calls Tcl_DoOneEvent, we need to make sure we * don't clobber the AutoreleasePool set up by the caller. */ + [NSApp _lockAutoreleasePool]; /* - * Try to prevent flickers and flashes. + * Disable Tk drawing until the window has been completely configured. */ - NSDisableScreenUpdates(); - /* Disable Tk drawing until the window has been completely configured.*/ TkMacOSXSetDrawingEnabled(winPtr, 0); - /* Generate and handle a ConfigureNotify event for the new size.*/ + /* + * Generate and handle a ConfigureNotify event for the new size. + */ + TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height, TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY); oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg); - while (Tk_DoOneEvent(TK_X_EVENTS|TK_DONT_WAIT)) {} Tk_RestrictEvents(oldProc, oldArg, &oldArg); - /* Now that Tk has configured all subwindows we can create the clip regions. */ + /* + * Now that Tk has configured all subwindows, create the clip regions. + */ + TkMacOSXSetDrawingEnabled(winPtr, 1); TkMacOSXInvalClipRgns(tkwin); TkMacOSXUpdateClipRgn(winPtr); - /* Finally, generate and process expose events to redraw the window. */ + /* + * Finally, generate and process expose events to redraw the window. + */ + HIRect bounds = NSRectToCGRect([self bounds]); HIShapeRef shape = HIShapeCreateWithRect(&bounds); [self generateExposeEvents: shape]; - while (Tk_DoOneEvent(TK_ALL_EVENTS|TK_DONT_WAIT)) {} [w displayIfNeeded]; - NSEnableScreenUpdates(); [NSApp _unlockAutoreleasePool]; } } /* - * As insurance against bugs that might cause layout glitches during a live - * resize, we redraw the window one more time at the end of the resize - * operation. + * Core method of this class: generates expose events for redrawing. The + * expose events are immediately removed from the Tcl event loop and processed. + * This causes drawing procedures to be scheduled as idle events. Then all + * pending idle events are processed so the drawing will actually take place. */ -- (void)viewDidEndLiveResize -{ - HIRect bounds = NSRectToCGRect([self bounds]); - HIShapeRef shape = HIShapeCreateWithRect(&bounds); - [super viewDidEndLiveResize]; - [self generateExposeEvents: shape]; -} - -/* Core method of this class: generates expose events for redrawing. If the - * Tcl_ServiceMode is set to TCL_SERVICE_ALL then the expose events will be - * immediately removed from the Tcl event loop and processed. Typically, they - * should be queued, however. - */ - (void) generateExposeEvents: (HIShapeRef) shape { unsigned long serial; @@ -906,19 +895,89 @@ ConfigureRestrictProc( return; } - /* Generate Tk Expose events. */ + /* + * Generate Tk Expose events. + */ + HIShapeGetBounds(shape, &updateBounds); - /* All of these events will share the same serial number. */ + + /* + * All of these events will share the same serial number. + */ + serial = LastKnownRequestProcessed(Tk_Display(winPtr)); updatesNeeded = GenerateUpdates(shape, &updateBounds, winPtr); - /* Process the Expose events if the service mode is TCL_SERVICE_ALL */ - if (updatesNeeded && Tcl_GetServiceMode() == TCL_SERVICE_ALL) { + if (updatesNeeded) { + + /* + * First process all of the Expose events. + */ + ClientData oldArg; Tk_RestrictProc *oldProc = Tk_RestrictEvents(ExposeRestrictProc, UINT2PTR(serial), &oldArg); - while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {} + while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {}; Tk_RestrictEvents(oldProc, oldArg, &oldArg); + + /* + * Starting with OSX 10.14, which uses Core Animation to draw windows, + * all drawing must be done within the drawRect method. (The CGContext + * which draws to the backing CALayer is created by the NSView before + * calling drawRect, and destroyed when drawRect returns. Drawing done + * with the current CGContext outside of the drawRect method has no + * effect.) + * + * Fortunately, Tk schedules all drawing to be done while Tcl is idle. + * So we can do the drawing by processing all of the idle events that + * were created when the expose events were processed. + */ + + while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {} + } +} + + +/* + * These two methods allow Tk to register a virtual event which fires when the + * appearance changes on 10.14. + */ + +- (void) viewDidChangeEffectiveAppearance +{ + [self updateAppearanceEvent]; +} + +- (void) updateAppearanceEvent +{ + NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; + NSWindow *w = [self window]; + TkWindow *winPtr = TkMacOSXGetTkWindow(w); + XVirtualEvent event; + int x, y; + Tk_Window tkwin = (Tk_Window) winPtr; + bzero(&event, sizeof(XVirtualEvent)); + event.type = VirtualEvent; + event.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); + event.send_event = false; + event.display = Tk_Display(tkwin); + event.event = Tk_WindowId(tkwin); + event.root = XRootWindow(Tk_Display(tkwin), 0); + event.subwindow = None; + event.time = TkpGetMS(); + XQueryPointer(NULL, winPtr->window, NULL, NULL, + &event.x_root, &event.y_root, &x, &y, &event.state); + Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y); + event.same_screen = true; + if (osxMode == nil) { + event.name = Tk_GetUid("LightAqua"); + Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); + return; + } + if ([osxMode isEqual:@"Dark"]) { + event.name = Tk_GetUid("DarkAqua"); + Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); + return; } } @@ -926,6 +985,7 @@ ConfigureRestrictProc( * 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 @@ -955,7 +1015,6 @@ ConfigureRestrictProc( - (BOOL) isOpaque { NSWindow *w = [self window]; - return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) || ![w isOpaque]) ? NO : YES); } diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index a0fda96..55a6633 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -399,8 +399,7 @@ NSStatusItem *exitFullScreen; - (void)toggleFullScreen:(id)sender { TkWindow *winPtr = TkMacOSXGetTkWindow(self); - Tk_Window tkwin = (TkWindow*)winPtr; - Tcl_Interp *interp = Tk_Interp(tkwin); + Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr); if (([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask) { TkMacOSXMakeFullscreen(winPtr, self, 0, interp); @@ -412,8 +411,7 @@ NSStatusItem *exitFullScreen; -(void)restoreOldScreen:(id)sender { TkWindow *winPtr = TkMacOSXGetTkWindow(self); - Tk_Window tkwin = (TkWindow*)winPtr; - Tcl_Interp *interp = Tk_Interp(tkwin); + Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr); TkMacOSXMakeFullscreen(winPtr, self, 0, interp); [[NSStatusBar systemStatusBar] removeStatusItem: exitFullScreen]; @@ -5646,7 +5644,6 @@ TkMacOSXMakeRealWindowExist( } TKContentView *contentView = [[TKContentView alloc] initWithFrame:NSZeroRect]; - [window setColorSpace:[NSColorSpace deviceRGBColorSpace]]; [window setContentView:contentView]; [contentView release]; [window setDelegate:NSApp]; @@ -5659,7 +5656,7 @@ TkMacOSXMakeRealWindowExist( if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) && !(styleMask & NSDocModalWindowMask)) { /* - * Workaround for [Bug 2824538]: Texured windows are draggable + * Workaround for [Bug 2824538]: Textured windows are draggable * from opaque content. */ [window setMovableByWindowBackground:NO]; diff --git a/tests/text.test b/tests/text.test index c656446..6155802 100644 --- a/tests/text.test +++ b/tests/text.test @@ -5873,7 +5873,219 @@ test text-22.225 {TextSearchCmd, strict limits} -body { } -cleanup { destroy .t } -result {} - +test text-22.226 {TextSearchCmd, exact search for the empty string} -body { + text .t + set res [.t search -count C "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.227 {TextSearchCmd, exact search for the empty string} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C "" 2.5] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.5 0} +test text-22.228 {TextSearchCmd, exact search all empty strings} -body { + text .t + set res [.t search -count C -all "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.229 {TextSearchCmd, exact search all empty strings} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -all "" 2.5 2.8] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.5 2.6 2.7 {0 0 0}} +test text-22.230 {TextSearchCmd, exact search all empty strings, with overlap} -body { + text .t + set res [.t search -count C -all -overlap "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.231 {TextSearchCmd, exact search all empty strings, with overlap} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -all -overlap "" 2.5 2.8] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.5 2.6 2.7 {0 0 0}} +test text-22.232 {TextSearchCmd, regexp search for the empty string} -body { + text .t + set res [.t search -count C -regexp "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.233 {TextSearchCmd, regexp search for the empty string} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -regexp "" 2.5] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.5 0} +test text-22.234 {TextSearchCmd, regexp search all empty strings} -body { + text .t + set res [.t search -count C -all -regexp "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.235 {TextSearchCmd, regexp search all empty strings} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -all -regexp "" 2.5 2.8] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.5 2.6 2.7 {0 0 0}} +test text-22.236 {TextSearchCmd, regexp search all empty strings, with overlap} -body { + text .t + set res [.t search -count C -all -regexp -overlap "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.237 {TextSearchCmd, regexp search all empty strings, with overlap} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -all -regexp -overlap "" 2.5 2.8] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.5 2.6 2.7 {0 0 0}} +test text-22.238 {TextSearchCmd, exact backwards search for the empty string} -body { + text .t + set res [.t search -count C -backwards "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.239 {TextSearchCmd, exact backwards search for the empty string} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -backwards "" 2.5] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.4 0} +test text-22.240 {TextSearchCmd, exact backwards search all empty strings} -body { + text .t + set res [.t search -count C -backwards -all "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.241 {TextSearchCmd, exact backwards search all empty strings} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -backwards -all "" 2.5 2.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}} +test text-22.242 {TextSearchCmd, exact backwards search all empty strings, with overlap} -body { + text .t + set res [.t search -count C -backwards -all -overlap "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.243 {TextSearchCmd, exact backwards search all empty strings, with overlap} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -backwards -all -overlap "" 2.5 2.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}} +test text-22.244 {TextSearchCmd, regexp backwards search for the empty string} -body { + text .t + set res [.t search -count C -backwards -regexp "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.245 {TextSearchCmd, regexpbackwards search for the empty string} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -backwards -regexp "" 2.5] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.4 0} +test text-22.246 {TextSearchCmd, regexp backwards search all empty strings} -body { + text .t + set res [.t search -count C -backwards -all -regexp "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.247 {TextSearchCmd, regexp backwards search all empty strings} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -backwards -all -regexp "" 2.5 2.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}} +test text-22.248 {TextSearchCmd, regexp backwards search all empty strings, with overlap} -body { + text .t + set res [.t search -count C -backwards -all -regexp -overlap "" 1.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {1.0 0} +test text-22.249 {TextSearchCmd, regexp backwards search all empty strings, with overlap} -body { + text .t + .t insert end "Searching for the\nempty string!" + set res [.t search -count C -backwards -all -regexp -overlap "" 2.5 2.0] + lappend res $C +} -cleanup { + destroy .t + unset -nocomplain res C +} -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}} +test text-22.250 {TextSearchCmd, backwards search all matching at start of line} -body { + text .t + .t insert end "abc" + set res [.t search -backwards -all b end] ; # works + lappend res [.t search -backwards a end] ; # works + lappend res [.t search -backwards -all a end] ; # used to hang +} -cleanup { + destroy .t +} -result {1.1 1.0 1.0} test text-23.1 {TkTextGetTabs procedure} -setup { text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100 |