Skip to content

Commit 2f48a05

Browse files
author
csaba
committed
Fix for bug [265ff202e9]: Artifacts in a few themed widgets on x11 and aqua.
2 parents 99aa59f + e85a9ac commit 2f48a05

File tree

2 files changed

+118
-33
lines changed

2 files changed

+118
-33
lines changed

generic/ttk/ttkDefaultTheme.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,19 @@ static const enum BorderColor thinShadowColors[6][4] = {
5959
static void DrawCorner(
6060
Tk_Window tkwin,
6161
Drawable d,
62-
Tk_3DBorder border, /* get most GCs from here... */
63-
GC borderGC, /* "window border" color GC */
62+
Tk_3DBorder border, /* get most GCs from here... */
63+
GC borderGC, /* "window border" color GC */
6464
int x, int y, int width, int height, /* where to draw */
65-
bool corner, /* false => top left; true => bottom right */
65+
bool corner, /* false => top left; true => bottom right */
6666
enum BorderColor color)
6767
{
6868
XPoint points[3];
6969
GC gc;
7070

7171
--width; --height;
72-
points[0].x = x; points[0].y = y+height;
73-
points[1].x = corner ? x + width : x; points[1].y = corner ? y + height : y;
74-
points[2].x = x+width; points[2].y = y;
72+
points[0].x = x; points[0].y = y+height;
73+
points[1].x = corner ? x + width : x; points[1].y = corner ? y + height : y;
74+
points[2].x = x+width; points[2].y = y;
7575

7676
if (corner) {
7777
points[2].y -= WIN32_XDRAWLINE_HACK;
@@ -379,10 +379,11 @@ static void FieldElementDraw(
379379
XColor *focusColor = Tk_GetColorFromObj(tkwin, field->focusColorObj);
380380
GC focusGC = Tk_GCForColor(focusColor, d);
381381

382-
if (focusWidth > 1) {
382+
if (focusWidth > 1 && b.width >= 2 && b.height >= 2) {
383383
int x1 = b.x, x2 = b.x + b.width - 1;
384384
int y1 = b.y, y2 = b.y + b.height - 1;
385385
int w = WIN32_XDRAWLINE_HACK;
386+
GC bgGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
386387

387388
/*
388389
* Draw the outer rounded rectangle
@@ -401,7 +402,6 @@ static void FieldElementDraw(
401402
/*
402403
* Fill the inner rectangle
403404
*/
404-
GC bgGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
405405
XFillRectangle(disp, d, bgGC, b.x+1, b.y+1, b.width-2, b.height-2);
406406
} else {
407407
/*

generic/ttk/ttkElements.c

Lines changed: 110 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,69 @@
1919
#define DEFAULT_ARROW_SIZE "15"
2020
#define MIN_THUMB_SIZE 10
2121

22+
/*
23+
*----------------------------------------------------------------------
24+
*
25+
* Helper routine for drawing a few style elements:
26+
*
27+
* The following function is needed when drawing the trough element
28+
* (which is used in scrollbars, scales, and progressbars) and the
29+
* arrow and thumb elements of a scrollbar. It draws the light or dark
30+
* border color along the entire bottom and right edges, contrary to
31+
* the Tk_Fill3DRectangle function, which on the windowing systems x11
32+
* and aqua draws the light or dark border color along the entire top
33+
* and left edges instead.
34+
*
35+
* An alternative approach would be to modify the function
36+
* Tk_3DHorizontalBevel in the file unix/tkUnix3d.c. That function is
37+
* called in Tk_Draw3DRectangle, which in turn is invoked in
38+
* Tk_Fill3DRectangle (both functions are implemented in the file
39+
* generic/tk3d.c). With that approach there would be no need for the
40+
* Fill3DRectangle function below, but it would result in some (minor)
41+
* changes related to the appearance of most Tk and Ttk widgets on x11
42+
* and aqua.
43+
*/
44+
45+
#if defined(_WIN32)
46+
#define Fill3DRectangle Tk_Fill3DRectangle
47+
#else
48+
static void Fill3DRectangle(
49+
Tk_Window tkwin, /* Window for which border was allocated. */
50+
Drawable drawable, /* X window or pixmap in which to draw. */
51+
Tk_3DBorder border, /* Token for border to draw. */
52+
int x, int y, /* Upper-left corner of the rectangle. */
53+
int width, int height, /* The width and height of the rectangle. */
54+
int borderWidth, /* Desired width for border, in pixels. Border
55+
* will be *inside* region. */
56+
int relief) /* Indicates 3D effect: TK_RELIEF_FLAT,
57+
* TK_RELIEF_RAISED, TK_RELIEF_SUNKEN, etc. */
58+
{
59+
if (borderWidth == 1 && width >= 2 && height >= 2 &&
60+
(relief == TK_RELIEF_RAISED || relief == TK_RELIEF_SUNKEN)) {
61+
GC flatGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
62+
GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
63+
GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
64+
GC nGC, wGC, sGC, eGC;
65+
int x1 = x, x2 = x + width - 1;
66+
int y1 = y, y2 = y + height - 1;
67+
68+
XFillRectangle(Tk_Display(tkwin), drawable, flatGC,
69+
x + 1, y + 1, width - 2, height - 2);
70+
71+
nGC = wGC = (relief == TK_RELIEF_RAISED ? lightGC : darkGC);
72+
sGC = eGC = (relief == TK_RELIEF_RAISED ? darkGC : lightGC);
73+
74+
XDrawLine(Tk_Display(tkwin), drawable, nGC, x1, y1, x2-1, y1); /* N */
75+
XDrawLine(Tk_Display(tkwin), drawable, wGC, x1, y1, x1, y2-1); /* W */
76+
XDrawLine(Tk_Display(tkwin), drawable, sGC, x1, y2, x2, y2); /* S */
77+
XDrawLine(Tk_Display(tkwin), drawable, eGC, x2, y1, x2, y2); /* E */
78+
} else {
79+
Tk_Fill3DRectangle(tkwin, drawable, border, x, y, width, height,
80+
borderWidth, relief);
81+
}
82+
}
83+
#endif
84+
2285
/*----------------------------------------------------------------------
2386
* +++ Null element. Does nothing; used as a stub.
2487
* Null element methods, option table and element spec are public,
@@ -243,11 +306,11 @@ static void FieldElementDraw(
243306
XColor *focusColor = Tk_GetColorFromObj(tkwin, field->focusColorObj);
244307
GC focusGC = Tk_GCForColor(focusColor, d);
245308

246-
if (focusWidth > 1) {
309+
if (focusWidth > 1 && b.width >= 2 && b.height >= 2) {
247310
int x1 = b.x, x2 = b.x + b.width - 1;
248311
int y1 = b.y, y2 = b.y + b.height - 1;
249312
int w = WIN32_XDRAWLINE_HACK;
250-
GC bgGC;
313+
GC bgGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
251314

252315
/*
253316
* Draw the outer rounded rectangle
@@ -266,7 +329,6 @@ static void FieldElementDraw(
266329
/*
267330
* Fill the inner rectangle
268331
*/
269-
bgGC = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC);
270332
XFillRectangle(disp, d, bgGC, b.x+1, b.y+1, b.width-2, b.height-2);
271333
} else {
272334
/*
@@ -384,15 +446,25 @@ static void DrawFocusRing(
384446
gc = Tk_GetGC(tkwin, GCForeground, &gcValues);
385447

386448
if (solid) {
387-
XRectangle rects[4] = {
388-
{(short)b.x, (short)b.y, (unsigned short)b.width, (unsigned short)thickness}, /* N */
389-
{(short)b.x, (short)(b.y + b.height - thickness), (unsigned short)b.width, (unsigned short)thickness}, /* S */
390-
{(short)b.x, (short)(b.y + thickness), (unsigned short)thickness, (unsigned short)(b.height - 2*thickness)}, /* W */
391-
{(short)(b.x + b.width - thickness), (short)(b.y + thickness), /* E */
392-
(unsigned short)thickness, (unsigned short)(b.height - 2*thickness)}
393-
};
394-
395-
XFillRectangles(disp, d, gc, rects, 4);
449+
if (b.width >= 2*thickness && b.height >= 2*thickness) {
450+
XRectangle rects[4] = {
451+
{(short)b.x, (short)b.y,
452+
(unsigned short)b.width, (unsigned short)thickness}, /* N */
453+
454+
{(short)b.x, (short)(b.y + b.height - thickness),
455+
(unsigned short)b.width, (unsigned short)thickness}, /* S */
456+
457+
{(short)b.x, (short)(b.y + thickness),
458+
(unsigned short)thickness,
459+
(unsigned short)(b.height - 2*thickness)}, /* W */
460+
461+
{(short)(b.x + b.width - thickness), (short)(b.y + thickness),
462+
(unsigned short)thickness,
463+
(unsigned short)(b.height - 2*thickness)} /* E */
464+
};
465+
466+
XFillRectangles(disp, d, gc, rects, 4);
467+
}
396468
} else {
397469
TkDrawDottedRect(disp, d, gc, b.x, b.y, b.width, b.height);
398470
}
@@ -609,16 +681,19 @@ static void SizegripDraw(
609681
GC lightGC = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
610682
GC darkGC = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
611683
int x1 = b.x + b.width-1, y1 = b.y + b.height-1, x2 = x1, y2 = y1;
684+
int w = WIN32_XDRAWLINE_HACK;
612685

613686
Tk_GetPixelsFromObj(NULL, tkwin, grip->gripSizeObj, &gripSize);
614687
gripThickness = gripSize * 3 / (gripCount * 5);
615688
gripSpace = gripSize / 3 - gripThickness;
616689
while (gripCount--) {
617690
x1 -= gripSpace; y2 -= gripSpace;
618691
for (int i = 1; i < gripThickness; i++) {
619-
XDrawLine(Tk_Display(tkwin), d, darkGC, x1,y1, x2,y2); --x1; --y2;
692+
XDrawLine(Tk_Display(tkwin), d, darkGC,
693+
x1, y1, x2+w, y2-w); --x1; --y2;
620694
}
621-
XDrawLine(Tk_Display(tkwin), d, lightGC, x1,y1, x2,y2); --x1; --y2;
695+
XDrawLine(Tk_Display(tkwin), d, lightGC,
696+
x1, y1, x2+w, y2-w); --x1; --y2;
622697
}
623698
}
624699

@@ -976,7 +1051,7 @@ static void ArrowElementDraw(
9761051
Tk_GetPixelsFromObj(NULL, tkwin, arrow->borderWidthObj, &borderWidth);
9771052
Tk_GetReliefFromObj(NULL, arrow->reliefObj, &relief);
9781053

979-
Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
1054+
Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
9801055
borderWidth, relief);
9811056

9821057
padding.left = round(ArrowPadding.left * scalingLevel);
@@ -1257,7 +1332,7 @@ static void TroughElementDraw(
12571332
}
12581333
}
12591334

1260-
Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
1335+
Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
12611336
borderWidth, relief);
12621337
}
12631338

