Skip to content

Commit b1147aa

Browse files
author
jan.nijtmans
committed
Merge 9.0
2 parents 2f48a05 + 532d8ad commit b1147aa

File tree

3 files changed

+119
-14
lines changed

3 files changed

+119
-14
lines changed

changes.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ necessarily in Tk 8.
2222
- [Add a ttk::toggleswitch widget to the core](https://core.tcl-lang.org/tips/doc/trunk/tip/727.md)
2323
- [Add a tk attribtable command to the core](https://core.tcl-lang.org/tips/doc/trunk/tip/729.md)
2424
- [Implement more X11 region functions on Windows and Aqua](https://core.tcl-lang.org/tk/info/50fdbc36ad)
25-
25+
2626
# Potential incompatibilities to 9.0
2727
- [MS-Win: the undocumented option -xpstyle was removed from tk_chooseDirectory and tk_getOpenFile](https://core.tcl-lang.org/tk/tktview/441c52)
2828
- [MS-Win: The "xpnative" ttk style is gone too, in favor of "vista"](https://core.tcl-lang.org/tk/tktview/441c52)
29-

generic/ttk/ttkCache.c

Lines changed: 117 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,34 @@
2121
* The plumbing and control flow here is quite contorted;
2222
* it would be better to address this problem in the core instead.
2323
*
24-
* @@@ BUGS/TODO: Need distinct caches for each combination
25-
* of display, visual, and colormap.
26-
*
2724
* @@@ Colormap flashing on PseudoColor visuals is still possible,
2825
* but this will be a transient effect.
2926
*/
3027

3128
#include "tkInt.h"
3229
#include "ttkTheme.h"
3330

31+
#if defined(_WIN32) || defined(MAC_OSX_TK)
32+
# define NEED_EXTRA_INFO 0
33+
#else
34+
/*
35+
* Display, Screen, Visual, and Colormap need be tracked, too.
36+
* Required on X11 with multiple display connections or
37+
* special visuals/colormaps.
38+
*/
39+
# define NEED_EXTRA_INFO 1
40+
#endif
41+
42+
#if NEED_EXTRA_INFO
43+
typedef struct {
44+
Tcl_Obj *objPtr; /* The cached Tcl_Obj*. */
45+
Display *display; /* Display of (Font|Border|Color)Obj */
46+
int screenNum; /* Screen number of (Font|Border|Color)Obj */
47+
Visual *visual; /* Visual of (Font|Border|Color)Obj */
48+
Colormap colormap; /* Colormap of (Font|Border|Color)Obj */
49+
} Ttk_Cached;
50+
#endif
51+
3452
#ifdef _WIN32
3553
#include "tkWinInt.h"
3654
#endif
@@ -79,11 +97,27 @@ static void Ttk_ClearCache(Ttk_ResourceCache cache)
7997
*/
8098
entryPtr = Tcl_FirstHashEntry(&cache->fontTable, &search);
8199
while (entryPtr != NULL) {
100+
#if !NEED_EXTRA_INFO
82101
Tcl_Obj *fontObj = (Tcl_Obj *)Tcl_GetHashValue(entryPtr);
83102
if (fontObj) {
84103
Tk_FreeFontFromObj(cache->tkwin, fontObj);
85104
Tcl_DecrRefCount(fontObj);
86105
}
106+
#else
107+
Ttk_Cached *cachedPtr = Tcl_GetHashValue(entryPtr);
108+
if (cachedPtr) {
109+
TkWindow fakeWin;
110+
Tcl_Obj *fontObj = cachedPtr->objPtr;
111+
fakeWin = *((TkWindow *) cache->tkwin);
112+
fakeWin.display = cachedPtr->display;
113+
fakeWin.screenNum = cachedPtr->screenNum;
114+
fakeWin.visual = cachedPtr->visual;
115+
fakeWin.atts.colormap = cachedPtr->colormap;
116+
Tk_FreeFontFromObj((Tk_Window) &fakeWin, fontObj);
117+
Tcl_DecrRefCount(fontObj);
118+
ckfree(cachedPtr);
119+
}
120+
#endif
87121
entryPtr = Tcl_NextHashEntry(&search);
88122
}
89123
Tcl_DeleteHashTable(&cache->fontTable);
@@ -94,11 +128,27 @@ static void Ttk_ClearCache(Ttk_ResourceCache cache)
94128
*/
95129
entryPtr = Tcl_FirstHashEntry(&cache->colorTable, &search);
96130
while (entryPtr != NULL) {
131+
#if !NEED_EXTRA_INFO
97132
Tcl_Obj *colorObj = (Tcl_Obj *)Tcl_GetHashValue(entryPtr);
98133
if (colorObj) {
99134
Tk_FreeColorFromObj(cache->tkwin, colorObj);
100135
Tcl_DecrRefCount(colorObj);
101136
}
137+
#else
138+
Ttk_Cached *cachedPtr = Tcl_GetHashValue(entryPtr);
139+
if (cachedPtr) {
140+
TkWindow fakeWin;
141+
Tcl_Obj *colorObj = cachedPtr->objPtr;
142+
fakeWin = *((TkWindow *) cache->tkwin);
143+
fakeWin.display = cachedPtr->display;
144+
fakeWin.screenNum = cachedPtr->screenNum;
145+
fakeWin.visual = cachedPtr->visual;
146+
fakeWin.atts.colormap = cachedPtr->colormap;
147+
Tk_FreeColorFromObj((Tk_Window) &fakeWin, colorObj);
148+
Tcl_DecrRefCount(colorObj);
149+
ckfree(cachedPtr);
150+
}
151+
#endif
102152
entryPtr = Tcl_NextHashEntry(&search);
103153
}
104154
Tcl_DeleteHashTable(&cache->colorTable);
@@ -109,11 +159,27 @@ static void Ttk_ClearCache(Ttk_ResourceCache cache)
109159
*/
110160
entryPtr = Tcl_FirstHashEntry(&cache->borderTable, &search);
111161
while (entryPtr != NULL) {
162+
#if !NEED_EXTRA_INFO
112163
Tcl_Obj *borderObj = (Tcl_Obj *)Tcl_GetHashValue(entryPtr);
113164
if (borderObj) {
114165
Tk_Free3DBorderFromObj(cache->tkwin, borderObj);
115166
Tcl_DecrRefCount(borderObj);
116167
}
168+
#else
169+
Ttk_Cached *cachedPtr = Tcl_GetHashValue(entryPtr);
170+
if (cachedPtr) {
171+
TkWindow fakeWin;
172+
Tcl_Obj *borderObj = cachedPtr->objPtr;
173+
fakeWin = *((TkWindow *) cache->tkwin);
174+
fakeWin.display = cachedPtr->display;
175+
fakeWin.screenNum = cachedPtr->screenNum;
176+
fakeWin.visual = cachedPtr->visual;
177+
fakeWin.atts.colormap = cachedPtr->colormap;
178+
Tk_Free3DBorderFromObj((Tk_Window) &fakeWin, borderObj);
179+
Tcl_DecrRefCount(borderObj);
180+
ckfree(cachedPtr);
181+
}
182+
#endif
117183
entryPtr = Tcl_NextHashEntry(&search);
118184
}
119185
Tcl_DeleteHashTable(&cache->borderTable);
@@ -186,14 +252,12 @@ static void CacheWinEventHandler(void *clientData, XEvent *eventPtr)
186252
/*
187253
* InitCacheWindow --
188254
* Specify the cache window if not already set.
189-
* @@@ SHOULD: use separate caches for each combination
190-
* @@@ of display, visual, and colormap.
191255
*/
192256
static void InitCacheWindow(Ttk_ResourceCache cache, Tk_Window tkwin)
193257
{
194258
if (cache->tkwin == NULL) {
195-
cache->tkwin = tkwin;
196-
Tk_CreateEventHandler(tkwin, StructureNotifyMask,
259+
cache->tkwin = Tk_MainWindow(cache->interp);
260+
Tk_CreateEventHandler(cache->tkwin, StructureNotifyMask,
197261
CacheWinEventHandler, cache);
198262
}
199263
}
@@ -266,19 +330,47 @@ static Tcl_Obj *Ttk_Use(
266330
Tcl_Obj *objPtr)
267331
{
268332
int newEntry;
269-
Tcl_HashEntry *entryPtr =
270-
Tcl_CreateHashEntry(table,Tcl_GetString(objPtr),&newEntry);
333+
Tcl_HashEntry *entryPtr;
271334
Tcl_Obj *cacheObj;
335+
#if !NEED_EXTRA_INFO
336+
entryPtr = Tcl_CreateHashEntry(table, Tcl_GetString(objPtr), &newEntry);
337+
#else
338+
Tcl_DString ds;
339+
char buffer[64];
340+
341+
Tcl_DStringInit(&ds);
342+
Tcl_DStringAppend(&ds, Tcl_GetString(objPtr), -1);
343+
snprintf(buffer, 64, ",%d,%lu,%lu", ConnectionNumber(Tk_Display(tkwin)),
344+
Tk_Visual(tkwin)->visualid, (unsigned long)Tk_Colormap(tkwin));
345+
Tcl_DStringAppend(&ds, buffer, -1);
346+
entryPtr = Tcl_CreateHashEntry(table, Tcl_DStringValue(&ds), &newEntry);
347+
Tcl_DStringFree(&ds);
348+
#endif
272349

273350
if (!newEntry) {
351+
#if !NEED_EXTRA_INFO
274352
return (Tcl_Obj *)Tcl_GetHashValue(entryPtr);
353+
#else
354+
Ttk_Cached *cachedPtr = Tcl_GetHashValue(entryPtr);
355+
return cachedPtr ? cachedPtr->objPtr : NULL;
356+
#endif
275357
}
276358

277359
cacheObj = Tcl_DuplicateObj(objPtr);
278360
Tcl_IncrRefCount(cacheObj);
279361

280362
if (allocate(interp, tkwin, cacheObj)) {
363+
#if !NEED_EXTRA_INFO
281364
Tcl_SetHashValue(entryPtr, cacheObj);
365+
#else
366+
Ttk_Cached *cachedPtr = ckalloc(sizeof(*cachedPtr));
367+
cachedPtr->objPtr = cacheObj;
368+
cachedPtr->display = Tk_Display(tkwin);
369+
cachedPtr->screenNum = Tk_ScreenNumber(tkwin);
370+
cachedPtr->visual = Tk_Visual(tkwin);
371+
cachedPtr->colormap = Tk_Colormap(tkwin);
372+
Tcl_SetHashValue(entryPtr, cachedPtr);
373+
#endif
282374
return cacheObj;
283375
} else {
284376
Tcl_DecrRefCount(cacheObj);
@@ -347,11 +439,25 @@ Tk_Image Ttk_UseImage(Ttk_ResourceCache cache, Tk_Window tkwin, Tcl_Obj *objPtr)
347439
{
348440
const char *imageName = Tcl_GetString(objPtr);
349441
int newEntry;
350-
Tcl_HashEntry *entryPtr =
351-
Tcl_CreateHashEntry(&cache->imageTable,imageName,&newEntry);
442+
Tcl_HashEntry *entryPtr;
352443
Tk_Image image;
353444

354445
InitCacheWindow(cache, tkwin);
446+
#if !NEED_EXTRA_INFO
447+
entryPtr = Tcl_CreateHashEntry(&cache->imageTable, imageName, &newEntry);
448+
#else
449+
Tcl_DString ds;
450+
char buffer[64];
451+
452+
Tcl_DStringInit(&ds);
453+
Tcl_DStringAppend(&ds, imageName, -1);
454+
snprintf(buffer, 64, ",%d,%lu,%lu", ConnectionNumber(Tk_Display(tkwin)),
455+
Tk_Visual(tkwin)->visualid, (unsigned long)Tk_Colormap(tkwin));
456+
Tcl_DStringAppend(&ds, buffer, -1);
457+
entryPtr = Tcl_CreateHashEntry(&cache->imageTable,
458+
Tcl_DStringValue(&ds), &newEntry);
459+
Tcl_DStringFree(&ds);
460+
#endif
355461

356462
if (!newEntry) {
357463
return (Tk_Image)Tcl_GetHashValue(entryPtr);

generic/ttk/ttkElements.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*
2525
* Helper routine for drawing a few style elements:
2626
*
27-
* The following function is needed when drawing the trough element
27+
* The following function is needed when drawing the trough element
2828
* (which is used in scrollbars, scales, and progressbars) and the
2929
* arrow and thumb elements of a scrollbar. It draws the light or dark
3030
* border color along the entire bottom and right edges, contrary to

0 commit comments

Comments
 (0)