From 4df76b314d77e2c1b739d5acb5ad3683f613209c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 8 Sep 2024 21:17:45 +0000 Subject: [PATCH 1/2] Backport from 9.0 --- generic/tkImgSVGnano.c | 56 +++++++++++++++++++++--------------------- unix/tkUnixSysTray.c | 20 +++++++-------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/generic/tkImgSVGnano.c b/generic/tkImgSVGnano.c index 73bbbf823..de7073368 100644 --- a/generic/tkImgSVGnano.c +++ b/generic/tkImgSVGnano.c @@ -194,15 +194,15 @@ FileMatchSVG( nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj, &ropts); Tcl_DecrRefCount(dataObj); if (nsvgImage != NULL) { - GetScaleFromParameters(nsvgImage, &ropts, widthPtr, heightPtr); - if ((*widthPtr <= 0.0) || (*heightPtr <= 0.0)) { + GetScaleFromParameters(nsvgImage, &ropts, widthPtr, heightPtr); + if ((*widthPtr <= 0.0) || (*heightPtr <= 0.0)) { nsvgDelete(nsvgImage); return 0; - } - if (!CacheSVG(interp, chan, formatObj, nsvgImage, &ropts)) { + } + if (!CacheSVG(interp, chan, formatObj, nsvgImage, &ropts)) { nsvgDelete(nsvgImage); - } - return 1; + } + return 1; } return 0; } @@ -243,7 +243,7 @@ FileReadSVG( NSVGimage *nsvgImage = GetCachedSVG(interp, chan, formatObj, &ropts); if (nsvgImage == NULL) { - Tcl_Obj *dataObj = Tcl_NewObj(); + Tcl_Obj *dataObj = Tcl_NewObj(); if (Tcl_ReadChars(chan, dataObj, TCL_INDEX_NONE, 0) == TCL_IO_FAILURE) { /* in case of an error reading the file */ @@ -304,15 +304,15 @@ StringMatchSVG( } nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj, &ropts); if (nsvgImage != NULL) { - GetScaleFromParameters(nsvgImage, &ropts, widthPtr, heightPtr); - if ((*widthPtr <= 0.0) || (*heightPtr <= 0.0)) { + GetScaleFromParameters(nsvgImage, &ropts, widthPtr, heightPtr); + if ((*widthPtr <= 0.0) || (*heightPtr <= 0.0)) { nsvgDelete(nsvgImage); return 0; - } - if (!CacheSVG(interp, dataObj, formatObj, nsvgImage, &ropts)) { + } + if (!CacheSVG(interp, dataObj, formatObj, nsvgImage, &ropts)) { nsvgDelete(nsvgImage); - } - return 1; + } + return 1; } return 0; } @@ -392,7 +392,7 @@ ParseSVGWithOptions( NSVGimage *nsvgImage; int parameterScaleSeen = 0; static const char *const fmtOptions[] = { - "-dpi", "-scale", "-scaletoheight", "-scaletowidth", NULL + "-dpi", "-scale", "-scaletoheight", "-scaletowidth", NULL }; enum fmtOptionsEnum { OPT_DPI, OPT_SCALE, OPT_SCALE_TO_HEIGHT, OPT_SCALE_TO_WIDTH @@ -421,7 +421,7 @@ ParseSVGWithOptions( ropts->scaleToWidth = 0; if ((formatObj != NULL) && Tcl_ListObjGetElements(interp, formatObj, &objc, &objv) != TCL_OK) { - goto error; + goto error; } for (; objc > 0 ; objc--, objv++) { int optIndex; @@ -475,7 +475,7 @@ ParseSVGWithOptions( switch ((enum fmtOptionsEnum) optIndex) { case OPT_DPI: if (Tcl_GetDoubleFromObj(interp, objv[0], &dpi) == TCL_ERROR) { - goto error; + goto error; } if (dpi < 0.0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( @@ -488,7 +488,7 @@ ParseSVGWithOptions( case OPT_SCALE: if (Tcl_GetDoubleFromObj(interp, objv[0], &ropts->scale) == TCL_ERROR) { - goto error; + goto error; } if (ropts->scale <= 0.0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( @@ -501,7 +501,7 @@ ParseSVGWithOptions( case OPT_SCALE_TO_HEIGHT: if (Tcl_GetIntFromObj(interp, objv[0], &ropts->scaleToHeight) == TCL_ERROR) { - goto error; + goto error; } if (ropts->scaleToHeight <= 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( @@ -514,7 +514,7 @@ ParseSVGWithOptions( case OPT_SCALE_TO_WIDTH: if (Tcl_GetIntFromObj(interp, objv[0], &ropts->scaleToWidth) == TCL_ERROR) { - goto error; + goto error; } if (ropts->scaleToWidth <= 0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( @@ -538,7 +538,7 @@ ParseSVGWithOptions( error: if (inputCopy != NULL) { - ckfree(inputCopy); + ckfree(inputCopy); } return NULL; } @@ -669,8 +669,8 @@ GetScaleFromParameters( int width, height; if ((nsvgImage->width == 0.0) || (nsvgImage->height == 0.0)) { - width = height = 0; - scale = 1.0; + width = height = 0; + scale = 1.0; } else if (ropts->scaleToHeight > 0) { /* * Fixed height @@ -759,7 +759,7 @@ CacheSVG( NSVGcache *cachePtr = GetCachePtr(interp); if (cachePtr != NULL) { - cachePtr->dataOrChan = dataOrChan; + cachePtr->dataOrChan = dataOrChan; if (formatObj != NULL) { data = Tcl_GetStringFromObj(formatObj, &length); Tcl_DStringAppend(&cachePtr->formatString, data, length); @@ -801,10 +801,10 @@ GetCachedSVG( if ((cachePtr != NULL) && (cachePtr->nsvgImage != NULL) && (cachePtr->dataOrChan == dataOrChan)) { - if (formatObj != NULL) { + if (formatObj != NULL) { data = Tcl_GetStringFromObj(formatObj, &length); if (strcmp(data, Tcl_DStringValue(&cachePtr->formatString)) == 0) { - nsvgImage = cachePtr->nsvgImage; + nsvgImage = cachePtr->nsvgImage; *ropts = cachePtr->ropts; cachePtr->nsvgImage = NULL; } @@ -838,8 +838,8 @@ CleanCache(Tcl_Interp *interp) NSVGcache *cachePtr = GetCachePtr(interp); if (cachePtr != NULL) { - cachePtr->dataOrChan = NULL; - Tcl_DStringSetLength(&cachePtr->formatString, 0); + cachePtr->dataOrChan = NULL; + Tcl_DStringSetLength(&cachePtr->formatString, 0); if (cachePtr->nsvgImage != NULL) { nsvgDelete(cachePtr->nsvgImage); cachePtr->nsvgImage = NULL; @@ -869,7 +869,7 @@ FreeCache(void *clientData, TCL_UNUSED(Tcl_Interp *)) Tcl_DStringFree(&cachePtr->formatString); if (cachePtr->nsvgImage != NULL) { - nsvgDelete(cachePtr->nsvgImage); + nsvgDelete(cachePtr->nsvgImage); } ckfree(cachePtr); } diff --git a/unix/tkUnixSysTray.c b/unix/tkUnixSysTray.c index a3cdb505c..ebcc89d2f 100644 --- a/unix/tkUnixSysTray.c +++ b/unix/tkUnixSysTray.c @@ -190,8 +190,8 @@ typedef struct { int requestedWidth, requestedHeight; int visible; /* whether XEMBED_MAPPED should be set */ int docked; /* whether an icon should be docked */ - char *imageString, /* option: -image as string */ - *classString; /* option: -class as string */ + Tcl_Obj *imageStringObj; /* option: -image */ + Tcl_Obj *classStringObj; /* option: -class */ } DockIcon; /* @@ -604,7 +604,7 @@ CreateTrayIconWindow( tkwin = icon->drawingWin = Tk_CreateWindow(icon->interp, icon->tkwin, Tk_Name(icon->tkwin), ""); if (tkwin) { - Tk_SetClass(icon->drawingWin,icon->classString); + Tk_SetClass(icon->drawingWin, Tcl_GetString(icon->classStringObj)); Tk_CreateEventHandler(icon->drawingWin,ExposureMask|StructureNotifyMask| ButtonPressMask|ButtonReleaseMask| EnterWindowMask|LeaveWindowMask|PointerMotionMask, @@ -667,11 +667,11 @@ DockToManager( static const Tk_OptionSpec IconOptionSpec[] = { {TK_OPTION_STRING,"-image","image","Image", - NULL, TCL_INDEX_NONE, offsetof(DockIcon, imageString), + NULL, offsetof(DockIcon, imageStringObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, ICON_CONF_IMAGE | ICON_CONF_REDISPLAY}, {TK_OPTION_STRING,"-class","class","Class", - "TrayIcon", TCL_INDEX_NONE, offsetof(DockIcon, classString), + "TrayIcon", offsetof(DockIcon, classStringObj), TCL_INDEX_NONE, 0, NULL, ICON_CONF_CLASS}, {TK_OPTION_BOOLEAN,"-docked","docked","Docked", "1", TCL_INDEX_NONE, offsetof(DockIcon, docked), 0, NULL, @@ -901,13 +901,13 @@ DisplayIcon( Tk_WindowId(icon->drawingWin), w, h, 32); } if (!icon->photo) { - icon->photo = Tk_FindPhoto(icon->interp, icon->imageString); + icon->photo = Tk_FindPhoto(icon->interp, Tcl_GetString(icon->imageStringObj)); } if (!icon->photo && !icon->imageVisualInstance) { Tcl_InterpState saved = Tcl_SaveInterpState(icon->interp, TCL_OK); icon->imageVisualInstance = Tk_GetImage(icon->interp,icon->drawingWin, - icon->imageString, IgnoreImageChange, NULL); + Tcl_GetString(icon->imageStringObj), IgnoreImageChange, NULL); Tcl_RestoreInterpState(icon->interp,saved); } if (icon->photo && !icon->offscreenImage) { @@ -1418,7 +1418,7 @@ TrayIconUpdate( */ if (mask & ICON_CONF_CLASS) { if (icon->drawingWin) - Tk_SetClass(icon->drawingWin,Tk_GetUid(icon->classString)); + Tk_SetClass(icon->drawingWin,Tk_GetUid(Tcl_GetString(icon->classStringObj))); } /* * First, ensure right icon visibility. @@ -1517,8 +1517,8 @@ TrayIconConfigureMethod( mask |= addflags; /* now check option validity */ if (mask & ICON_CONF_IMAGE) { - if (icon->imageString) { - newImage = Tk_GetImage(interp, icon->tkwin, icon->imageString, + if (icon->imageStringObj) { + newImage = Tk_GetImage(interp, icon->tkwin, Tcl_GetString(icon->imageStringObj), TrayIconImageChanged, icon); if (!newImage) { Tk_RestoreSavedOptions(&saved); From ad6691fa7237d17d897ca1861d5722e017ca50e9 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 8 Sep 2024 21:19:16 +0000 Subject: [PATCH 2/2] Fix [29ba539501] for listbox: many PIXEL options don't keep their configured value --- generic/tkListbox.c | 204 +++++++++++++++++++++++++------------------- tests/listbox.test | 4 +- 2 files changed, 120 insertions(+), 88 deletions(-) diff --git a/generic/tkListbox.c b/generic/tkListbox.c index d67676998..be602d97e 100644 --- a/generic/tkListbox.c +++ b/generic/tkListbox.c @@ -44,7 +44,7 @@ typedef struct { Tk_OptionTable itemAttrOptionTable; /* Table that defines configuration options * available for listbox items. */ - char *listVarName; /* List variable name */ + Tcl_Obj *listVarNameObj; /* List variable name */ Tcl_Obj *listObj; /* Pointer to the list object being used */ Tcl_Size nElements; /* Holds the current count of elements */ Tcl_HashTable *selection; /* Tracks selection */ @@ -57,9 +57,9 @@ typedef struct { Tk_3DBorder normalBorder; /* Used for drawing border around whole * window, plus used for background. */ - int borderWidth; /* Width of 3-D border around window. */ + Tcl_Obj *borderWidthObj; /* Width of 3-D border around window. */ int relief; /* 3-D effect: TK_RELIEF_RAISED, etc. */ - 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; @@ -77,7 +77,7 @@ typedef struct { GC textGC; /* For drawing normal text. */ Tk_3DBorder selBorder; /* Borders and backgrounds for selected * elements. */ - int selBorderWidth; /* Width of border around selection. */ + Tcl_Obj *selBorderWidthObj; /* Width of border around selection. */ XColor *selFgColorPtr; /* Foreground color for selected elements. */ GC selTextGC; /* For drawing selected text. */ int width; /* Desired width of window, in characters. */ @@ -117,7 +117,7 @@ typedef struct { * Information about what's selected or active, if any. */ - Tk_Uid selectMode; /* Selection style: single, browse, multiple, + Tcl_Obj *selectModeObj; /* Selection style: single, browse, multiple, * or extended. This value isn't used in C * code, but the Tcl bindings use it. */ int numSelected; /* Number of elements currently selected. */ @@ -149,15 +149,15 @@ typedef struct { */ Tk_Cursor cursor; /* Current cursor for window, or None. */ - 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. */ - char *yScrollCmd; /* Command prefix for communicating with + * scripts. May be NULL. */ + Tcl_Obj *yScrollCmdObj; /* Command prefix for communicating with * vertical scrollbar. NULL means no command - * to issue. Malloc'ed. */ - char *xScrollCmd; /* Command prefix for communicating with + * to issue. May be NULL. */ + Tcl_Obj *xScrollCmdObj; /* Command prefix for communicating with * horizontal scrollbar. NULL means no command - * to issue. Malloc'ed. */ + * to issue. May be NULL. */ int state; /* Listbox state. */ Pixmap gray; /* Pixmap for displaying disabled text. */ int flags; /* Various flag bits: see below for @@ -241,7 +241,7 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_LISTBOX_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Listbox, borderWidth), + DEF_LISTBOX_BORDER_WIDTH, offsetof(Listbox, borderWidthObj), TCL_INDEX_NONE, 0, 0, 0}, {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", DEF_LISTBOX_CURSOR, TCL_INDEX_NONE, offsetof(Listbox, cursor), @@ -267,8 +267,8 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_LISTBOX_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Listbox, highlightColorPtr), 0, 0, 0}, {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", - "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, TCL_INDEX_NONE, - offsetof(Listbox, highlightWidth), 0, 0, 0}, + "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, + offsetof(Listbox, highlightWidthObj), TCL_INDEX_NONE, 0, 0, 0}, {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", DEF_LISTBOX_JUSTIFY, TCL_INDEX_NONE, offsetof(Listbox, justify), TK_OPTION_ENUM_VAR, 0, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", @@ -277,13 +277,13 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_LISTBOX_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selBorder), 0, DEF_LISTBOX_SELECT_MONO, 0}, {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", - "BorderWidth", DEF_LISTBOX_SELECT_BD, TCL_INDEX_NONE, - offsetof(Listbox, selBorderWidth), 0, 0, 0}, + "BorderWidth", DEF_LISTBOX_SELECT_BD, offsetof(Listbox, selBorderWidthObj), + TCL_INDEX_NONE, 0, 0, 0}, {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", DEF_LISTBOX_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selFgColorPtr), TK_OPTION_NULL_OK, DEF_LISTBOX_SELECT_FG_MONO, 0}, {TK_OPTION_STRING, "-selectmode", "selectMode", "SelectMode", - DEF_LISTBOX_SELECT_MODE, TCL_INDEX_NONE, offsetof(Listbox, selectMode), + DEF_LISTBOX_SELECT_MODE, offsetof(Listbox, selectModeObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid", DEF_LISTBOX_SET_GRID, TCL_INDEX_NONE, offsetof(Listbox, setGrid), 0, 0, 0}, @@ -291,18 +291,18 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_LISTBOX_STATE, TCL_INDEX_NONE, offsetof(Listbox, state), 0, &tkStateStrings[1], 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_LISTBOX_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Listbox, takeFocus), + DEF_LISTBOX_TAKE_FOCUS, offsetof(Listbox, takeFocusObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_INT, "-width", "width", "Width", DEF_LISTBOX_WIDTH, TCL_INDEX_NONE, offsetof(Listbox, width), 0, 0, 0}, {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", - DEF_LISTBOX_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Listbox, xScrollCmd), + DEF_LISTBOX_SCROLL_COMMAND, offsetof(Listbox, xScrollCmdObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand", - DEF_LISTBOX_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Listbox, yScrollCmd), + DEF_LISTBOX_SCROLL_COMMAND, offsetof(Listbox, yScrollCmdObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-listvariable", "listVariable", "Variable", - DEF_LISTBOX_LIST_VARIABLE, TCL_INDEX_NONE, offsetof(Listbox, listVarName), + DEF_LISTBOX_LIST_VARIABLE, offsetof(Listbox, listVarNameObj), TCL_INDEX_NONE, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0} }; @@ -1007,7 +1007,7 @@ ListboxWidgetObjCmd( if (diff <= listPtr->fullLines / 3) { ChangeListboxView(listPtr, index); } else { - ChangeListboxView(listPtr, index - (listPtr->fullLines-1)/2); + ChangeListboxView(listPtr, index - (listPtr->fullLines - 1)/2); } } else { diff = index - (listPtr->topIndex + listPtr->fullLines - 1); @@ -1015,7 +1015,7 @@ ListboxWidgetObjCmd( if (diff <= listPtr->fullLines / 3) { ChangeListboxView(listPtr, listPtr->topIndex + diff); } else { - ChangeListboxView(listPtr, index-(listPtr->fullLines-1)/2); + ChangeListboxView(listPtr, index-(listPtr->fullLines - 1)/2); } } } @@ -1093,6 +1093,7 @@ ListboxBboxSubCmd( int pixelWidth, x, y, result; Tcl_Size stringLen; Tk_FontMetrics fm; + int selBorderWidth; /* * Compute the pixel width of the requested element. @@ -1107,17 +1108,18 @@ ListboxBboxSubCmd( Tk_GetFontMetrics(listPtr->tkfont, &fm); pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen); + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->selBorderWidthObj, &selBorderWidth); if (listPtr->justify == TK_JUSTIFY_LEFT) { - x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset; + x = (listPtr->inset + selBorderWidth) - listPtr->xOffset; } else if (listPtr->justify == TK_JUSTIFY_RIGHT) { - x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth) + x = Tk_Width(tkwin) - (listPtr->inset + selBorderWidth) - pixelWidth - listPtr->xOffset + GetMaxOffset(listPtr); } else { - x = (Tk_Width(tkwin) - pixelWidth)/2 - - listPtr->xOffset + GetMaxOffset(listPtr)/2; + x = (Tk_Width(tkwin) - pixelWidth) / 2 + - listPtr->xOffset + GetMaxOffset(listPtr) / 2; } y = ((index - listPtr->topIndex)*listPtr->lineHeight) - + listPtr->inset + listPtr->selBorderWidth; + + listPtr->inset + selBorderWidth; results[0] = Tcl_NewWideIntObj(x); results[1] = Tcl_NewWideIntObj(y); results[2] = Tcl_NewWideIntObj(pixelWidth); @@ -1245,9 +1247,11 @@ ListboxXviewSubCmd( int index, count, windowWidth, windowUnits; int offset = 0; /* Initialized to stop gcc warnings. */ double fraction; + int selBorderWidth; + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->selBorderWidthObj, &selBorderWidth); windowWidth = Tk_Width(listPtr->tkwin) - - 2*(listPtr->inset + listPtr->selBorderWidth); + - 2 * (listPtr->inset + selBorderWidth); if (objc == 2) { Tcl_Obj *results[2]; @@ -1453,8 +1457,8 @@ DestroyListbox( listPtr->listObj = NULL; } - if (listPtr->listVarName != NULL) { - Tcl_UntraceVar2(listPtr->interp, listPtr->listVarName, NULL, + if (listPtr->listVarNameObj != NULL) { + Tcl_UntraceVar2(listPtr->interp, Tcl_GetString(listPtr->listVarNameObj), NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ListboxListVarProc, listPtr); } @@ -1558,10 +1562,11 @@ ConfigureListbox( Tcl_Obj *oldListObj = NULL; Tcl_Obj *errorResult = NULL; int oldExport, error; + int borderWidth, selBorderWidth, highlightWidth; oldExport = (listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp)); - if (listPtr->listVarName != NULL) { - Tcl_UntraceVar2(interp, listPtr->listVarName, NULL, + if (listPtr->listVarNameObj != NULL) { + Tcl_UntraceVar2(interp, Tcl_GetString(listPtr->listVarNameObj), NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ListboxListVarProc, listPtr); } @@ -1594,10 +1599,28 @@ ConfigureListbox( Tk_SetBackgroundFromBorder(listPtr->tkwin, listPtr->normalBorder); - if (listPtr->highlightWidth < 0) { - listPtr->highlightWidth = 0; - } - listPtr->inset = listPtr->highlightWidth + listPtr->borderWidth; + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->borderWidthObj, &borderWidth); + if (borderWidth < 0) { + borderWidth = 0; + Tcl_DecrRefCount(listPtr->borderWidthObj); + listPtr->borderWidthObj = Tcl_NewIntObj(0); + Tcl_IncrRefCount(listPtr->borderWidthObj); + } + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->highlightWidthObj, &highlightWidth); + if (highlightWidth < 0) { + highlightWidth = 0; + Tcl_DecrRefCount(listPtr->highlightWidthObj); + listPtr->highlightWidthObj = Tcl_NewIntObj(0); + Tcl_IncrRefCount(listPtr->highlightWidthObj); + } + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->selBorderWidthObj, &selBorderWidth); + if (selBorderWidth < 0) { + selBorderWidth = 0; + Tcl_DecrRefCount(listPtr->selBorderWidthObj); + listPtr->selBorderWidthObj = Tcl_NewIntObj(0); + Tcl_IncrRefCount(listPtr->selBorderWidthObj); + } + listPtr->inset = highlightWidth + borderWidth; /* * Claim the selection if we've suddenly started exporting it and @@ -1629,14 +1652,14 @@ ConfigureListbox( */ oldListObj = listPtr->listObj; - if (listPtr->listVarName != NULL) { - Tcl_Obj *listVarObj = Tcl_GetVar2Ex(interp, listPtr->listVarName, + if (listPtr->listVarNameObj != NULL) { + Tcl_Obj *listVarObj = Tcl_GetVar2Ex(interp, Tcl_GetString(listPtr->listVarNameObj), NULL, TCL_GLOBAL_ONLY); Tcl_Size dummy; if (listVarObj == NULL) { listVarObj = (oldListObj ? oldListObj : Tcl_NewObj()); - if (Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL, + if (Tcl_SetVar2Ex(interp, Tcl_GetString(listPtr->listVarNameObj), NULL, listVarObj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { continue; @@ -1655,7 +1678,7 @@ ConfigureListbox( } listPtr->listObj = listVarObj; - Tcl_TraceVar2(listPtr->interp, listPtr->listVarName, + Tcl_TraceVar2(listPtr->interp, Tcl_GetString(listPtr->listVarNameObj), NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ListboxListVarProc, listPtr); } else if (listPtr->listObj == NULL) { @@ -1850,6 +1873,7 @@ DisplayListbox( * off-screen. */ Pixmap pixmap; int textWidth; + int borderWidth, selBorderWidth, highlightWidth; listPtr->flags &= ~REDRAW_PENDING; if (listPtr->flags & LISTBOX_DELETED) { @@ -1901,17 +1925,18 @@ DisplayListbox( * Display each item in the listbox. */ + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->selBorderWidthObj, &selBorderWidth); limit = listPtr->topIndex + listPtr->fullLines + listPtr->partialLine - 1; if (limit >= (int)listPtr->nElements) { limit = listPtr->nElements-1; } left = right = 0; if (listPtr->xOffset > 0) { - left = listPtr->selBorderWidth+1; + left = selBorderWidth + 1; } if ((listPtr->maxWidth - listPtr->xOffset) > (Tk_Width(listPtr->tkwin) - - 2*(listPtr->inset + listPtr->selBorderWidth))) { - right = listPtr->selBorderWidth+1; + - 2 * (listPtr->inset + selBorderWidth))) { + right = selBorderWidth + 1; } prevSelected = 0; @@ -1943,7 +1968,7 @@ DisplayListbox( */ gc = listPtr->selTextGC; - width = Tk_Width(tkwin) - 2*listPtr->inset; + width = Tk_Width(tkwin) - 2 * listPtr->inset; selectedBg = listPtr->selBorder; /* @@ -2000,29 +2025,29 @@ DisplayListbox( /* Draw left bevel */ if (left == 0) { Tk_3DVerticalBevel(tkwin, pixmap, selectedBg, - x, y, listPtr->selBorderWidth, listPtr->lineHeight, + x, y, selBorderWidth, listPtr->lineHeight, 1, TK_RELIEF_RAISED); } /* Draw right bevel */ if (right == 0) { Tk_3DVerticalBevel(tkwin, pixmap, selectedBg, - x + width - listPtr->selBorderWidth, y, - listPtr->selBorderWidth, listPtr->lineHeight, + x + width - selBorderWidth, y, + selBorderWidth, listPtr->lineHeight, 0, TK_RELIEF_RAISED); } /* Draw top bevel */ if (!prevSelected) { Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg, x-left, y, width+left+right, - listPtr->selBorderWidth, + selBorderWidth, 1, 1, 1, TK_RELIEF_RAISED); } /* Draw bottom bevel */ if (i + 1 == (int)listPtr->nElements || !Tcl_FindHashEntry(listPtr->selection, KEY(i + 1))) { Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg, x-left, - y + listPtr->lineHeight - listPtr->selBorderWidth, - width+left+right, listPtr->selBorderWidth, 0, 0, 0, + y + listPtr->lineHeight - selBorderWidth, + width+left+right, selBorderWidth, 0, 0, 0, TK_RELIEF_RAISED); } prevSelected = 1; @@ -2044,7 +2069,7 @@ DisplayListbox( */ if (attrs->border != NULL) { - width = Tk_Width(tkwin) - 2*listPtr->inset; + width = Tk_Width(tkwin) - 2 * listPtr->inset; Tk_Fill3DRectangle(tkwin, pixmap, attrs->border, x, y, width, listPtr->lineHeight, 0, TK_RELIEF_FLAT); } @@ -2074,12 +2099,12 @@ DisplayListbox( textWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen); Tk_GetFontMetrics(listPtr->tkfont, &fm); - y += fm.ascent + listPtr->selBorderWidth; + y += fm.ascent + selBorderWidth; if (listPtr->justify == TK_JUSTIFY_LEFT) { - x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset; + x = (listPtr->inset + selBorderWidth) - listPtr->xOffset; } else if (listPtr->justify == TK_JUSTIFY_RIGHT) { - x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth) + x = Tk_Width(tkwin) - (listPtr->inset + selBorderWidth) - textWidth - listPtr->xOffset + GetMaxOffset(listPtr); } else { x = (Tk_Width(tkwin) - textWidth)/2 @@ -2109,7 +2134,7 @@ DisplayListbox( x = listPtr->inset; y = (i - listPtr->topIndex) * listPtr->lineHeight + listPtr->inset; - width = Tk_Width(tkwin) - 2*listPtr->inset; + width = Tk_Width(tkwin) - 2 * listPtr->inset; TkDrawDottedRect(disp, pixmap, gc, x, y, width, listPtr->lineHeight); @@ -2135,22 +2160,24 @@ DisplayListbox( * of the text of the listbox entries. */ + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->borderWidthObj, &borderWidth); + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->highlightWidthObj, &highlightWidth); Tk_Draw3DRectangle(tkwin, pixmap, listPtr->normalBorder, - listPtr->highlightWidth, listPtr->highlightWidth, - Tk_Width(tkwin) - 2*listPtr->highlightWidth, - Tk_Height(tkwin) - 2*listPtr->highlightWidth, - listPtr->borderWidth, listPtr->relief); - if (listPtr->highlightWidth > 0) { + highlightWidth, highlightWidth, + Tk_Width(tkwin) - 2 * highlightWidth, + Tk_Height(tkwin) - 2 * highlightWidth, + borderWidth, listPtr->relief); + if (highlightWidth > 0) { GC fgGC, bgGC; bgGC = Tk_GCForColor(listPtr->highlightBgColorPtr, pixmap); if (listPtr->flags & GOT_FOCUS) { fgGC = Tk_GCForColor(listPtr->highlightColorPtr, pixmap); Tk_DrawHighlightBorder(tkwin, fgGC, bgGC, - listPtr->highlightWidth, pixmap); + highlightWidth, pixmap); } else { Tk_DrawHighlightBorder(tkwin, bgGC, bgGC, - listPtr->highlightWidth, pixmap); + highlightWidth, pixmap); } } #ifndef TK_NO_DOUBLE_BUFFERING @@ -2199,6 +2226,7 @@ ListboxComputeGeometry( Tk_FontMetrics fm; Tcl_Obj *element; const char *text; + int selBorderWidth; if (fontChanged || maxIsStale) { listPtr->xScrollUnit = Tk_TextWidth(listPtr->tkfont, "0", 1); @@ -2226,7 +2254,8 @@ ListboxComputeGeometry( } Tk_GetFontMetrics(listPtr->tkfont, &fm); - listPtr->lineHeight = fm.linespace + 1 + 2*listPtr->selBorderWidth; + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->selBorderWidthObj, &selBorderWidth); + listPtr->lineHeight = fm.linespace + 1 + 2 * selBorderWidth; width = listPtr->width; if (width <= 0) { width = (listPtr->maxWidth + listPtr->xScrollUnit - 1) @@ -2235,8 +2264,8 @@ ListboxComputeGeometry( width = 1; } } - pixelWidth = width*listPtr->xScrollUnit + 2*listPtr->inset - + 2*listPtr->selBorderWidth; + pixelWidth = width*listPtr->xScrollUnit + 2 * listPtr->inset + + 2 * selBorderWidth; height = listPtr->height; if (listPtr->height <= 0) { height = (int)listPtr->nElements; @@ -2244,7 +2273,7 @@ ListboxComputeGeometry( height = 1; } } - pixelHeight = height*listPtr->lineHeight + 2*listPtr->inset; + pixelHeight = height*listPtr->lineHeight + 2 * listPtr->inset; Tk_GeometryRequest(listPtr->tkwin, pixelWidth, pixelHeight); Tk_SetInternalBorder(listPtr->tkwin, listPtr->inset); if (updateGrid) { @@ -2335,8 +2364,8 @@ ListboxInsertSubCmd( Tcl_IncrRefCount(newListObj); Tcl_DecrRefCount(listPtr->listObj); listPtr->listObj = newListObj; - if (listPtr->listVarName != NULL) { - Tcl_SetVar2Ex(listPtr->interp, listPtr->listVarName, NULL, + if (listPtr->listVarNameObj != NULL) { + Tcl_SetVar2Ex(listPtr->interp, Tcl_GetString(listPtr->listVarNameObj), NULL, listPtr->listObj, TCL_GLOBAL_ONLY); } @@ -2495,8 +2524,8 @@ ListboxDeleteSubCmd( Tcl_IncrRefCount(newListObj); Tcl_DecrRefCount(listPtr->listObj); listPtr->listObj = newListObj; - if (listPtr->listVarName != NULL) { - Tcl_SetVar2Ex(listPtr->interp, listPtr->listVarName, NULL, + if (listPtr->listVarNameObj != NULL) { + Tcl_SetVar2Ex(listPtr->interp, Tcl_GetString(listPtr->listVarNameObj), NULL, listPtr->listObj, TCL_GLOBAL_ONLY); } @@ -2593,7 +2622,7 @@ ListboxEventProc( } else if (eventPtr->type == ConfigureNotify) { int vertSpace; - vertSpace = Tk_Height(listPtr->tkwin) - 2*listPtr->inset; + vertSpace = Tk_Height(listPtr->tkwin) - 2 * listPtr->inset; listPtr->fullLines = vertSpace / listPtr->lineHeight; if ((listPtr->fullLines*listPtr->lineHeight) < vertSpace) { listPtr->partialLine = 1; @@ -3260,7 +3289,7 @@ ListboxUpdateVScrollbar( Tcl_Interp *interp; Tcl_DString buf; - if (listPtr->yScrollCmd == NULL) { + if (listPtr->yScrollCmdObj == NULL) { return; } if (listPtr->nElements == 0) { @@ -3285,7 +3314,7 @@ ListboxUpdateVScrollbar( interp = listPtr->interp; Tcl_Preserve(interp); Tcl_DStringInit(&buf); - Tcl_DStringAppend(&buf, listPtr->yScrollCmd, TCL_INDEX_NONE); + Tcl_DStringAppend(&buf, Tcl_GetString(listPtr->yScrollCmdObj), TCL_INDEX_NONE); Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE); Tcl_DStringAppend(&buf, firstStr, TCL_INDEX_NONE); Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE); @@ -3329,13 +3358,15 @@ ListboxUpdateHScrollbar( double first, last; Tcl_Interp *interp; Tcl_DString buf; + int selBorderWidth; - if (listPtr->xScrollCmd == NULL) { + if (listPtr->xScrollCmdObj == NULL) { return; } + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->selBorderWidthObj, &selBorderWidth); windowWidth = Tk_Width(listPtr->tkwin) - - 2*(listPtr->inset + listPtr->selBorderWidth); + - 2 * (listPtr->inset + selBorderWidth); if (listPtr->maxWidth == 0) { first = 0; last = 1.0; @@ -3357,7 +3388,7 @@ ListboxUpdateHScrollbar( interp = listPtr->interp; Tcl_Preserve(interp); Tcl_DStringInit(&buf); - Tcl_DStringAppend(&buf, listPtr->xScrollCmd, TCL_INDEX_NONE); + Tcl_DStringAppend(&buf, Tcl_GetString(listPtr->xScrollCmdObj), TCL_INDEX_NONE); Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE); Tcl_DStringAppend(&buf, firstStr, TCL_INDEX_NONE); Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE); @@ -3407,12 +3438,12 @@ ListboxListVarProc( if (flags & TCL_TRACE_UNSETS) { - if (!Tcl_InterpDeleted(interp) && listPtr->listVarName) { + if (!Tcl_InterpDeleted(interp) && listPtr->listVarNameObj) { void *probe = NULL; do { probe = Tcl_VarTraceInfo(interp, - listPtr->listVarName, + Tcl_GetString(listPtr->listVarNameObj), TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ListboxListVarProc, probe); if (probe == (void *)listPtr) { @@ -3428,16 +3459,16 @@ ListboxListVarProc( */ return NULL; } - Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL, + Tcl_SetVar2Ex(interp, Tcl_GetString(listPtr->listVarNameObj), NULL, listPtr->listObj, TCL_GLOBAL_ONLY); - Tcl_TraceVar2(interp, listPtr->listVarName, + Tcl_TraceVar2(interp, Tcl_GetString(listPtr->listVarNameObj), NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ListboxListVarProc, clientData); return NULL; } } else { oldListObj = listPtr->listObj; - varListObj = Tcl_GetVar2Ex(listPtr->interp, listPtr->listVarName, + varListObj = Tcl_GetVar2Ex(listPtr->interp, Tcl_GetString(listPtr->listVarNameObj), NULL, TCL_GLOBAL_ONLY); /* @@ -3447,7 +3478,7 @@ ListboxListVarProc( */ if (Tcl_ListObjLength(listPtr->interp, varListObj, &i) != TCL_OK) { - Tcl_SetVar2Ex(interp, listPtr->listVarName, NULL, oldListObj, + Tcl_SetVar2Ex(interp, Tcl_GetString(listPtr->listVarNameObj), NULL, oldListObj, TCL_GLOBAL_ONLY); return (char *) "invalid listvar value"; } @@ -3606,11 +3637,12 @@ MigrateHashEntries( static int GetMaxOffset( Listbox *listPtr) { - int maxOffset; + int maxOffset, selBorderWidth; + Tk_GetPixelsFromObj(NULL, listPtr->tkwin, listPtr->selBorderWidthObj, &selBorderWidth); maxOffset = listPtr->maxWidth - - (Tk_Width(listPtr->tkwin) - 2*listPtr->inset - - 2*listPtr->selBorderWidth) + listPtr->xScrollUnit - 1; + (Tk_Width(listPtr->tkwin) - 2 * listPtr->inset - + 2 * selBorderWidth) + listPtr->xScrollUnit - 1; if (maxOffset < 0) { /* diff --git a/tests/listbox.test b/tests/listbox.test index be7e383e7..80461a344 100644 --- a/tests/listbox.test +++ b/tests/listbox.test @@ -107,7 +107,7 @@ test listbox-1.9 {configuration options} -body { list [lindex [.l configure -borderwidth] 4] [.l cget -borderwidth] } -cleanup { .l configure -borderwidth [lindex [.l configure -borderwidth] 3] -} -result {1 1} +} -result {1.3 1.3} test listbox-1.10 {configuration options} -body { .l configure -borderwidth badValue } -returnCodes error -result {expected screen distance but got "badValue"} @@ -242,7 +242,7 @@ test listbox-1.37 {configuration options} -body { list [lindex [.l configure -selectborderwidth] 4] [.l cget -selectborderwidth] } -cleanup { .l configure -selectborderwidth [lindex [.l configure -selectborderwidth] 3] -} -result {1 1} +} -result {1.3 1.3} test listbox-1.38 {configuration options} -body { .l configure -selectborderwidth badValue } -returnCodes error -result {expected screen distance but got "badValue"}