summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/tk.h6
-rw-r--r--generic/tkButton.c6
-rw-r--r--generic/tkImgPhInstance.c71
-rw-r--r--generic/tkInt.decls6
-rw-r--r--generic/tkIntPlatDecls.h8
-rw-r--r--generic/tkMenuDraw.c36
-rw-r--r--generic/tkOption.c5
-rw-r--r--generic/tkStubInit.c2
-rw-r--r--generic/tkTest.c60
-rw-r--r--generic/tkText.c18
-rw-r--r--generic/tkTextDisp.c50
-rw-r--r--generic/ttk/ttkDefaultTheme.c66
-rw-r--r--generic/ttk/ttkTheme.c8
-rw-r--r--generic/ttk/ttkTreeview.c2
14 files changed, 212 insertions, 132 deletions
diff --git a/generic/tk.h b/generic/tk.h
index 87150e9..c94882c 100644
--- a/generic/tk.h
+++ b/generic/tk.h
@@ -75,10 +75,10 @@ extern "C" {
#define TK_MAJOR_VERSION 8
#define TK_MINOR_VERSION 6
#define TK_RELEASE_LEVEL TCL_FINAL_RELEASE
-#define TK_RELEASE_SERIAL 8
+#define TK_RELEASE_SERIAL 9
#define TK_VERSION "8.6"
-#define TK_PATCH_LEVEL "8.6.8"
+#define TK_PATCH_LEVEL "8.6.9"
/*
* A special definition used to allow this header file to be included from
@@ -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/tkButton.c b/generic/tkButton.c
index fc2c7ec..7760359 100644
--- a/generic/tkButton.c
+++ b/generic/tkButton.c
@@ -879,7 +879,13 @@ ButtonWidgetObjCmd(
Tcl_CancelIdleCall(TkpDisplayButton, butPtr);
XFlush(butPtr->display);
+ #ifndef MAC_OSX_TK
+ /*
+ * On the mac you can not sleep in a display proc, and the
+ * flash command doesn't do anything anyway.
+ */
Tcl_Sleep(50);
+ #endif
}
}
break;
diff --git a/generic/tkImgPhInstance.c b/generic/tkImgPhInstance.c
index ec9ee04..0daca2f 100644
--- a/generic/tkImgPhInstance.c
+++ b/generic/tkImgPhInstance.c
@@ -19,6 +19,9 @@
*/
#include "tkImgPhoto.h"
+#ifdef MAC_OSX_TK
+#define TKPUTIMAGE_CAN_BLEND
+#endif
/*
* Declaration for internal Xlib function used here:
@@ -30,8 +33,10 @@ extern int _XInitImageFuncPtrs(XImage *image);
* Forward declarations
*/
+#ifndef TKPUTIMAGE_CAN_BLEND
static void BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
int xOffset, int yOffset, int width, int height);
+#endif
static int IsValidPalette(PhotoInstance *instancePtr,
const char *palette);
static int CountBits(pixel mask);
@@ -409,7 +414,7 @@ TkImgPhotoGet(
*
*----------------------------------------------------------------------
*/
-
+#ifndef TKPUTIMAGE_CAN_BLEND
#ifndef _WIN32
#define GetRValue(rgb) (UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb) (UCHAR(((rgb) & green_mask) >> green_shift))
@@ -418,13 +423,6 @@ TkImgPhotoGet(
(UCHAR(r) << red_shift) | \
(UCHAR(g) << green_shift) | \
(UCHAR(b) << blue_shift) ))
-#ifdef MAC_OSX_TK
-#define RGBA(r, g, b, a) ((unsigned)( \
- (UCHAR(r) << red_shift) | \
- (UCHAR(g) << green_shift) | \
- (UCHAR(b) << blue_shift) | \
- (UCHAR(a) << alpha_shift) ))
-#endif
#define RGB15(r, g, b) ((unsigned)( \
(((r) * red_mask / 255) & red_mask) | \
(((g) * green_mask / 255) & green_mask) | \
@@ -443,16 +441,7 @@ BlendComplexAlpha(
unsigned long pixel;
unsigned char r, g, b, alpha, unalpha, *masterPtr;
unsigned char *alphaAr = iPtr->masterPtr->pix32;
-#if defined(MAC_OSX_TK)
- /* Background "pixels" are actually 2^pp x 2^pp blocks of subpixels. Each
- * block gets blended with the color of one image pixel. Since we iterate
- * over the background subpixels, we reset the width and height to the
- * subpixel dimensions of the background image we are using.
- */
- int pp = bgImg->pixelpower;
- width = width << pp;
- height = height << pp;
-#endif
+
/*
* This blending is an integer version of the Source-Over compositing rule
* (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
@@ -492,13 +481,6 @@ BlendComplexAlpha(
while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
blue_shift++;
}
-#ifdef MAC_OSX_TK
- unsigned long alpha_mask = visual->alpha_mask;
- unsigned long alpha_shift = 0;
- while ((0x0001 & (alpha_mask >> alpha_shift)) == 0) {
- alpha_shift++;
- }
-#endif
#endif /* !_WIN32 */
/*
@@ -507,7 +489,7 @@ BlendComplexAlpha(
* optimized.
*/
-#if !(defined(_WIN32) || defined(MAC_OSX_TK))
+#if !defined(_WIN32)
if (bgImg->depth < 24) {
unsigned char red_mlen, green_mlen, blue_mlen;
@@ -555,19 +537,12 @@ BlendComplexAlpha(
}
return;
}
-#endif /* !_WIN32 && !MAC_OSX_TK */
+#endif /* !_WIN32 */
for (y = 0; y < height; y++) {
-# if !defined(MAC_OSX_TK)
line = (y + yOffset) * iPtr->masterPtr->width;
for (x = 0; x < width; x++) {
masterPtr = alphaAr + ((line + x + xOffset) * 4);
-#else
- /* Repeat each image row and column 2^pp times. */
- line = ((y>>pp) + yOffset) * iPtr->masterPtr->width;
- for (x = 0; x < width; x++) {
- masterPtr = alphaAr + ((line + (x>>pp) + xOffset) * 4);
-#endif
alpha = masterPtr[3];
/*
@@ -599,16 +574,13 @@ BlendComplexAlpha(
g = ALPHA_BLEND(ga, g, alpha, unalpha);
b = ALPHA_BLEND(ba, b, alpha, unalpha);
}
-#ifndef MAC_OSX_TK
XPutPixel(bgImg, x, y, RGB(r, g, b));
-#else
- XPutPixel(bgImg, x, y, RGBA(r, g, b, alpha));
-#endif
}
}
}
#undef ALPHA_BLEND
}
+#endif /* TKPUTIMAGE_CAN_BLEND */
/*
*----------------------------------------------------------------------
@@ -640,8 +612,10 @@ TkImgPhotoDisplay(
* to imageX and imageY. */
{
PhotoInstance *instancePtr = clientData;
+#ifndef TKPUTIMAGE_CAN_BLEND
XVisualInfo visInfo = instancePtr->visualInfo;
-
+#endif
+
/*
* If there's no pixmap, it means that an error occurred while creating
* the image instance so it can't be displayed.
@@ -651,6 +625,24 @@ TkImgPhotoDisplay(
return;
}
+#ifdef TKPUTIMAGE_CAN_BLEND
+ /*
+ * If TkPutImage can handle RGBA Ximages directly there is
+ * no need to call XGetImage or to do the Porter-Duff compositing by hand.
+ */
+
+ unsigned char *rgbaPixels = instancePtr->masterPtr->pix32;
+ XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
+ (unsigned int)instancePtr->width,
+ (unsigned int)instancePtr->height,
+ 0, (unsigned int)(4 * instancePtr->width));
+ TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
+ photo, imageX, imageY, drawableX, drawableY,
+ (unsigned int) width, (unsigned int) height);
+ photo->data = NULL;
+ XDestroyImage(photo);
+#else
+
if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
&& visInfo.depth >= 15
&& (visInfo.class == DirectColor || visInfo.class == TrueColor)) {
@@ -709,6 +701,7 @@ TkImgPhotoDisplay(
XSetClipOrigin(display, instancePtr->gc, 0, 0);
}
XFlush(display);
+#endif
}
/*
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..ded5ac5 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/tkMenuDraw.c b/generic/tkMenuDraw.c
index 1abe1c4..3f492db 100644
--- a/generic/tkMenuDraw.c
+++ b/generic/tkMenuDraw.c
@@ -624,7 +624,6 @@ DisplayMenu(
int width;
int borderWidth;
Tk_3DBorder border;
- int activeBorderWidth;
int relief;
@@ -636,8 +635,6 @@ DisplayMenu(
Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
&borderWidth);
border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
- Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
- menuPtr->activeBorderWidthPtr, &activeBorderWidth);
if (menuPtr->menuType == MENUBAR) {
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth,
@@ -668,28 +665,16 @@ DisplayMenu(
}
mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY;
- if (menuPtr->menuType == MENUBAR) {
- width = mePtr->width;
- } else {
- if (mePtr->entryFlags & ENTRY_LAST_COLUMN) {
- width = Tk_Width(menuPtr->tkwin) - mePtr->x
- - activeBorderWidth;
- } else {
- width = mePtr->width + borderWidth;
- }
- }
TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont,
- &menuMetrics, mePtr->x, mePtr->y, width,
+ &menuMetrics, mePtr->x, mePtr->y, mePtr->width,
mePtr->height, strictMotif, 1);
if ((index > 0) && (menuPtr->menuType != MENUBAR)
&& mePtr->columnBreak) {
mePtr = menuPtr->entries[index - 1];
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border,
- mePtr->x, mePtr->y + mePtr->height,
- mePtr->width,
- Tk_Height(tkwin) - mePtr->y - mePtr->height -
- activeBorderWidth, 0,
- TK_RELIEF_FLAT);
+ mePtr->x, mePtr->y + mePtr->height, mePtr->width,
+ Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth,
+ 0, TK_RELIEF_FLAT);
}
}
@@ -698,19 +683,18 @@ DisplayMenu(
if (menuPtr->numEntries == 0) {
x = y = borderWidth;
- width = Tk_Width(tkwin) - 2 * activeBorderWidth;
- height = Tk_Height(tkwin) - 2 * activeBorderWidth;
+ width = Tk_Width(tkwin) - 2 * borderWidth;
+ height = Tk_Height(tkwin) - 2 * borderWidth;
} else {
mePtr = menuPtr->entries[menuPtr->numEntries - 1];
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
border, mePtr->x, mePtr->y + mePtr->height, mePtr->width,
- Tk_Height(tkwin) - mePtr->y - mePtr->height
- - activeBorderWidth, 0,
- TK_RELIEF_FLAT);
+ Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth,
+ 0, TK_RELIEF_FLAT);
x = mePtr->x + mePtr->width;
y = mePtr->y + mePtr->height;
- width = Tk_Width(tkwin) - x - activeBorderWidth;
- height = Tk_Height(tkwin) - y - activeBorderWidth;
+ width = Tk_Width(tkwin) - x - borderWidth;
+ height = Tk_Height(tkwin) - y - borderWidth;
}
Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y,
width, height, 0, TK_RELIEF_FLAT);
diff --git a/generic/tkOption.c b/generic/tkOption.c
index 24e7fb3..545a9b9 100644
--- a/generic/tkOption.c
+++ b/generic/tkOption.c
@@ -996,6 +996,9 @@ AddFromString(
while ((*src == ' ') || (*src == '\t')) {
src++;
}
+ if (*src == '\\' && (src[1] == '\t' || src[1] == ' ')) {
+ src++;
+ }
if (*src == '\0') {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"missing value on line %d", lineNum));
@@ -1025,7 +1028,7 @@ AddFromString(
src += 2;
*dst++ = '\n';
continue;
- } else if (src[1] == '\t' || src[1] == ' ' || src[1] == '\\') {
+ } else if (src[1] == '\\') {
++src;
} else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' &&
src[2] <= '9' && src[3] >= '0' && src[3] <= '9') {
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/tkTest.c b/generic/tkTest.c
index 1fa461e..6712017 100644
--- a/generic/tkTest.c
+++ b/generic/tkTest.c
@@ -31,6 +31,9 @@
#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#include "tkScrollbar.h"
+#define APP_IS_DRAWING TkTestAppIsDrawing()
+#else
+#define APP_IS_DRAWING 0
#endif
#ifdef __UNIX__
@@ -168,7 +171,7 @@ static int TestmenubarObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
#endif
-#if defined(_WIN32) || defined(MAC_OSX_TK)
+#if defined(_WIN32)
static int TestmetricsObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj * const objv[]);
@@ -266,17 +269,17 @@ Tktest_Init(
Tcl_CreateObjCommand(interp, "testtext", TkpTesttextCmd,
(ClientData) Tk_MainWindow(interp), NULL);
-#if defined(_WIN32) || defined(MAC_OSX_TK)
+#if defined(_WIN32)
Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
-#elif !defined(__CYGWIN__)
+#elif !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testsend", TkpTestsendCmd,
(ClientData) Tk_MainWindow(interp), NULL);
Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd,
(ClientData) Tk_MainWindow(interp), NULL);
-#endif /* _WIN32 || MAC_OSX_TK */
+#endif /* _WIN32 */
/*
* Create test image type.
@@ -1550,16 +1553,36 @@ ImageDisplay(
TImageInstance *instPtr = (TImageInstance *) clientData;
char buffer[200 + TCL_INTEGER_SPACE * 6];
+ /*
+ * The purpose of the test image type is to track the calls to an image
+ * display proc and record the parameters passed in each call. On macOS
+ * these tests will fail because of the asynchronous drawing. The low
+ * level graphics calls below which are supposed to draw a rectangle will
+ * not draw anything to the screen because the idle task will not be
+ * processed inside of the drawRect method and hence will not be able to
+ * obtain a valid graphics context. Instead, the window will be marked as
+ * needing display, and will be redrawn during a future asynchronous call
+ * to drawRect. This will generate an other call to this display proc,
+ * and the recorded data will show extra calls, causing the test to fail.
+ * To avoid this, we can set the [NSApp simulateDrawing] flag, which will
+ * cause all low level drawing routines to return immediately and not
+ * schedule the window for drawing later. This flag is cleared by the
+ * next call to XSync, which is called by the update command.
+ */
+
sprintf(buffer, "%s display %d %d %d %d",
instPtr->masterPtr->imageName, imageX, imageY, width, height);
- Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
- buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ if (!APP_IS_DRAWING) {
+ Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName,
+ NULL, buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+ }
if (width > (instPtr->masterPtr->width - imageX)) {
width = instPtr->masterPtr->width - imageX;
}
if (height > (instPtr->masterPtr->height - imageY)) {
height = instPtr->masterPtr->height - imageY;
}
+
XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
(unsigned) (width-1), (unsigned) (height-1));
XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,
@@ -1764,7 +1787,7 @@ TestmenubarObjCmd(
*----------------------------------------------------------------------
*/
-#if defined(_WIN32) || defined(MAC_OSX_TK)
+#if defined(_WIN32)
static int
TestmetricsObjCmd(
ClientData clientData, /* Main window for application. */
@@ -1775,38 +1798,15 @@ TestmetricsObjCmd(
char buf[TCL_INTEGER_SPACE];
int val;
-#ifdef _WIN32
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
return TCL_ERROR;
}
-#else
- Tk_Window tkwin = (Tk_Window) clientData;
- TkWindow *winPtr;
-
- if (objc != 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "option window");
- return TCL_ERROR;
- }
-
- winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
- if (winPtr == NULL) {
- return TCL_ERROR;
- }
-#endif
if (strcmp(Tcl_GetString(objv[1]), "cyvscroll") == 0) {
-#ifdef _WIN32
val = GetSystemMetrics(SM_CYVSCROLL);
-#else
- val = ((TkScrollbar *) winPtr->instanceData)->width;
-#endif
} else if (strcmp(Tcl_GetString(objv[1]), "cxhscroll") == 0) {
-#ifdef _WIN32
val = GetSystemMetrics(SM_CXHSCROLL);
-#else
- val = ((TkScrollbar *) winPtr->instanceData)->width;
-#endif
} else {
Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
"\": must be cxhscroll or cyvscroll", NULL);
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/tkTextDisp.c b/generic/tkTextDisp.c
index 126b631..348b8c4 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -24,6 +24,11 @@
#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
+#define OK_TO_LOG (!TkpAppIsDrawing())
+#define FORCE_DISPLAY(winPtr) TkpDisplayWindow(winPtr)
+#else
+#define OK_TO_LOG 1
+#define FORCE_DISPLAY(winPtr)
#endif
/*
@@ -203,12 +208,21 @@ typedef struct TextStyle {
(fabs((double1)-(double2))*((scaleFactor)+1.0) < 0.3)
/*
- * Macro to make debugging/testing logging a little easier.
+ * Macros to make debugging/testing logging a little easier.
+ *
+ * On OSX 10.14 Drawing procedures are sometimes run because the system has
+ * decided to redraw the window. This can corrupt the data that a test is
+ * trying to collect. So we don't write to the logging variables when the
+ * drawing procedure is being run that way. Other systems can always log.
*/
-#define LOG(toVar,what) \
- Tcl_SetVar2(textPtr->interp, toVar, NULL, (what), \
- TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT)
+#define LOG(toVar,what) \
+ if (OK_TO_LOG) \
+ Tcl_SetVar2(textPtr->interp, toVar, NULL, (what), \
+ TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT)
+#define CLEAR(var) \
+ if (OK_TO_LOG) \
+ Tcl_SetVar2(interp, var, NULL, "", TCL_GLOBAL_ONLY)
/*
* The following structure describes one line of the display, which may be
@@ -3121,6 +3135,18 @@ GenerateWidgetViewSyncEvent(
TkText *textPtr, /* Information about text widget. */
Bool InSync) /* true if in sync, false otherwise */
{
+ /*
+ * OSX 10.14 needs to be told to display the window when the Text Widget
+ * is in sync. (That is, to run DisplayText inside of the drawRect
+ * method.) Otherwise the screen might not get updated until an event
+ * like a mouse click is received. But that extra drawing corrupts the
+ * data that the test suite is trying to collect.
+ */
+
+ if (!tkTextDebug) {
+ FORCE_DISPLAY(textPtr->tkwin);
+ }
+
TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
Tcl_NewBooleanObj(InSync));
}
@@ -4136,7 +4162,7 @@ DisplayText(
Tcl_Preserve(interp);
if (tkTextDebug) {
- Tcl_SetVar2(interp, "tk_textRelayout", NULL, "", TCL_GLOBAL_ONLY);
+ CLEAR("tk_textRelayout");
}
if (!Tk_IsMapped(textPtr->tkwin) || (dInfoPtr->maxX <= dInfoPtr->x)
@@ -4147,7 +4173,7 @@ DisplayText(
}
numRedisplays++;
if (tkTextDebug) {
- Tcl_SetVar2(interp, "tk_textRedraw", NULL, "", TCL_GLOBAL_ONLY);
+ CLEAR("tk_textRedraw");
}
/*
@@ -5134,6 +5160,7 @@ TkTextRelayoutWindow(
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
GC newGC;
XGCValues gcValues;
+ Bool inSync = 1;
/*
* Schedule the window redisplay. See TkTextChanged for the reason why
@@ -5142,6 +5169,7 @@ TkTextRelayoutWindow(
if (!(dInfoPtr->flags & REDRAW_PENDING)) {
Tcl_DoWhenIdle(DisplayText, textPtr);
+ inSync = 0;
}
dInfoPtr->flags |= REDRAW_PENDING|REDRAW_BORDERS|DINFO_OUT_OF_DATE
|REPICK_NEEDED;
@@ -5213,6 +5241,7 @@ TkTextRelayoutWindow(
dInfoPtr->yScrollFirst = dInfoPtr->yScrollLast = -1;
if (mask & TK_TEXT_LINE_GEOMETRY) {
+
/*
* Set up line metric recalculation.
*
@@ -5237,7 +5266,11 @@ TkTextRelayoutWindow(
textPtr->refCount++;
dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
AsyncUpdateLineMetrics, textPtr);
- GenerateWidgetViewSyncEvent(textPtr, 0);
+ inSync = 0;
+ }
+
+ if (!inSync) {
+ GenerateWidgetViewSyncEvent(textPtr, 0);
}
}
}
@@ -6264,7 +6297,8 @@ TkTextPendingsync(
TextDInfo *dInfoPtr = textPtr->dInfoPtr;
return (
- ((dInfoPtr->metricEpoch == -1) &&
+ (!(dInfoPtr->flags & REDRAW_PENDING) &&
+ (dInfoPtr->metricEpoch == -1) &&
(dInfoPtr->lastMetricUpdateLine == dInfoPtr->currentMetricUpdateLine)) ?
0 : 1);
}
diff --git a/generic/ttk/ttkDefaultTheme.c b/generic/ttk/ttkDefaultTheme.c
index 4a06192..d331655 100644
--- a/generic/ttk/ttkDefaultTheme.c
+++ b/generic/ttk/ttkDefaultTheme.c
@@ -18,6 +18,10 @@ static const int WIN32_XDRAWLINE_HACK = 1;
static const int WIN32_XDRAWLINE_HACK = 0;
#endif
+#if defined(MAC_OSX_TK)
+ #define IGNORES_VISUAL
+#endif
+
#define BORDERWIDTH 2
#define SCROLLBAR_WIDTH 14
#define MIN_THUMB_SIZE 8
@@ -510,7 +514,7 @@ static void IndicatorElementDraw(
XGCValues gcValues;
GC copyGC;
unsigned long imgColors[8];
- XImage *img;
+ XImage *img = NULL;
Ttk_GetPaddingFromObj(NULL, tkwin, indicator->marginObj, &padding);
b = Ttk_PadBox(b, padding);
@@ -550,15 +554,48 @@ static void IndicatorElementDraw(
/*
* Create a scratch buffer to store the image:
*/
- img = XGetImage(display,d, 0, 0,
- (unsigned int)spec->width, (unsigned int)spec->height,
- AllPlanes, ZPixmap);
- if (img == NULL)
+
+#if defined(IGNORES_VISUAL)
+
+ /*
+ * Platforms which ignore the VisualInfo can use XCreateImage to get the
+ * scratch image. This is essential on macOS, where it is not safe to call
+ * XGetImage in a display procedure.
+ */
+
+ img = XCreateImage(display, NULL, 32, ZPixmap, 0, NULL,
+ (unsigned int)spec->width, (unsigned int)spec->height,
+ 0, 0);
+#else
+
+ /*
+ * This trick allows creating the scratch XImage without having to
+ * construct a VisualInfo.
+ */
+
+ img = XGetImage(display, d, 0, 0,
+ (unsigned int)spec->width, (unsigned int)spec->height,
+ AllPlanes, ZPixmap);
+#endif
+
+ if (img == NULL) {
+ return;
+ }
+
+#if defined(IGNORES_VISUAL)
+
+ img->data = ckalloc(img->bytes_per_line * img->height);
+ if (img->data == NULL) {
+ XDestroyImage(img);
return;
+ }
+
+#endif
/*
- * Create the image, painting it into an XImage one pixel at a time.
+ * Create the image, painting it into the XImage one pixel at a time.
*/
+
index = Ttk_StateTableLookup(spec->map, state);
for (iy=0 ; iy<spec->height ; iy++) {
for (ix=0 ; ix<spec->width ; ix++) {
@@ -568,18 +605,31 @@ static void IndicatorElementDraw(
}
/*
- * Copy onto our target drawable surface.
+ * Copy the image onto our target drawable surface.
*/
+
memset(&gcValues, 0, sizeof(gcValues));
copyGC = Tk_GetGC(tkwin, 0, &gcValues);
-
TkPutImage(NULL, 0, display, d, copyGC, img, 0, 0, b.x, b.y,
spec->width, spec->height);
/*
* Tidy up.
*/
+
Tk_FreeGC(display, copyGC);
+
+ /*
+ * Protect against the possibility that some future platform might
+ * not use the Tk memory manager in its implementation of XDestroyImage,
+ * even though that would be an extremely strange thing to do.
+ */
+
+#if defined(IGNORES_VISUAL)
+ ckfree(img->data);
+ img->data = NULL;
+#endif
+
XDestroyImage(img);
}
diff --git a/generic/ttk/ttkTheme.c b/generic/ttk/ttkTheme.c
index 2f95962..c0bd784 100644
--- a/generic/ttk/ttkTheme.c
+++ b/generic/ttk/ttkTheme.c
@@ -18,6 +18,13 @@
#define PKG_ASSOC_KEY "Ttk"
+#ifdef MAC_OSX_TK
+ extern void TkMacOSXFlushWindows(void);
+ #define UPDATE_WINDOWS() TkMacOSXFlushWindows()
+#else
+ #define UPDATE_WINDOWS()
+#endif
+
/*------------------------------------------------------------------------
* +++ Styles.
*
@@ -513,6 +520,7 @@ static void ThemeChangedProc(ClientData clientData)
Tcl_BackgroundException(pkgPtr->interp, code);
}
pkgPtr->themeChangePending = 0;
+ UPDATE_WINDOWS();
}
/*
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;
}