Author: Jan Nijtmans <[email protected]>
State: Final
Type: Project
Vote: Done
Created: 04-11-2022
Tcl-Version: 9.0
Tk-branch: tip-647
Vote-Summary: 4 / 0 / 0
Votes-For: BG, DKF, JN, SL
Votes-Against: none
Votes-Present: none
Abstract
In december 1999, the TK_CONFIG_OBJS flag was introduced in Tk, making it possible to use the Tcl_Obj-interface in a lot more places than before (e.g. the canvas) . Since this was Tk 8.1, the signature of the Tk_ConfigureWidgets() function could not be changed, therefore it's 4th and 5th argument were kept as argc/argv, although they could be objc/objv as well.
Now that Tk 9.0 is approaching, we can correct the Tk_ConfigureWidgets() signature as it should have been from the beginning, and also remove the possibility to use argc/argv any more.
Background & Rationale
The function Tk_ConfigureWidget
is typically used like this:
if (Tk_ConfigureWidget(interp, canvasPtr->tkwin, configSpecs, objc, (const char **)objv, (char *)canvasPtr, flags|TK_CONFIG_OBJS) != TCL_OK) { return TCL_ERROR; }The goal of this TIP is to allow to get rid of the type-casts and the
TK_CONFIG_OBJS
flag in Tk 9.0:
if (Tk_ConfigureWidget(interp, canvasPtr->tkwin, configSpecs, objc, objv, canvasPtr, flags) != TCL_OK) { return TCL_ERROR; }
This can be done by changing the 5th argument in the function signature from
const char **
to Tcl_Obj *const *
and the 6th argument to void *
.
Of course it would be possible to keep the TK_CONFIG_OBJS
flag. In my view
it's not really worth maintaining this for a long time more: the one-time
effort converting the extensions is fully worth the trouble. And after
the suggested conversion, everything still works with Tk 8.6 too.
Specification
The signature of the function is modified from:
int Tk_ConfigureWidget(Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, Tcl_Size argc, const char **argv, char *widgRec, int flags)to
int Tk_ConfigureWidget(Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, Tcl_Size objc, Tcl_Obj *const *objv, void *widgRec, int flags)
Also, all usages of the flag TK_CONFIG_OBJS
in Tk are removed, assuming that the flag is set.
In addition, the alwaysRedraw
field in Tk_ItemType
will be renamed to flags
. Currently
it can contains two different flags, TK_ALWAYS_REDRAW
and TK_MOVABLE_POINTS
. For
compatibility, TK_ALWAYS_REDRAW
has the value 1
. This field also located the TK_CONFIG_OBJS
flag, but that flags becomes obsolete now. The flag TK_MOVABLE_POINTS
is not new, the alwaysRedraw
field was where this flag had to be set (and exactly
this is the motivation for the suggestion to change the field name).
Since the Tk_ItemType
is generally statically initialized, the field name change
doesn't need any user code modification: All extensions using it will work unmodified.
Compatibility
For code which needs to work with both Tk 8.6 and 9.0, the following construct can be used:
if (Tk_ConfigureWidget(interp, canvasPtr->tkwin, configSpecs, objc, (void *)objv, (char *)canvasPtr, flags|TK_CONFIG_OBJS) != TCL_OK) { return TCL_ERROR; }So just change the typecast for objv to
(void *)
, this way will
compile and run fine with both Tk 8.6 and 9.0.
Code which still is not using the TK_CONFIG_OBJS
flag will need to be
modified: No longer use the argv/argc
functions but switch to
using the objc/objv
concept. This will become clear when compiling
such extensions with Tk 9 header files: The signature change will
cause a compiler warning if the conversion is not yet done.
Tkimg
is already converted this way. It will still compile
fine after this TIP is accepted. The Tkimg
conversion commit
can be found here
Some extensions (like vu Widget Set
and tkzinc
) are
already modified to use the TK_CONFIG_OBJS
flag, those are
quite easy to be ported to this signature change. Other extensions
(like blt
, snack
, tkhtml
, tkled
, tknotebook
, tkpath
and tktable
) will need more work, because the already-mentioned
argc/argv
->objc/objv
conversion needs to be done first.
Implementation
Implementation is available in the tip-647 branch of the Tk repository.
Copyright
This document has been placed in the public domain.