@@ -1332,7 +1407,7 @@ static void ThumbElementDraw(
13321407

13331408
Tk_GetPixelsFromObj(NULL, tkwin, thumb->borderWidthObj, &borderWidth);
13341409
Tk_GetReliefFromObj(NULL, thumb->reliefObj, &relief);
1335-
Tk_Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
1410+
Fill3DRectangle(tkwin, d, border, b.x, b.y, b.width, b.height,
13361411
borderWidth, relief);
13371412
}
13381413

@@ -1818,20 +1893,30 @@ static void TabElementDraw(
18181893
switch (nbTabsStickBit) {
18191894
default:
18201895
case TTK_STICK_S:
1821-
XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
1822-
b.x + cut, b.y, b.width - 2*cut, cut);
1896+
if (b.width >= 2*cut) {
1897+
XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
1898+
b.x + cut, b.y, b.width - 2*cut, cut);
1899+
}
18231900
break;
18241901
case TTK_STICK_N:
1825-
XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
1826-
b.x + cut, b.y + b.height - cut, b.width - 2*cut, cut);
1902+
if (b.width >= 2*cut) {
1903+
XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
1904+
b.x + cut, b.y + b.height - cut,
1905+
b.width - 2*cut, cut);
1906+
}
18271907
break;
18281908
case TTK_STICK_E:
1829-
XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
1830-
b.x, b.y + cut, cut, b.height - 2*cut);
1909+
if (b.height >= 2*cut) {
1910+
XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
1911+
b.x, b.y + cut, cut, b.height - 2*cut);
1912+
}
18311913
break;
18321914
case TTK_STICK_W:
1833-
XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
1834-
b.x + b.width - cut, b.y + cut, cut, b.height - 2*cut);
1915+
if (b.height >= 2*cut) {
1916+
XFillRectangle(disp, d, Tk_GCForColor(hlColor, d),
1917+
b.x + b.width - cut, b.y + cut,
1918+
cut, b.height - 2*cut);
1919+
}
18351920
break;
18361921
}
18371922
}

0 commit comments

Comments
 (0)