Skip to content

Commit

Permalink
Fix "scrollbar" part of [610a73a179]: Canvas widget handles pixel obj…
Browse files Browse the repository at this point in the history
…ects incorrectly in Tk 9.0
  • Loading branch information
jan.nijtmans committed Sep 7, 2024
2 parents a161811 + 07b9686 commit d1f1f07
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 90 deletions.
4 changes: 2 additions & 2 deletions generic/tk.h
Original file line number Diff line number Diff line change
Expand Up @@ -1197,8 +1197,8 @@ typedef struct Tk_Outline {
Tk_Dash dash; /* Dash pattern. */
Tk_Dash activeDash; /* Dash pattern if state is active. */
Tk_Dash disabledDash; /* Dash pattern if state is disabled. */
void *reserved1; /* Reserved for future expansion. */
void *reserved2;
Tcl_Obj *offsetObj; /* Dash offset. */
void *reserved2; /* Reserved for future expansion. */
void *reserved3;
Tk_TSOffset tsoffset; /* Stipple offset for outline. */
XColor *color; /* Outline color. */
Expand Down
59 changes: 45 additions & 14 deletions generic/tkOldConfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,9 @@ Tk_ConfigureWidget(
}
Tcl_DecrRefCount(arg);
} else {
if (specPtr->defValue != NULL) {
value = Tk_GetUid(specPtr->defValue);
} else {
value = NULL;
}
if ((value != NULL) && !(specPtr->specFlags
if ((specPtr->defValue != NULL) && !(specPtr->specFlags
& TK_CONFIG_DONT_SET_DEFAULT)) {
Tcl_Obj *arg = Tcl_NewStringObj(value, TCL_INDEX_NONE);
Tcl_Obj *arg = Tcl_NewStringObj(specPtr->defValue, TCL_INDEX_NONE);
Tcl_IncrRefCount(arg);
if (DoConfig(interp, tkwin, specPtr, arg, widgRec) !=
TCL_OK) {
Expand Down Expand Up @@ -351,8 +346,9 @@ DoConfig(
nullValue = 1;
}

if (specPtr->specFlags & TK_CONFIG_OBJS) {
/* Prevent surprises, TK_CONFIG_OBJS is not supported yet */
if ((specPtr->specFlags & TK_CONFIG_OBJS) && (specPtr->type != TK_CONFIG_STRING)
&& (specPtr->type != TK_CONFIG_PIXELS)) {
/* Prevent surprises for other options than TK_CONFIG_(STRING|PIXELS) */
Tcl_AppendResult(interp, "TK_CONFIG_OBJS not supported", (char *)NULL);
return TCL_ERROR;
}
Expand Down Expand Up @@ -382,13 +378,20 @@ DoConfig(

if (nullValue) {
newStr = NULL;
} else if (specPtr->specFlags & TK_CONFIG_OBJS) {
Tcl_IncrRefCount(arg);
newStr = (char *)arg;
} else {
newStr = (char *)ckalloc(strlen(value) + 1);
strcpy(newStr, value);
}
oldStr = *((char **)ptr);
if (oldStr != NULL) {
ckfree(oldStr);
if (specPtr->specFlags & TK_CONFIG_OBJS) {
Tcl_DecrRefCount((Tcl_Obj *)oldStr);
} else {
ckfree(oldStr);
}
}
*((char **)ptr) = newStr;
break;
Expand Down Expand Up @@ -424,7 +427,7 @@ DoConfig(
if (nullValue) {
newFont = NULL;
} else {
newFont = Tk_GetFont(interp, tkwin, value);
newFont = Tk_AllocFontFromObj(interp, tkwin, arg);
if (newFont == NULL) {
return TCL_ERROR;
}
Expand All @@ -439,7 +442,7 @@ DoConfig(
if (nullValue) {
newBmp = None;
} else {
newBmp = Tk_GetBitmap(interp, tkwin, value);
newBmp = Tk_AllocBitmapFromObj(interp, tkwin, arg);
if (newBmp == None) {
return TCL_ERROR;
}
Expand Down Expand Up @@ -517,7 +520,24 @@ DoConfig(
}
break;
case TK_CONFIG_PIXELS:
if (nullValue) {
if (specPtr->specFlags & TK_CONFIG_OBJS) {
int dummy;
if (nullValue) {
if (*(Tcl_Obj **)ptr != NULL) {
Tcl_DecrRefCount(*(Tcl_Obj **)ptr);
*(Tcl_Obj **)ptr = NULL;
}
} else if (Tk_GetPixelsFromObj(interp, tkwin, arg, &dummy)
!= TCL_OK) {
return TCL_ERROR;
} else {
Tcl_IncrRefCount(arg);
if (*(Tcl_Obj **)ptr != NULL) {
Tcl_DecrRefCount(*(Tcl_Obj **)ptr);
}
*(Tcl_Obj **)ptr = arg;
}
} else if (nullValue) {
*(int *)ptr = INT_MIN;
} else if (Tk_GetPixelsFromObj(interp, tkwin, arg, (int *)ptr)
!= TCL_OK) {
Expand Down Expand Up @@ -771,6 +791,12 @@ FormatConfigValue(
}
ptr = (char *)widgRec + specPtr->offset;
result = "";
if (specPtr->specFlags & TK_CONFIG_OBJS) {
if (*(Tcl_Obj **)ptr != NULL) {
result = Tcl_GetString(*(Tcl_Obj **)ptr);
}
return result;
}
switch (specPtr->type) {
case TK_CONFIG_BOOLEAN:
if (*((int *)ptr) == 0) {
Expand All @@ -788,7 +814,7 @@ FormatConfigValue(
result = buffer;
break;
case TK_CONFIG_STRING:
result = (*(char **)ptr);
result = *(char **)ptr;
if (result == NULL) {
result = "";
}
Expand Down Expand Up @@ -996,6 +1022,11 @@ Tk_FreeOptions(
continue;
}
ptr = (char *)widgRec + specPtr->offset;
if ((specPtr->specFlags & TK_CONFIG_OBJS) && (*(Tcl_Obj **)ptr != NULL)) {
Tcl_DecrRefCount(*(Tcl_Obj **)ptr);
*(Tcl_Obj **)ptr = NULL;
continue;
}
switch (specPtr->type) {
case TK_CONFIG_STRING:
if (*((char **)ptr) != NULL) {
Expand Down
67 changes: 44 additions & 23 deletions generic/tkScrollbar.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ static const Tk_ConfigSpec configSpecs[] = {
{TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0, NULL},
{TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0, NULL},
{TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
DEF_SCROLLBAR_BORDER_WIDTH, offsetof(TkScrollbar, borderWidth), 0, NULL},
DEF_SCROLLBAR_BORDER_WIDTH, offsetof(TkScrollbar, borderWidthObj), TK_CONFIG_OBJS, NULL},
{TK_CONFIG_STRING, "-command", "command", "Command",
DEF_SCROLLBAR_COMMAND, offsetof(TkScrollbar, command),
TK_CONFIG_NULL_OK, NULL},
{TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
DEF_SCROLLBAR_CURSOR, offsetof(TkScrollbar, cursor), TK_CONFIG_NULL_OK, NULL},
{TK_CONFIG_PIXELS, "-elementborderwidth", "elementBorderWidth",
"BorderWidth", DEF_SCROLLBAR_EL_BORDER_WIDTH,
offsetof(TkScrollbar, elementBorderWidth), TK_CONFIG_NULL_OK, NULL},
offsetof(TkScrollbar, elementBorderWidthObj), TK_CONFIG_OBJS|TK_CONFIG_NULL_OK, NULL},
{TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
"HighlightBackground", DEF_SCROLLBAR_HIGHLIGHT_BG,
offsetof(TkScrollbar, highlightBgColorPtr), 0, NULL},
Expand All @@ -66,7 +66,7 @@ static const Tk_ConfigSpec configSpecs[] = {
offsetof(TkScrollbar, highlightColorPtr), 0, NULL},
{TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
"HighlightThickness",
DEF_SCROLLBAR_HIGHLIGHT_WIDTH, offsetof(TkScrollbar, highlightWidth), 0, NULL},
DEF_SCROLLBAR_HIGHLIGHT_WIDTH, offsetof(TkScrollbar, highlightWidthObj), TK_CONFIG_OBJS, NULL},
{TK_CONFIG_BOOLEAN, "-jump", "jump", "Jump",
DEF_SCROLLBAR_JUMP, offsetof(TkScrollbar, jump), 0, NULL},
{TK_CONFIG_CUSTOM, "-orient", "orient", "Orient",
Expand All @@ -79,16 +79,16 @@ static const Tk_ConfigSpec configSpecs[] = {
{TK_CONFIG_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
DEF_SCROLLBAR_REPEAT_INTERVAL, offsetof(TkScrollbar, repeatInterval), 0, NULL},
{TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
DEF_SCROLLBAR_TAKE_FOCUS, offsetof(TkScrollbar, takeFocus),
TK_CONFIG_NULL_OK, NULL},
DEF_SCROLLBAR_TAKE_FOCUS, offsetof(TkScrollbar, takeFocusObj),
TK_CONFIG_NULL_OK|TK_CONFIG_OBJS, NULL},
{TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
DEF_SCROLLBAR_TROUGH_COLOR, offsetof(TkScrollbar, troughColorPtr),
TK_CONFIG_COLOR_ONLY, NULL},
{TK_CONFIG_COLOR, "-troughcolor", "troughColor", "Background",
DEF_SCROLLBAR_TROUGH_MONO, offsetof(TkScrollbar, troughColorPtr),
TK_CONFIG_MONO_ONLY, NULL},
{TK_CONFIG_PIXELS, "-width", "width", "Width",
tkDefScrollbarWidth, offsetof(TkScrollbar, width), 0, NULL},
tkDefScrollbarWidth, offsetof(TkScrollbar, widthObj), TK_CONFIG_OBJS, NULL},
{TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

Expand Down Expand Up @@ -158,21 +158,21 @@ Tk_ScrollbarObjCmd(
Tk_PathName(scrollPtr->tkwin), ScrollbarWidgetObjCmd,
scrollPtr, ScrollbarCmdDeletedProc);
scrollPtr->vertical = 0;
scrollPtr->width = 0;
scrollPtr->widthObj = 0;
scrollPtr->command = NULL;
scrollPtr->commandSize = 0;
scrollPtr->repeatDelay = 0;
scrollPtr->repeatInterval = 0;
scrollPtr->borderWidth = 0;
scrollPtr->borderWidthObj = NULL;
scrollPtr->bgBorder = NULL;
scrollPtr->activeBorder = NULL;
scrollPtr->troughColorPtr = NULL;
scrollPtr->relief = TK_RELIEF_FLAT;
scrollPtr->highlightWidth = 0;
scrollPtr->highlightWidthObj = NULL;
scrollPtr->highlightBgColorPtr = NULL;
scrollPtr->highlightColorPtr = NULL;
scrollPtr->inset = 0;
scrollPtr->elementBorderWidth = INT_MIN;
scrollPtr->elementBorderWidthObj = NULL;
scrollPtr->arrowLength = 0;
scrollPtr->sliderFirst = 0;
scrollPtr->sliderLast = 0;
Expand All @@ -181,7 +181,7 @@ Tk_ScrollbarObjCmd(
scrollPtr->firstFraction = 0.0;
scrollPtr->lastFraction = 0.0;
scrollPtr->cursor = NULL;
scrollPtr->takeFocus = NULL;
scrollPtr->takeFocusObj = NULL;
scrollPtr->flags = 0;

if (ConfigureScrollbar(interp, scrollPtr, objc-2, objv+2, 0) != TCL_OK) {
Expand Down Expand Up @@ -317,11 +317,11 @@ ScrollbarWidgetObjCmd(
if (scrollPtr->vertical) {
pixels = yDelta;
length = Tk_Height(scrollPtr->tkwin) - 1
- 2*(scrollPtr->arrowLength + scrollPtr->inset);
- 2 * (scrollPtr->arrowLength + scrollPtr->inset);
} else {
pixels = xDelta;
length = Tk_Width(scrollPtr->tkwin) - 1
- 2*(scrollPtr->arrowLength + scrollPtr->inset);
- 2 * (scrollPtr->arrowLength + scrollPtr->inset);
}
if (length == 0) {
fraction = 0.0;
Expand All @@ -346,11 +346,11 @@ ScrollbarWidgetObjCmd(
if (scrollPtr->vertical) {
pos = y - (scrollPtr->arrowLength + scrollPtr->inset);
length = Tk_Height(scrollPtr->tkwin) - 1
- 2*(scrollPtr->arrowLength + scrollPtr->inset);
- 2 * (scrollPtr->arrowLength + scrollPtr->inset);
} else {
pos = x - (scrollPtr->arrowLength + scrollPtr->inset);
length = Tk_Width(scrollPtr->tkwin) - 1
- 2*(scrollPtr->arrowLength + scrollPtr->inset);
- 2 * (scrollPtr->arrowLength + scrollPtr->inset);
}
if (length == 0) {
fraction = 0.0;
Expand Down Expand Up @@ -472,6 +472,8 @@ ConfigureScrollbar(
Tcl_Obj *const objv[], /* Arguments. */
int flags) /* Flags to pass to Tk_ConfigureWidget. */
{
int width, borderWidth, highlightWidth, elementBorderWidth;

if (Tk_ConfigureWidget(interp, scrollPtr->tkwin, configSpecs, objc,
objv, scrollPtr, flags) != TCL_OK) {
return TCL_ERROR;
Expand All @@ -487,14 +489,30 @@ ConfigureScrollbar(
} else {
scrollPtr->commandSize = 0;
}
if (scrollPtr->highlightWidth < 0) {
scrollPtr->highlightWidth = 0;
Tk_GetPixelsFromObj(NULL, scrollPtr->tkwin, scrollPtr->borderWidthObj, &borderWidth);
if (borderWidth < 0) {
Tcl_DecrRefCount(scrollPtr->borderWidthObj);
scrollPtr->borderWidthObj = Tcl_NewIntObj(0);
Tcl_IncrRefCount(scrollPtr->borderWidthObj);
}
if (scrollPtr->borderWidth < 0) {
scrollPtr->borderWidth = 0;
Tk_GetPixelsFromObj(NULL, scrollPtr->tkwin, scrollPtr->highlightWidthObj, &highlightWidth);
if (highlightWidth < 0) {
Tcl_DecrRefCount(scrollPtr->highlightWidthObj);
scrollPtr->highlightWidthObj = Tcl_NewIntObj(0);
Tcl_IncrRefCount(scrollPtr->highlightWidthObj);
}
if (scrollPtr->elementBorderWidth < 0) {
scrollPtr->elementBorderWidth = INT_MIN;
Tk_GetPixelsFromObj(NULL, scrollPtr->tkwin, scrollPtr->widthObj, &width);
if (width < 0) {
Tcl_DecrRefCount(scrollPtr->widthObj);
scrollPtr->widthObj = Tcl_NewIntObj(0);
Tcl_IncrRefCount(scrollPtr->widthObj);
}
if (scrollPtr->elementBorderWidthObj) {
Tk_GetPixelsFromObj(NULL, scrollPtr->tkwin, scrollPtr->elementBorderWidthObj, &elementBorderWidth);
if (elementBorderWidth < 0) {
Tcl_DecrRefCount(scrollPtr->elementBorderWidthObj);
scrollPtr->elementBorderWidthObj = NULL;
}
}
/*
* Configure platform specific options.
Expand Down Expand Up @@ -537,6 +555,7 @@ TkScrollbarEventProc(
XEvent *eventPtr) /* Information about event. */
{
TkScrollbar *scrollPtr = (TkScrollbar *)clientData;
int highlightWidth;

if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
TkScrollbarEventuallyRedraw(scrollPtr);
Expand All @@ -563,14 +582,16 @@ TkScrollbarEventProc(
} else if (eventPtr->type == FocusIn) {
if (eventPtr->xfocus.detail != NotifyInferior) {
scrollPtr->flags |= GOT_FOCUS;
if (scrollPtr->highlightWidth > 0) {
Tk_GetPixelsFromObj(NULL, scrollPtr->tkwin, scrollPtr->highlightWidthObj, &highlightWidth);
if (highlightWidth > 0) {
TkScrollbarEventuallyRedraw(scrollPtr);
}
}
} else if (eventPtr->type == FocusOut) {
if (eventPtr->xfocus.detail != NotifyInferior) {
scrollPtr->flags &= ~GOT_FOCUS;
if (scrollPtr->highlightWidth > 0) {
Tk_GetPixelsFromObj(NULL, scrollPtr->tkwin, scrollPtr->highlightWidthObj, &highlightWidth);
if (highlightWidth > 0) {
TkScrollbarEventuallyRedraw(scrollPtr);
}
}
Expand Down
12 changes: 6 additions & 6 deletions generic/tkScrollbar.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ typedef struct TkScrollbar {
Tcl_Command widgetCmd; /* Token for scrollbar's widget command. */
int vertical; /* Non-zero means vertical orientation
* requested, zero means horizontal. */
int width; /* Desired narrow dimension of scrollbar, in
Tcl_Obj *widthObj; /* Desired narrow dimension of scrollbar, in
* pixels. */
char *command; /* Command prefix to use when invoking
* scrolling commands. NULL means don't invoke
Expand All @@ -48,15 +48,15 @@ typedef struct TkScrollbar {
* Information used when displaying widget:
*/

int borderWidth; /* Width of 3-D borders. */
Tcl_Obj *borderWidthObj; /* Width of 3-D borders. */
Tk_3DBorder bgBorder; /* Used for drawing background (all flat
* surfaces except for trough). */
Tk_3DBorder activeBorder; /* For drawing backgrounds when active (i.e.
* when mouse is positioned over element). */
XColor *troughColorPtr; /* Color for drawing trough. */
int relief; /* Indicates whether window as a whole is
* raised, sunken, or flat. */
int highlightWidth; /* Width in pixels of highlight to draw around
Tcl_Obj *highlightWidthObj; /* Width in pixels of highlight to draw around
* widget when it has the focus. <= 0 means
* don't draw a highlight. */
XColor *highlightBgColorPtr;
Expand All @@ -68,7 +68,7 @@ typedef struct TkScrollbar {
* Indicates how much interior stuff must be
* offset from outside edges to leave room for
* borders. */
int elementBorderWidth; /* Width of border to draw around elements
Tcl_Obj *elementBorderWidthObj; /* Width of border to draw around elements
* inside scrollbar (arrows and slider). -1
* means use borderWidth. */
int arrowLength; /* Length of arrows along long dimension of
Expand Down Expand Up @@ -108,9 +108,9 @@ typedef struct TkScrollbar {
*/

Tk_Cursor cursor; /* Current cursor for window, or NULL. */
char *takeFocus; /* Value of -takefocus option; not used in the
Tcl_Obj *takeFocusObj; /* Value of -takefocus option; not used in the
* C code, but used by keyboard traversal
* scripts. Malloc'ed, but may be NULL. */
* scripts. May be NULL. */
int flags; /* Various flags; see below for
* definitions. */
} TkScrollbar;
Expand Down
Loading

0 comments on commit d1f1f07

Please sign in to comment.