diff options
author | dgp <dgp@users.sourceforge.net> | 2016-07-21 20:06:34 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2016-07-21 20:06:34 (GMT) |
commit | a80e603c517d2682ef25067ac6daf1d2692d5864 (patch) | |
tree | cd7aaee28e7876e8bfdd77e835c534b13cbe5f98 | |
parent | 682d30ed7f59d3c732d08cf6ccc715e738784453 (diff) | |
parent | 2aa945d6a8109c74d9ff3331fb99a093635e0cd7 (diff) | |
download | tk-a80e603c517d2682ef25067ac6daf1d2692d5864.zip tk-a80e603c517d2682ef25067ac6daf1d2692d5864.tar.gz tk-a80e603c517d2682ef25067ac6daf1d2692d5864.tar.bz2 |
merge 8.6bug_450bb0ecad
133 files changed, 2488 insertions, 964 deletions
@@ -1,5 +1,5 @@ README: Tk - This is the Tk 8.6.4 source distribution. + This is the Tk 8.6.5 source distribution. http://sourceforge.net/projects/tcl/files/Tcl/ You can get any source release of Tk from the URL above. @@ -7167,3 +7167,102 @@ Tk Cocoa 2.0: App Store enabled (walzer,culler,desmera,owen,nyberg,reincke) *** POTENTIAL INCOMPATIBILITY *** --- Released 8.6.4, March 12, 2015 --- http://core.tcl.tk/tk/ for details + +2015-03-10 (bug) Cocoa: premature image free crash (walzer) + +2015-03-15 (bug) Cocoa: wish launches in front. [focus -force] works (culler) + +2015-04-09 (bug)[e4ed00] [$text index "1.0 display wordstart"] crash (vogel) + +2015-04-09 (bug)[562118] Unicode support of "wordstart" modifier (vogel) + +2015-05-05 (bug)[06c3fc] PNG alpha error corrupted output file (gauthier,porter) + +2015-05-20 (bug)[dece63] various mem corruptions in images (mic42,porter) + +2015-05-24 (bug)[53f8fc] panedwindow geometry management (vogel) + +2015-05-26 (bug)[1641721] tk_getOpenFile symlink display doubled (nijtmans) + +2015-06-01 (bug)[d7bad5][2368195][3592454][1714535][1292219][3592454] + panedwindow fixes (vogel) + +2015-06-25 (bug)[805cff] Tk_ConfigureWidget() segfault (aspect,nijtmans) + +2015-07-13 (bug)[3f179a] Text widget crash with elided text (vogel) + +2015-07-16 (bug)[2886436] Stop [$text delete] acting before start index (vogel) + +2015-07-28 (bug)[1236306] TraverseToMenu error bound to toplevel destroy (vogel) + +2015-08-20 (bug)[00189c] MSVC 14: semi-static UCRT support (dower,nijtmans) + +2015-09-13 (bug)[cc0ba3] PNG read buffer overflow (maxjarek,porter) + +2015-09-29 (bug)[1501749] Crash embedded window delete bound to <Map> (vogel) + +2015-10-04 (license) Replace icons that lacked clear free license (cowals) + +2015-10-06 (bug)[46c83f] Win: tk_getOpenFile -initialdir (koend,nadkarni) + +2015-10-08 (new feature)[TIP 437] New panedwindow options (vogel) + +2015-10-09 (bug)[1669632] [text] autoseparator placement (nash,vogel) + +2015-10-09 (bug)[2262711] [text] RE search Unicode+elided (kaitzschu,vogel) + +2015-10-09 (bug)[1815161] [$text count -ypixels] needs management (vogel) + +2015-10-22 (bug)[1520118] Document spinbox validate expectations (vogel) + +2015-10-22 (bug)[1414025] $entry insertion cursor visibility (vogel) + +2015-10-26 (bug) PNG rendering on El Capitan (meier,walzer) + +2015-11-08 (bug)[2160206] menubutton panic (vogel) + +2015-11-08 (bug)[220854] Display trailing TAB in entry (vogel) + +2015-11-08 (bug)[542199] double click on lone char in entry (vogel) + +2015-11-08 (bug)[297442d] strict motif binding on <Control-underscore> (vogel) + +2015-11-08 (bug)[3601604] $listbox -takefocus (vogel) + +2015-11-09 (bug)[5ee8af] X, Win: 64-bit enable embedded windows (vogel) + +2015-11-29 (bug)[1997299] [text] tag borderwidth leak (vogel) + +2015-12-12 (bug)[1739605] [text see] misbehavior (danckaert) + +2015-12-13 (bug)[ff8a1e] Never-mapped [text] performance (danckaert) + +2015-12-19 (bug)[1700065] Report errors from -textvariable write trace (vogel) + +2015-12-19 (bug)[793909] -textvariable handle undefined namespace (vogel) + +2015-12-26 (bug)[2f78c7] crash with [text] and [tablelist] (vogel) + +2016-01-06 (bug)[1288433,3102228] <<ListboxSelect>> misfires (vogel) + +2016-01-08 (bug)[1510538] initial scrollbar width (vogel,nijtmans) + +2016-01-08 (bug)[1305128] event not received by scrollbar (vogel,nijtmans) + +2016-01-09 (bug)[1927212] Mousewheel/scrollbar bindings (vogel) + +2016-01-11 (bug)[63c354] Cocoa message boxes (culler) + +2016-01-12 (bug)[2049429] get more $text options from database (vogel) + +2016-01-22 (TIP 441) New option [listbox ... -justify] (vogel) + +2016-01-25 (bug) OBOE in ttk::notebook options parsing (bromley,english) + +2016-02-08 (enhance) [option readile] expects utf-8 file (oehlmann,nijtmans) + +2016-02-08 (bug) crash in [$text delete] (griffin,vogel) + +Tk Cocoa 2.0: More drawing internals refinements (culler,walzer) + +--- Released 8.6.5, February 29, 2016 --- http://core.tcl.tk/tk/ for details diff --git a/doc/ConfigWidg.3 b/doc/ConfigWidg.3 index ddc1030..92be073 100644 --- a/doc/ConfigWidg.3 +++ b/doc/ConfigWidg.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_ConfigureWidget 3 4.1 Tk "Tk Library Procedures" .so man.macros .BS @@ -174,7 +174,7 @@ legal values for \fItype\fR, and the corresponding actions, are: \fBTK_CONFIG_ACTIVE_CURSOR\fR The value must be an ASCII string identifying a cursor in a form -suitable for passing to \fBTk_GetCursor\fR. +suitable for passing to \fBTk_GetCursor\fR. The value is converted to a \fBTk_Cursor\fR by calling \fBTk_GetCursor\fR and the result is stored in the target. In addition, the resulting cursor is made the active cursor diff --git a/doc/CrtSelHdlr.3 b/doc/CrtSelHdlr.3 index 2aeffa9..2292ccc 100644 --- a/doc/CrtSelHdlr.3 +++ b/doc/CrtSelHdlr.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CreateSelHandler 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS @@ -44,7 +44,7 @@ requestor. \fBTk_CreateSelHandler\fR arranges for a particular procedure (\fIproc\fR) to be called whenever \fIselection\fR is owned by \fItkwin\fR and the selection contents are requested in the -form given by \fItarget\fR. +form given by \fItarget\fR. \fITarget\fR should be one of the entries defined in the left column of Table 2 of the X Inter-Client Communication Conventions Manual (ICCCM) or diff --git a/doc/CrtWindow.3 b/doc/CrtWindow.3 index 8f44545..b254460 100644 --- a/doc/CrtWindow.3 +++ b/doc/CrtWindow.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CreateWindow 3 4.2 Tk "Tk Library Procedures" .so man.macros .BS @@ -52,7 +52,7 @@ Name of new window, specified as path name within application .BE .SH DESCRIPTION .PP -The procedures \fBTk_CreateWindow\fR, +The procedures \fBTk_CreateWindow\fR, \fBTk_CreateAnonymousWindow\fR, and \fBTk_CreateWindowFromPath\fR are used to create new windows for use in Tk-based applications. Each of the procedures returns a token diff --git a/doc/FindPhoto.3 b/doc/FindPhoto.3 index d6ccb5b..e4d83f0 100644 --- a/doc/FindPhoto.3 +++ b/doc/FindPhoto.3 @@ -99,6 +99,8 @@ being written to the photo image. particular photo image to the other procedures. The parameter is the name of the image, that is, the name specified to the \fBimage create photo\fR command, or assigned by that command if no name was specified. +If \fIimageName\fR does not exist or is not a photo image, +\fBTk_FindPhoto\fR returns NULL. .PP \fBTk_PhotoPutBlock\fR is used to supply blocks of image data to be displayed. The call affects an area of the image of size @@ -181,6 +183,18 @@ in the structure pointed to by the \fIblockPtr\fR parameter with values that describe the address and layout of the image data that the photo image has stored internally. The values are valid until the image is destroyed or its size is changed. +.PP +It is possible to modify an image by writing directly to the data +the \fIpixelPtr\fR field points to. The size of the image cannot be +changed this way, though. +Also, changes made by writing directly to \fIpixelPtr\fR will not be +immediately visible, but only after a call to +\fBTk_ImageChanged\fR or after an event that causes the interested +widgets to redraw themselves. +For these reasons usually it is preferable to make changes to +a copy of the image data and write it back with +\fBTk_PhotoPutBlock\fR or \fBTk_PhotoPutZoomedBlock\fR. +.PP \fBTk_PhotoGetImage\fR returns 1 for compatibility with the corresponding procedure in the old photo widget. .PP diff --git a/doc/FontId.3 b/doc/FontId.3 index c79b89f..9d35ae6 100644 --- a/doc/FontId.3 +++ b/doc/FontId.3 @@ -3,12 +3,12 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_FontId 3 8.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME -Tk_FontId, Tk_GetFontMetrics, Tk_PostscriptFontName \- accessor functions for +Tk_FontId, Tk_GetFontMetrics, Tk_PostscriptFontName \- accessor functions for fonts .SH SYNOPSIS .nf @@ -37,7 +37,7 @@ Postscript font that corresponds to \fItkfont\fR will be appended. .PP Given a \fItkfont\fR, \fBTk_FontId\fR returns the token that should be selected into an XGCValues structure in order to construct a graphics -context that can be used to draw text in the specified font. +context that can be used to draw text in the specified font. .PP \fBTk_GetFontMetrics\fR computes the ascent, descent, and linespace of the \fItkfont\fR in pixels and stores those values in the structure pointer to by @@ -45,7 +45,7 @@ context that can be used to draw text in the specified font. multiple lines of text, to align the baselines of text in different fonts, and to vertically align text in a given region. See the documentation for the \fBfont\fR command for definitions of the terms -ascent, descent, and linespace, used in font metrics. +ascent, descent, and linespace, used in font metrics. .PP \fBTk_PostscriptFontName\fR maps a \fItkfont\fR to the corresponding Postscript font name that should be used when printing. The return value @@ -56,10 +56,10 @@ appended to \fIdsPtr\fR. \fIDsPtr\fR must refer to an initialized Postscript printer, the following screen font families should print correctly: .IP -\fBAvant Garde\fR, \fBArial\fR, \fBBookman\fR, \fBCourier\fR, +\fBAvant Garde\fR, \fBArial\fR, \fBBookman\fR, \fBCourier\fR, \fBCourier New\fR, \fBGeneva\fR, \fBHelvetica\fR, \fBMonaco\fR, \fBNew Century Schoolbook\fR, \fBNew York\fR, \fBPalatino\fR, \fBSymbol\fR, -\fBTimes\fR, \fBTimes New Roman\fR, \fBZapf Chancery\fR, and +\fBTimes\fR, \fBTimes New Roman\fR, \fBZapf Chancery\fR, and \fBZapf Dingbats\fR. .PP Any other font families may not print correctly because the computed diff --git a/doc/GetColor.3 b/doc/GetColor.3 index 9d07d95..15254aa 100644 --- a/doc/GetColor.3 +++ b/doc/GetColor.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_AllocColorFromObj 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS @@ -127,7 +127,7 @@ This package maintains a database of all the colors currently in use. If the same color is requested multiple times from \fBTk_GetColor\fR or \fBTk_AllocColorFromObj\fR (e.g. by different -windows), or if the +windows), or if the same intensities are requested multiple times from \fBTk_GetColorByValue\fR, then existing pixel values will be re-used. Re-using an existing pixel avoids any interaction diff --git a/doc/GetCursor.3 b/doc/GetCursor.3 index 8526a47..403c05e 100644 --- a/doc/GetCursor.3 +++ b/doc/GetCursor.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_AllocCursorFromObj 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS @@ -118,7 +118,7 @@ in preference to black and white cursors. In this form, \fIsourceName\fR and \fImaskName\fR are the names of files describing cursors for the cursor's source bits and mask. Each file must be in standard X11 cursor format. -\fIFgColor\fR and \fIbgColor\fR +\fIFgColor\fR and \fIbgColor\fR indicate the colors to use for the cursor, in any of the forms acceptable to \fBTk_GetColor\fR. This form of the command will not work on Macintosh or Windows computers. diff --git a/doc/GetFont.3 b/doc/GetFont.3 index cf02f00..0504916 100644 --- a/doc/GetFont.3 +++ b/doc/GetFont.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_AllocFontFromObj 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS @@ -14,19 +14,19 @@ Tk_AllocFontFromObj, Tk_GetFont, Tk_GetFontFromObj, Tk_NameOfFont, Tk_FreeFontFr .nf \fB#include <tk.h>\fR .sp -Tk_Font +Tk_Font \fBTk_AllocFontFromObj(\fIinterp, tkwin, objPtr\fB)\fR .sp -Tk_Font -\fBTk_GetFont(\fIinterp, tkwin, string\fB)\fR +Tk_Font +\fBTk_GetFont(\fIinterp, tkwin, string\fB)\fR .sp -Tk_Font +Tk_Font \fBTk_GetFontFromObj(\fItkwin, objPtr\fB)\fR .sp const char * \fBTk_NameOfFont(\fItkfont\fB)\fR .sp -Tk_Font +Tk_Font \fBTk_FreeFontFromObj(\fItkwin, objPtr\fB)\fR .sp void @@ -55,7 +55,7 @@ returns a token that represents the font. The return value can be used in subsequent calls to procedures such as \fBTk_GetFontMetrics\fR, \fBTk_MeasureChars\fR, and \fBTk_FreeFont\fR. The Tk_Font token will remain valid until -\fBTk_FreeFontFromObj\fR or \fBTk_FreeFont\fR is called to release it. +\fBTk_FreeFontFromObj\fR or \fBTk_FreeFont\fR is called to release it. \fIObjPtr\fR can contain either a symbolic name or a font description; see the documentation for the \fBfont\fR command for a description of the valid formats. If \fBTk_AllocFontFromObj\fR is unsuccessful (because, diff --git a/doc/MapWindow.3 b/doc/MapWindow.3 index 8abce64..a3c6296 100644 --- a/doc/MapWindow.3 +++ b/doc/MapWindow.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_MapWindow 3 "" Tk "Tk Library Procedures" .so man.macros .BS @@ -35,9 +35,9 @@ deferred window creation. from the screen. .PP If \fItkwin\fR is a child window (i.e. \fBTk_CreateWindow\fR was -used to create a child window), then event handlers interested in map -and unmap events are invoked immediately. If \fItkwin\fR is not an -internal window, then the event handlers will be invoked later, after +used to create a child window), then event handlers interested in map +and unmap events are invoked immediately. If \fItkwin\fR is not an +internal window, then the event handlers will be invoked later, after X has seen the request and returned an event for it. .PP These procedures should be used in place of the X procedures diff --git a/doc/MeasureChar.3 b/doc/MeasureChar.3 index 7433451..3959978 100644 --- a/doc/MeasureChar.3 +++ b/doc/MeasureChar.3 @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_MeasureChars 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS @@ -32,7 +32,7 @@ returned by a previous call to \fBTk_GetFont\fR. Text to be measured or displayed. Need not be null terminated. Any non-printing meta-characters in the string (such as tabs, newlines, and other control characters) will be measured or displayed in a -platform-dependent manner. +platform-dependent manner. .AP int numBytes in The maximum number of bytes to consider when measuring or drawing \fIstring\fR. Must be greater than or equal to 0. @@ -60,11 +60,11 @@ Display on which to draw. .AP Drawable drawable in Window or pixmap in which to draw. .AP GC gc in -Graphics context for drawing characters. The font selected into this GC +Graphics context for drawing characters. The font selected into this GC must be the same as the \fItkfont\fR. .AP int "x, y" in Coordinates at which to place the left edge of the baseline when displaying -\fIstring\fR. +\fIstring\fR. .AP int firstByte in The index of the first byte of the first character to underline in the \fIstring\fR. Underlining begins at the left edge of this character. @@ -80,7 +80,7 @@ single-line strings. To measure and display single-font, multi-line, justified text, refer to the documentation for \fBTk_ComputeTextLayout\fR. There is no programming interface in the core of Tk that supports multi-font, multi-line text; support for that behavior must be built on -top of simpler layers. +top of simpler layers. Note that the interfaces described here are byte-oriented not character-oriented, so index values coming from Tcl scripts need to be converted to byte offsets using the @@ -95,7 +95,7 @@ escape sequences, while under Windows and Macintosh hollow or solid boxes may be substituted. Refer to the documentation for \fBTk_ComputeTextLayout\fR for a programming interface that supports the platform-independent expansion of tab characters into columns and -newlines/returns into multi-line text. +newlines/returns into multi-line text. .PP \fBTk_MeasureChars\fR is used both to compute the length of a given string and to compute how many characters from a string fit in a given @@ -106,12 +106,12 @@ value will be \fInumBytes\fR. \fI*lengthPtr\fR is filled with the computed width, in pixels, of the portion of the string that was measured. For example, if the return value is 5, then \fI*lengthPtr\fR is filled with the distance between the left edge of \fIstring\fR[0] and the right edge of -\fIstring\fR[4]. +\fIstring\fR[4]. .PP \fBTk_TextWidth\fR is a wrapper function that provides a simpler interface to the \fBTk_MeasureChars\fR function. The return value is how much space in pixels the given \fIstring\fR needs. -.PP +.PP \fBTk_DrawChars\fR draws the \fIstring\fR at the given location in the given \fIdrawable\fR. .PP @@ -120,7 +120,7 @@ given \fIstring\fR. It does not draw the characters (which are assumed to have been displayed previously by \fBTk_DrawChars\fR); it just draws the underline. This procedure is used to underline a few characters without having to construct an underlined font. To produce natively underlined -text, the appropriate underlined font should be constructed and used. +text, the appropriate underlined font should be constructed and used. .SH "SEE ALSO" font(n), FontId(3) .SH KEYWORDS diff --git a/doc/TextLayout.3 b/doc/TextLayout.3 index 3863ee7..5729a44 100644 --- a/doc/TextLayout.3 +++ b/doc/TextLayout.3 @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_ComputeTextLayout 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS @@ -48,7 +48,7 @@ have been returned by a previous call to \fBTk_GetFont\fR. .AP "const char" *string in Potentially multi-line string whose dimensions are to be computed and stored in the text layout. The \fIstring\fR must remain valid for the -lifetime of the text layout. +lifetime of the text layout. .AP int numChars in The number of characters to consider from \fIstring\fR. If \fInumChars\fR is less than 0, then assumes \fIstring\fR is null @@ -77,7 +77,7 @@ measured and displayed in a platform-dependent manner as described in \fBTk_MeasureChars\fR, and will not have any special behaviors. .AP int *widthPtr out If non-NULL, filled with either the width, in pixels, of the widest -line in the text layout, or the width, in pixels, of the bounding box for the +line in the text layout, or the width, in pixels, of the bounding box for the character specified by \fIindex\fR. .AP int *heightPtr out If non-NULL, filled with either the total height, in pixels, of all @@ -101,7 +101,7 @@ text layout when it is being drawn, or the coordinates of a point (with respect to the upper-left hand corner of the text layout) to check against the text layout. .AP int firstChar in -The index of the first character to draw from the given text layout. +The index of the first character to draw from the given text layout. The number 0 means to draw from the beginning. .AP int lastChar in The index of the last character up to which to draw. The character @@ -119,7 +119,7 @@ for the character specified by \fIindex\fR. Either or both \fIxPtr\fR and \fIyPtr\fR may be NULL, in which case the corresponding value is not calculated. .AP int "width, height" in -Specifies the width and height, in pixels, of the rectangular area to +Specifies the width and height, in pixels, of the rectangular area to compare for intersection against the text layout. .AP Tcl_Interp *interp out Postscript code that will print the text layout is appended to @@ -132,7 +132,7 @@ justified text. To measure and display simple single-font, single-line strings, refer to the documentation for \fBTk_MeasureChars\fR. There is no programming interface in the core of Tk that supports multi-font, multi-line text; support for that behavior must be built on top of -simpler layers. +simpler layers. Note that unlike the lower level text display routines, the functions described here all operate on character-oriented lengths and indices rather than byte-oriented values. See the description of @@ -150,11 +150,11 @@ returns a Tk_TextLayout token that holds this information. This token is used in subsequent calls to procedures such as \fBTk_DrawTextLayout\fR, \fBTk_DistanceToTextLayout\fR, and \fBTk_FreeTextLayout\fR. The \fIstring\fR and \fItkfont\fR used when computing the layout must remain -valid for the lifetime of this token. +valid for the lifetime of this token. .PP \fBTk_FreeTextLayout\fR is called to release the storage associated with \fIlayout\fR when it is no longer needed. A \fIlayout\fR should not be used -in any other text layout procedures once it has been released. +in any other text layout procedures once it has been released. .PP \fBTk_DrawTextLayout\fR uses the information in \fIlayout\fR to display a single-font, multi-line, justified string of text at the specified location. @@ -191,7 +191,7 @@ placeholder character. \fBTk_CharBbox\fR uses the information in \fIlayout\fR to return the bounding box for the character specified by \fIindex\fR. The width of the bounding box is the advance width of the character, and does not include any -left or right bearing. Any character that extends partially outside of +left or right bearing. Any character that extends partially outside of \fIlayout\fR is considered to be truncated at the edge. Any character that would be located completely outside of \fIlayout\fR is considered to be zero-width and pegged against the edge. The height of the bounding @@ -264,13 +264,13 @@ much as fits placed on the line and the rest on subsequent line(s). If \fIwrapLength\fR is so small that not even one character can fit on a given line, the \fIwrapLength\fR is ignored for that line and one character will be placed on the line anyhow. When wrapping is turned -off, only newline/return characters may cause a line break. +off, only newline/return characters may cause a line break. .PP When a text layout has been created using an underlined \fItkfont\fR, then any space characters that occur at the end of individual lines, -newlines/returns, and tabs will not be displayed underlined when +newlines/returns, and tabs will not be displayed underlined when \fBTk_DrawTextLayout\fR is called, because those characters are never actually drawn \- they are merely placeholders maintained in the -\fIlayout\fR. +\fIlayout\fR. .SH KEYWORDS font diff --git a/doc/Tk_Main.3 b/doc/Tk_Main.3 index a1bb149..ea5f771 100644 --- a/doc/Tk_Main.3 +++ b/doc/Tk_Main.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_Main 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS @@ -29,7 +29,7 @@ The value for this argument is usually \fBTcl_AppInit\fR. .SH DESCRIPTION .PP \fBTk_Main\fR acts as the main program for most Tk-based applications. -Starting with Tk 4.0 it is not called \fBmain\fR anymore because it +Starting with Tk 4.0 it is not called \fBmain\fR anymore because it is part of the Tk library and having a function \fBmain\fR in a library (particularly a shared library) causes problems on many systems. diff --git a/doc/WindowId.3 b/doc/WindowId.3 index 6d55dc0..f937963 100644 --- a/doc/WindowId.3 +++ b/doc/WindowId.3 @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_WindowId 3 "8.4" Tk "Tk Library Procedures" .so man.macros .BS @@ -168,7 +168,7 @@ the window's minimum requested size. These values correspond to the last call to \fBTk_SetMinimumRequestSize\fR for \fItkwin\fR. .PP \fBTk_InternalBorderLeft\fR, \fBTk_InternalBorderRight\fR, -\fBTk_InternalBorderTop\fR and \fBTk_InternalBorderBottom\fR +\fBTk_InternalBorderTop\fR and \fBTk_InternalBorderBottom\fR return the width of one side of the internal border that has been requested for \fItkwin\fR, or 0 if no internal border was requested. The return value is simply the last value passed to diff --git a/doc/button.n b/doc/button.n index e9a45a3..233feb6 100644 --- a/doc/button.n +++ b/doc/button.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH button n 4.4 Tk "Tk Built-In Commands" .so man.macros .BS @@ -69,7 +69,7 @@ In this state the \fB\-disabledforeground\fR and Specifies a desired width for the button. If an image or bitmap is being displayed in the button then the value is in screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR). -For a text button (no image or with \fB\-compound none\fR) then the width +For a text button (no image or with \fB\-compound none\fR) then the width specifies how much space in characters to allocate for the text label. If the width is negative then this specifies a minimum width. If this option is not specified, the button's desired width is computed @@ -96,7 +96,7 @@ one of the characters may optionally be underlined using the \fB\-underline\fR option. It can display itself in either of three different ways, according to -the \fB\-state\fR option; +the \fB\-state\fR option; it can be made to appear raised, sunken, or flat; and it can be made to flash. When a user invokes the button (by pressing mouse button 1 with the cursor over the diff --git a/doc/canvas.n b/doc/canvas.n index bc29cc3..38697cd 100644 --- a/doc/canvas.n +++ b/doc/canvas.n @@ -263,7 +263,7 @@ automatically decremented by one. A number less than 0 is treated as if it were zero, and a number greater than the length of the text item is treated as if it were equal to the length of the text item. For -polygons, numbers less than 0 or greater then the length +polygons, numbers less than 0 or greater than the length of the coordinate list will be adjusted by adding or subtracting the length until the result is between zero and the length, inclusive. @@ -405,7 +405,7 @@ behaves as if the \fIstart\fR argument had not been specified. . Selects all the items completely enclosed within the rectangular region given by \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR. -\fIX1\fR must be no greater then \fIx2\fR and \fIy1\fR must be +\fIX1\fR must be no greater than \fIx2\fR and \fIy1\fR must be no greater than \fIy2\fR. .TP \fBoverlapping\fR \fIx1\fR \fIy1\fR \fIx2\fR \fIy2\fR @@ -413,7 +413,7 @@ no greater than \fIy2\fR. Selects all the items that overlap or are enclosed within the rectangular region given by \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR. -\fIX1\fR must be no greater then \fIx2\fR and \fIy1\fR must be +\fIX1\fR must be no greater than \fIx2\fR and \fIy1\fR must be no greater than \fIy2\fR. .TP \fBwithtag \fItagOrId\fR diff --git a/doc/checkbutton.n b/doc/checkbutton.n index 2e6f840..bfefca4 100644 --- a/doc/checkbutton.n +++ b/doc/checkbutton.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH checkbutton n 4.4 Tk "Tk Built-In Commands" .so man.macros .BS @@ -52,7 +52,7 @@ and setting \fB\-indicatoron\fR to false and \fB\-overrelief\fR to the effect is achieved of having a flat button that raises on mouse-over and which is depressed when activated. This is the behavior typically exhibited by -the Bold, Italic, and Underline checkbuttons on the toolbar of a +the Bold, Italic, and Underline checkbuttons on the toolbar of a word-processor, for example. .OP \-offvalue offValue Value Specifies value to store in the button's associated variable whenever diff --git a/doc/chooseDirectory.n b/doc/chooseDirectory.n index 86c593d..8528ddb 100644 --- a/doc/chooseDirectory.n +++ b/doc/chooseDirectory.n @@ -1,7 +1,7 @@ '\" '\" Copyright (c) 1998-2000 by Scriptics Corporation. '\" All rights reserved. -'\" +'\" .TH tk_chooseDirectory n 8.3 Tk "Tk Built-In Commands" .so man.macros .BS @@ -20,7 +20,7 @@ possible as command line arguments: \fB\-initialdir\fR \fIdirname\fR Specifies that the directories in \fIdirectory\fR should be displayed when the dialog pops up. If this parameter is not specified, -the initial directory defaults to the current working directory +the initial directory defaults to the current working directory on non-Windows systems and on Windows systems prior to Vista. On Vista and later systems, the initial directory defaults to the last user-selected directory for the application. If the diff --git a/doc/clipboard.n b/doc/clipboard.n index 374cbd1..6f047dd 100644 --- a/doc/clipboard.n +++ b/doc/clipboard.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH clipboard n 8.4 Tk "Tk Built-In Commands" .so man.macros .BS @@ -17,7 +17,7 @@ clipboard \- Manipulate Tk clipboard .SH DESCRIPTION .PP This command provides a Tcl interface to the Tk clipboard, -which stores data for later retrieval using the selection mechanism +which stores data for later retrieval using the selection mechanism (via the \fB\-selection CLIPBOARD\fR option). In order to copy data into the clipboard, \fBclipboard clear\fR must be called, followed by a sequence of one or more calls to \fBclipboard @@ -52,7 +52,7 @@ Table 2 of the ICCCM), and defaults to \fBSTRING\fR. If \fIformat\fR is divided into fields separated by white space; each field is converted to its atom value, and the 32-bit atom value is transmitted instead of the atom name. For any other \fIformat\fR, \fIdata\fR is divided -into fields separated by white space and each +into fields separated by white space and each field is converted to a 32-bit integer; an array of integers is transmitted to the selection requester. Note that strings passed to \fBclipboard append\fR are concatenated before conversion, so the diff --git a/doc/event.n b/doc/event.n index 7a3cfca..54ad42e 100644 --- a/doc/event.n +++ b/doc/event.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH event n 8.3 Tk "Tk Built-In Commands" .so man.macros .BS @@ -172,7 +172,7 @@ one of \fBNotifyNormal\fR, \fBNotifyGrab\fR, \fBNotifyUngrab\fR, or \fBNotifyWhileGrabbed\fR. Valid for \fBEnter\fR, \fBLeave\fR, \fBFocusIn\fR, and \fBFocusOut\fR events. -Corresponds to the \fB%m\fR substitution for binding scripts. +Corresponds to the \fB%m\fR substitution for binding scripts. .TP \fB\-override\fI boolean\fR \fIBoolean\fR must be a boolean value; it specifies the @@ -224,7 +224,7 @@ Corresponds to the \fB%#\fR substitution for binding scripts. For \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR, \fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events it must be an integer value. -For \fBVisibility\fR events it must be one of \fBVisibilityUnobscured\fR, +For \fBVisibility\fR events it must be one of \fBVisibilityUnobscured\fR, \fBVisibilityPartiallyObscured\fR, or \fBVisibilityFullyObscured\fR. This option overrides any modifiers such as \fBMeta\fR or \fBControl\fR specified in the base \fIevent\fR. @@ -302,9 +302,9 @@ If \fIWindow\fR is empty the coordinate is relative to the screen, and this option corresponds to the \fB%Y\fR substitution for binding scripts. .PP -Any options that are not specified when generating an event are filled -with the value 0, except for \fIserial\fR, which is filled with the -next X event serial number. +Any options that are not specified when generating an event are filled +with the value 0, except for \fIserial\fR, which is filled with the +next X event serial number. .SH "PREDEFINED VIRTUAL EVENTS" .PP Tk defines the following virtual events for the purposes of @@ -351,6 +351,16 @@ This is sent to a widget when the focus leaves the widget because of a user-driven .QW "tab to widget" action. +.TP +\fB<<UndoStack>>\fR +This is sent to a text widget when its undo stack or redo stack becomes +empty or unempty. +.TP +\fB<<WidgetViewSync>>\fR +This is sent to a text widget when its internal data become obsolete, +and again when these internal data are back in sync with the widget +view. The detail field (%d substitution) is either true (when the +widget is in sync) or false (when it is not). .PP Tk defines the following virtual events for the purposes of unifying bindings across multiple platforms. Users expect them to behave in the @@ -540,7 +550,7 @@ will be invoked, because a physical event is considered more specific than a virtual event, all other things being equal. However, when the user types Meta-Control-y the \fB<<Paste>>\fR binding will be invoked, because the -\fBMeta\fR modifier in the physical pattern associated with the +\fBMeta\fR modifier in the physical pattern associated with the virtual binding is more specific than the \fB<Control-y\fR> sequence for the physical event. .PP @@ -560,7 +570,7 @@ bind Entry <Control-y> {} .PP the behavior will change such in two ways. First, the shadowed \fB<<Paste>>\fR binding will emerge. -Typing Control-y will no longer invoke the \fB<Control-y>\fR binding, +Typing Control-y will no longer invoke the \fB<Control-y>\fR binding, but instead invoke the virtual event \fB<<Paste>>\fR. Second, pressing the F6 key will now also invoke the \fB<<Paste>>\fR binding. .SS "MOVING THE MOUSE POINTER" @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH font n 8.0 Tk "Tk Built-In Commands" .so man.macros .BS @@ -38,7 +38,7 @@ that character, which will be different from the base font if the base font does not contain the given character. If \fIchar\fR may be a hyphen, it should be preceded by \fB\-\|\-\fR to distinguish it from a misspelled \fIoption\fR. -.TP +.TP \fBfont configure \fIfontname\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? . Query or modify the desired attributes for the named font called @@ -88,7 +88,7 @@ omitted, it defaults to the main window. Measures the amount of space the string \fItext\fR would use in the given \fIfont\fR when displayed in \fIwindow\fR. \fIfont\fR is a font description; see \fBFONT DESCRIPTIONS\fR below. If the \fIwindow\fR argument is -omitted, it +omitted, it defaults to the main window. The return value is the total width in pixels of \fItext\fR, not including the extra pixels used by highly exaggerated characters such as cursive diff --git a/doc/getOpenFile.n b/doc/getOpenFile.n index f5e92ff..39bce41 100644 --- a/doc/getOpenFile.n +++ b/doc/getOpenFile.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tk_getOpenFile n 4.2 Tk "Tk Built-In Commands" .so man.macros .BS @@ -65,8 +65,8 @@ discussion on the contents of \fIfilePatternList\fR. \fB\-initialdir\fR \fIdirectory\fR . Specifies that the files in \fIdirectory\fR should be displayed -when the dialog pops up. If this parameter is not specified, -the initial directory defaults to the current working directory +when the dialog pops up. If this parameter is not specified, +the initial directory defaults to the current working directory on non-Windows systems and on Windows systems prior to Vista. On Vista and later systems, the initial directory defaults to the last user-selected directory for the application. If the @@ -95,7 +95,7 @@ turns the file dialog into a sheet attached to the parent window. \fB\-title\fR \fItitleString\fR . Specifies a string to display as the title of the dialog box. If this -option is not specified, then a default title is displayed. +option is not specified, then a default title is displayed. .TP \fB\-typevariable\fR \fIvariableName\fR . diff --git a/doc/listbox.n b/doc/listbox.n index 9f34b5e..66b75b9 100644 --- a/doc/listbox.n +++ b/doc/listbox.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH listbox n 8.4 Tk "Tk Built-In Commands" .so man.macros .BS @@ -17,9 +17,10 @@ listbox \- Create and manipulate 'listbox' item list widgets \-background \-borderwidth \-cursor \-disabledforeground \-exportselection \-font \-foreground \-highlightbackground \-highlightcolor -\-highlightthickness \-relief \-selectbackground -\-selectborderwidth \-selectforeground \-setgrid -\-takefocus \-xscrollcommand \-yscrollcommand +\-highlightthickness \-justify \-relief +\-selectbackground \-selectborderwidth \-selectforeground +\-setgrid \-takefocus \-xscrollcommand +\-yscrollcommand .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-activestyle activeStyle ActiveStyle @@ -228,7 +229,7 @@ list. Returns an empty string. \fIpathName \fBitemcget \fIindex option\fR . Returns the current value of the item configuration option given -by \fIoption\fR. \fIOption\fR may have any of the values accepted +by \fIoption\fR. \fIOption\fR may have any of the values accepted by the \fBitemconfigure\fR command. .TP \fIpathName \fBitemconfigure \fIindex\fR ?\fIoption\fR? ?\fIvalue\fR? ?\fIoption value ...\fR? @@ -248,7 +249,7 @@ are currently supported for items: .TP \fB\-background \fIcolor\fR . -\fIColor\fR specifies the background color to use when displaying the +\fIColor\fR specifies the background color to use when displaying the item. It may have any of the forms accepted by \fBTk_GetColor\fR. .TP \fB\-foreground \fIcolor\fR diff --git a/doc/loadTk.n b/doc/loadTk.n index d4ec51e..3673e98 100644 --- a/doc/loadTk.n +++ b/doc/loadTk.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH "Safe Tk" n 8.0 Tk "Tk Built-In Commands" .so man.macros .BS @@ -11,7 +11,7 @@ .SH NAME safe::loadTk \- Load Tk into a safe interpreter. .SH SYNOPSIS -\fBsafe::loadTk \fIslave\fR ?\fB\-use\fR \fIwindowId\fR? ?\fB\-display\fR \fIdisplayName\fR? +\fBsafe::loadTk \fIslave\fR ?\fB\-use\fR \fIwindowId\fR? ?\fB\-display\fR \fIdisplayName\fR? .BE .SH DESCRIPTION .PP @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH menu n 4.1 Tk "Tk Built-In Commands" .so man.macros .BS @@ -269,8 +269,8 @@ are appended to the standard Help menu of the user's menubar whenever the window's menubar is in front. The first items in the menu are provided by Mac OS X. .PP -When Tk sees a System menu on Windows, its items are appended to the -system menu that the menubar is attached to. This menu is tied to the +When Tk sees a System menu on Windows, its items are appended to the +system menu that the menubar is attached to. This menu is tied to the application icon and can be invoked with the mouse or by typing Alt+Spacebar. Due to limitations in the Windows API, any font changes, colors, images, bitmaps, or tearoff images will not appear in the @@ -676,7 +676,7 @@ option for the menu along with the \fB\-activebackground\fR option from the entry. Disabled state means that the entry should be insensitive: the default bindings will refuse to activate or invoke the entry. -In this state the entry is displayed according to the +In this state the entry is displayed according to the \fB\-disabledforeground\fR option for the menu and the \fB\-background\fR option from the entry. This option is not available for separator entries. diff --git a/doc/option.n b/doc/option.n index 8699c0d..2763d64 100644 --- a/doc/option.n +++ b/doc/option.n @@ -59,6 +59,12 @@ options specified in that file to the option database. If \fIpriority\fR is specified, it indicates the priority level at which to enter the options; \fIpriority\fR defaults to \fBinteractive\fR. .PP +The file is read through a channel which is in "utf-8" encoding, +invalid byte sequences are automatically converted to valid ones. +This means that encodings like ISO 8859-1 or cp1252 with high +probability will work as well, but this cannot be guaranteed. +This cannot be changed, setting the [encoding system] has no effect. +.PP The \fIpriority\fR arguments to the \fBoption\fR command are normally specified symbolically using one of the following values: .TP diff --git a/doc/options.n b/doc/options.n index 36937b1..738a1c6 100644 --- a/doc/options.n +++ b/doc/options.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH options n 4.4 Tk "Tk Built-In Commands" .so man.macros .BS @@ -268,7 +268,7 @@ traversal (e.g., Tab and Shift-Tab). Before setting the focus to a window, the traversal scripts consult the value of the \fB\-takefocus\fR option. A value of \fB0\fR means that the window should be skipped entirely -during keyboard traversal. +during keyboard traversal. \fB1\fR means that the window should receive the input focus as long as it is viewable (it and all of its ancestors are mapped). An empty value for the option means that the traversal scripts make @@ -278,7 +278,7 @@ disabled, if it has no key bindings, or if it is not viewable. If the value has any other form, then the traversal scripts take the value, append the name of the window to it (with a separator space), and evaluate the resulting string as a Tcl script. -The script must return \fB0\fR, \fB1\fR, or an empty string: a +The script must return \fB0\fR, \fB1\fR, or an empty string: a \fB0\fR or \fB1\fR value specifies whether the window will receive the input focus, and an empty string results in the default decision described above. diff --git a/doc/panedwindow.n b/doc/panedwindow.n index e2c954a..fcfebf4 100644 --- a/doc/panedwindow.n +++ b/doc/panedwindow.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH panedwindow n 8.4 Tk "Tk Built-In Commands" .so man.macros .BS @@ -151,7 +151,7 @@ Remove the proxy from the display. .TP \fIpathName \fBproxy place \fIx y\fR . -Place the proxy at the given \fIx\fR and \fIy\fR coordinates. +Place the proxy at the given \fIx\fR and \fIy\fR coordinates. .RE .TP \fIpathName \fBsash \fR?\fIargs\fR? @@ -239,13 +239,13 @@ dimension for vertical panedwindows. May be any value accepted by \fB\-padx \fIn\fR . Specifies a non-negative value indicating how much extra space to -leave on each side of the window in the X-direction. The value may +leave on each side of the window in the X-direction. The value may have any of the forms accepted by \fBTk_GetPixels\fR. .TP \fB\-pady \fIn\fR . Specifies a non-negative value indicating how much extra space to -leave on each side of the window in the Y-direction. The value may +leave on each side of the window in the Y-direction. The value may have any of the forms accepted by \fBTk_GetPixels\fR. .TP \fB\-sticky \fIstyle\fR diff --git a/doc/radiobutton.n b/doc/radiobutton.n index 557b42c..c79aa23 100644 --- a/doc/radiobutton.n +++ b/doc/radiobutton.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH radiobutton n 4.4 Tk "Tk Built-In Commands" .so man.macros .BS @@ -59,10 +59,10 @@ By setting this option to .QW flat and setting \fB\-indicatoron\fR to false and \fB\-overrelief\fR to .QW raised , -the effect is achieved +the effect is achieved of having a flat button that raises on mouse-over and which is depressed when activated. This is the behavior typically exhibited by -the Align-Left, Align-Right, and Center radiobuttons on the toolbar of a +the Align-Left, Align-Right, and Center radiobuttons on the toolbar of a word-processor, for example. .OP \-overrelief overRelief OverRelief Specifies an alternative relief for the radiobutton, to be used when the diff --git a/doc/scale.n b/doc/scale.n index 7bc5c59..0504b4b 100644 --- a/doc/scale.n +++ b/doc/scale.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH scale n 4.1 Tk "Tk Built-In Commands" .so man.macros .BS @@ -209,7 +209,7 @@ the horizontal behavior is described in parentheses. .IP [1] If button 1 is pressed in the trough, the scale's value will be incremented or decremented by the value of the \fB\-resolution\fR -option so that the slider moves in the direction of the cursor. +option so that the slider moves in the direction of the cursor. If the button is held down, the action auto-repeats. .IP [2] If button 1 is pressed over the slider, the slider can be dragged diff --git a/doc/selection.n b/doc/selection.n index e06a716..f5bb660 100644 --- a/doc/selection.n +++ b/doc/selection.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH selection n 8.1 Tk "Tk Built-In Commands" .so man.macros .BS @@ -36,7 +36,7 @@ atom name such as \fBPRIMARY\fR or \fBCLIPBOARD\fR; see the Inter-Client Communication Conventions Manual for complete details. \fISelection\fR defaults to \fBPRIMARY\fR and \fIwindow\fR defaults to .QW . . -Returns an empty string. +Returns an empty string. .TP \fBselection get\fR ?\fB\-displayof\fR \fIwindow\fR? ?\fB\-selection\fR \fIselection\fR? ?\fB\-type\fR \fItype\fR? . @@ -79,7 +79,7 @@ automatically handled as type \fBUTF8_STRING\fR as well. When \fIselection\fR is requested, \fIwindow\fR is the selection owner, and \fItype\fR is the requested type, \fIcommand\fR will be executed as a Tcl command with two additional numbers appended to it -(with space separators). +(with space separators). The two additional numbers are \fIoffset\fR and \fImaxChars\fR: \fIoffset\fR specifies a starting character position in the selection and \fImaxChars\fR gives the maximum diff --git a/doc/spinbox.n b/doc/spinbox.n index 7227cf1..330bb17 100644 --- a/doc/spinbox.n +++ b/doc/spinbox.n @@ -55,7 +55,7 @@ A floating-point value corresponding to the lowest value for a spinbox, to be used in conjunction with \fB\-to\fR and \fB\-increment\fR. When all are specified correctly, the spinbox will use these values to control its contents. This value must be less than the \fB\-to\fR option. -If \fB\-values\fR is specified, it supercedes this option. +If \fB\-values\fR is specified, it supersedes this option. .OP "\-invalidcommand or \-invcmd" invalidCommand InvalidCommand Specifies a script to eval when \fB\-validatecommand\fR returns 0. Setting it to an empty string disables this feature (the default). The best use of @@ -84,7 +84,7 @@ A floating-point value corresponding to the highest value for the spinbox, to be used in conjunction with \fB\-from\fR and \fB\-increment\fR. When all are specified correctly, the spinbox will use these values to control its contents. This value must be greater than the \fB\-from\fR option. -If \fB\-values\fR is specified, it supercedes this option. +If \fB\-values\fR is specified, it supersedes this option. .OP \-validate validate Validate Specifies the mode in which validation should operate: \fBnone\fR, \fBfocus\fR, \fBfocusin\fR, \fBfocusout\fR, \fBkey\fR, or \fBall\fR. @@ -486,6 +486,15 @@ much the line should be indented from the left edge of the window. option is only used when wrapping is enabled, and it only applies to the second and later display lines for a text line. .TP +\fB\-lmargincolor \fIcolor\fR +. +\fIColor\fR specifies the background color to use in regions that do not +contain characters because they are indented by \fB\-lmargin1\fR or +\fB\-lmargin2\fR. It may have any of the forms accepted by +\fBTk_GetColor\fR.If \fIcolor\fR has not been specified, or if it is +specified as an empty string, then the color specified by the +\fB-background\fR widget option is used. +.TP \fB\-offset \fIpixels\fR . \fIPixels\fR specifies an amount by which the text's baseline should be offset @@ -500,6 +509,13 @@ Specifies whether or not to draw a horizontal rule through the middle of characters. \fIBoolean\fR may have any of the forms accepted by \fBTcl_GetBoolean\fR. .TP +\fB\-overstrikefg \fIcolor\fR +. +\fIColor\fR specifies the color to use when displaying the overstrike. It may +have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not +been specified, or if it is specified as an empty string, then the color +specified by the \fB\-foreground\fR tag option is used. +.TP \fB\-relief \fIrelief\fR . \fIRelief\fR specifies the relief style to use for drawing the border, in any @@ -517,6 +533,28 @@ option is only used when wrapping is enabled. If a text line wraps, the right margin for each line on the display is determined by the first non-elided character of that display line. .TP +\fB\-rmargincolor \fIcolor\fR +. +\fIColor\fR specifies the background color to use in regions that do not +contain characters because they are indented by \fB\-rmargin1\fR. It may +have any of the forms accepted by \fBTk_GetColor\fR.If \fIcolor\fR has not +been specified, or if it is specified as an empty string, then the color +specified by the \fB-background\fR widget option is used. +.TP +\fB\-selectbackground \fIcolor\fR +\fIColor\fR specifies the background color to use when displaying selected +items. It may have any of the forms accepted by \fBTk_GetColor\fR. If +\fIcolor\fR has not been specified, or if it is specified as an empty +string, then the color specified by the \fB\-background\fR tag option is +used. +.TP +\fB\-selectforeground \fIcolor\fR +\fIColor\fR specifies the foreground color to use when displaying selected +items. It may have any of the forms accepted by \fBTk_GetColor\fR. If +\fIcolor\fR has not been specified, or if it is specified as an empty +string, then the color specified by the \fB\-foreground\fR tag option is +used. +.TP \fB\-spacing1 \fIpixels\fR . \fIPixels\fR specifies how much additional space should be left above each @@ -559,6 +597,13 @@ unspecified for the tag (the default). \fIBoolean\fR specifies whether or not to draw an underline underneath characters. It may have any of the forms accepted by \fBTcl_GetBoolean\fR. .TP +\fB\-underlinefg \fIcolor\fR +. +\fIColor\fR specifies the color to use when displaying the underline. It may +have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not +been specified, or if it is specified as an empty string, then the color +specified by the \fB\-foreground\fR tag option is used. +.TP \fB\-wrap \fImode\fR . \fIMode\fR specifies how to handle lines that are wider than the text's @@ -852,6 +897,9 @@ separator is already present at the top of the undo stack no other will be inserted. That means that two separators on the undo stack are always separated by at least one insert or delete action. .PP +The \fB<<UndoStack>>\fR virtual event is generated every time the undo stack +or the redo stack becomes empty or unempty. +.PP The undo mechanism is also linked to the modified flag. This means that undoing or redoing changes can take a modified text widget back to the unmodified state or vice versa. The modified flag will be set automatically to @@ -935,7 +983,7 @@ geometry manager), one can resort to \fIpathName \fBsync\fR and \fIpathName \fBpendingsync\fR to control the synchronization of the view of text widgets. .PP The \fB<<WidgetViewSync>>\fR virtual event fires when the line heights of the -text widget becomes obsolete (due to some editing command or configuration +text widget become obsolete (due to some editing command or configuration change), and again when the internal data of the text widget are back in sync with the widget view. The detail field (%d substitution) is either true (when the widget is in sync) or false (when it is not). @@ -1128,22 +1176,30 @@ test suite. .TP \fIpathName \fBdelete \fIindex1 \fR?\fIindex2 ...\fR? . -Delete a range of characters from the text. If both \fIindex1\fR and -\fIindex2\fR are specified, then delete all the characters starting with the -one given by \fIindex1\fR and stopping just before \fIindex2\fR (i.e. the -character at \fIindex2\fR is not deleted). If \fIindex2\fR does not specify a -position later in the text than \fIindex1\fR then no characters are deleted. -If \fIindex2\fR is not specified then the single character at \fIindex1\fR is -deleted. It is not allowable to delete characters in a way that would leave -the text without a newline as the last character. The command returns an empty -string. If more indices are given, multiple ranges of text will be deleted. -All indices are first checked for validity before any deletions are made. They -are sorted and the text is removed from the last range to the first range so -deleted text does not cause an undesired index shifting side-effects. If -multiple ranges with the same start index are given, then the longest range is -used. If overlapping ranges are given, then they will be merged into spans -that do not cause deletion of text outside the given ranges due to text -shifted during deletion. +Delete a range of characters from the text. +If both \fIindex1\fR and \fIindex2\fR are specified, then delete +all the characters starting with the one given by \fIindex1\fR +and stopping just before \fIindex2\fR (i.e. the character at +\fIindex2\fR is not deleted). +If \fIindex2\fR does not specify a position later in the text +than \fIindex1\fR then no characters are deleted. +If \fIindex2\fR is not specified then the single character at +\fIindex1\fR is deleted. +Attempts to delete characters in a way that would leave +the text without a newline as the last character will be tweaked by the +text widget to avoid this. In particular, deletion of complete lines of +text up to the end of the text will also delete the newline character just +before the deleted block so that it is replaced by the new final newline +of the text widget. +The command returns an empty string. +If more indices are given, multiple ranges of text will be deleted. +All indices are first checked for validity before any deletions are made. +They are sorted and the text is removed from the last range to the +first range so deleted text does not cause an undesired index shifting +side-effects. If multiple ranges with the same start index are given, +then the longest range is used. If overlapping ranges are given, then +they will be merged into spans that do not cause deletion of text +outside the given ranges due to text shifted during deletion. .TP \fIpathName \fBdlineinfo \fIindex\fR . @@ -1229,6 +1285,16 @@ behavior of the command depends on the \fIoption\fR argument that follows the supported: .RS .TP +\fIpathName \fBedit canredo\fR +. +Returns a boolean true if redo is possible, i.e. when the redo stack is not +empty. Otherwise returns false. +.TP +\fIpathName \fBedit canundo\fR +. +Returns a boolean true if undo is possible, i.e. when the undo stack is not +empty. Otherwise returns false. +.TP \fIpathName \fBedit modified \fR?\fIboolean\fR? . If \fIboolean\fR is not specified, returns the modified flag of the widget. diff --git a/doc/tkerror.n b/doc/tkerror.n index 0780901..53cb0d1 100644 --- a/doc/tkerror.n +++ b/doc/tkerror.n @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tkerror n 4.1 Tk "Tk Built-In Commands" .so man.macros .BS @@ -20,11 +20,11 @@ Note: as of Tk 4.1 the \fBtkerror\fR command has been renamed to \fBbgerror\fR because the event loop (which is what usually invokes it) is now part of Tcl. For backward compatibility the \fBbgerror\fR provided by the current Tk version still -tries to call \fBtkerror\fR if there is one (or an auto loadable one), +tries to call \fBtkerror\fR if there is one (or an auto loadable one), so old script defining that error handler should still work, but you -should anyhow modify your scripts to use \fBbgerror\fR instead +should anyhow modify your scripts to use \fBbgerror\fR instead of \fBtkerror\fR because that support for the old name might vanish -in the near future. If that call fails, \fBbgerror\fR +in the near future. If that call fails, \fBbgerror\fR posts a dialog showing the error and offering to see the stack trace to the user. If you want your own error management you should directly override \fBbgerror\fR instead of \fBtkerror\fR. diff --git a/doc/ttk_Geometry.3 b/doc/ttk_Geometry.3 index 8dfae37..61015c5 100644 --- a/doc/ttk_Geometry.3 +++ b/doc/ttk_Geometry.3 @@ -75,7 +75,7 @@ Used to store error messages. .AP int left in Extra padding (in pixels) to add to the left side of a region. .AP "Tcl_Obj *" objPtr in -String value contains a symbolic name +String value contains a symbolic name to be converted to an enumerated value or bitmask. Internal rep may be be modified to cache corresponding value. .AP Ttk_Padding padding in @@ -84,18 +84,18 @@ Extra padding to add on the inside of a region. .AP Ttk_Box parcel in A rectangular region, allocated from a cavity. .AP int relief in -One of the standard Tk relief options -(TK_RELIEF_RAISED, TK_RELIEF_SUNKEN, etc.). +One of the standard Tk relief options +(TK_RELIEF_RAISED, TK_RELIEF_SUNKEN, etc.). See \fBTk_GetReliefFromObj\fR. .AP short right in Extra padding (in pixels) to add to the right side of a region. .AP Ttk_Side side in -One of \fBTTK_SIDE_LEFT\fR, \fBTTK_SIDE_TOP\fR, +One of \fBTTK_SIDE_LEFT\fR, \fBTTK_SIDE_TOP\fR, \fBTTK_SIDE_RIGHT\fR, or \fBTTK_SIDE_BOTTOM\fR. .AP unsigned sticky in A bitmask containing one or more of the bits -\fBTTK_STICK_W\fR (west, or left), -\fBTTK_STICK_E\fR (east, or right, +\fBTTK_STICK_W\fR (west, or left), +\fBTTK_STICK_E\fR (east, or right, \fBTTK_STICK_N\fR (north, or top), and \fBTTK_STICK_S\fR (south, or bottom). \fBTTK_FILL_X\fR is defined as a synonym for (TTK_STICK_W|TTK_STICK_E), @@ -104,7 +104,7 @@ and \fBTTK_FILL_BOTH\fR and \fBTTK_STICK_ALL\fR are synonyms for (TTK_FILL_X|TTK_FILL_Y). See also: \fIgrid(n)\fR. .AP Tk_Window tkwin in -Window whose screen geometry determines +Window whose screen geometry determines the conversion between absolute units and pixels. .AP short top in Extra padding at the top of a region. @@ -184,14 +184,14 @@ with all components equal to the specified \fIborder\fR. and returns a combined padding containing the sum of the individual padding components. .PP -\fBTtk_RelievePadding\fR +\fBTtk_RelievePadding\fR adds an extra 2 pixels of padding to \fIpadding\fR according to the specified \fIrelief\fR. -If \fIrelief\fR is \fBTK_RELIEF_SUNKEN\fR, +If \fIrelief\fR is \fBTK_RELIEF_SUNKEN\fR, adds two pixels at the top and left so the inner region is shifted down and to the left. If it is \fBTK_RELIEF_RAISED\fR, adds two pixels -at the bottom and right so +at the bottom and right so the inner region is shifted up and to the right. Otherwise, adds 1 pixel on all sides. This is typically used in element geometry procedures to simulate a @@ -201,17 +201,17 @@ look for pushbuttons. .PP \fBTtk_GetPaddingFromObj\fR converts the string in \fIobjPtr\fR to a \fBTtk_Padding\fR structure. -The string representation is a list of -up to four length specifications +The string representation is a list of +up to four length specifications .QW "\fIleft top right bottom\fR" . -If fewer than four elements are specified, +If fewer than four elements are specified, \fIbottom\fR defaults to \fItop\fR, -\fIright\fR defaults to \fIleft\fR, and +\fIright\fR defaults to \fIleft\fR, and \fItop\fR defaults to \fIleft\fR. See \fBTk_GetPixelsFromObj(3)\fR for the syntax of length specifications. .PP \fBTtk_GetBorderFromObj\fR is the same as \fBTtk_GetPaddingFromObj\fR -except that the lengths are specified as integers +except that the lengths are specified as integers (i.e., resolution-dependant values like \fI3m\fR are not allowed). .PP \fBTtk_GetStickyFromObj\fR converts the string in \fIobjPtr\fR diff --git a/doc/ttk_button.n b/doc/ttk_button.n index 2f3c845..62ebe47 100644 --- a/doc/ttk_button.n +++ b/doc/ttk_button.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::button n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -36,12 +36,12 @@ button (meaning, roughly, The default is \fBnormal\fR. .RS .PP -Depending on the theme, the default button may be displayed +Depending on the theme, the default button may be displayed with an extra highlight ring, or with a different border color. .RE .OP \-width width Width -If greater than zero, specifies how much space, in character widths, -to allocate for the text label. +If greater than zero, specifies how much space, in character widths, +to allocate for the text label. If less than zero, specifies a minimum width. If zero or unspecified, the natural width of the text label is used. Note that some themes may specify a non-zero \fB\-width\fR @@ -55,8 +55,8 @@ in the style. .\" .OP \-relief relief Relief .SH "WIDGET COMMAND" .PP -In addition to the standard -\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR +In addition to the standard +\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR commands, buttons support the following additional widget commands: .TP \fIpathName \fBinvoke\fR diff --git a/doc/ttk_checkbutton.n b/doc/ttk_checkbutton.n index 6236503..ed79f5a 100644 --- a/doc/ttk_checkbutton.n +++ b/doc/ttk_checkbutton.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::checkbutton n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -14,7 +14,7 @@ ttk::checkbutton \- On/off widget .BE .SH DESCRIPTION A \fBttk::checkbutton\fR widget is used to show or change a setting. -It has two states, selected and deselected. +It has two states, selected and deselected. The state of the checkbutton may be linked to a Tcl variable. .SO ttk_widget \-class \-compound \-cursor @@ -26,18 +26,18 @@ The state of the checkbutton may be linked to a Tcl variable. .OP \-command command Command A Tcl script to execute whenever the widget is invoked. .OP \-offvalue offValue OffValue -The value to store in the associated \fB\-variable\fR +The value to store in the associated \fB\-variable\fR when the widget is deselected. Defaults to \fB0\fR. .OP \-onvalue onValue OnValue -The value to store in the associated \fB\-variable\fR +The value to store in the associated \fB\-variable\fR when the widget is selected. Defaults to \fB1\fR. .OP \-variable variable Variable The name of a global variable whose value is linked to the widget. Defaults to the widget pathname if not specified. .SH "WIDGET COMMAND" .PP -In addition to the standard -\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR +In addition to the standard +\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR commands, checkbuttons support the following additional widget commands: .TP @@ -48,17 +48,17 @@ If the widget is currently selected, sets the \fB\-variable\fR to the \fB\-offvalue\fR and deselects the widget; otherwise, sets the \fB\-variable\fR to the \fB\-onvalue\fR Returns the result of the \fB\-command\fR. -.\" Missing: select, deselect, toggle +.\" Missing: select, deselect, toggle .\" Are these useful? They don't invoke the -command .\" Missing: flash. This is definitely not useful. .SH "WIDGET STATES" .PP The widget does not respond to user input if the \fBdisabled\fR state is set. -The widget sets the \fBselected\fR state whenever +The widget sets the \fBselected\fR state whenever the linked \fB\-variable\fR is set to the widget's \fB\-onvalue\fR, and clears it otherwise. -The widget sets the \fBalternate\fR state whenever the -linked \fB\-variable\fR is unset. +The widget sets the \fBalternate\fR state whenever the +linked \fB\-variable\fR is unset. (The \fBalternate\fR state may be used to indicate a .QW tri-state or diff --git a/doc/ttk_combobox.n b/doc/ttk_combobox.n index dc1c7d1..5e5b3fc 100644 --- a/doc/ttk_combobox.n +++ b/doc/ttk_combobox.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::combobox n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -15,7 +15,7 @@ ttk::combobox \- text field with popdown selection list .SH DESCRIPTION .PP A \fBttk::combobox\fR combines a text field with a pop-down list of values; -the user may select the value of the text field from among the +the user may select the value of the text field from among the values in the list. .SO ttk_widget \-class \-cursor \-takefocus @@ -37,14 +37,14 @@ The \fB\-postcommand\fR script may specify the \fB\-values\fR to display. .OP \-state state State One of \fBnormal\fR, \fBreadonly\fR, or \fBdisabled\fR. In the \fBreadonly\fR state, -the value may not be edited directly, and +the value may not be edited directly, and the user can only select one of the \fB\-values\fR from the dropdown list. -In the \fBnormal\fR state, +In the \fBnormal\fR state, the text field is directly editable. In the \fBdisabled\fR state, no interaction is possible. .OP \-textvariable textVariable TextVariable -Specifies the name of a global variable whose value is linked +Specifies the name of a global variable whose value is linked to the widget value. Whenever the variable changes value the widget value is updated, and vice versa. @@ -66,7 +66,7 @@ The following subcommands are possible for combobox widgets: '\"See \fIttk::widget(n)\fR. .TP \fIpathName \fBcurrent\fR ?\fInewIndex\fR? -If \fInewIndex\fR is supplied, sets the combobox value +If \fInewIndex\fR is supplied, sets the combobox value to the element at position \fInewIndex\fR in the list of \fB\-values\fR. Otherwise, returns the index of the current value in the list of \fB\-values\fR or \fB\-1\fR if the current value does not appear in the list. diff --git a/doc/ttk_entry.n b/doc/ttk_entry.n index 34779a6..984e957 100644 --- a/doc/ttk_entry.n +++ b/doc/ttk_entry.n @@ -5,7 +5,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::entry n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -18,9 +18,9 @@ ttk::entry \- Editable text field widget .PP An \fBttk::entry\fR widget displays a one-line text string and allows that string to be edited by the user. -The value of the string may be linked to a Tcl variable +The value of the string may be linked to a Tcl variable with the \fB\-textvariable\fR option. -Entry widgets support horizontal scrolling with the +Entry widgets support horizontal scrolling with the standard \fB\-xscrollcommand\fR option and \fBxview\fR widget command. .SO ttk_widget \-class \-cursor \-style @@ -28,7 +28,7 @@ standard \fB\-xscrollcommand\fR option and \fBxview\fR widget command. .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-exportselection exportSelection ExportSelection -A boolean value specifying whether or not +A boolean value specifying whether or not a selection in the widget should be linked to the X selection. If the selection is exported, then selecting in the widget deselects the current X selection, selecting outside the widget deselects any @@ -65,7 +65,7 @@ Specifies one of three states for the entry, \fBnormal\fR, \fBdisabled\fR, or \fBreadonly\fR. See \fBWIDGET STATES\fR, below. .OP \-textvariable textVariable Variable -Specifies the name of a global variable whose value is linked +Specifies the name of a global variable whose value is linked to the entry widget's contents. Whenever the variable changes value, the widget's contents are updated, and vice versa. @@ -217,7 +217,7 @@ earlier one, then the entry's selection is cleared. '\"See \fIttk::widget(n)\fR. .TP \fIpathName \fBvalidate\fR -Force revalidation, independent of the conditions specified +Force revalidation, independent of the conditions specified by the \fB\-validate\fR option. Returns 0 if validation fails, 1 if it succeeds. Sets or clears the \fBinvalid\fR state accordingly. @@ -277,20 +277,20 @@ options are used to enable entry widget validation. .PP There are two main validation modes: \fIprevalidation\fR, in which the \fB\-validatecommand\fR is evaluated prior to each edit -and the return value is used to determine whether to accept +and the return value is used to determine whether to accept or reject the change; -and \fIrevalidation\fR, in which the \fB\-validatecommand\fR is +and \fIrevalidation\fR, in which the \fB\-validatecommand\fR is evaluated to determine whether the current value is valid. .PP The \fB\-validate\fR option determines when validation occurs; it may be set to any of the following values: .RS .IP \fBnone\fR -Default. This means validation will only occur when +Default. This means validation will only occur when specifically requested by the \fBvalidate\fR widget command. .IP \fBkey\fR The entry will be prevalidated prior to each edit -(specifically, whenever the \fBinsert\fR or \fBdelete\fR +(specifically, whenever the \fBinsert\fR or \fBdelete\fR widget commands are called). If prevalidation fails, the edit is rejected. .IP \fBfocus\fR @@ -311,20 +311,20 @@ may modify the entry widget's value via the widget \fBinsert\fR or \fBdelete\fR commands, or by setting the linked \fB\-textvariable\fR. If either does so during prevalidation, -then the edit is rejected +then the edit is rejected regardless of the value returned by the \fB\-validatecommand\fR. .PP -If \fB\-validatecommand\fR is empty (the default), +If \fB\-validatecommand\fR is empty (the default), validation always succeeds. .SS "VALIDATION SCRIPT SUBSTITUTIONS" .PP -It is possible to perform percent substitutions on the +It is possible to perform percent substitutions on the \fB\-validatecommand\fR and \fB\-invalidcommand\fR, just as in a \fBbind\fR script. The following substitutions are recognized: .RS .IP \fB%d\fR -Type of action: 1 for \fBinsert\fR prevalidation, +Type of action: 1 for \fBinsert\fR prevalidation, 0 for \fBdelete\fR prevalidation, or \-1 for revalidation. .IP \fB%i\fR @@ -348,19 +348,19 @@ The name of the entry widget. .PP The standard Tk entry widget automatically disables validation (by setting \fB\-validate\fR to \fBnone\fR) -if the \fB\-validatecommand\fR or \fB\-invalidcommand\fR modifies +if the \fB\-validatecommand\fR or \fB\-invalidcommand\fR modifies the entry's value. The Tk themed entry widget only disables validation if one of the validation scripts raises an error, or if \fB\-validatecommand\fR does not return a valid boolean value. -(Thus, it is not necessary to re-enable validation after +(Thus, it is not necessary to re-enable validation after modifying the entry value in a validation script). .PP In addition, the standard entry widget invokes validation whenever the linked \fB\-textvariable\fR is modified; the Tk themed entry widget does not. .SH "DEFAULT BINDINGS" .PP -The entry widget's default bindings enable the following behavior. +The entry widget's default bindings enable the following behavior. In the descriptions below, .QW word refers to a contiguous group of letters, digits, or @@ -442,22 +442,22 @@ Control-k deletes all the characters to the right of the insertion cursor. .SH "WIDGET STATES" .PP -In the \fBdisabled\fR state, +In the \fBdisabled\fR state, the entry cannot be edited and the text cannot be selected. In the \fBreadonly\fR state, -no insert cursor is displayed and -the entry cannot be edited +no insert cursor is displayed and +the entry cannot be edited (specifically: the \fBinsert\fR and \fBdelete\fR commands have no effect). -The \fBdisabled\fR state is the same as \fBreadonly\fR, +The \fBdisabled\fR state is the same as \fBreadonly\fR, and in addition text cannot be selected. .PP -Note that changes to the linked \fB\-textvariable\fR will +Note that changes to the linked \fB\-textvariable\fR will still be reflected in the entry, even if it is disabled or readonly. .PP Typically, the text is .QW grayed-out in the \fBdisabled\fR state, -and a different background is used in the \fBreadonly\fR state. +and a different background is used in the \fBreadonly\fR state. .PP The entry widget sets the \fBinvalid\fR state if revalidation fails, and clears it whenever validation succeeds. diff --git a/doc/ttk_frame.n b/doc/ttk_frame.n index 3b885e0..b54ce96 100644 --- a/doc/ttk_frame.n +++ b/doc/ttk_frame.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::frame n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -22,9 +22,9 @@ together. .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-borderwidth borderWidth BorderWidth -The desired width of the widget border. Defaults to 0. +The desired width of the widget border. Defaults to 0. .OP \-relief relief Relief -One of the standard Tk border styles: +One of the standard Tk border styles: \fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR, \fBsolid\fR, or \fBsunken\fR. Defaults to \fBflat\fR. diff --git a/doc/ttk_image.n b/doc/ttk_image.n index 99d38c6..4985c20 100644 --- a/doc/ttk_image.n +++ b/doc/ttk_image.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk_image n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -16,7 +16,7 @@ ttk_image \- Define an element based on an image .PP The \fIimage\fR element factory creates a new element in the current theme whose visual appearance is determined -by Tk images. +by Tk images. \fIimageSpec\fP is a list of one or more elements. The first element is the default image name. The rest of the list is a sequence of \fIstatespec / value\fR @@ -36,7 +36,7 @@ Specifies a minimum height for the element. If less than zero, the base image's height is used as a default. .TP \fB\-padding\fR \fIpadding\fR -Specifies the element's interior padding. Defaults to +Specifies the element's interior padding. Defaults to \fB\-border\fR if not specified. .TP \fB\-sticky\fR \fIspec\fR @@ -53,13 +53,13 @@ Specifies a minimum width for the element. If less than zero, the base image's width is used as a default. .SH "IMAGE STRETCHING" .PP -If the element's allocated parcel is larger than the image, +If the element's allocated parcel is larger than the image, the image will be placed in the parcel based on the \fB\-sticky\fR option. If the image needs to stretch horizontally (i.e., \fB\-sticky ew\fR) or vertically (\fB\-sticky ns\fR), subregions of the image are replicated to fill the parcel based on the \fB\-border\fR option. -The \fB\-border\fR divides the image into 9 regions: +The \fB\-border\fR divides the image into 9 regions: four fixed corners, top and left edges (which may be tiled horizontally), left and right edges (which may be tiled vertically), and the central area (which may be tiled in both directions). diff --git a/doc/ttk_intro.n b/doc/ttk_intro.n index baef34d..bc3cd69 100644 --- a/doc/ttk_intro.n +++ b/doc/ttk_intro.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::intro n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -24,7 +24,7 @@ all aspects of the widget's appearance are controlled by the style of the widget (i.e. the style of the elements of the widget). .SH "THEMES" .PP -A \fItheme\fR is a collection of elements and styles +A \fItheme\fR is a collection of elements and styles that determine the look and feel of the widget set. Themes can be used to: .IP \(bu @@ -47,7 +47,7 @@ For example, a vertical scrollbar widget contains \fBuparrow\fR, .PP Element names use a recursive dotted notation. For example, \fBuparrow\fR identifies a generic arrow element, -and \fBScrollbar.uparrow\fR and \fBCombobox.uparrow\fR identify +and \fBScrollbar.uparrow\fR and \fBCombobox.uparrow\fR identify widget-specific elements. When looking for an element, the style engine looks for the specific name first, and if an element of that name is @@ -56,9 +56,9 @@ successive leading components of the element name. .PP Like widgets, elements have \fIoptions\fR which specify what to display and how to display it. -For example, the \fBtext\fR element +For example, the \fBtext\fR element (which displays a text string) has -\fB\-text\fR, \fB\-font\fR, \fB\-foreground\fR, \fB\-background\fR, +\fB\-text\fR, \fB\-font\fR, \fB\-foreground\fR, \fB\-background\fR, \fB\-underline\fR, and \fB\-width\fR options. The value of an element option is taken from: .IP \(bu @@ -105,14 +105,14 @@ and the various flavors of buttons which have \fBactive\fR state. The themed Tk widgets generalizes this idea: every widget has a bitmap of independent state flags. Widget state flags include \fBactive\fR, \fBdisabled\fR, -\fBpressed\fR, \fBfocus\fR, etc., +\fBpressed\fR, \fBfocus\fR, etc., (see \fIttk::widget(n)\fR for the full list of state flags). .PP -Instead of a \fB\-state\fR option, every widget now has +Instead of a \fB\-state\fR option, every widget now has a \fBstate\fR widget command which is used to set or query the state. A \fIstate specification\fR is a list of symbolic state names -indicating which bits are set, each optionally prefixed with an +indicating which bits are set, each optionally prefixed with an exclamation point indicating that the bit is cleared instead. .PP For example, the class bindings for the \fBttk::button\fR @@ -132,7 +132,7 @@ This specifies that the widget becomes \fBactive\fR when the pointer enters the widget, and inactive when it leaves. Similarly it becomes \fBpressed\fR when the mouse button is pressed, and \fB!pressed\fR on the ButtonRelease event. -In addition, the button unpresses if +In addition, the button unpresses if pointer is dragged outside the widget while Button-1 is held down, and represses if it's dragged back in. Finally, when the mouse button is released, the widget's @@ -143,7 +143,7 @@ but not by much). '\" Note to self: rewrite that paragraph. It's horrible. .SH "STYLES" .PP -Each widget is associated with a \fIstyle\fR, +Each widget is associated with a \fIstyle\fR, which specifies values for element options. Style names use a recursive dotted notation like layouts and elements; by default, widgets use the class name to look up a style in the current theme. @@ -157,7 +157,7 @@ ttk::\fBstyle configure\fR TButton \e ; .CE .PP -Many elements are displayed differently depending on the widget state. +Many elements are displayed differently depending on the widget state. For example, buttons have a different background when they are active, a different foreground when disabled, and a different relief when pressed. The \fBstyle map\fR command specifies dynamic option settings diff --git a/doc/ttk_label.n b/doc/ttk_label.n index ff93adf..6781b47 100644 --- a/doc/ttk_label.n +++ b/doc/ttk_label.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::label n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -15,7 +15,7 @@ ttk::label \- Display a text string and/or image .SH DESCRIPTION .PP A \fBttk::label\fR widget displays a textual label and/or image. -The label may be linked to a Tcl variable +The label may be linked to a Tcl variable to automatically change the displayed text. .SO ttk_widget \-class \-compound \-cursor @@ -31,7 +31,7 @@ relative to the inner margins. Legal values are \fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, and \fBcenter\fR. See also \fB\-justify\fR. .OP \-background frameColor FrameColor -The widget's background color. +The widget's background color. If unspecified, the theme default is used. .OP \-font font Font Font to use for label text. @@ -45,17 +45,17 @@ One of \fBleft\fR, \fBcenter\fR, or \fBright\fR. See also \fB\-anchor\fR. .OP \-padding padding Padding Specifies the amount of extra space to allocate for the widget. -The padding is a list of up to four length specifications +The padding is a list of up to four length specifications \fIleft top right bottom\fR. -If fewer than four elements are specified, +If fewer than four elements are specified, \fIbottom\fR defaults to \fItop\fR, -\fIright\fR defaults to \fIleft\fR, and +\fIright\fR defaults to \fIleft\fR, and \fItop\fR defaults to \fIleft\fR. .OP \-relief relief Relief .\" Rewrite this: Specifies the 3-D effect desired for the widget border. Valid values are -\fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR, \fBsolid\fR, +\fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR, \fBsolid\fR, and \fBsunken\fR. .OP \-text text Text Specifies a text string to be displayed inside the widget diff --git a/doc/ttk_labelframe.n b/doc/ttk_labelframe.n index 2dae91f..64edf6a 100644 --- a/doc/ttk_labelframe.n +++ b/doc/ttk_labelframe.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::labelframe n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -22,7 +22,7 @@ another widget. \-style .SE .SH "WIDGET-SPECIFIC OPTIONS" -.\" XXX: Currently included, but may go away: +.\" XXX: Currently included, but may go away: .\" XXX: .OP -borderwidth borderWidth BorderWidth .\" XXX: The desired width of the widget border. Default is theme-dependent. .\" XXX: .OP -relief relief Relief @@ -31,7 +31,7 @@ another widget. .\" XXX: \fBsolid\fR, or \fBsunken\fR. .\" XXX: Default is theme-dependent. .OP \-labelanchor labelAnchor LabelAnchor -Specifies where to place the label. +Specifies where to place the label. Allowed values are (clockwise from the top upper left corner): \fBnw\fR, \fBn\fR, \fBne\fR, \fBen\fR, \fBe\fR, \fBes\fR, \fBse\fR, \fBs\fR,\fBsw\fR, \fBws\fR, \fBw\fR and \fBwn\fR. @@ -43,10 +43,10 @@ The default value is theme-dependent. .OP \-text text Text Specifies the text of the label. .OP \-underline underline Underline -If set, specifies the integer index (0-based) of a character to +If set, specifies the integer index (0-based) of a character to underline in the text string. -The underlined character is used for mnemonic activation. -Mnemonic activation for a \fBttk::labelframe\fR +The underlined character is used for mnemonic activation. +Mnemonic activation for a \fBttk::labelframe\fR sets the keyboard focus to the first child of the \fBttk::labelframe\fR widget. .OP \-padding padding Padding Additional padding to include inside the border. diff --git a/doc/ttk_menubutton.n b/doc/ttk_menubutton.n index 33189e8..698bd0c 100644 --- a/doc/ttk_menubutton.n +++ b/doc/ttk_menubutton.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::menubutton n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -24,10 +24,10 @@ and displays a menu when pressed. .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-direction direction Direction -Specifies where the menu is to be popped up relative -to the menubutton. +Specifies where the menu is to be popped up relative +to the menubutton. One of: \fBabove\fR, \fBbelow\fR, \fBleft\fR, \fBright\fR, -or \fBflush\fR. The default is \fBbelow\fR. +or \fBflush\fR. The default is \fBbelow\fR. \fBflush\fR pops the menu up directly over the menubutton. .OP \-menu menu Menu Specifies the path name of the menu associated with the menubutton. @@ -38,8 +38,8 @@ menubutton. .\" .OP \-padding padding Pad .SH "WIDGET COMMAND" .PP -Menubutton widgets support the standard -\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR +Menubutton widgets support the standard +\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR methods. No other widget methods are used. .SH "STANDARD STYLES" .PP diff --git a/doc/ttk_notebook.n b/doc/ttk_notebook.n index cecae48..4d1b789 100644 --- a/doc/ttk_notebook.n +++ b/doc/ttk_notebook.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::notebook n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -18,7 +18,7 @@ ttk::notebook \- Multi-paned container widget .fi .BE .SH DESCRIPTION -A \fBttk::notebook\fR widget manages a collection of windows +A \fBttk::notebook\fR widget manages a collection of windows and displays a single one at a time. Each slave window is associated with a \fItab\fR, which the user may select to change the currently-displayed window. @@ -28,35 +28,35 @@ which the user may select to change the currently-displayed window. .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-height height Height -If present and greater than zero, +If present and greater than zero, specifies the desired height of the pane area (not including internal padding or tabs). Otherwise, the maximum height of all panes is used. .OP \-padding padding Padding Specifies the amount of extra space to add around the outside of the notebook. -The padding is a list of up to four length specifications +The padding is a list of up to four length specifications \fIleft top right bottom\fR. -If fewer than four elements are specified, +If fewer than four elements are specified, \fIbottom\fR defaults to \fItop\fR, -\fIright\fR defaults to \fIleft\fR, and +\fIright\fR defaults to \fIleft\fR, and \fItop\fR defaults to \fIleft\fR. .OP \-width width Width -If present and greater than zero, +If present and greater than zero, specifies the desired width of the pane area (not including internal padding). Otherwise, the maximum width of all panes is used. .SH "TAB OPTIONS" The following options may be specified for individual notebook panes: .OP \-state state State -Either \fBnormal\fR, \fBdisabled\fR or \fBhidden\fR. +Either \fBnormal\fR, \fBdisabled\fR or \fBhidden\fR. If \fBdisabled\fR, then the tab is not selectable. If \fBhidden\fR, then the tab is not shown. .OP \-sticky sticky Sticky Specifies how the slave window is positioned within the pane area. Value is a string containing zero or more of the characters \fBn, s, e,\fR or \fBw\fR. -Each letter refers to a side (north, south, east, or west) +Each letter refers to a side (north, south, east, or west) that the slave window will .QW stick to, as per the \fBgrid\fR geometry manager. @@ -73,7 +73,7 @@ Specifies how to display the image relative to the text, in the case both \fB\-text\fR and \fB\-image\fR are present. See \fIlabel(n)\fR for legal values. .OP \-underline underline Underline -Specifies the integer index (0-based) of a character to underline +Specifies the integer index (0-based) of a character to underline in the text string. The underlined character is used for mnemonic activation if \fBttk::notebook::enableTraversal\fR is called. @@ -87,7 +87,7 @@ The name of a slave window; .IP \(bu A positional specification of the form .QW @\fIx\fR,\fIy\fR , -which identifies the tab +which identifies the tab .IP \(bu The literal string .QW \fBcurrent\fR , @@ -95,7 +95,7 @@ which identifies the currently-selected tab; or: .IP \(bu The literal string .QW \fBend\fR , -which returns the number of tabs +which returns the number of tabs (only valid for .QW "\fIpathname \fBindex\fR" ). .SH "WIDGET COMMAND" @@ -142,9 +142,9 @@ or the total number of tabs if \fItabid\fR is the string .TP \fIpathname \fBinsert \fIpos subwindow options...\fR Inserts a pane at the specified position. -\fIpos\fR is either the string \fBend\fR, an integer index, +\fIpos\fR is either the string \fBend\fR, an integer index, or the name of a managed subwindow. -If \fIsubwindow\fR is already managed by the notebook, +If \fIsubwindow\fR is already managed by the notebook, moves it to the specified position. See \fBTAB OPTIONS\fR for the list of available options. .TP @@ -190,7 +190,7 @@ containing the notebook as follows: of any tab, will select that tab. .PP Multiple notebooks in a single toplevel may be enabled for traversal, -including nested notebooks. +including nested notebooks. However, notebook traversal only works properly if all panes are direct children of the notebook. .SH "VIRTUAL EVENTS" diff --git a/doc/ttk_progressbar.n b/doc/ttk_progressbar.n index 6306450..1945f70 100644 --- a/doc/ttk_progressbar.n +++ b/doc/ttk_progressbar.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::progressbar n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -44,15 +44,15 @@ that is, the progress bar completes one when the \fB\-value\fR increases by \fB\-maximum\fR. .OP \-variable variable Variable The name of a global Tcl variable which is linked to the \fB\-value\fR. -If specified, the \fB\-value\fR of the progress bar is -automatically set to the value of the variable whenever +If specified, the \fB\-value\fR of the progress bar is +automatically set to the value of the variable whenever the latter is modified. .OP \-phase phase Phase Read-only option. -The widget periodically increments the value of this option +The widget periodically increments the value of this option whenever the \fB\-value\fR is greater than 0 and, in \fIdeterminate\fR mode, less than \fB\-maximum\fR. -This option may be used by the current theme +This option may be used by the current theme to provide additional animation effects. .SH "WIDGET COMMAND" .PP @@ -72,7 +72,7 @@ Test the widget state; see \fIttk::widget(n)\fR. .TP \fIpathName \fBstart\fR ?\fIinterval\fR? Begin autoincrement mode: -schedules a recurring timer event that calls \fBstep\fR +schedules a recurring timer event that calls \fBstep\fR every \fIinterval\fR milliseconds. If omitted, \fIinterval\fR defaults to 50 milliseconds (20 steps/second). .TP @@ -80,7 +80,7 @@ If omitted, \fIinterval\fR defaults to 50 milliseconds (20 steps/second). Modify or query the widget state; see \fIttk::widget(n)\fR. .TP \fIpathName \fBstep\fR ?\fIamount\fR? -Increments the \fB\-value\fR by \fIamount\fR. +Increments the \fB\-value\fR by \fIamount\fR. \fIamount\fR defaults to 1.0 if omitted. .TP \fIpathName \fBstop\fR diff --git a/doc/ttk_radiobutton.n b/doc/ttk_radiobutton.n index c16f2cd..5b4dcce 100644 --- a/doc/ttk_radiobutton.n +++ b/doc/ttk_radiobutton.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::radiobutton n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -29,21 +29,21 @@ it sets the variable to its associated value. .OP \-command command Command A Tcl script to evaluate whenever the widget is invoked. .OP \-value Value Value -The value to store in the associated \fB\-variable\fR -when the widget is selected. +The value to store in the associated \fB\-variable\fR +when the widget is selected. .OP \-variable variable Variable The name of a global variable whose value is linked to the widget. Default value is \fB::selectedButton\fR. .SH "WIDGET COMMAND" .PP -In addition to the standard -\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR +In addition to the standard +\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR commands, radiobuttons support the following additional widget commands: .TP \fIpathname\fB invoke\fR Sets the \fB\-variable\fR to the \fB\-value\fR, selects the widget, -and evaluates the associated \fB\-command\fR. +and evaluates the associated \fB\-command\fR. Returns the result of the \fB\-command\fR, or the empty string if no \fB\-command\fR is specified. .\" Missing: select, deselect. Useful? @@ -51,11 +51,11 @@ string if no \fB\-command\fR is specified. .SH "WIDGET STATES" .PP The widget does not respond to user input if the \fBdisabled\fR state is set. -The widget sets the \fBselected\fR state whenever +The widget sets the \fBselected\fR state whenever the linked \fB\-variable\fR is set to the widget's \fB\-value\fR, and clears it otherwise. -The widget sets the \fBalternate\fR state whenever the -linked \fB\-variable\fR is unset. +The widget sets the \fBalternate\fR state whenever the +linked \fB\-variable\fR is unset. (The \fBalternate\fR state may be used to indicate a .QW tri-state or diff --git a/doc/ttk_scrollbar.n b/doc/ttk_scrollbar.n index 56df214..03d09f2 100644 --- a/doc/ttk_scrollbar.n +++ b/doc/ttk_scrollbar.n @@ -4,12 +4,12 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::scrollbar n 8.5 Tk "Tk Themed Widget" .so man.macros .BS .SH NAME -ttk::scrollbar \- Control the viewport of a scrollable widget +ttk::scrollbar \- Control the viewport of a scrollable widget .SH SYNOPSIS \fBttk::scrollbar\fR \fIpathName \fR?\fIoptions...\fR? .BE @@ -30,7 +30,7 @@ these are used to scroll the visible region in discrete units. .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-command command Command -A Tcl script prefix to evaluate +A Tcl script prefix to evaluate to change the view in the widget associated with the scrollbar. Additional arguments are appended to the value of this option, as described in \fBSCROLLING COMMANDS\fR below, @@ -66,7 +66,7 @@ See \fIttk::widget(n)\fR. Test the widget state; see \fIttk::widget(n)\fR. .TP \fIpathName \fBset \fIfirst last\fR -This command is normally invoked by the scrollbar's associated widget +This command is normally invoked by the scrollbar's associated widget from an \fB\-xscrollcommand\fR or \fB\-yscrollcommand\fR callback. Specifies the visible range to be displayed. \fIfirst\fR and \fIlast\fR are real fractions between 0 and 1. @@ -147,7 +147,7 @@ of individual elements, based on the position and state of the mouse pointer. set f [frame .f] ttk::scrollbar $f.hsb \-orient horizontal \-command [list $f.t xview] ttk::scrollbar $f.vsb \-orient vertical \-command [list $f.t yview] -text $f.t \-xscrollcommand [list $f.hsb set] \-yscrollcommand [list $f.vsb set] +text $f.t \-xscrollcommand [list $f.hsb set] \-yscrollcommand [list $f.vsb set] grid $f.t \-row 0 \-column 0 \-sticky nsew grid $f.vsb \-row 0 \-column 1 \-sticky nsew grid $f.hsb \-row 1 \-column 0 \-sticky nsew diff --git a/doc/ttk_separator.n b/doc/ttk_separator.n index d955fc4..fea2701 100644 --- a/doc/ttk_separator.n +++ b/doc/ttk_separator.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::separator n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -26,8 +26,8 @@ One of \fBhorizontal\fR or \fBvertical\fR. Specifies the orientation of the separator. .SH "WIDGET COMMAND" .PP -Separator widgets support the standard -\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR +Separator widgets support the standard +\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR methods. No other widget methods are used. .SH "SEE ALSO" ttk::widget(n) diff --git a/doc/ttk_spinbox.n b/doc/ttk_spinbox.n index f10af3d..7ae586f 100644 --- a/doc/ttk_spinbox.n +++ b/doc/ttk_spinbox.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::spinbox n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -42,7 +42,7 @@ time one of the widget spin buttons is pressed. The up button applies a positive increment, the down button applies a negative increment. .OP \-values values Values This must be a Tcl list of values. If this option is set then this will -override any range set using the \fB\-from\fR, \fB\-to\fR and +override any range set using the \fB\-from\fR, \fB\-to\fR and \fB\-increment\fR options. The widget will instead use the values specified beginning with the first value. .OP \-wrap wrap Wrap @@ -60,7 +60,7 @@ Specifies a Tcl command to be invoked whenever a spinbutton is invoked. See the \fBttk::entry\fR manual for information about indexing characters. .SH "VALIDATION" .PP -See the \fBttk::entry\fR manual for information about using the +See the \fBttk::entry\fR manual for information about using the \fB\-validate\fR and \fB\-validatecommand\fR options. .SH "WIDGET COMMAND" .PP diff --git a/doc/ttk_style.n b/doc/ttk_style.n index dc3bade..985e3cd 100644 --- a/doc/ttk_style.n +++ b/doc/ttk_style.n @@ -1,9 +1,9 @@ '\" '\" Copyright (c) 2004 Joe English -'\" +'\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::style n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -23,9 +23,9 @@ which specifies the set of elements making up the widget and how they are arranged, along with dynamic and default settings for element options. By default, the style name is the same as the widget's class; -this may be overridden by the \fB\-style\fR option. +this may be overridden by the \fB\-style\fR option. .PP -A \fItheme\fR is a collection of elements and styles +A \fItheme\fR is a collection of elements and styles which controls the overall look and feel of an application. .SH DESCRIPTION .PP @@ -43,31 +43,31 @@ is used. \fBttk::style lookup \fIstyle\fR \fI\-option \fR?\fIstate \fR?\fIdefault\fR?? Returns the value specified for \fI\-option\fR in style \fIstyle\fR in state \fIstate\fR, using the standard lookup rules for element options. -\fIstate\fR is a list of state names; if omitted, +\fIstate\fR is a list of state names; if omitted, it defaults to all bits off (the .QW normal state). If the \fIdefault\fR argument is present, it is used as a fallback value in case no specification for \fI\-option\fR is found. -.\" Otherwise -- signal error? return empty string? Leave unspecified for now. +.\" Otherwise -- signal error? return empty string? Leave unspecified for now. .TP \fBttk::style layout \fIstyle\fR ?\fIlayoutSpec\fR? -Define the widget layout for style \fIstyle\fR. +Define the widget layout for style \fIstyle\fR. See \fBLAYOUTS\fR below for the format of \fIlayoutSpec\fR. If \fIlayoutSpec\fR is omitted, return the layout specification for style \fIstyle\fR. -.TP +.TP \fBttk::style element create\fR \fIelementName\fR \fItype\fR ?\fIargs...\fR? Creates a new element in the current theme of type \fItype\fR. -The only cross-platform built-in element type is \fIimage\fR -(see \fBttk_image\fR(n)) but themes may define other element types +The only cross-platform built-in element type is \fIimage\fR +(see \fBttk_image\fR(n)) but themes may define other element types (see \fBTtk_RegisterElementFactory\fR). On suitable versions of Windows an element factory is registered to create Windows theme elements (see \fBttk_vsapi\fR(n)). -.TP +.TP \fBttk::style element names\fR Returns the list of elements defined in the current theme. -.TP +.TP \fBttk::style element options \fIelement\fR Returns the list of \fIelement\fR's options. .TP @@ -79,7 +79,7 @@ If \fB\-settings\fR is present, \fIscript\fR is evaluated in the context of the new theme as per \fBttk::style theme settings\fR. .TP \fBttk::style theme settings \fIthemeName\fR \fIscript\fR -Temporarily sets the current theme to \fIthemeName\fR, +Temporarily sets the current theme to \fIthemeName\fR, evaluate \fIscript\fR, then restore the previous theme. Typically \fIscript\fR simply defines styles and elements, though arbitrary Tcl code may appear. @@ -99,7 +99,7 @@ The layout mechanism uses a simplified version of the \fBpack\fR geometry manager: given an initial cavity, each element is allocated a parcel. Valid options are: -.TP +.TP \fB\-side \fIside\fR Specifies which side of the cavity to place the element; one of \fBleft\fR, \fBright\fR, \fBtop\fR, or \fBbottom\fR. diff --git a/doc/ttk_treeview.n b/doc/ttk_treeview.n index dd83c20..660b076 100644 --- a/doc/ttk_treeview.n +++ b/doc/ttk_treeview.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::treeview n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -15,15 +15,15 @@ ttk::treeview \- hierarchical multicolumn data display widget .SH DESCRIPTION .PP The \fBttk::treeview\fR widget displays a hierarchical collection of items. -Each item has a textual label, an optional image, +Each item has a textual label, an optional image, and an optional list of data values. The data values are displayed in successive columns after the tree label. .PP The order in which data values are displayed may be controlled -by setting the \fB\-displaycolumns\fR widget option. +by setting the \fB\-displaycolumns\fR widget option. The tree widget can also display column headings. -Columns may be accessed by number or by symbolic names +Columns may be accessed by number or by symbolic names listed in the \fB\-columns\fR widget option; see \fBCOLUMN IDENTIFIERS\fR. .PP @@ -40,7 +40,7 @@ and control the appearance of the item. .\" @@@HERE: describe selection, focus item .PP Treeview widgets support horizontal and vertical scrolling with the -standard \fB\-\fR[\fBxy\fR]\fBscrollcommand\fR options +standard \fB\-\fR[\fBxy\fR]\fBscrollcommand\fR options and [\fBxy\fR]\fBview\fR widget commands. .SO ttk_widget \-class \-cursor \-takefocus @@ -48,14 +48,14 @@ and [\fBxy\fR]\fBview\fR widget commands. .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-columns columns Columns -A list of column identifiers, +A list of column identifiers, specifying the number of columns and their names. .\"X: This is a read-only option; it may only be set when the widget is created. .OP \-displaycolumns displayColumns DisplayColumns -A list of column identifiers +A list of column identifiers (either symbolic names or integer indices) -specifying which data columns are displayed -and the order in which they appear, +specifying which data columns are displayed +and the order in which they appear, or the string \fB#all\fP. If set to \fB#all\fP (the default), all columns are shown in the order given. @@ -76,7 +76,7 @@ If set to \fBextended\fR (the default), multiple items may be selected. If \fBbrowse\fR, only a single item will be selected at a time. If \fBnone\fR, the selection will not be changed. .PP -Note that application code and tag bindings can set the selection +Note that application code and tag bindings can set the selection however they wish, regardless of the value of \fB\-selectmode\fR. .RE .OP \-show show Show @@ -84,7 +84,7 @@ A list containing zero or more of the following values, specifying which elements of the tree to display. .RS .IP \fBtree\fR -Display tree labels in column #0. +Display tree labels in column #0. .IP \fBheadings\fR Display the heading row. .PP @@ -114,7 +114,7 @@ returns the list of children belonging to \fIitem\fR. .RS .PP If \fInewchildren\fR is specified, replaces \fIitem\fR's child list -with \fInewchildren\fR. +with \fInewchildren\fR. Items in the old child list not present in the new child list are detached from the tree. None of the items in \fInewchildren\fR may be an ancestor @@ -125,7 +125,7 @@ of \fIitem\fR. Query or modify the options for the specified \fIcolumn\fR. If no \fI\-option\fR is specified, returns a dictionary of option/value pairs. -If a single \fI\-option\fR is specified, +If a single \fI\-option\fR is specified, returns the value of that option. Otherwise, the options are updated with the specified values. The following options may be set on each column: @@ -134,7 +134,7 @@ The following options may be set on each column: \fB\-id \fIname\fR The column name. This is a read-only option. For example, [\fI$pathname \fBcolumn #\fIn \fB\-id\fR] -returns the data column associated with display column #\fIn\fR. +returns the data column associated with display column #\fIn\fR. .TP \fB\-anchor\fR Specifies how the text in this column should be aligned @@ -145,7 +145,7 @@ with respect to the cell. One of \fB\-minwidth\fR The minimum width of the column in pixels. The treeview widget will not make the column any smaller than -\fB\-minwidth\fR when the widget is resized or the user drags a +\fB\-minwidth\fR when the widget is resized or the user drags a column separator. .TP \fB\-stretch\fR @@ -184,7 +184,7 @@ Returns 1 if the specified \fIitem\fR is present in the tree, If \fIitem\fR is specified, sets the focus item to \fIitem\fR. Otherwise, returns the current focus item, or \fB{}\fR if there is none. .\" Need: way to clear the focus item. {} works for this... -.TP +.TP \fIpathname \fBheading \fIcolumn\fR ?\fI\-option \fR?\fIvalue \-option value...\fR? Query or modify the heading options for the specified \fIcolumn\fR. Valid options are: @@ -251,13 +251,13 @@ and data columns. Returns the integer index of \fIitem\fR within its parent's list of children. .TP \fIpathname \fBinsert \fIparent index\fR ?\fB\-id \fIid\fR? \fIoptions...\fR -Creates a new item. +Creates a new item. \fIparent\fR is the item ID of the parent item, or the empty string \fB{}\fR to create a new top-level item. \fIindex\fR is an integer, or the value \fBend\fR, specifying where in the list of \fIparent\fR's children to insert the new item. -If \fIindex\fR is less than or equal to zero, +If \fIindex\fR is less than or equal to zero, the new node is inserted at the beginning; if \fIindex\fR is greater than or equal to the current number of children, it is inserted at the end. @@ -276,9 +276,9 @@ Test the widget state; see \fIttk::widget(n)\fR. .TP \fIpathname \fBitem \fIitem\fR ?\fI\-option \fR?\fIvalue \-option value...\fR? Query or modify the options for the specified \fIitem\fR. -If no \fI\-option\fR is specified, +If no \fI\-option\fR is specified, returns a dictionary of option/value pairs. -If a single \fI\-option\fR is specified, +If a single \fI\-option\fR is specified, returns the value of that option. Otherwise, the item's options are updated with the specified values. See \fBITEM OPTIONS\fR for the list of available options. @@ -292,7 +292,7 @@ If \fIindex\fR is less than or equal to zero, \fIitem\fR is moved to the beginning; if greater than or equal to the number of children, it is moved to the end. .RE -.TP +.TP \fIpathname \fBnext \fIitem\fR Returns the identifier of \fIitem\fR's next sibling, or \fB{}\fR if \fIitem\fR is the last child of its parent. @@ -300,7 +300,7 @@ or \fB{}\fR if \fIitem\fR is the last child of its parent. \fIpathname \fBparent \fIitem\fR Returns the ID of the parent of \fIitem\fR, or \fB{}\fR if \fIitem\fR is at the top level of the hierarchy. -.TP +.TP \fIpathname \fBprev \fIitem\fR Returns the identifier of \fIitem\fR's previous sibling, or \fB{}\fR if \fIitem\fR is the first child of its parent. @@ -308,7 +308,7 @@ or \fB{}\fR if \fIitem\fR is the first child of its parent. \fIpathname \fBsee \fIitem\fR Ensure that \fIitem\fR is visible: sets all of \fIitem\fR's ancestors to \fB\-open true\fR, -and scrolls the widget if necessary so that \fIitem\fR is +and scrolls the widget if necessary so that \fIitem\fR is within the visible portion of the tree. .TP \fIpathname \fBselection\fR ?\fIselop itemList\fR? @@ -344,7 +344,7 @@ Modify or query the widget state; see \fIttk::widget(n)\fR. .RS .TP \fIpathName \fBtag bind \fItagName \fR?\fIsequence\fR? ?\fIscript\fR? -Add a Tk binding script for the event sequence \fIsequence\fR +Add a Tk binding script for the event sequence \fIsequence\fR to the tag \fItagName\fR. When an X event is delivered to an item, binding scripts for each of the item's \fB\-tags\fR are evaluated in order as per \fIbindtags(n)\fR. @@ -353,10 +353,10 @@ in order as per \fIbindtags(n)\fR. \fB<KeyPress>\fR, \fB<KeyRelease>\fR, and virtual events are sent to the focus item. \fB<ButtonPress>\fR, \fB<ButtonRelease>\fR, and \fB<Motion>\fR events -are sent to the item under the mouse pointer. +are sent to the item under the mouse pointer. No other event types are supported. .PP -The binding \fIscript\fR undergoes \fB%\fR-substitutions before +The binding \fIscript\fR undergoes \fB%\fR-substitutions before evaluation; see \fBbind(n)\fR for details. .RE .TP @@ -364,10 +364,10 @@ evaluation; see \fBbind(n)\fR for details. Query or modify the options for the specified \fItagName\fR. If one or more \fIoption/value\fR pairs are specified, sets the value of those options for the specified tag. -If a single \fIoption\fR is specified, -returns the value of that option +If a single \fIoption\fR is specified, +returns the value of that option (or the empty string if the option has not been specified for \fItagName\fR). -With no additional arguments, +With no additional arguments, returns a dictionary of the option settings for \fItagName\fR. See \fBTAG OPTIONS\fR for the list of available options. .TP @@ -420,7 +420,7 @@ the extra values are ignored. A boolean value indicating whether the item's children should be displayed (\fB\-open true\fR) or hidden (\fB\-open false\fR). .OP \-tags tags Tags -A list of tags associated with this item. +A list of tags associated with this item. .SH "TAG OPTIONS" .PP The following options may be specified on tags: @@ -448,8 +448,8 @@ An integer \fIn\fR, specifying the \fIn\fRth data column. A string of the form \fB#\fIn\fR, where \fIn\fR is an integer, specifying the \fIn\fRth display column. .PP -\fBNOTE:\fR -Item \fB\-values\fR may be displayed in a different order than +\fBNOTE:\fR +Item \fB\-values\fR may be displayed in a different order than the order in which they are stored. .PP \fBNOTE:\fR Column #0 always refers to the tree column, @@ -457,7 +457,7 @@ even if \fB\-show tree\fR is not specified. .PP A \fIdata column number\fR is an index into an item's \fB\-values\fR list; a \fIdisplay column number\fR is the column number in the tree -where the values are displayed. +where the values are displayed. Tree labels are displayed in column #0. If \fB\-displaycolumns\fR is not set, then data column \fIn\fR is displayed in display column \fB#\fIn+1\fR. diff --git a/doc/ttk_vsapi.n b/doc/ttk_vsapi.n index 34145fb..334836c 100644 --- a/doc/ttk_vsapi.n +++ b/doc/ttk_vsapi.n @@ -3,7 +3,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk_vsapi n 8.5 Tk "Tk Themed Widget" .so man.macros .BS @@ -72,7 +72,7 @@ If no \fIstateMap\fR parameter is given there is an implicit default map of {{} 1} .SH "EXAMPLE" .PP -Create a correctly themed close button by changing the layout of +Create a correctly themed close button by changing the layout of a \fBttk::button\fR(n). This uses the WINDOW part WP_SMALLCLOSEBUTTON and as documented the states CBS_DISABLED, CBS_HOT, CBS_NORMAL and CBS_PUSHED are mapped from ttk states. @@ -4,7 +4,7 @@ '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH wm n 8.5 Tk "Tk Built-In Commands" .so man.macros .BS @@ -796,7 +796,7 @@ Gridded geometry management is typically invoked by turning on the \fBsetGrid\fR option for a widget; it can also be invoked with the \fBwm grid\fR command or by calling \fBTk_SetGrid\fR. In each of these approaches the particular widget (or sometimes -code in the application as a whole) specifies the relationship between +code in the application as a whole) specifies the relationship between integral grid sizes for the window and pixel sizes. To return to non-gridded geometry management, invoke \fBwm grid\fR with empty argument strings. diff --git a/generic/tk.h b/generic/tk.h index 4a655a4..75d82ba 100644 --- a/generic/tk.h +++ b/generic/tk.h @@ -75,10 +75,10 @@ extern "C" { #define TK_MAJOR_VERSION 8 #define TK_MINOR_VERSION 6 #define TK_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TK_RELEASE_SERIAL 4 +#define TK_RELEASE_SERIAL 5 #define TK_VERSION "8.6" -#define TK_PATCH_LEVEL "8.6.4" +#define TK_PATCH_LEVEL "8.6.5" /* * A special definition used to allow this header file to be included from diff --git a/generic/tkBind.c b/generic/tkBind.c index 9cd3b7b..3b05066 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -3535,8 +3535,20 @@ DoWarp( { TkDisplay *dispPtr = clientData; - TkpWarpPointer(dispPtr); - XForceScreenSaver(dispPtr->display, ScreenSaverReset); + /* + * DoWarp was scheduled only if the window was mapped. It needs to be + * still mapped at the time the present idle callback is executed. Also + * one needs to guard against window destruction in the meantime. + * Finally, the case warpWindow == NULL is special in that it means + * the whole screen. + */ + + if ((dispPtr->warpWindow == NULL) || + (Tk_IsMapped(dispPtr->warpWindow) + && (Tk_WindowId(dispPtr->warpWindow) != None))) { + TkpWarpPointer(dispPtr); + XForceScreenSaver(dispPtr->display, ScreenSaverReset); + } dispPtr->flags &= ~TK_DISPLAY_IN_WARP; } diff --git a/generic/tkEvent.c b/generic/tkEvent.c index bcc6d98..95aeda1 100644 --- a/generic/tkEvent.c +++ b/generic/tkEvent.c @@ -2039,6 +2039,12 @@ TkFinalize( { ExitHandler *exitPtr; +#if defined(_WIN32) && !defined(STATIC_BUILD) + if (!tclStubsPtr) { + return; + } +#endif + Tcl_DeleteExitHandler(TkFinalize, NULL); Tcl_MutexLock(&exitMutex); diff --git a/generic/tkFrame.c b/generic/tkFrame.c index 057b4b8..f6edfb0 100644 --- a/generic/tkFrame.c +++ b/generic/tkFrame.c @@ -447,6 +447,30 @@ TkCreateFrame( return result; } +int +TkListCreateFrame( + ClientData clientData, /* Either NULL or pointer to option table. */ + Tcl_Interp *interp, /* Current interpreter. */ + Tcl_Obj *listObj, /* List of arguments. */ + int toplevel, /* Non-zero means create a toplevel window, + * zero means create a frame. */ + Tcl_Obj *nameObj) /* Should only be non-NULL if there is no main + * window associated with the interpreter. + * Gives the base name to use for the new + * application. */ + +{ + int objc; + Tcl_Obj **objv; + + if (TCL_OK != Tcl_ListObjGetElements(interp, listObj, &objc, &objv)) { + return TCL_ERROR; + } + return CreateFrame(clientData, interp, objc, objv, + toplevel ? TYPE_TOPLEVEL : TYPE_FRAME, + nameObj ? Tcl_GetString(nameObj) : NULL); +} + static int CreateFrame( ClientData clientData, /* NULL. */ diff --git a/generic/tkImgPNG.c b/generic/tkImgPNG.c index 2ee515b..c6e3029 100644 --- a/generic/tkImgPNG.c +++ b/generic/tkImgPNG.c @@ -335,7 +335,7 @@ InitPNGImage( if (Tcl_ZlibStreamInit(NULL, dir, TCL_ZLIB_FORMAT_ZLIB, TCL_ZLIB_COMPRESS_DEFAULT, NULL, &pngPtr->stream) != TCL_OK) { - if (interp) { + if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "zlib initialization failed", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "ZLIB_INIT", NULL); diff --git a/generic/tkImgPhInstance.c b/generic/tkImgPhInstance.c index 666a9b0..bd152f2 100644 --- a/generic/tkImgPhInstance.c +++ b/generic/tkImgPhInstance.c @@ -404,6 +404,9 @@ TkImgPhotoGet( * * Note that Win32 pre-defines those operations that we really need. * + * Note that on MacOS, if the background comes from a Retina display + * then it will be twice as wide and twice as high as the photoimage. + * *---------------------------------------------------------------------- */ @@ -433,7 +436,16 @@ BlendComplexAlpha( unsigned long pixel; unsigned char r, g, b, alpha, unalpha, *masterPtr; unsigned char *alphaAr = iPtr->masterPtr->pix32; - +#if defined(MAC_OSX_TK) + /* Background "pixels" are actually 2^pp x 2^pp blocks of subpixels. Each + * block gets blended with the color of one image pixel. Since we iterate + * over the background subpixels, we reset the width and height to the + * subpixel dimensions of the background image we are using. + */ + int pp = bgImg->pixelpower; + width = width << pp; + height = height << pp; +#endif /* * This blending is an integer version of the Source-Over compositing rule * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH @@ -532,9 +544,16 @@ BlendComplexAlpha( #endif /* !_WIN32 && !MAC_OSX_TK */ for (y = 0; y < height; y++) { +# if !defined(MAC_OSX_TK) line = (y + yOffset) * iPtr->masterPtr->width; for (x = 0; x < width; x++) { masterPtr = alphaAr + ((line + x + xOffset) * 4); +#else + /* Repeat each image row and column 2^pp times. */ + line = ((y>>pp) + yOffset) * iPtr->masterPtr->width; + for (x = 0; x < width; x++) { + masterPtr = alphaAr + ((line + (x>>pp) + xOffset) * 4); +#endif alpha = masterPtr[3]; /* @@ -635,7 +654,9 @@ TkImgPhotoDisplay( (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap); if (bgImg == NULL) { Tk_DeleteErrorHandler(handler); - /* We failed to get the image so draw without blending alpha. It's the best we can do */ + /* We failed to get the image, so draw without blending alpha. + * It's the best we can do. + */ goto fallBack; } diff --git a/generic/tkInt.h b/generic/tkInt.h index b644c5b..dd5dcad 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1208,7 +1208,7 @@ MODULE_SCOPE void TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef, MODULE_SCOPE int TkBackgroundEvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, int flags); MODULE_SCOPE void TkSendVirtualEvent(Tk_Window tgtWin, - const char *eventName); + const char *eventName, Tcl_Obj *detail); MODULE_SCOPE Tcl_Command TkMakeEnsemble(Tcl_Interp *interp, const char *nsname, const char *name, ClientData clientData, const TkEnsemble *map); @@ -1217,6 +1217,9 @@ MODULE_SCOPE int TkInitTkCmd(Tcl_Interp *interp, MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp, ClientData clientData); MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr); +MODULE_SCOPE int TkListCreateFrame(ClientData clientData, + Tcl_Interp *interp, Tcl_Obj *listObj, + int toplevel, Tcl_Obj *nameObj); #ifdef _WIN32 #define TkParseColor XParseColor diff --git a/generic/tkListbox.c b/generic/tkListbox.c index 95f7862..b059727 100644 --- a/generic/tkListbox.c +++ b/generic/tkListbox.c @@ -90,14 +90,14 @@ typedef struct { * display. */ int topIndex; /* Index of top-most element visible in * window. */ - int fullLines; /* Number of lines that fit are completely + int fullLines; /* Number of lines that are completely * visible in window. There may be one * additional line at the bottom that is * partially visible. */ int partialLine; /* 0 means that the window holds exactly * fullLines lines. 1 means that there is one * additional line that is partially - * visble. */ + * visible. */ int setGrid; /* Non-zero means pass gridding information to * window manager. */ @@ -114,7 +114,8 @@ typedef struct { int xOffset; /* The left edge of each string in the listbox * is offset to the left by this many pixels * (0 means no offset, positive means there is - * an offset). */ + * an offset). This is x scrolling information + * is not linked to justification. */ /* * Information about what's selected or active, if any. @@ -131,7 +132,7 @@ typedef struct { int active; /* Index of "active" element (the one that has * been selected by keyboard traversal). -1 * means none. */ - int activeStyle; /* style in which to draw the active element. + int activeStyle; /* Style in which to draw the active element. * One of: underline, none, dotbox */ /* @@ -165,6 +166,7 @@ typedef struct { Pixmap gray; /* Pixmap for displaying disabled text. */ int flags; /* Various flag bits: see below for * definitions. */ + Tk_Justify justify; /* Justification. */ } Listbox; /* @@ -197,7 +199,7 @@ typedef struct { * be updated. * GOT_FOCUS: Non-zero means this widget currently has the * input focus. - * MAXWIDTH_IS_STALE: Stored maxWidth may be out-of-date + * MAXWIDTH_IS_STALE: Stored maxWidth may be out-of-date. * LISTBOX_DELETED: This listbox has been effectively destroyed. */ @@ -275,6 +277,8 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, -1, Tk_Offset(Listbox, highlightWidth), 0, 0, 0}, + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + DEF_LISTBOX_JUSTIFY, -1, Tk_Offset(Listbox, justify), 0, 0, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", DEF_LISTBOX_RELIEF, -1, Tk_Offset(Listbox, relief), 0, 0, 0}, {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", @@ -313,7 +317,7 @@ static const Tk_OptionSpec optionSpecs[] = { /* * The itemAttrOptionSpecs table defines the valid configuration options for - * listbox items + * listbox items. */ static const Tk_OptionSpec itemAttrOptionSpecs[] = { @@ -340,7 +344,7 @@ static const Tk_OptionSpec itemAttrOptionSpecs[] = { }; /* - * The following tables define the listbox widget commands (and sub- commands) + * The following tables define the listbox widget commands (and sub-commands) * and map the indexes into the string tables into enumerated types used to * dispatch the listbox widget command. */ @@ -436,6 +440,7 @@ static char * ListboxListVarProc(ClientData clientData, const char *name2, int flags); static void MigrateHashEntries(Tcl_HashTable *table, int first, int last, int offset); +static int GetMaxOffset(Listbox *listPtr); /* * The structure below defines button class behavior by means of procedures @@ -546,6 +551,7 @@ Tk_ListboxObjCmd( listPtr->cursor = None; listPtr->state = STATE_NORMAL; listPtr->gray = None; + listPtr->justify = TK_JUSTIFY_LEFT; /* * Keep a hold of the associated tkwin until we destroy the listbox, @@ -613,7 +619,7 @@ ListboxWidgetObjCmd( /* * Parse the command by looking up the second argument in the list of - * valid subcommand names + * valid subcommand names. */ result = Tcl_GetIndexFromObj(interp, objv[1], commandNames, @@ -1076,6 +1082,7 @@ ListboxBboxSubCmd( Listbox *listPtr, /* Information about the listbox */ int index) /* Index of the element to get bbox info on */ { + register Tk_Window tkwin = listPtr->tkwin; int lastVisibleIndex; /* @@ -1111,7 +1118,15 @@ ListboxBboxSubCmd( Tk_GetFontMetrics(listPtr->tkfont, &fm); pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen); - x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset; + if (listPtr->justify == TK_JUSTIFY_LEFT) { + x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset; + } else if (listPtr->justify == TK_JUSTIFY_RIGHT) { + x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth) + - pixelWidth - listPtr->xOffset + GetMaxOffset(listPtr); + } else { + x = (Tk_Width(tkwin) - pixelWidth)/2 + - listPtr->xOffset + GetMaxOffset(listPtr)/2; + } y = ((index - listPtr->topIndex)*listPtr->lineHeight) + listPtr->inset + listPtr->selBorderWidth; results[0] = Tcl_NewIntObj(x); @@ -1837,6 +1852,7 @@ DisplayListbox( * or right edge of the listbox is * off-screen. */ Pixmap pixmap; + int textWidth; listPtr->flags &= ~REDRAW_PENDING; if (listPtr->flags & LISTBOX_DELETED) { @@ -2016,7 +2032,7 @@ DisplayListbox( } else { /* * If there is an item attributes record for this item, draw - * the background box and set the foreground color accordingly + * the background box and set the foreground color accordingly. */ if (entry != NULL) { @@ -2056,12 +2072,24 @@ DisplayListbox( * Draw the actual text of this item. */ + Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement); + stringRep = Tcl_GetStringFromObj(curElement, &stringLen); + textWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen); + Tk_GetFontMetrics(listPtr->tkfont, &fm); y += fm.ascent + listPtr->selBorderWidth; - x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset; - Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement); - stringRep = Tcl_GetStringFromObj(curElement, &stringLen); - Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont, + + if (listPtr->justify == TK_JUSTIFY_LEFT) { + x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset; + } else if (listPtr->justify == TK_JUSTIFY_RIGHT) { + x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth) + - textWidth - listPtr->xOffset + GetMaxOffset(listPtr); + } else { + x = (Tk_Width(tkwin) - textWidth)/2 + - listPtr->xOffset + GetMaxOffset(listPtr)/2; + } + + Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont, stringRep, stringLen, x, y); /* @@ -2458,7 +2486,7 @@ ListboxDeleteSubCmd( /* * Check width of the element. We only have to check if widthChanged * has not already been set to 1, because we only need one maxWidth - * element to disappear for us to have to recompute the width + * element to disappear for us to have to recompute the width. */ if (widthChanged == 0) { @@ -2735,7 +2763,11 @@ GetListboxIndex( stringRep = Tcl_GetString(indexObj); if (stringRep[0] == '@') { - /* @x,y index */ + + /* + * @x,y index + */ + int y; const char *start; char *end; @@ -2844,9 +2876,7 @@ ChangeListboxOffset( */ offset += listPtr->xScrollUnit / 2; - maxOffset = listPtr->maxWidth - (Tk_Width(listPtr->tkwin) - - 2*listPtr->inset - 2*listPtr->selBorderWidth) - + listPtr->xScrollUnit - 1; + maxOffset = GetMaxOffset(listPtr); if (offset > maxOffset) { offset = maxOffset; } @@ -2887,9 +2917,7 @@ ListboxScanTo( int newTopIndex, newOffset, maxIndex, maxOffset; maxIndex = listPtr->nElements - listPtr->fullLines; - maxOffset = listPtr->maxWidth + (listPtr->xScrollUnit - 1) - - (Tk_Width(listPtr->tkwin) - 2*listPtr->inset - - 2*listPtr->selBorderWidth - listPtr->xScrollUnit); + maxOffset = GetMaxOffset(listPtr); /* * Compute new top line for screen by amplifying the difference between @@ -3195,16 +3223,7 @@ static void GenerateListboxSelectEvent( Listbox *listPtr) /* Information about widget. */ { - union {XEvent general; XVirtualEvent virtual;} event; - - memset(&event, 0, sizeof(event)); - event.general.xany.type = VirtualEvent; - event.general.xany.serial = NextRequest(Tk_Display(listPtr->tkwin)); - event.general.xany.send_event = False; - event.general.xany.window = Tk_WindowId(listPtr->tkwin); - event.general.xany.display = Tk_Display(listPtr->tkwin); - event.virtual.name = Tk_GetUid("ListboxSelect"); - Tk_HandleEvent(&event.general); + TkSendVirtualEvent(listPtr->tkwin, "ListboxSelect", NULL); } /* @@ -3465,7 +3484,7 @@ ListboxListVarProc( /* * If the list length has decreased, then we should clean up selection and - * attributes information for elements past the end of the new list + * attributes information for elements past the end of the new list. */ oldLength = listPtr->nElements; @@ -3583,6 +3602,42 @@ MigrateHashEntries( } /* + *---------------------------------------------------------------------- + * + * GetMaxOffset -- + * + * Passing in a listbox pointer, returns the maximum offset for the box, + * i.e. the maximum possible horizontal scrolling value (in pixels). + * + * Results: + * Listbox's maxOffset. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- +*/ +static int GetMaxOffset( + register Listbox *listPtr) +{ + int maxOffset; + + maxOffset = listPtr->maxWidth - + (Tk_Width(listPtr->tkwin) - 2*listPtr->inset - + 2*listPtr->selBorderWidth) + listPtr->xScrollUnit - 1; + if (maxOffset < 0) { + + /* + * Listbox is larger in width than its largest width item. + */ + + maxOffset = 0; + } + maxOffset -= maxOffset % listPtr->xScrollUnit; + + return maxOffset; +} +/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/generic/tkOption.c b/generic/tkOption.c index d758b6f..24e7fb3 100644 --- a/generic/tkOption.c +++ b/generic/tkOption.c @@ -560,7 +560,7 @@ Tk_GetOption( count -= levelPtr[-1].bases[currentStack]; } - if (currentStack && CLASS) { + if (currentStack & CLASS) { nodeId = winClassId; } else { nodeId = winNameId; @@ -1080,10 +1080,10 @@ ReadOptionFile( * TK_MAX_PRIO. */ { const char *realName; - char *buffer; + Tcl_Obj *buffer; int result, bufferSize; Tcl_Channel chan; - Tcl_DString newName, optString; + Tcl_DString newName; /* * Prevent file system access in a safe interpreter. @@ -1108,24 +1108,10 @@ ReadOptionFile( return TCL_ERROR; } - /* - * Compute size of file by seeking to the end of the file. This will - * overallocate if we are performing CRLF translation. - */ - - bufferSize = (int) Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_END); - Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_SET); - - if (bufferSize < 0) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "error seeking to end of file \"%s\": %s", - fileName, Tcl_PosixError(interp))); - Tcl_Close(NULL, chan); - return TCL_ERROR; - } - - buffer = ckalloc(bufferSize + 1); - bufferSize = Tcl_Read(chan, buffer, bufferSize); + buffer = Tcl_NewObj(); + Tcl_IncrRefCount(buffer); + Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8"); + bufferSize = Tcl_ReadChars(chan, buffer, -1, 0); if (bufferSize < 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error reading file \"%s\": %s", @@ -1134,18 +1120,8 @@ ReadOptionFile( return TCL_ERROR; } Tcl_Close(NULL, chan); - buffer[bufferSize] = 0; - if ((bufferSize>2) && !memcmp(buffer, "\357\273\277", 3)) { - /* File starts with UTF-8 BOM */ - result = AddFromString(interp, tkwin, buffer+3, priority); - } else { - Tcl_DStringInit(&optString); - Tcl_ExternalToUtfDString(NULL, buffer, bufferSize, &optString); - result = AddFromString(interp, tkwin, Tcl_DStringValue(&optString), - priority); - Tcl_DStringFree(&optString); - } - ckfree(buffer); + result = AddFromString(interp, tkwin, Tcl_GetString(buffer), priority); + Tcl_DecrRefCount(buffer); return result; } diff --git a/generic/tkPanedWindow.c b/generic/tkPanedWindow.c index 2451647..f350d0a 100644 --- a/generic/tkPanedWindow.c +++ b/generic/tkPanedWindow.c @@ -1370,11 +1370,15 @@ PanedWindowEventProc( DestroyPanedWindow(pwPtr); } else if (eventPtr->type == UnmapNotify) { for (i = 0; i < pwPtr->numSlaves; i++) { - Tk_UnmapWindow(pwPtr->slaves[i]->tkwin); + if (!pwPtr->slaves[i]->hide) { + Tk_UnmapWindow(pwPtr->slaves[i]->tkwin); + } } } else if (eventPtr->type == MapNotify) { for (i = 0; i < pwPtr->numSlaves; i++) { - Tk_MapWindow(pwPtr->slaves[i]->tkwin); + if (!pwPtr->slaves[i]->hide) { + Tk_MapWindow(pwPtr->slaves[i]->tkwin); + } } } } diff --git a/generic/tkScale.c b/generic/tkScale.c index cc7c294..cbc5202 100644 --- a/generic/tkScale.c +++ b/generic/tkScale.c @@ -303,6 +303,12 @@ Tk_ScaleObjCmd( return TCL_ERROR; } + /* + * The widget was just created, no command callback must be invoked. + */ + + scalePtr->flags &= ~INVOKE_COMMAND; + Tcl_SetObjResult(interp, TkNewWindowObj(scalePtr->tkwin)); return TCL_OK; } @@ -1268,7 +1274,14 @@ TkScaleSetValue( return; } scalePtr->value = value; - if (invokeCommand) { + + /* + * Schedule command callback invocation only if there is such a command + * already registered, otherwise the callback would trigger later when + * configuring the widget -command option even if the value did not change. + */ + + if ((invokeCommand) && (scalePtr->command != NULL)) { scalePtr->flags |= INVOKE_COMMAND; } TkEventuallyRedrawScale(scalePtr, REDRAW_SLIDER); diff --git a/generic/tkText.c b/generic/tkText.c index 3079417..5ad527a 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -122,7 +122,8 @@ static const Tk_ObjCustomOption lineOption = { static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_BOOLEAN, "-autoseparators", "autoSeparators", "AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, -1, - Tk_Offset(TkText, autoSeparators), 0, 0, 0}, + Tk_Offset(TkText, autoSeparators), + TK_OPTION_DONT_SET_DEFAULT, 0, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_TEXT_BG_COLOR, -1, Tk_Offset(TkText, border), 0, DEF_TEXT_BG_MONO, 0}, @@ -193,7 +194,8 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_TEXT_INSERT_WIDTH, -1, Tk_Offset(TkText, insertWidth), 0, 0, 0}, {TK_OPTION_INT, "-maxundo", "maxUndo", "MaxUndo", - DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo), 0, 0, 0}, + DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo), + TK_OPTION_DONT_SET_DEFAULT, 0, 0}, {TK_OPTION_PIXELS, "-padx", "padX", "Pad", DEF_TEXT_PADX, -1, Tk_Offset(TkText, padX), 0, 0, TK_TEXT_LINE_GEOMETRY}, @@ -239,7 +241,8 @@ static const Tk_OptionSpec optionSpecs[] = { DEF_TEXT_TAKE_FOCUS, -1, Tk_Offset(TkText, takeFocus), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BOOLEAN, "-undo", "undo", "Undo", - DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo), 0, 0 , 0}, + DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo), + TK_OPTION_DONT_SET_DEFAULT, 0 , 0}, {TK_OPTION_INT, "-width", "width", "Width", DEF_TEXT_WIDTH, -1, Tk_Offset(TkText, width), 0, 0, TK_TEXT_LINE_GEOMETRY}, @@ -401,6 +404,7 @@ static Tcl_Obj * TextGetText(const TkText *textPtr, const TkTextIndex *index1, const TkTextIndex *index2, int visibleOnly); static void GenerateModifiedEvent(TkText *textPtr); +static void GenerateUndoStackEvent(TkText *textPtr); static void UpdateDirtyFlag(TkSharedText *sharedPtr); static void RunAfterSyncCmd(ClientData clientData); static void TextPushUndoAction(TkText *textPtr, @@ -919,43 +923,43 @@ TextWidgetObjCmd( * We're going to count up all display lines in the logical * line of 'indexFromPtr' up to, but not including the logical * line of 'indexToPtr' (except if this line is elided), and - * then subtract off what came in too much from elided lines, - * also subtract off what we didn't want from 'from' and add + * then subtract off what came in too much from elided lines, + * also subtract off what we didn't want from 'from' and add * on what we didn't count from 'to'. */ - while (TkTextIndexCmp(&index,indexToPtr) < 0) { + while (TkTextIndexCmp(&index,indexToPtr) < 0) { value += TkTextUpdateOneLine(textPtr, index.linePtr, - 0, &index, 0); + 0, &index, 0); } - index2 = index; - - /* - * Now we need to adjust the count to: - * - subtract off the number of display lines between - * indexToPtr and index2, since we might have skipped past - * indexToPtr, if we have several logical lines in a - * single display line - * - subtract off the number of display lines overcounted - * in the first logical line - * - add on the number of display lines in the last logical - * line - * This logic is still ok if both indexFromPtr and indexToPtr - * are in the same logical line. - */ - - index = *indexToPtr; - index.byteIndex = 0; - while (TkTextIndexCmp(&index,&index2) < 0) { - value -= TkTextUpdateOneLine(textPtr, index.linePtr, - 0, &index, 0); - } + index2 = index; + + /* + * Now we need to adjust the count to: + * - subtract off the number of display lines between + * indexToPtr and index2, since we might have skipped past + * indexToPtr, if we have several logical lines in a + * single display line + * - subtract off the number of display lines overcounted + * in the first logical line + * - add on the number of display lines in the last logical + * line + * This logic is still ok if both indexFromPtr and indexToPtr + * are in the same logical line. + */ + + index = *indexToPtr; + index.byteIndex = 0; + while (TkTextIndexCmp(&index,&index2) < 0) { + value -= TkTextUpdateOneLine(textPtr, index.linePtr, + 0, &index, 0); + } index.linePtr = indexFromPtr->linePtr; index.byteIndex = 0; while (1) { TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL); - if (TkTextIndexCmp(&index,indexFromPtr) >= 0) { + if (TkTextIndexCmp(&index,indexFromPtr) >= 0) { break; } TkTextIndexForwBytes(textPtr, &index, 1, &index); @@ -967,7 +971,7 @@ TextWidgetObjCmd( index.byteIndex = 0; while (1) { TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL); - if (TkTextIndexCmp(&index,indexToPtr) >= 0) { + if (TkTextIndexCmp(&index,indexToPtr) >= 0) { break; } TkTextIndexForwBytes(textPtr, &index, 1, &index); @@ -1395,14 +1399,14 @@ TextWidgetObjCmd( result = TextPeerCmd(textPtr, interp, objc, objv); break; case TEXT_PENDINGSYNC: { - if (objc != 2) { - Tcl_WrongNumArgs(interp, 2, objv, NULL); - result = TCL_ERROR; - goto done; - } - Tcl_SetObjResult(interp, - Tcl_NewBooleanObj(TkTextPendingsync(textPtr))); - break; + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, NULL); + result = TCL_ERROR; + goto done; + } + Tcl_SetObjResult(interp, + Tcl_NewBooleanObj(TkTextPendingsync(textPtr))); + break; } case TEXT_REPLACE: { const TkTextIndex *indexFromPtr, *indexToPtr; @@ -1535,7 +1539,7 @@ TextWidgetObjCmd( textPtr->afterSyncCmd = cmd; } else { textPtr->afterSyncCmd = cmd; - Tcl_DoWhenIdle(RunAfterSyncCmd, (ClientData) textPtr); + Tcl_DoWhenIdle(RunAfterSyncCmd, (ClientData) textPtr); } break; } else if (objc != 2) { @@ -2093,7 +2097,7 @@ ConfigureText( textPtr->sharedTextPtr->maxUndo = textPtr->maxUndo; textPtr->sharedTextPtr->autoSeparators = textPtr->autoSeparators; - TkUndoSetDepth(textPtr->sharedTextPtr->undoStack, + TkUndoSetMaxDepth(textPtr->sharedTextPtr->undoStack, textPtr->sharedTextPtr->maxUndo); /* @@ -2191,10 +2195,10 @@ ConfigureText( * Also, clamp the insert and current (unshared) marks to the new * -startline/-endline range limits of the widget. All other (shared) * marks are unchanged. - * The return value of TkTextMarkNameToIndex does not need to be - * checked: "insert" and "current" marks always exist, and the - * purpose of the code below precisely is to move them inside the - * -startline/-endline range. + * The return value of TkTextMarkNameToIndex does not need to be + * checked: "insert" and "current" marks always exist, and the + * purpose of the code below precisely is to move them inside the + * -startline/-endline range. */ textPtr->sharedTextPtr->stateEpoch++; @@ -2253,12 +2257,20 @@ ConfigureText( * replaced in the widget record. */ - textPtr->selTagPtr->border = textPtr->selBorder; + if (textPtr->selTagPtr->selBorder == NULL) { + textPtr->selTagPtr->border = textPtr->selBorder; + } else { + textPtr->selTagPtr->selBorder = textPtr->selBorder; + } if (textPtr->selTagPtr->borderWidthPtr != textPtr->selBorderWidthPtr) { textPtr->selTagPtr->borderWidthPtr = textPtr->selBorderWidthPtr; textPtr->selTagPtr->borderWidth = textPtr->selBorderWidth; } - textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr; + if (textPtr->selTagPtr->selFgColor == NULL) { + textPtr->selTagPtr->fgColor = textPtr->selFgColorPtr; + } else { + textPtr->selTagPtr->selFgColor = textPtr->selFgColorPtr; + } textPtr->selTagPtr->affectsDisplay = 0; textPtr->selTagPtr->affectsDisplayGeometry = 0; if ((textPtr->selTagPtr->elideString != NULL) @@ -2277,12 +2289,18 @@ ConfigureText( textPtr->selTagPtr->affectsDisplayGeometry = 1; } if ((textPtr->selTagPtr->border != NULL) + || (textPtr->selTagPtr->selBorder != NULL) || (textPtr->selTagPtr->reliefString != NULL) || (textPtr->selTagPtr->bgStipple != None) || (textPtr->selTagPtr->fgColor != NULL) + || (textPtr->selTagPtr->selFgColor != NULL) || (textPtr->selTagPtr->fgStipple != None) || (textPtr->selTagPtr->overstrikeString != NULL) - || (textPtr->selTagPtr->underlineString != NULL)) { + || (textPtr->selTagPtr->overstrikeColor != NULL) + || (textPtr->selTagPtr->underlineString != NULL) + || (textPtr->selTagPtr->underlineColor != NULL) + || (textPtr->selTagPtr->lMarginColor != NULL) + || (textPtr->selTagPtr->rMarginColor != NULL)) { textPtr->selTagPtr->affectsDisplay = 1; } TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr, 1); @@ -2406,7 +2424,7 @@ TextWorldChanged( textPtr->charHeight = 1; } if (textPtr->charHeight != oldCharHeight) { - TkBTreeClientRangeChanged(textPtr, textPtr->charHeight); + TkBTreeClientRangeChanged(textPtr, textPtr->charHeight); } border = textPtr->borderWidth + textPtr->highlightWidth; Tk_GeometryRequest(textPtr->tkwin, @@ -2755,6 +2773,7 @@ TextPushUndoAction( /* Index describing second location. */ { TkUndoSubAtom *iAtom, *dAtom; + int canUndo, canRedo; /* * Create the helpers. @@ -2841,6 +2860,9 @@ TextPushUndoAction( Tcl_DecrRefCount(index1Obj); Tcl_DecrRefCount(index2Obj); + canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack); + canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack); + /* * Depending whether the action is to insert or delete, we provide the * appropriate second and third arguments to TkUndoPushAction. (The first @@ -2852,6 +2874,10 @@ TextPushUndoAction( } else { TkUndoPushAction(textPtr->sharedTextPtr->undoStack, dAtom, iAtom); } + + if (!canUndo || canRedo) { + GenerateUndoStackEvent(textPtr); + } } /* @@ -3075,11 +3101,16 @@ DeleteIndexRange( * The code below is ugly, but it's needed to make sure there is always a * dummy empty line at the end of the text. If the final newline of the * file (just before the dummy line) is being deleted, then back up index - * to just before the newline. Furthermore, remove any tags that are - * present on the newline that isn't going to be deleted after all (this - * simulates deleting the newline and then adding a "clean" one back - * again). Note that index1 and index2 might now be equal again which - * means that no text will be deleted but tags might be removed. + * to just before the newline. If there is a newline just before the first + * character being deleted, then back up the first index too. The idea is + * that a deletion involving a range starting at a line start and + * including the final \n (i.e. index2 is "end") is an attempt to delete + * complete lines, so the \n before the deleted block shall become the new + * final \n. Furthermore, remove any tags that are present on the newline + * that isn't going to be deleted after all (this simulates deleting the + * newline and then adding a "clean" one back again). Note that index1 and + * index2 might now be equal again which means that no text will be + * deleted but tags might be removed. */ line1 = TkBTreeLinesTo(textPtr, index1.linePtr); @@ -3092,6 +3123,10 @@ DeleteIndexRange( oldIndex2 = index2; TkTextIndexBackChars(NULL, &oldIndex2, 1, &index2, COUNT_INDICES); line2--; + if ((index1.byteIndex == 0) && (line1 != 0)) { + TkTextIndexBackChars(NULL, &index1, 1, &index1, COUNT_INDICES); + line1--; + } arrayPtr = TkBTreeGetTags(&index2, NULL, &arraySize); if (arrayPtr != NULL) { for (i = 0; i < arraySize; i++) { @@ -3179,11 +3214,11 @@ DeleteIndexRange( resetView = 1; line = line1; byteIndex = tPtr->topIndex.byteIndex; - } else { - /* - * Deletion range starts after the top line. This peers's view - * will not need to be reset. Nothing to do. - */ + } else { + /* + * Deletion range starts after the top line. This peers's view + * will not need to be reset. Nothing to do. + */ } } else if (index2.linePtr == tPtr->topIndex.linePtr) { /* @@ -3200,11 +3235,11 @@ DeleteIndexRange( } else { byteIndex -= (index2.byteIndex - index1.byteIndex); } - } else { - /* - * Deletion range ends before the top line. This peers's view - * will not need to be reset. Nothing to do. - */ + } else { + /* + * Deletion range ends before the top line. This peers's view + * will not need to be reset. Nothing to do. + */ } if (resetView) { lineAndByteIndex[resetViewCount] = line; @@ -3249,43 +3284,43 @@ DeleteIndexRange( TkTextIndex indexTmp; if (tPtr == textPtr) { - if (viewUpdate) { - /* - * line cannot be before -startline of textPtr because - * this line corresponds to an index which is necessarily - * between "1.0" and "end" relative to textPtr. - * Therefore no need to clamp line to the -start/-end - * range. - */ + if (viewUpdate) { + /* + * line cannot be before -startline of textPtr because + * this line corresponds to an index which is necessarily + * between "1.0" and "end" relative to textPtr. + * Therefore no need to clamp line to the -start/-end + * range. + */ TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, line, byteIndex, &indexTmp); TkTextSetYView(tPtr, &indexTmp, 0); } } else { - TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line, + TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, line, byteIndex, &indexTmp); - /* - * line may be before -startline of tPtr and must be - * clamped to -startline before providing it to - * TkTextSetYView otherwise lines before -startline - * would be displayed. - * There is no need to worry about -endline however, - * because the view will only be reset if the deletion - * involves the TOP line of the screen - */ - - if (tPtr->start != NULL) { - int start; - TkTextIndex indexStart; - - start = TkBTreeLinesTo(NULL, tPtr->start); - TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start, + /* + * line may be before -startline of tPtr and must be + * clamped to -startline before providing it to + * TkTextSetYView otherwise lines before -startline + * would be displayed. + * There is no need to worry about -endline however, + * because the view will only be reset if the deletion + * involves the TOP line of the screen + */ + + if (tPtr->start != NULL) { + int start; + TkTextIndex indexStart; + + start = TkBTreeLinesTo(NULL, tPtr->start); + TkTextMakeByteIndex(sharedTextPtr->tree, NULL, start, 0, &indexStart); - if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) { - indexTmp = indexStart; - } - } + if (TkTextIndexCmp(&indexTmp, &indexStart) < 0) { + indexTmp = indexStart; + } + } TkTextSetYView(tPtr, &indexTmp, 0); } } @@ -3531,16 +3566,7 @@ TkTextSelectionEvent( * event generate $textWidget <<Selection>> */ - union {XEvent general; XVirtualEvent virtual;} event; - - memset(&event, 0, sizeof(event)); - event.general.xany.type = VirtualEvent; - event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); - event.general.xany.send_event = False; - event.general.xany.window = Tk_WindowId(textPtr->tkwin); - event.general.xany.display = Tk_Display(textPtr->tkwin); - event.virtual.name = Tk_GetUid("Selection"); - Tk_HandleEvent(&event.general); + TkSendVirtualEvent(textPtr->tkwin, "Selection", NULL); } /* @@ -5141,11 +5167,16 @@ TextEditCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { int index, setModified, oldModified; + int canRedo = 0; + int canUndo = 0; + static const char *const editOptionStrings[] = { - "modified", "redo", "reset", "separator", "undo", NULL + "canundo", "canredo", "modified", "redo", "reset", "separator", + "undo", NULL }; enum editOptions { - EDIT_MODIFIED, EDIT_REDO, EDIT_RESET, EDIT_SEPARATOR, EDIT_UNDO + EDIT_CANUNDO, EDIT_CANREDO, EDIT_MODIFIED, EDIT_REDO, EDIT_RESET, + EDIT_SEPARATOR, EDIT_UNDO }; if (objc < 3) { @@ -5159,6 +5190,26 @@ TextEditCmd( } switch ((enum editOptions) index) { + case EDIT_CANREDO: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, NULL); + return TCL_ERROR; + } + if (textPtr->sharedTextPtr->undo) { + canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack); + } + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canRedo)); + break; + case EDIT_CANUNDO: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, NULL); + return TCL_ERROR; + } + if (textPtr->sharedTextPtr->undo) { + canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack); + } + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(canUndo)); + break; case EDIT_MODIFIED: if (objc == 3) { Tcl_SetObjResult(interp, @@ -5200,18 +5251,28 @@ TextEditCmd( Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } + canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack); if (TextEditRedo(textPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to redo", -1)); Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_REDO", NULL); return TCL_ERROR; } + canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack); + if (!canUndo || !canRedo) { + GenerateUndoStackEvent(textPtr); + } break; case EDIT_RESET: if (objc != 3) { Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } + canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack); + canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack); TkUndoClearStacks(textPtr->sharedTextPtr->undoStack); + if (canUndo || canRedo) { + GenerateUndoStackEvent(textPtr); + } break; case EDIT_SEPARATOR: if (objc != 3) { @@ -5225,11 +5286,16 @@ TextEditCmd( Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } + canRedo = TkUndoCanRedo(textPtr->sharedTextPtr->undoStack); if (TextEditUndo(textPtr)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("nothing to undo", -1)); Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_UNDO", NULL); return TCL_ERROR; } + canUndo = TkUndoCanUndo(textPtr->sharedTextPtr->undoStack); + if (!canRedo || !canUndo) { + GenerateUndoStackEvent(textPtr); + } break; } return TCL_OK; @@ -5324,6 +5390,7 @@ TextGetText( * * Send an event that the text was modified. This is equivalent to: * event generate $textWidget <<Modified>> + * for all peers of $textWidget. * * Results: * None @@ -5338,21 +5405,41 @@ static void GenerateModifiedEvent( TkText *textPtr) /* Information about text widget. */ { - union { - XEvent general; - XVirtualEvent virtual; - } event; - - Tk_MakeWindowExist(textPtr->tkwin); - - memset(&event, 0, sizeof(event)); - event.general.xany.type = VirtualEvent; - event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); - event.general.xany.send_event = False; - event.general.xany.window = Tk_WindowId(textPtr->tkwin); - event.general.xany.display = Tk_Display(textPtr->tkwin); - event.virtual.name = Tk_GetUid("Modified"); - Tk_HandleEvent(&event.general); + for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL; + textPtr = textPtr->next) { + Tk_MakeWindowExist(textPtr->tkwin); + TkSendVirtualEvent(textPtr->tkwin, "Modified", NULL); + } +} + +/* + *---------------------------------------------------------------------- + * + * GenerateUndoStackEvent -- + * + * Send an event that the undo or redo stack became empty or unempty. + * This is equivalent to: + * event generate $textWidget <<UndoStack>> + * for all peers of $textWidget. + * + * Results: + * None + * + * Side effects: + * May force the text window (and all peers) into existence. + * + *---------------------------------------------------------------------- + */ + +static void +GenerateUndoStackEvent( + TkText *textPtr) /* Information about text widget. */ +{ + for (textPtr = textPtr->sharedTextPtr->peers; textPtr != NULL; + textPtr = textPtr->next) { + Tk_MakeWindowExist(textPtr->tkwin); + TkSendVirtualEvent(textPtr->tkwin, "UndoStack", NULL); + } } /* @@ -5376,7 +5463,6 @@ UpdateDirtyFlag( TkSharedText *sharedTextPtr)/* Information about text widget. */ { int oldDirtyFlag; - TkText *textPtr; /* * If we've been forced to be dirty, we stay dirty (until explicitly @@ -5407,10 +5493,7 @@ UpdateDirtyFlag( } if (sharedTextPtr->isDirty == 0 || oldDirtyFlag == 0) { - for (textPtr = sharedTextPtr->peers; textPtr != NULL; - textPtr = textPtr->next) { - GenerateModifiedEvent(textPtr); - } + GenerateModifiedEvent(sharedTextPtr->peers); } } @@ -5439,21 +5522,21 @@ RunAfterSyncCmd( int code; if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) { - /* - * The widget has been deleted. Don't do anything. - */ + /* + * The widget has been deleted. Don't do anything. + */ - if (--textPtr->refCount == 0) { - ckfree((char *) textPtr); - } - return; + if (--textPtr->refCount == 0) { + ckfree((char *) textPtr); + } + return; } Tcl_Preserve((ClientData) textPtr->interp); code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd, TCL_EVAL_GLOBAL); if (code == TCL_ERROR) { - Tcl_AddErrorInfo(textPtr->interp, "\n (text sync)"); - Tcl_BackgroundError(textPtr->interp); + Tcl_AddErrorInfo(textPtr->interp, "\n (text sync)"); + Tcl_BackgroundError(textPtr->interp); } Tcl_Release((ClientData) textPtr->interp); Tcl_DecrRefCount(textPtr->afterSyncCmd); diff --git a/generic/tkText.h b/generic/tkText.h index fc92644..5d88784 100644 --- a/generic/tkText.h +++ b/generic/tkText.h @@ -347,6 +347,9 @@ typedef struct TkTextTag { int lMargin2; /* Left margin for second and later display * lines of each text line, in pixels. Only * valid if lMargin2String is non-NULL. */ + Tk_3DBorder lMarginColor; /* Used for drawing background in left margins. + * This is used for both lmargin1 and lmargin2. + * NULL means no value specified here. */ char *offsetString; /* -offset option string (malloc-ed). NULL * means option not specified. */ int offset; /* Vertical offset of text's baseline from @@ -358,10 +361,18 @@ typedef struct TkTextTag { int overstrike; /* Non-zero means draw horizontal line through * middle of text. Only valid if * overstrikeString is non-NULL. */ + XColor *overstrikeColor; /* Color for the overstrike. NULL means same + * color as foreground. */ char *rMarginString; /* -rmargin option string (malloc-ed). NULL * means option not specified. */ int rMargin; /* Right margin for text, in pixels. Only * valid if rMarginString is non-NULL. */ + Tk_3DBorder rMarginColor; /* Used for drawing background in right margin. + * NULL means no value specified here. */ + Tk_3DBorder selBorder; /* Used for drawing background for selected text. + * NULL means no value specified here. */ + XColor *selFgColor; /* Foreground color for selected text. NULL means + * no value specified here. */ char *spacing1String; /* -spacing1 option string (malloc-ed). NULL * means option not specified. */ int spacing1; /* Extra spacing above first display line for @@ -389,6 +400,8 @@ typedef struct TkTextTag { int underline; /* Non-zero means draw underline underneath * text. Only valid if underlineString is * non-NULL. */ + XColor *underlineColor; /* Color for the underline. NULL means same + * color as foreground. */ TkWrapMode wrapMode; /* How to handle wrap-around for this tag. * Must be TEXT_WRAPMODE_CHAR, * TEXT_WRAPMODE_NONE, TEXT_WRAPMODE_WORD, or diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 18b373f..81bce94 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -136,11 +136,15 @@ typedef struct StyleValues { * line of each text line. */ int lMargin2; /* Left margin, in pixels, for second and * later display lines of each text line. */ + Tk_3DBorder lMarginColor; /* Color of left margins (1 and 2). */ int offset; /* Offset in pixels of baseline, relative to * baseline of line. */ int overstrike; /* Non-zero means draw overstrike through * text. */ + XColor *overstrikeColor; /* Foreground color for overstrike through + * text. */ int rMargin; /* Right margin, in pixels. */ + Tk_3DBorder rMarginColor; /* Color of right margin. */ int spacing1; /* Spacing above first dline in text line. */ int spacing2; /* Spacing between lines of dline. */ int spacing3; /* Spacing below last dline in text line. */ @@ -149,6 +153,8 @@ typedef struct StyleValues { int tabStyle; /* One of TABULAR or WORDPROCESSOR. */ int underline; /* Non-zero means draw underline underneath * text. */ + XColor *underlineColor; /* Foreground color for underline underneath + * text. */ int elide; /* Zero means draw text, otherwise not. */ TkWrapMode wrapMode; /* How to handle wrap-around for this tag. * One of TEXT_WRAPMODE_CHAR, @@ -167,6 +173,8 @@ typedef struct TextStyle { GC bgGC; /* Graphics context for background. None means * use widget background. */ GC fgGC; /* Graphics context for foreground. */ + GC ulGC; /* Graphics context for underline. */ + GC ovGC; /* Graphics context for overstrike. */ StyleValues *sValuePtr; /* Raw information from which GCs were * derived. */ Tcl_HashEntry *hPtr; /* Pointer to entry in styleTable. Used to @@ -234,6 +242,14 @@ typedef struct DLine { int spaceBelow; /* How much extra space was added to the * bottom of the line because of spacing * options. This is included in height. */ + Tk_3DBorder lMarginColor; /* Background color of the area corresponding + * to the left margin of the display line. */ + int lMarginWidth; /* Pixel width of the area corresponding to + * the left margin. */ + Tk_3DBorder rMarginColor; /* Background color of the area corresponding + * to the right margin of the display line. */ + int rMarginWidth; /* Pixel width of the area corresponding to + * the right margin. */ int length; /* Total length of line, in pixels. */ TkTextDispChunk *chunkPtr; /* Pointer to first chunk in list of all of * those that are displayed on this line of @@ -748,6 +764,7 @@ GetStyle( TextStyle *stylePtr; Tcl_HashEntry *hPtr; int numTags, isNew, i; + int isSelected; XGCValues gcValues; unsigned long mask; /* @@ -758,6 +775,7 @@ GetStyle( int fgPrio, fontPrio, fgStipplePrio; int underlinePrio, elidePrio, justifyPrio, offsetPrio; int lMargin1Prio, lMargin2Prio, rMarginPrio; + int lMarginColorPrio, rMarginColorPrio; int spacing1Prio, spacing2Prio, spacing3Prio; int overstrikePrio, tabPrio, tabStylePrio, wrapPrio; @@ -772,11 +790,14 @@ GetStyle( fgPrio = fontPrio = fgStipplePrio = -1; underlinePrio = elidePrio = justifyPrio = offsetPrio = -1; lMargin1Prio = lMargin2Prio = rMarginPrio = -1; + lMarginColorPrio = rMarginColorPrio = -1; spacing1Prio = spacing2Prio = spacing3Prio = -1; overstrikePrio = tabPrio = tabStylePrio = wrapPrio = -1; memset(&styleValues, 0, sizeof(StyleValues)); styleValues.relief = TK_RELIEF_FLAT; styleValues.fgColor = textPtr->fgColor; + styleValues.underlineColor = textPtr->fgColor; + styleValues.overstrikeColor = textPtr->fgColor; styleValues.tkfont = textPtr->tkfont; styleValues.justify = TK_JUSTIFY_LEFT; styleValues.spacing1 = textPtr->spacing1; @@ -786,12 +807,22 @@ GetStyle( styleValues.tabStyle = textPtr->tabStyle; styleValues.wrapMode = textPtr->wrapMode; styleValues.elide = 0; + isSelected = 0; + + for (i = 0 ; i < numTags; i++) { + if (textPtr->selTagPtr == tagPtrs[i]) { + isSelected = 1; + break; + } + } for (i = 0 ; i < numTags; i++) { Tk_3DBorder border; + XColor *fgColor; tagPtr = tagPtrs[i]; border = tagPtr->border; + fgColor = tagPtr->fgColor; /* * If this is the selection tag, and inactiveSelBorder is NULL (the @@ -811,6 +842,14 @@ GetStyle( border = textPtr->inactiveSelBorder; } + if ((tagPtr->selBorder != NULL) && (isSelected)) { + border = tagPtr->selBorder; + } + + if ((tagPtr->selFgColor != None) && (isSelected)) { + fgColor = tagPtr->selFgColor; + } + if ((border != NULL) && (tagPtr->priority > borderPrio)) { styleValues.border = border; borderPrio = tagPtr->priority; @@ -834,8 +873,8 @@ GetStyle( styleValues.bgStipple = tagPtr->bgStipple; bgStipplePrio = tagPtr->priority; } - if ((tagPtr->fgColor != None) && (tagPtr->priority > fgPrio)) { - styleValues.fgColor = tagPtr->fgColor; + if ((fgColor != None) && (tagPtr->priority > fgPrio)) { + styleValues.fgColor = fgColor; fgPrio = tagPtr->priority; } if ((tagPtr->tkfont != None) && (tagPtr->priority > fontPrio)) { @@ -862,6 +901,11 @@ GetStyle( styleValues.lMargin2 = tagPtr->lMargin2; lMargin2Prio = tagPtr->priority; } + if ((tagPtr->lMarginColor != NULL) + && (tagPtr->priority > lMarginColorPrio)) { + styleValues.lMarginColor = tagPtr->lMarginColor; + lMarginColorPrio = tagPtr->priority; + } if ((tagPtr->offsetString != NULL) && (tagPtr->priority > offsetPrio)) { styleValues.offset = tagPtr->offset; @@ -871,12 +915,22 @@ GetStyle( && (tagPtr->priority > overstrikePrio)) { styleValues.overstrike = tagPtr->overstrike; overstrikePrio = tagPtr->priority; + if (tagPtr->overstrikeColor != None) { + styleValues.overstrikeColor = tagPtr->overstrikeColor; + } else if (fgColor != None) { + styleValues.overstrikeColor = fgColor; + } } if ((tagPtr->rMarginString != NULL) && (tagPtr->priority > rMarginPrio)) { styleValues.rMargin = tagPtr->rMargin; rMarginPrio = tagPtr->priority; } + if ((tagPtr->rMarginColor != NULL) + && (tagPtr->priority > rMarginColorPrio)) { + styleValues.rMarginColor = tagPtr->rMarginColor; + rMarginColorPrio = tagPtr->priority; + } if ((tagPtr->spacing1String != NULL) && (tagPtr->priority > spacing1Prio)) { styleValues.spacing1 = tagPtr->spacing1; @@ -906,6 +960,11 @@ GetStyle( && (tagPtr->priority > underlinePrio)) { styleValues.underline = tagPtr->underline; underlinePrio = tagPtr->priority; + if (tagPtr->underlineColor != None) { + styleValues.underlineColor = tagPtr->underlineColor; + } else if (fgColor != None) { + styleValues.underlineColor = fgColor; + } } if ((tagPtr->elideString != NULL) && (tagPtr->priority > elidePrio)) { @@ -962,6 +1021,11 @@ GetStyle( mask |= GCStipple|GCFillStyle; } stylePtr->fgGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues); + mask = GCForeground; + gcValues.foreground = styleValues.underlineColor->pixel; + stylePtr->ulGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues); + gcValues.foreground = styleValues.overstrikeColor->pixel; + stylePtr->ovGC = Tk_GetGC(textPtr->tkwin, mask, &gcValues); stylePtr->sValuePtr = (StyleValues *) Tcl_GetHashKey(&textPtr->dInfoPtr->styleTable, hPtr); stylePtr->hPtr = hPtr; @@ -1002,6 +1066,12 @@ FreeStyle( if (stylePtr->fgGC != None) { Tk_FreeGC(textPtr->display, stylePtr->fgGC); } + if (stylePtr->ulGC != None) { + Tk_FreeGC(textPtr->display, stylePtr->ulGC); + } + if (stylePtr->ovGC != None) { + Tk_FreeGC(textPtr->display, stylePtr->ovGC); + } Tcl_DeleteHashEntry(stylePtr->hPtr); ckfree(stylePtr); } @@ -1113,6 +1183,10 @@ LayoutDLine( dlPtr->nextPtr = NULL; dlPtr->flags = NEW_LAYOUT | OLD_Y_INVALID; dlPtr->logicalLinesMerged = 0; + dlPtr->lMarginColor = NULL; + dlPtr->lMarginWidth = 0; + dlPtr->rMarginColor = NULL; + dlPtr->rMarginWidth = 0; /* * This is not necessarily totally correct, where we have merged logical @@ -1387,6 +1461,7 @@ LayoutDLine( x = chunkPtr->stylePtr->sValuePtr->lMargin2; } + dlPtr->lMarginWidth = x; if (wrapMode == TEXT_WRAPMODE_NONE) { maxX = -1; } else { @@ -1640,7 +1715,7 @@ LayoutDLine( * Make one more pass over the line to recompute various things like its * height, length, and total number of bytes. Also modify the x-locations * of chunks to reflect justification. If we're not wrapping, I'm not sure - * what is the best way to handle left and center justification: should + * what is the best way to handle right and center justification: should * the total length, for purposes of justification, be (a) the window * width, (b) the length of the longest line in the window, or (c) the * length of the longest line in the text? (c) isn't available, (b) seems @@ -1698,6 +1773,11 @@ LayoutDLine( } dlPtr->height += dlPtr->spaceAbove + dlPtr->spaceBelow; dlPtr->baseline += dlPtr->spaceAbove; + dlPtr->lMarginColor = sValuePtr->lMarginColor; + dlPtr->rMarginColor = sValuePtr->rMarginColor; + if (wrapMode != TEXT_WRAPMODE_NONE) { + dlPtr->rMarginWidth = rMargin; + } /* * Recompute line length: may have changed because of justification. @@ -2384,6 +2464,20 @@ DisplayDLine( Tk_Width(textPtr->tkwin), dlPtr->height, 0, TK_RELIEF_FLAT); /* + * Second, draw the background color of the left and right margins. + */ + if (dlPtr->lMarginColor != NULL) { + Tk_Fill3DRectangle(textPtr->tkwin, pixmap, dlPtr->lMarginColor, 0, y, + dlPtr->lMarginWidth + dInfoPtr->x - dInfoPtr->curXPixelOffset, + dlPtr->height, 0, TK_RELIEF_FLAT); + } + if (dlPtr->rMarginColor != NULL) { + Tk_Fill3DRectangle(textPtr->tkwin, pixmap, dlPtr->rMarginColor, + dInfoPtr->maxX - dlPtr->rMarginWidth + dInfoPtr->curXPixelOffset, + y, dlPtr->rMarginWidth, dlPtr->height, 0, TK_RELIEF_FLAT); + } + + /* * Next, draw background information for the whole line. */ @@ -3010,7 +3104,7 @@ AsyncUpdateLineMetrics( * Send the <<WidgetViewSync>> event related to the text widget * line metrics asynchronous update. * This is equivalent to: - * event generate $textWidget <<WidgetViewSync>> -detail $s + * event generate $textWidget <<WidgetViewSync>> -data $s * where $s is the sync status: true (when the widget view is in * sync with its internal data) or false (when it is not). * @@ -3026,19 +3120,10 @@ AsyncUpdateLineMetrics( static void GenerateWidgetViewSyncEvent( TkText *textPtr, /* Information about text widget. */ - Bool InSync) /* True if in sync, false otherwise */ + Bool InSync) /* true if in sync, false otherwise */ { - union {XEvent general; XVirtualEvent virtual;} event; - - memset(&event, 0, sizeof(event)); - event.general.xany.type = VirtualEvent; - event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); - event.general.xany.send_event = False; - event.general.xany.window = Tk_WindowId(textPtr->tkwin); - event.general.xany.display = Tk_Display(textPtr->tkwin); - event.virtual.name = Tk_GetUid("WidgetViewSync"); - event.virtual.user_data = Tcl_NewBooleanObj(InSync); - Tk_HandleEvent(&event.general); + TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync", + Tcl_NewBooleanObj(InSync)); } /* @@ -4869,16 +4954,9 @@ TextRedrawTag( /* * Round up the starting position if it's before the first line visible on - * the screen (we only care about what's on the screen). Beware that the - * display info structure might need update, for instance if we arrived - * here from an 'after idle' script removing tags in a range whose - * display lines (and dInfo) were partially invalidated by a previous - * delete operation in the text widget. + * the screen (we only care about what's on the screen). */ - if (dInfoPtr->flags & DINFO_OUT_OF_DATE) { - UpdateDisplayInfo(textPtr); - } dlPtr = dInfoPtr->dLinePtr; if (dlPtr == NULL) { return; @@ -5240,7 +5318,10 @@ TkTextSetYView( dInfoPtr->newTopPixelOffset = 0; goto scheduleUpdate; - } + } + /* + * The line is already on screen, with no need to scroll. + */ return; } } @@ -6703,6 +6784,7 @@ FindDLine( const TkTextIndex *indexPtr)/* Index of desired character. */ { DLine *dlPtrPrev; + TkTextIndex indexPtr2; if (dlPtr == NULL) { return NULL; @@ -6727,24 +6809,58 @@ FindDLine( dlPtrPrev = dlPtr; dlPtr = dlPtr->nextPtr; if (dlPtr == NULL) { - TkTextIndex indexPtr2; /* * We're past the last display line, either because the desired * index lies past the visible text, or because the desired index - * is on the last display line showing the last logical line. + * is on the last display line. */ indexPtr2 = dlPtrPrev->index; TkTextIndexForwBytes(textPtr, &indexPtr2, dlPtrPrev->byteCount, &indexPtr2); if (TkTextIndexCmp(&indexPtr2,indexPtr) > 0) { + /* + * The desired index is on the last display line. + * --> return this display line. + */ dlPtr = dlPtrPrev; - break; } else { - return NULL; + /* + * The desired index is past the visible text. There is no + * display line displaying something at the desired index. + * --> return NULL. + */ } + break; } if (TkTextIndexCmp(&dlPtr->index,indexPtr) > 0) { - dlPtr = dlPtrPrev; + /* + * If we're here then we would normally expect that: + * dlPtrPrev->index <= indexPtr < dlPtr->index + * i.e. we have found the searched display line being dlPtr. + * However it is possible that some DLines were unlinked + * previously, leading to a situation where going through + * the list of display lines skips display lines that did + * exist just a moment ago. + */ + indexPtr2 = dlPtrPrev->index; + TkTextIndexForwBytes(textPtr, &indexPtr2, dlPtrPrev->byteCount, + &indexPtr2); + if (TkTextIndexCmp(&indexPtr2,indexPtr) > 0) { + /* + * Confirmed: + * dlPtrPrev->index <= indexPtr < dlPtr->index + * --> return dlPtrPrev. + */ + dlPtr = dlPtrPrev; + } else { + /* + * The last (rightmost) index shown by dlPtrPrev is still + * before the desired index. This may be because there was + * previously a display line between dlPtrPrev and dlPtr + * and this display line has been unlinked. + * --> return dlPtr. + */ + } break; } } @@ -7814,7 +7930,7 @@ CharDisplayProc( y + baseline - sValuePtr->offset); if (sValuePtr->underline) { - TkUnderlineCharsInContext(display, dst, stylePtr->fgGC, + TkUnderlineCharsInContext(display, dst, stylePtr->ulGC, sValuePtr->tkfont, string, numBytes, ciPtr->baseChunkPtr->x + xDisplacement, y + baseline - sValuePtr->offset, @@ -7824,7 +7940,7 @@ CharDisplayProc( Tk_FontMetrics fm; Tk_GetFontMetrics(sValuePtr->tkfont, &fm); - TkUnderlineCharsInContext(display, dst, stylePtr->fgGC, + TkUnderlineCharsInContext(display, dst, stylePtr->ovGC, sValuePtr->tkfont, string, numBytes, ciPtr->baseChunkPtr->x + xDisplacement, y + baseline - sValuePtr->offset @@ -7841,7 +7957,7 @@ CharDisplayProc( Tk_DrawChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, string, numBytes, offsetX, y + baseline - sValuePtr->offset); if (sValuePtr->underline) { - Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, + Tk_UnderlineChars(display, dst, stylePtr->ulGC, sValuePtr->tkfont, string, offsetX, y + baseline - sValuePtr->offset, 0, numBytes); @@ -7851,7 +7967,7 @@ CharDisplayProc( Tk_FontMetrics fm; Tk_GetFontMetrics(sValuePtr->tkfont, &fm); - Tk_UnderlineChars(display, dst, stylePtr->fgGC, sValuePtr->tkfont, + Tk_UnderlineChars(display, dst, stylePtr->ovGC, sValuePtr->tkfont, string, offsetX, y + baseline - sValuePtr->offset - fm.descent - (fm.ascent * 3) / 10, diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index 3363d25..a212615 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -61,15 +61,26 @@ static const Tk_OptionSpec tagOptionSpecs[] = { NULL, -1, Tk_Offset(TkTextTag, lMargin1String), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-lmargin2", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, lMargin2String), TK_OPTION_NULL_OK,0,0}, + {TK_OPTION_BORDER, "-lmargincolor", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, lMarginColor), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-offset", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, offsetString), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-overstrike", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, overstrikeString), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_COLOR, "-overstrikefg", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, overstrikeColor), + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-relief", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, reliefString), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-rmargin", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, rMarginString), TK_OPTION_NULL_OK, 0,0}, + {TK_OPTION_BORDER, "-rmargincolor", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, rMarginColor), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_BORDER, "-selectbackground", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, selBorder), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_COLOR, "-selectforeground", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, selFgColor), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-spacing1", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, spacing1String), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-spacing2", NULL, NULL, @@ -84,6 +95,9 @@ static const Tk_OptionSpec tagOptionSpecs[] = { {TK_OPTION_STRING, "-underline", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, underlineString), TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_COLOR, "-underlinefg", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, underlineColor), + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-wrap", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, wrapMode), TK_OPTION_NULL_OK, wrapStrings, 0}, @@ -484,10 +498,18 @@ TkTextTagCmd( */ if (tagPtr == textPtr->selTagPtr) { - textPtr->selBorder = tagPtr->border; + if (tagPtr->selBorder == NULL) { + textPtr->selBorder = tagPtr->border; + } else { + textPtr->selBorder = tagPtr->selBorder; + } textPtr->selBorderWidth = tagPtr->borderWidth; textPtr->selBorderWidthPtr = tagPtr->borderWidthPtr; - textPtr->selFgColorPtr = tagPtr->fgColor; + if (tagPtr->selFgColor == NULL) { + textPtr->selFgColorPtr = tagPtr->fgColor; + } else { + textPtr->selFgColorPtr = tagPtr->selFgColor; + } } tagPtr->affectsDisplay = 0; @@ -509,12 +531,18 @@ TkTextTagCmd( tagPtr->affectsDisplayGeometry = 1; } if ((tagPtr->border != NULL) + || (tagPtr->selBorder != NULL) || (tagPtr->reliefString != NULL) || (tagPtr->bgStipple != None) || (tagPtr->fgColor != NULL) + || (tagPtr->selFgColor != NULL) || (tagPtr->fgStipple != None) || (tagPtr->overstrikeString != NULL) - || (tagPtr->underlineString != NULL)) { + || (tagPtr->overstrikeColor != NULL) + || (tagPtr->underlineString != NULL) + || (tagPtr->underlineColor != NULL) + || (tagPtr->lMarginColor != NULL) + || (tagPtr->rMarginColor != NULL)) { tagPtr->affectsDisplay = 1; } if (!newTag) { @@ -1011,12 +1039,17 @@ TkTextCreateTag( tagPtr->lMargin1 = 0; tagPtr->lMargin2String = NULL; tagPtr->lMargin2 = 0; + tagPtr->lMarginColor = NULL; tagPtr->offsetString = NULL; tagPtr->offset = 0; tagPtr->overstrikeString = NULL; tagPtr->overstrike = 0; + tagPtr->overstrikeColor = NULL; tagPtr->rMarginString = NULL; tagPtr->rMargin = 0; + tagPtr->rMarginColor = NULL; + tagPtr->selBorder = NULL; + tagPtr->selFgColor = NULL; tagPtr->spacing1String = NULL; tagPtr->spacing1 = 0; tagPtr->spacing2String = NULL; @@ -1028,6 +1061,7 @@ TkTextCreateTag( tagPtr->tabStyle = TK_TEXT_TABSTYLE_NONE; tagPtr->underlineString = NULL; tagPtr->underline = 0; + tagPtr->underlineColor = NULL; tagPtr->elideString = NULL; tagPtr->elide = 0; tagPtr->wrapMode = TEXT_WRAPMODE_NULL; diff --git a/generic/tkUndo.c b/generic/tkUndo.c index 8359e0a..c66905d 100644 --- a/generic/tkUndo.c +++ b/generic/tkUndo.c @@ -353,7 +353,7 @@ TkUndoInitStack( /* *---------------------------------------------------------------------- * - * TkUndoSetDepth -- + * TkUndoSetMaxDepth -- * * Set the maximum depth of stack. * @@ -368,7 +368,7 @@ TkUndoInitStack( */ void -TkUndoSetDepth( +TkUndoSetMaxDepth( TkUndoRedoStack *stack, /* An Undo/Redo stack */ int maxdepth) /* The maximum stack depth */ { @@ -478,6 +478,52 @@ TkUndoFreeStack( /* *---------------------------------------------------------------------- * + * TkUndoCanRedo -- + * + * Returns true if redo is possible, i.e. if the redo stack is not empty. + * + * Results: + * A boolean. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TkUndoCanRedo( + TkUndoRedoStack *stack) /* An Undo/Redo stack */ +{ + return stack->redoStack != NULL; +} + +/* + *---------------------------------------------------------------------- + * + * TkUndoCanUndo -- + * + * Returns true if undo is possible, i.e. if the undo stack is not empty. + * + * Results: + * A boolean. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TkUndoCanUndo( + TkUndoRedoStack *stack) /* An Undo/Redo stack */ +{ + return stack->undoStack != NULL; +} + +/* + *---------------------------------------------------------------------- + * * TkUndoInsertUndoSeparator -- * * Insert a separator on the undo stack, indicating a border for an @@ -498,7 +544,7 @@ TkUndoInsertUndoSeparator( { if (TkUndoInsertSeparator(&stack->undoStack)) { stack->depth++; - TkUndoSetDepth(stack, stack->maxdepth); + TkUndoSetMaxDepth(stack, stack->maxdepth); } } diff --git a/generic/tkUndo.h b/generic/tkUndo.h index e63aac4..490ede9 100644 --- a/generic/tkUndo.h +++ b/generic/tkUndo.h @@ -96,9 +96,11 @@ MODULE_SCOPE void TkUndoClearStack(TkUndoAtom **stack); */ MODULE_SCOPE TkUndoRedoStack *TkUndoInitStack(Tcl_Interp *interp, int maxdepth); -MODULE_SCOPE void TkUndoSetDepth(TkUndoRedoStack *stack, int maxdepth); +MODULE_SCOPE void TkUndoSetMaxDepth(TkUndoRedoStack *stack, int maxdepth); MODULE_SCOPE void TkUndoClearStacks(TkUndoRedoStack *stack); MODULE_SCOPE void TkUndoFreeStack(TkUndoRedoStack *stack); +MODULE_SCOPE int TkUndoCanRedo(TkUndoRedoStack *stack); +MODULE_SCOPE int TkUndoCanUndo(TkUndoRedoStack *stack); MODULE_SCOPE void TkUndoInsertUndoSeparator(TkUndoRedoStack *stack); MODULE_SCOPE TkUndoSubAtom *TkUndoMakeCmdSubAtom(Tcl_Command command, Tcl_Obj *actionScript, TkUndoSubAtom *subAtomList); diff --git a/generic/tkUtil.c b/generic/tkUtil.c index 7ff9ecb..6563165 100644 --- a/generic/tkUtil.c +++ b/generic/tkUtil.c @@ -1162,7 +1162,8 @@ TkMakeEnsemble( * TkSendVirtualEvent -- * * Send a virtual event notification to the specified target window. - * Equivalent to "event generate $target <<$eventName>>" + * Equivalent to: + * "event generate $target <<$eventName>> -data $detail" * * Note that we use Tk_QueueWindowEvent, not Tk_HandleEvent, so this * routine does not reenter the interpreter. @@ -1173,7 +1174,8 @@ TkMakeEnsemble( void TkSendVirtualEvent( Tk_Window target, - const char *eventName) + const char *eventName, + Tcl_Obj *detail) { union {XEvent general; XVirtualEvent virtual;} event; @@ -1184,6 +1186,9 @@ TkSendVirtualEvent( event.general.xany.window = Tk_WindowId(target); event.general.xany.display = Tk_Display(target); event.virtual.name = Tk_GetUid(eventName); + if (detail != NULL) { + event.virtual.user_data = detail; + } Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL); } diff --git a/generic/tkWindow.c b/generic/tkWindow.c index 1e88844..0c60321 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -54,12 +54,6 @@ typedef struct ThreadSpecificData { static Tcl_ThreadDataKey dataKey; /* - * The Mutex below is used to lock access to the Tk_Uid structs above. - */ - -TCL_DECLARE_MUTEX(windowMutex) - -/* * Default values for "changes" and "atts" fields of TkWindows. Note that Tk * always requests all events for all windows, except StructureNotify events * on internal windows: these events are generated internally. @@ -206,40 +200,6 @@ static const TkCmd commands[] = { }; /* - * The variables and table below are used to parse arguments from the "argv" - * variable in Tk_Init. - */ - -static int synchronize = 0; -static char *name = NULL; -static char *display = NULL; -static char *geometry = NULL; -static char *colormap = NULL; -static char *use = NULL; -static char *visual = NULL; -static int rest = 0; - -static const Tk_ArgvInfo argTable[] = { - {"-colormap", TK_ARGV_STRING, NULL, (char *) &colormap, - "Colormap for main window"}, - {"-display", TK_ARGV_STRING, NULL, (char *) &display, - "Display to use"}, - {"-geometry", TK_ARGV_STRING, NULL, (char *) &geometry, - "Initial geometry for window"}, - {"-name", TK_ARGV_STRING, NULL, (char *) &name, - "Name to use for application"}, - {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize, - "Use synchronous mode for display server"}, - {"-visual", TK_ARGV_STRING, NULL, (char *) &visual, - "Visual for main window"}, - {"-use", TK_ARGV_STRING, NULL, (char *) &use, - "Id of window in which to embed application"}, - {"--", TK_ARGV_REST, (char *) 1, (char *) &rest, - "Pass all remaining arguments through to script"}, - {NULL, TK_ARGV_END, NULL, NULL, NULL} -}; - -/* * Forward declarations to functions defined later in this file: */ @@ -3031,16 +2991,51 @@ MODULE_SCOPE const TkStubs tkStubs; */ static int +CopyValue( + ClientData dummy, + Tcl_Obj *objPtr, + void *dstPtr) +{ + *(Tcl_Obj **)dstPtr = objPtr; + return 1; +} + +static int Initialize( Tcl_Interp *interp) /* Interpreter to initialize. */ { - char *p; - int argc, code; - const char **argv; - const char *args[20]; - const char *argString = NULL; - Tcl_DString class; + int code = TCL_OK; ThreadSpecificData *tsdPtr; + Tcl_Obj *value = NULL; + Tcl_Obj *cmd; + + Tcl_Obj *nameObj = NULL; + Tcl_Obj *classObj = NULL; + Tcl_Obj *displayObj = NULL; + Tcl_Obj *colorMapObj = NULL; + Tcl_Obj *useObj = NULL; + Tcl_Obj *visualObj = NULL; + Tcl_Obj *geometryObj = NULL; + + int sync = 0; + + const Tcl_ArgvInfo table[] = { + {TCL_ARGV_CONSTANT, "-sync", INT2PTR(1), &sync, + "Use synchronous mode for display server", NULL}, + {TCL_ARGV_FUNC, "-colormap", CopyValue, &colorMapObj, + "Colormap for main window", NULL}, + {TCL_ARGV_FUNC, "-display", CopyValue, &displayObj, + "Display to use", NULL}, + {TCL_ARGV_FUNC, "-geometry", CopyValue, &geometryObj, + "Initial geometry for window", NULL}, + {TCL_ARGV_FUNC, "-name", CopyValue, &nameObj, + "Name to use for application", NULL}, + {TCL_ARGV_FUNC, "-visual", CopyValue, &visualObj, + "Visual for main window", NULL}, + {TCL_ARGV_FUNC, "-use", CopyValue, &useObj, + "Id of window in which to embed application", NULL}, + TCL_ARGV_AUTO_REST, TCL_ARGV_AUTO_HELP, TCL_ARGV_TABLE_END + }; /* * Ensure that we are getting a compatible version of Tcl. @@ -3059,23 +3054,6 @@ Initialize( tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* - * Start by initializing all the static variables to default acceptable - * values so that no information is leaked from a previous run of this - * code. - */ - - Tcl_MutexLock(&windowMutex); - synchronize = 0; - name = NULL; - display = NULL; - geometry = NULL; - colormap = NULL; - use = NULL; - visual = NULL; - rest = 0; - argv = NULL; - - /* * We start by resetting the result because it might not be clean. */ @@ -3087,8 +3065,6 @@ Initialize( * master. */ - Tcl_DString ds; - /* * Step 1 : find the master and construct the interp name (could be a * function if new APIs were ok). We could also construct the path @@ -3098,18 +3074,13 @@ Initialize( Tcl_Interp *master = interp; - while (1) { + while (Tcl_IsSafe(master)) { master = Tcl_GetMaster(master); if (master == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no controlling master interpreter", -1)); Tcl_SetErrorCode(interp, "TK", "SAFE", "NO_MASTER", NULL); - code = TCL_ERROR; - goto done; - } - if (!Tcl_IsSafe(master)) { - /* Found the trusted master. */ - break; + return TCL_ERROR; } } @@ -3119,39 +3090,30 @@ Initialize( code = Tcl_GetInterpPath(master, interp); if (code != TCL_OK) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "error in Tcl_GetInterpPath", -1)); - Tcl_SetErrorCode(interp, "TK", "SAFE", "FAILED", NULL); - goto done; + Tcl_Panic("Tcl_GetInterpPath broken!"); } /* - * Build the string to eval. + * Build the command to eval in trusted master. */ - Tcl_DStringInit(&ds); - Tcl_DStringAppendElement(&ds, "::safe::TkInit"); - Tcl_DStringAppendElement(&ds, Tcl_GetString(Tcl_GetObjResult(master))); - + cmd = Tcl_NewListObj(2, NULL); + Tcl_ListObjAppendElement(NULL, cmd, + Tcl_NewStringObj("::safe::TkInit", -1)); + Tcl_ListObjAppendElement(NULL, cmd, Tcl_GetObjResult(master)); + /* * Step 2 : Eval in the master. The argument is the *reversed* interp * path of the slave. */ - code = Tcl_EvalEx(master, Tcl_DStringValue(&ds), -1, 0); + Tcl_IncrRefCount(cmd); + code = Tcl_EvalObjEx(master, cmd, 0); + Tcl_DecrRefCount(cmd); + Tcl_TransferResult(master, code, interp); if (code != TCL_OK) { - /* - * We might want to transfer the error message or not. We don't. - * (No API to do it and maybe security reasons). - */ - - Tcl_DStringFree(&ds); - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "not allowed to start Tk by master's safe::TkInit", -1)); - Tcl_SetErrorCode(interp, "TK", "SAFE", "FAILED", NULL); - goto done; + return code; } - Tcl_DStringFree(&ds); /* * Use the master's result as argv. Note: We don't use the Obj @@ -3159,7 +3121,7 @@ Initialize( * changing the code below. */ - argString = Tcl_GetString(Tcl_GetObjResult(master)); + value = Tcl_GetObjResult(interp); } else { /* * If there is an "argv" variable, get its value, extract out relevant @@ -3167,50 +3129,67 @@ Initialize( * that we used. */ - argString = Tcl_GetVar2(interp, "argv", NULL, TCL_GLOBAL_ONLY); + value = Tcl_GetVar2Ex(interp, "argv", NULL, TCL_GLOBAL_ONLY); } - if (argString != NULL) { - char buffer[TCL_INTEGER_SPACE]; - if (Tcl_SplitList(interp, argString, &argc, &argv) != TCL_OK) { - argError: + if (value) { + int objc; + Tcl_Obj **objv, **rest; + Tcl_Obj *parseList = Tcl_NewListObj(1, NULL); + + Tcl_ListObjAppendElement(NULL, parseList, Tcl_NewObj()); + + Tcl_IncrRefCount(value); + if (TCL_OK != Tcl_ListObjAppendList(interp, parseList, value) || + TCL_OK != Tcl_ListObjGetElements(NULL, parseList, &objc, &objv) || + TCL_OK != Tcl_ParseArgsObjv(interp, table, &objc, objv, &rest)) { Tcl_AddErrorInfo(interp, "\n (processing arguments in argv variable)"); code = TCL_ERROR; - goto done; } - if (Tk_ParseArgv(interp, (Tk_Window) NULL, &argc, argv, - argTable, TK_ARGV_DONT_SKIP_FIRST_ARG|TK_ARGV_NO_DEFAULTS) - != TCL_OK) { - goto argError; + if (code == TCL_OK) { + Tcl_SetVar2Ex(interp, "argv", NULL, + Tcl_NewListObj(objc-1, rest+1), TCL_GLOBAL_ONLY); + Tcl_SetVar2Ex(interp, "argc", NULL, + Tcl_NewIntObj(objc-1), TCL_GLOBAL_ONLY); + ckfree(rest); + } + Tcl_DecrRefCount(parseList); + if (code != TCL_OK) { + goto done; } - p = Tcl_Merge(argc, argv); - Tcl_SetVar2(interp, "argv", NULL, p, TCL_GLOBAL_ONLY); - sprintf(buffer, "%d", argc); - Tcl_SetVar2(interp, "argc", NULL, buffer, TCL_GLOBAL_ONLY); - ckfree(p); } /* * Figure out the application's name and class. */ - Tcl_DStringInit(&class); - if (name == NULL) { - int offset; + /* + * If we got no -name argument, fetch from TkpGetAppName(). + */ - TkpGetAppName(interp, &class); - offset = Tcl_DStringLength(&class)+1; - Tcl_DStringSetLength(&class, offset); - Tcl_DStringAppend(&class, Tcl_DStringValue(&class), offset-1); - name = Tcl_DStringValue(&class) + offset; - } else { - Tcl_DStringAppend(&class, name, -1); + if (nameObj == NULL) { + Tcl_DString nameDS; + + Tcl_DStringInit(&nameDS); + TkpGetAppName(interp, &nameDS); + nameObj = Tcl_NewStringObj(Tcl_DStringValue(&nameDS), + Tcl_DStringLength(&nameDS)); + Tcl_DStringFree(&nameDS); } - p = Tcl_DStringValue(&class); - if (*p) { - Tcl_UtfToTitle(p); + /* + * The -class argument is always the ToTitle of the -name + */ + + { + int numBytes; + const char *bytes = Tcl_GetStringFromObj(nameObj, &numBytes); + + classObj = Tcl_NewStringObj(bytes, numBytes); + + numBytes = Tcl_UtfToTitle(Tcl_GetString(classObj)); + Tcl_SetObjLength(classObj, numBytes); } /* @@ -3218,15 +3197,14 @@ Initialize( * information parsed from argv, if any. */ - args[0] = "toplevel"; - args[1] = "."; - args[2] = "-class"; - args[3] = Tcl_DStringValue(&class); - argc = 4; - if (display != NULL) { - args[argc] = "-screen"; - args[argc+1] = display; - argc += 2; + cmd = Tcl_NewStringObj("toplevel . -class", -1); + + Tcl_ListObjAppendElement(NULL, cmd, classObj); + classObj = NULL; + + if (displayObj) { + Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-screen", -1)); + Tcl_ListObjAppendElement(NULL, cmd, displayObj); /* * If this is the first application for this process, save the display @@ -3235,36 +3213,35 @@ Initialize( */ if (tsdPtr->numMainWindows == 0) { - Tcl_SetVar2(interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY); + Tcl_SetVar2Ex(interp, "env", "DISPLAY", displayObj, TCL_GLOBAL_ONLY); } + displayObj = NULL; } - if (colormap != NULL) { - args[argc] = "-colormap"; - args[argc+1] = colormap; - argc += 2; - colormap = NULL; + if (colorMapObj) { + Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-colormap", -1)); + Tcl_ListObjAppendElement(NULL, cmd, colorMapObj); + colorMapObj = NULL; } - if (use != NULL) { - args[argc] = "-use"; - args[argc+1] = use; - argc += 2; - use = NULL; + if (useObj) { + Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-use", -1)); + Tcl_ListObjAppendElement(NULL, cmd, useObj); + useObj = NULL; } - if (visual != NULL) { - args[argc] = "-visual"; - args[argc+1] = visual; - argc += 2; - visual = NULL; + if (visualObj) { + Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("-visual", -1)); + Tcl_ListObjAppendElement(NULL, cmd, visualObj); + visualObj = NULL; } - args[argc] = NULL; - code = TkCreateFrame(NULL, interp, argc, args, 1, name); - Tcl_DStringFree(&class); + code = TkListCreateFrame(NULL, interp, cmd, 1, nameObj); + + Tcl_DecrRefCount(cmd); + if (code != TCL_OK) { goto done; } Tcl_ResetResult(interp); - if (synchronize) { + if (sync) { XSynchronize(Tk_Display(Tk_MainWindow(interp)), True); } @@ -3273,19 +3250,19 @@ Initialize( * geometry into the "geometry" variable. */ - if (geometry != NULL) { - Tcl_DString buf; + if (geometryObj) { + + Tcl_SetVar2Ex(interp, "geometry", NULL, geometryObj, TCL_GLOBAL_ONLY); - Tcl_SetVar2(interp, "geometry", NULL, geometry, TCL_GLOBAL_ONLY); - Tcl_DStringInit(&buf); - Tcl_DStringAppend(&buf, "wm geometry . ", -1); - Tcl_DStringAppend(&buf, geometry, -1); - code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0); - Tcl_DStringFree(&buf); + cmd = Tcl_NewStringObj("wm geometry .", -1); + Tcl_ListObjAppendElement(NULL, cmd, geometryObj); + Tcl_IncrRefCount(cmd); + code = Tcl_EvalObjEx(interp, cmd, 0); + Tcl_DecrRefCount(cmd); + geometryObj = NULL; if (code != TCL_OK) { goto done; } - geometry = NULL; } /* @@ -3322,10 +3299,6 @@ Initialize( * console window interpreter. */ - Tcl_MutexUnlock(&windowMutex); - if (argv != NULL) { - ckfree(argv); - } code = TkpInit(interp); if (code == TCL_OK) { @@ -3358,12 +3331,10 @@ tkInit", -1, 0); TkCreateThreadExitHandler(DeleteWindowsExitProc, tsdPtr); } - return code; - done: - Tcl_MutexUnlock(&windowMutex); - if (argv != NULL) { - ckfree(argv); + if (value) { + Tcl_DecrRefCount(value); + value = NULL; } return code; } diff --git a/generic/ttk/ttkGenStubs.tcl b/generic/ttk/ttkGenStubs.tcl index 56ba2fa..8047e3f 100644 --- a/generic/ttk/ttkGenStubs.tcl +++ b/generic/ttk/ttkGenStubs.tcl @@ -18,8 +18,6 @@ # + Allow trailing semicolon in function declarations # -package require Tcl 8.4 - namespace eval genStubs { # libraryName -- # diff --git a/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c index 16a8bfe..81a8b64 100644 --- a/generic/ttk/ttkNotebook.c +++ b/generic/ttk/ttkNotebook.c @@ -901,7 +901,7 @@ static int NotebookAddCommand( if (tab->state == TAB_STATE_HIDDEN) { tab->state = TAB_STATE_NORMAL; } - if (ConfigureTab(interp, nb, tab, slaveWindow, objc-4,objv+4) != TCL_OK) { + if (ConfigureTab(interp, nb, tab, slaveWindow, objc-3,objv+3) != TCL_OK) { return TCL_ERROR; } diff --git a/library/button.tcl b/library/button.tcl index b2bafb2..80d8bf9 100644 --- a/library/button.tcl +++ b/library/button.tcl @@ -597,12 +597,25 @@ proc ::tk::ButtonUp w { # w - The name of the widget. proc ::tk::ButtonInvoke w { - if {[$w cget -state] ne "disabled"} { + if {[winfo exists $w] && [$w cget -state] ne "disabled"} { set oldRelief [$w cget -relief] set oldState [$w cget -state] $w configure -state active -relief sunken - update idletasks - after 100 + after 100 [list ::tk::ButtonInvokeEnd $w $oldState $oldRelief] + } +} + +# ::tk::ButtonInvokeEnd -- +# The procedure below is called after a button is invoked through +# the keyboard. It simulate a release of the button via the mouse. +# +# Arguments: +# w - The name of the widget. +# oldState - Old state to be set back. +# oldRelief - Old relief to be set back. + +proc ::tk::ButtonInvokeEnd {w oldState oldRelief} { + if {[winfo exists $w]} { $w configure -state $oldState -relief $oldRelief uplevel #0 [list $w invoke] } diff --git a/library/demos/ixset b/library/demos/ixset index ee6e072..13235de 100644 --- a/library/demos/ixset +++ b/library/demos/ixset @@ -9,7 +9,6 @@ exec wish "$0" ${1+"$@"} # 91/11/23 : pda@masi.ibp.fr, jt@ratp.fr : design # 92/08/01 : pda@masi.ibp.fr : cleaning -package require Tcl 8.4 package require Tk # diff --git a/library/demos/rmt b/library/demos/rmt index 51886de..00bdc9d 100644 --- a/library/demos/rmt +++ b/library/demos/rmt @@ -7,7 +7,6 @@ exec wish "$0" ${1+"$@"} # Tk applications. It allows you to select an application and # then type commands to that application. -package require Tcl 8.4 package require Tk wm title . "Tk Remote Controller" diff --git a/library/demos/states.tcl b/library/demos/states.tcl index 92b1f1e..aeb3d5b 100644 --- a/library/demos/states.tcl +++ b/library/demos/states.tcl @@ -19,6 +19,17 @@ positionWindow $w label $w.msg -font $font -wraplength 4i -justify left -text "A listbox containing the 50 states is displayed below, along with a scrollbar. You can scan the list either using the scrollbar or by scanning. To scan, press button 2 in the widget and drag up or down." pack $w.msg -side top +labelframe $w.justif -text Justification +foreach c {Left Center Right} { + set lower [string tolower $c] + radiobutton $w.justif.$lower -text $c -variable just \ + -relief flat -value $lower -anchor w \ + -command "$w.frame.list configure -justify \$just" \ + -tristatevalue "multi" + pack $w.justif.$lower -side left -pady 2 -fill x +} +pack $w.justif + ## See Code / Dismiss buttons set btns [addSeeDismiss $w.buttons $w] pack $btns -side bottom -fill x diff --git a/library/demos/timer b/library/demos/timer index e10b840..6b61ca4 100644 --- a/library/demos/timer +++ b/library/demos/timer @@ -5,7 +5,6 @@ exec wish "$0" ${1+"$@"} # timer -- # This script generates a counter with start and stop buttons. -package require Tcl 8.4 package require Tk label .counter -text 0.00 -relief raised -width 10 -padx 2m -pady 1m diff --git a/library/demos/widget b/library/demos/widget index 7604341..1d838ad 100644 --- a/library/demos/widget +++ b/library/demos/widget @@ -10,7 +10,6 @@ exec wish "$0" ${1+"$@"} # separate ".tcl" files is this directory, which are sourced by this script as # needed. -package require Tcl 8.5 package require Tk 8.5 package require msgcat diff --git a/library/megawidget.tcl b/library/megawidget.tcl index 9b9be92..aeb1263 100644 --- a/library/megawidget.tcl +++ b/library/megawidget.tcl @@ -29,14 +29,13 @@ package require Tk 8.6 } ::oo::class create ::tk::MegawidgetClass { - variable w hull OptionSpecification options IdleCallbacks + variable w hull options IdleCallbacks constructor args { # Extract the "widget name" from the object name set w [namespace tail [self]] # Configure things - set OptionSpecification [my GetSpecs] - my configure {*}$args + tclParseConfigSpec [my varname options] [my GetSpecs] "" $args # Move the object out of the way of the hull widget rename [self] _tmp @@ -46,7 +45,7 @@ package require Tk 8.6 bind $hull <Destroy> [list [namespace which my] destroy] # Rename things into their final places - rename ::$w theFrame + rename ::$w theWidget rename [self] ::$w # Make the contents @@ -63,28 +62,165 @@ package require Tk 8.6 } } + #################################################################### + # + # MegawidgetClass::configure -- + # + # Implementation of 'configure' for megawidgets. Emulates the operation + # of the standard Tk configure method fairly closely, which makes things + # substantially more complex than they otherwise would be. + # + # This method assumes that the 'GetSpecs' method returns a description + # of all the specifications of the options (i.e., as Tk returns except + # with the actual values removed). It also assumes that the 'options' + # array in the class holds all options; it is up to subclasses to set + # traces on that array if they want to respond to configuration changes. + # + # TODO: allow unambiguous abbreviations. + # method configure args { - tclParseConfigSpec [my varname options] $OptionSpecification "" $args + # Configure behaves differently depending on the number of arguments + set argc [llength $args] + if {$argc == 0} { + return [lmap spec [my GetSpecs] { + lappend spec $options([lindex $spec 0]) + }] + } elseif {$argc == 1} { + set opt [lindex $args 0] + if {[info exists options($opt)]} { + set spec [lsearch -inline -index 0 -exact [my GetSpecs] $opt] + return [linsert $spec end $options($opt)] + } + } elseif {$argc == 2} { + # Special case for where we're setting a single option. This + # avoids some of the costly operations. We still do the [array + # get] as this gives a sufficiently-consistent trace. + set opt [lindex $args 0] + if {[dict exists [array get options] $opt]} { + # Actually set the new value of the option. Use a catch to + # allow a megawidget user to throw an error from a write trace + # on the options array to reject invalid values. + try { + array set options $args + } on error {ret info} { + # Rethrow the error to get a clean stack trace + return -code error -errorcode [dict get $info -errorcode] $ret + } + return + } + } elseif {$argc % 2 == 0} { + # Check that all specified options exist. Any unknown option will + # cause the merged dictionary to be bigger than the options array + set merge [dict merge [array get options] $args] + if {[dict size $merge] == [array size options]} { + # Actually set the new values of the options. Use a catch to + # allow a megawidget user to throw an error from a write trace + # on the options array to reject invalid values + try { + array set options $args + } on error {ret info} { + # Rethrow the error to get a clean stack trace + return -code error -errorcode [dict get $info -errorcode] $ret + } + return + } + # Due to the order of the merge, the unknown options will be at + # the end of the dict. This makes the first unknown option easy to + # find. + set opt [lindex [dict keys $merge] [array size options]] + } else { + set opt [lindex $args end] + return -code error -errorcode [list TK VALUE_MISSING] \ + "value for \"$opt\" missing" + } + return -code error -errorcode [list TK LOOKUP OPTION $opt] \ + "bad option \"$opt\": must be [tclListValidFlags options]" } + + #################################################################### + # + # MegawidgetClass::cget -- + # + # Implementation of 'cget' for megawidgets. Emulates the operation of + # the standard Tk cget method fairly closely. + # + # This method assumes that the 'options' array in the class holds all + # options; it is up to subclasses to set traces on that array if they + # want to respond to configuration reads. + # + # TODO: allow unambiguous abbreviations. + # method cget option { return $options($option) } + #################################################################### + # + # MegawidgetClass::TraceOption -- + # + # Sets up the tracing of an element of the options variable. + # + method TraceOption {option method args} { + set callback [list my $method {*}$args] + trace add variable options($option) write [namespace code $callback] + } + + #################################################################### + # + # MegawidgetClass::GetSpecs -- + # + # Return a list of descriptions of options supported by this + # megawidget. Each option is described by the 4-tuple list, consisting + # of the name of the option, the "option database" name, the "option + # database" class-name, and the default value of the option. These are + # the same values returned by calling the configure method of a widget, + # except without the current values of the options. + # method GetSpecs {} { return { {-takefocus takeFocus TakeFocus {}} } } + #################################################################### + # + # MegawidgetClass::CreateHull -- + # + # Creates the real main widget of the megawidget. This is often a frame + # or toplevel widget, but isn't always (lightweight megawidgets might + # use a content widget directly). + # + # The name of the hull widget is given by the 'w' instance variable. The + # name should be written into the 'hull' instance variable. The command + # created by this method will be renamed. + # method CreateHull {} { return -code error -errorcode {TCL OO ABSTRACT_METHOD} \ "method must be overridden" } + + #################################################################### + # + # MegawidgetClass::Create -- + # + # Creates the content of the megawidget. The name of the widget to + # create the content in will be in the 'hull' instance variable. + # method Create {} { return -code error -errorcode {TCL OO ABSTRACT_METHOD} \ "method must be overridden" } + #################################################################### + # + # MegawidgetClass::WhenIdle -- + # + # Arrange for a method to be called on the current instance when Tk is + # idle. Only one such method call per method will be queued; subsequent + # queuing actions before the callback fires will be silently ignored. + # The additional args will be passed to the callback, and the callbacks + # will be properly cancelled if the widget is destroyed. + # method WhenIdle {method args} { if {![info exists IdleCallbacks($method)]} { set IdleCallbacks($method) [after idle [list \ @@ -97,6 +233,15 @@ package require Tk 8.6 } } +#################################################################### +# +# tk::SimpleWidget -- +# +# Simple megawidget class that makes it easy create widgets that behave +# like a ttk widget. It creates the hull as a ttk::frame and maps the +# state manipulation methods of the overall megawidget to the equivalent +# operations on the ttk::frame. +# ::tk::Megawidget create ::tk::SimpleWidget {} { variable w hull options method GetSpecs {} { @@ -107,12 +252,12 @@ package require Tk 8.6 } method CreateHull {} { set hull [::ttk::frame $w -cursor $options(-cursor)] - trace add variable options(-cursor) write \ - [namespace code {my UpdateCursorOption}] + my TraceOption -cursor UpdateCursorOption } method UpdateCursorOption args { $hull configure -cursor $options(-cursor) } + # Not fixed names, so can't forward method state args { tailcall $hull state {*}$args } @@ -121,6 +266,13 @@ package require Tk 8.6 } } +#################################################################### +# +# tk::FocusableWidget -- +# +# Simple megawidget class that makes a ttk-like widget that has a focus +# ring. +# ::tk::Megawidget create ::tk::FocusableWidget ::tk::SimpleWidget { variable w hull options method GetSpecs {} { @@ -133,8 +285,7 @@ package require Tk 8.6 ttk::frame $w set hull [ttk::entry $w.cHull -takefocus 0 -cursor $options(-cursor)] pack $hull -expand yes -fill both -ipadx 2 -ipady 2 - trace add variable options(-cursor) write \ - [namespace code {my UpdateCursorOption}] + my TraceOption -cursor UpdateCursorOption } } diff --git a/library/scrlbar.tcl b/library/scrlbar.tcl index b7be014..6f1caa2 100644 --- a/library/scrlbar.tcl +++ b/library/scrlbar.tcl @@ -430,6 +430,9 @@ proc ::tk::ScrollTopBottom {w x y} { proc ::tk::ScrollButton2Down {w x y} { variable ::tk::Priv + if {![winfo exists $w]} { + return + } set element [$w identify $x $y] if {[string match {arrow[12]} $element]} { ScrollButtonDown $w $x $y @@ -443,7 +446,9 @@ proc ::tk::ScrollButton2Down {w x y} { # slider drag. update idletasks - $w configure -activerelief sunken - $w activate slider - ScrollStartDrag $w $x $y + if {[winfo exists $w]} { + $w configure -activerelief sunken + $w activate slider + ScrollStartDrag $w $x $y + } } diff --git a/library/spinbox.tcl b/library/spinbox.tcl index 6a5f829..1965ed8 100644 --- a/library/spinbox.tcl +++ b/library/spinbox.tcl @@ -86,10 +86,12 @@ bind Spinbox <B1-Motion> { ::tk::spinbox::Motion %W %x %y } bind Spinbox <Double-1> { + ::tk::spinbox::ArrowPress %W %x %y set tk::Priv(selectMode) word ::tk::spinbox::MouseSelect %W %x sel.first } bind Spinbox <Triple-1> { + ::tk::spinbox::ArrowPress %W %x %y set tk::Priv(selectMode) line ::tk::spinbox::MouseSelect %W %x 0 } @@ -299,6 +301,10 @@ bind Spinbox <B2-Motion> { proc ::tk::spinbox::Invoke {w elem} { variable ::tk::Priv + if {![winfo exists $w]} { + return + } + if {![info exists Priv(outsideElement)]} { $w invoke $elem incr Priv(repeated) @@ -328,6 +334,35 @@ proc ::tk::spinbox::ClosestGap {w x} { incr pos } +# ::tk::spinbox::ArrowPress -- +# This procedure is invoked to handle button-1 presses in buttonup +# or buttondown elements of spinbox widgets. +# +# Arguments: +# w - The spinbox window in which the button was pressed. +# x - The x-coordinate of the button press. +# y - The y-coordinate of the button press. + +proc ::tk::spinbox::ArrowPress {w x y} { + variable ::tk::Priv + + if {[$w cget -state] ne "disabled" && \ + [string match "button*" $Priv(element)]} { + $w selection element $Priv(element) + set Priv(repeated) 0 + set Priv(relief) [$w cget -$Priv(element)relief] + catch {after cancel $Priv(afterId)} + set delay [$w cget -repeatdelay] + if {$delay > 0} { + set Priv(afterId) [after $delay \ + [list ::tk::spinbox::Invoke $w $Priv(element)]] + } + if {[info exists Priv(outsideElement)]} { + unset Priv(outsideElement) + } + } +} + # ::tk::spinbox::ButtonDown -- # This procedure is invoked to handle button-1 presses in spinbox # widgets. It moves the insertion cursor, sets the selection anchor, @@ -336,6 +371,7 @@ proc ::tk::spinbox::ClosestGap {w x} { # Arguments: # w - The spinbox window in which the button was pressed. # x - The x-coordinate of the button press. +# y - The y-coordinate of the button press. proc ::tk::spinbox::ButtonDown {w x y} { variable ::tk::Priv @@ -350,20 +386,7 @@ proc ::tk::spinbox::ButtonDown {w x y} { switch -exact $Priv(element) { "buttonup" - "buttondown" { - if {"disabled" ne [$w cget -state]} { - $w selection element $Priv(element) - set Priv(repeated) 0 - set Priv(relief) [$w cget -$Priv(element)relief] - catch {after cancel $Priv(afterId)} - set delay [$w cget -repeatdelay] - if {$delay > 0} { - set Priv(afterId) [after $delay \ - [list ::tk::spinbox::Invoke $w $Priv(element)]] - } - if {[info exists Priv(outsideElement)]} { - unset Priv(outsideElement) - } - } + ::tk::spinbox::ArrowPress $w $x $y } "entry" { set Priv(selectMode) char @@ -388,6 +411,7 @@ proc ::tk::spinbox::ButtonDown {w x y} { # Arguments: # w - The spinbox window in which the button was pressed. # x - The x-coordinate of the button press. +# y - The y-coordinate of the button press. proc ::tk::spinbox::ButtonUp {w x y} { variable ::tk::Priv @@ -491,6 +515,8 @@ proc ::tk::spinbox::Paste {w x} { # # Arguments: # w - The spinbox window. +# x - The x-coordinate of the mouse. +# y - The y-coordinate of the mouse. proc ::tk::spinbox::Motion {w x y} { variable ::tk::Priv diff --git a/library/tk.tcl b/library/tk.tcl index 946ab7e..54d8ffb 100644 --- a/library/tk.tcl +++ b/library/tk.tcl @@ -10,10 +10,8 @@ # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. -# Insist on running with compatible version of Tcl -package require Tcl 8.6 # Verify that we have Tk binary and script components from the same release -package require -exact Tk 8.6.4 +package require -exact Tk 8.6.5 # Create a ::tk namespace namespace eval ::tk { diff --git a/library/ttk/menubutton.tcl b/library/ttk/menubutton.tcl index 093bb02..2be064c 100644 --- a/library/ttk/menubutton.tcl +++ b/library/ttk/menubutton.tcl @@ -57,7 +57,7 @@ if {[tk windowingsystem] eq "x11"} { bind TMenubutton <ButtonPress-1> \ { %W state pressed ; ttk::menubutton::Popdown %W } bind TMenubutton <ButtonRelease-1> \ - { %W state !pressed } + { if {[winfo exists %W]} { %W state !pressed } } } # PostPosition -- diff --git a/macosx/GNUmakefile b/macosx/GNUmakefile index 02240ed..d0bab1a 100644 --- a/macosx/GNUmakefile +++ b/macosx/GNUmakefile @@ -35,7 +35,7 @@ MANDIR ?= ${PREFIX}/man TCL_BUILD_DIR ?= ${BUILD_DIR}/tcl/${BUILD_STYLE} # location of installed tcl, only used if tcl in TCL_BUILD_DIR can't be found TCL_FRAMEWORK_DIR ?= /Library/Frameworks -TCLSH_DIR ?= ${PREFIX} +TCLSH_DIR ?= ${PREFIX}/bin # set to non-empty value to install manpages in addition to html help: INSTALL_MANPAGES ?= diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c index 59d394e..f4fbc48 100644 --- a/macosx/tkMacOSXButton.c +++ b/macosx/tkMacOSXButton.c @@ -289,10 +289,10 @@ TkpComputeButtonGeometry( if ( butPtr->indicatorOn ) { switch (butPtr->type) { case TYPE_RADIO_BUTTON: - GetThemeMetric(kThemeMetricRadioButtonWidth, &butPtr->indicatorDiameter); + GetThemeMetric(kThemeMetricRadioButtonWidth, (SInt32 *)&butPtr->indicatorDiameter); break; case TYPE_CHECK_BUTTON: - GetThemeMetric(kThemeMetricCheckBoxWidth, &butPtr->indicatorDiameter); + GetThemeMetric(kThemeMetricCheckBoxWidth, (SInt32 *)&butPtr->indicatorDiameter); break; default: break; @@ -318,7 +318,8 @@ TkpComputeButtonGeometry( Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength, butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight); - txtWidth = butPtr->textWidth + DEF_INSET_LEFT + DEF_INSET_RIGHT; + /*Remove extraneous padding around label widgets.*/ + txtWidth = butPtr->textWidth; txtHeight = butPtr->textHeight + DEF_INSET_BOTTOM + DEF_INSET_TOP; charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1); Tk_GetFontMetrics(butPtr->tkfont, &fm); diff --git a/macosx/tkMacOSXDefault.h b/macosx/tkMacOSXDefault.h index 528ea10..65762b7 100644 --- a/macosx/tkMacOSXDefault.h +++ b/macosx/tkMacOSXDefault.h @@ -259,6 +259,7 @@ #define DEF_LISTBOX_HIGHLIGHT_BG NORMAL_BG #define DEF_LISTBOX_HIGHLIGHT BLACK #define DEF_LISTBOX_HIGHLIGHT_WIDTH "0" +#define DEF_LISTBOX_JUSTIFY "left" #define DEF_LISTBOX_RELIEF "solid" #define DEF_LISTBOX_SCROLL_COMMAND "" #define DEF_LISTBOX_LIST_VARIABLE "" diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index f6edb6d..80a7a11 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -1320,7 +1320,7 @@ FontchooserEvent( switch (kind) { case FontchooserClosed: if (fcdPtr->parent != None) { - TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility"); + TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL); fontchooserInterp = NULL; } break; @@ -1343,7 +1343,7 @@ FontchooserEvent( ckfree(tmpv); } } - TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged"); + TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged", NULL); } break; } @@ -1553,7 +1553,7 @@ FontchooserConfigureCmd( [fm setSelectedAttributes:fontPanelFontAttributes isMultiple:NO]; if ([fp isVisible]) { - TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged"); + TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserFontChanged", NULL); } break; case FontchooserCmd: @@ -1616,7 +1616,7 @@ FontchooserShowCmd( } if (![fp isVisible]) { [fm orderFrontFontPanel:NSApp]; - TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility"); + TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL); } fontchooserInterp = interp; diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index 6a0b409..f48538d 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -314,29 +314,35 @@ XCopyPlane( TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; unsigned long imageBackground = gc->background; if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){ - CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap); - CGRect rect = CGRectMake(dest_x, dest_y, width, height); - rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff); - CGContextSaveGState(context); - /* Move the origin of the destination to top left. */ - CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect)); - CGContextScaleCTM(context, 1, -1); - /* Fill with the background color, clipping to the mask. */ - CGContextClipToMask(context, rect, mask); - TkMacOSXSetColorInContext(gc, gc->background, dc.context); - CGContextFillRect(dc.context, rect); - /* Fill with the foreground color, clipping to the intersection of img and mask. */ - CGContextClipToMask(context, rect, img); - TkMacOSXSetColorInContext(gc, gc->foreground, context); - CGContextFillRect(context, rect); - CGContextRestoreGState(context); - CGImageRelease(mask); - CGImageRelease(img); + CGRect srcRect = CGRectMake(src_x, src_y, width, height); + CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap); + CGImageRef submask = CGImageCreateWithImageInRect(img, srcRect); + CGRect rect = CGRectMake(dest_x, dest_y, width, height); + rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff); + CGContextSaveGState(context); + /* Move the origin of the destination to top left. */ + CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect)); + CGContextScaleCTM(context, 1, -1); + /* Fill with the background color, clipping to the mask. */ + CGContextClipToMask(context, rect, submask); + TkMacOSXSetColorInContext(gc, gc->background, dc.context); + CGContextFillRect(context, rect); + /* Fill with the foreground color, clipping to the + intersection of img and mask. */ + CGImageRef subimage = CGImageCreateWithImageInRect(img, srcRect); + CGContextClipToMask(context, rect, subimage); + TkMacOSXSetColorInContext(gc, gc->foreground, context); + CGContextFillRect(context, rect); + CGContextRestoreGState(context); + CGImageRelease(img); + CGImageRelease(mask); + CGImageRelease(submask); + CGImageRelease(subimage); } else { DrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground, CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height), - CGRectMake(src_x, src_y, width, height), - CGRectMake(dest_x, dest_y, width, height)); + CGRectMake(src_x, src_y, width, height), + CGRectMake(dest_x, dest_y, width, height)); CGImageRelease(img); } } else { /* no image */ @@ -393,9 +399,11 @@ TkPutImage( CGImageRef img = CreateCGImageWithXImage(image); if (img) { + /* If the XImage has big pixels, rescale the source dimensions.*/ + int pp = image->pixelpower; DrawCGImage(d, gc, dc.context, img, gc->foreground, gc->background, - CGRectMake(0, 0, image->width, image->height), - CGRectMake(src_x, src_y, width, height), + CGRectMake(0, 0, image->width<<pp, image->height<<pp), + CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp), CGRectMake(dest_x, dest_y, width, height)); CFRelease(img); } else { @@ -786,9 +794,6 @@ DrawCGImage( CGContextDrawImage(context, dstBounds, image); CGContextRestoreGState(context); #endif /* TK_MAC_DEBUG_IMAGE_DRAWING */ - /*if (CGImageIsMask(image)) { - CGContextRestoreGState(context); - }*/ if (subImage) { CFRelease(subImage); } diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index b965a38..33a60f2 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -57,9 +57,7 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt @end @implementation TKApplication -#ifndef __clang__ @synthesize poolProtected = _poolProtected; -#endif @end @implementation TKApplication(TKInit) diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c index 1455688..f14e1b8 100644 --- a/macosx/tkMacOSXNotify.c +++ b/macosx/tkMacOSXNotify.c @@ -270,10 +270,15 @@ TkMacOSXEventsCheckProc( inMode:GetRunLoopMode(modalSession) dequeue:NO]; /* We must not steal any events during LiveResize. */ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 if (testEvent && [[testEvent window] inLiveResize]) { break; } - +#else + if (testEvent && [[[testEvent window] contentView] inLiveResize]) { + break; + } +#endif currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:GetRunLoopMode(modalSession) diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h index 2a411f6..65d60ce 100644 --- a/macosx/tkMacOSXPrivate.h +++ b/macosx/tkMacOSXPrivate.h @@ -276,6 +276,10 @@ VISIBILITY_HIDDEN NSArray *_defaultHelpMenuItems; NSWindow *_windowWithMouse; NSAutoreleasePool *_mainPool; +#ifdef __i386__ + /* The Objective C runtime used on i386 requires this. */ + BOOL _poolProtected; +#endif } @property BOOL poolProtected; @end diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index f026318..9851474 100644 --- a/macosx/tkMacOSXSubwindows.c +++ b/macosx/tkMacOSXSubwindows.c @@ -153,8 +153,6 @@ XMapWindow( if ( [win canBecomeKeyWindow] ) { [win makeKeyAndOrderFront:NSApp]; } - /* Why do we need this? (It is used by Carbon)*/ - [win windowRef]; TkMacOSXApplyWindowAttributes(macWin->winPtr, win); } TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr); @@ -316,7 +314,6 @@ XResizeWindow( display->request++; if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { NSWindow *w = macWin->winPtr->wmInfoPtr->window; - if (w) { NSRect r = [w contentRectForFrameRect:[w frame]]; r.origin.y += r.size.height - height; @@ -360,10 +357,19 @@ XMoveResizeWindow( if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { NSWindow *w = macWin->winPtr->wmInfoPtr->window; if (w) { - NSRect r = NSMakeRect(x + macWin->winPtr->wmInfoPtr->xInParent, - tkMacOSXZeroScreenHeight - (y + - macWin->winPtr->wmInfoPtr->yInParent + height), - width, height); + /* We explicitly convert everything to doubles so we don't get + * surprised (again) by what happens when you do arithmetic with + * unsigned ints. + */ + CGFloat X = (CGFloat)x; + CGFloat Y = (CGFloat)y; + CGFloat Width = (CGFloat)width; + CGFloat Height = (CGFloat)height; + CGFloat XOff = (CGFloat)macWin->winPtr->wmInfoPtr->xInParent; + CGFloat YOff = (CGFloat)macWin->winPtr->wmInfoPtr->yInParent; + NSRect r = NSMakeRect(X + XOff, + tkMacOSXZeroScreenHeight - Y - YOff - Height, + Width, Height); [w setFrame:[w frameRectForContentRect:r] display:YES]; } } else { diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index 3ea2f51..39990e6 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -1788,6 +1788,11 @@ WmForgetCmd( TkWmDeadWindow(winPtr); RemapWindows(winPtr, (MacDrawable *) winPtr->parentPtr->window); + /* + * Make sure wm no longer manages this window + */ + Tk_ManageGeometry(frameWin, NULL, NULL); + winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED); /* diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c index 5d6ffb9..a2d175b 100644 --- a/macosx/tkMacOSXXStubs.c +++ b/macosx/tkMacOSXXStubs.c @@ -805,6 +805,10 @@ XCreateImage( ximage->format = format; ximage->data = data; ximage->obdata = NULL; + /* The default pixelpower is 0. This must be explicitly set to 1 in the + * case of an XImage extracted from a Retina display. + */ + ximage->pixelpower = 0; if (format == ZPixmap) { ximage->bits_per_pixel = 32; @@ -856,7 +860,8 @@ XCreateImage( * Results: * Returns a newly allocated XImage containing the data from the given * rectangle of the given drawable, or NULL if the XImage could not be - * constructed. + * constructed. NOTE: If we are copying from a window on a Retina + * display, the dimensions of the XImage will be 2*width x 2*height. * * Side effects: * None. @@ -885,7 +890,19 @@ XGetImage( int bitmap_pad = 0; int bytes_per_row = 4*width; int size; - TkMacOSXDbgMsg("XGetImage"); + MacDrawable *macDraw = (MacDrawable *) d; + NSWindow *win = TkMacOSXDrawableWindow(d); + /* This code assumes that backing scale factors are integers. Currently + * Retina displays use a scale factor of 2.0 and normal displays use 1.0. + * We do not support any other values here. + */ + int scalefactor = 1; + if (win && [win respondsToSelector:@selector(backingScaleFactor)]) { + scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1; + } + int scaled_height = height * scalefactor; + int scaled_width = width * scalefactor; + if (format == ZPixmap) { if (width == 0 || height == 0) { /* This happens all the time. @@ -894,7 +911,7 @@ XGetImage( return NULL; } - bitmap_rep = BitmapRepFromDrawableRect(d, x, y,width, height); + bitmap_rep = BitmapRepFromDrawableRect(d, x, y, width, height); bitmap_fmt = [bitmap_rep bitmapFormat]; if ( bitmap_rep == Nil || @@ -913,7 +930,9 @@ XGetImage( if ( [bitmap_rep isPlanar ] == 0 && [bitmap_rep samplesPerPixel] == 4 ) { bytes_per_row = [bitmap_rep bytesPerRow]; - size = bytes_per_row*height; + assert(bytes_per_row == 4 * scaled_width); + assert([bitmap_rep bytesPerPlane] == bytes_per_row * scaled_height); + size = bytes_per_row*scaled_height; image_data = (char*)[bitmap_rep bitmapData]; if ( image_data ) { int row, n, m; @@ -924,7 +943,7 @@ XGetImage( */ if (bitmap_fmt == 0) { /* BGRA */ - for (row=0, n=0; row<height; row++, n+=bytes_per_row) { + for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) { for (m=n; m<n+bytes_per_row; m+=4) { *(bitmap+m) = *(image_data+m+2); *(bitmap+m+1) = *(image_data+m+1); @@ -934,7 +953,7 @@ XGetImage( } } else { /* ABGR */ - for (row=0, n=0; row<height; row++, n+=bytes_per_row) { + for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) { for (m=n; m<n+bytes_per_row; m+=4) { *(bitmap+m) = *(image_data+m+3); *(bitmap+m+1) = *(image_data+m+2); @@ -947,7 +966,11 @@ XGetImage( } if (bitmap) { imagePtr = XCreateImage(display, NULL, depth, format, offset, - (char*)bitmap, width, height, bitmap_pad, bytes_per_row); + (char*)bitmap, scaled_width, scaled_height, + bitmap_pad, bytes_per_row); + if (scalefactor == 2) { + imagePtr->pixelpower = 1; + } [ns_image removeRepresentation:bitmap_rep]; /*releases the rep*/ [ns_image release]; } diff --git a/macosx/ttkMacOSXTheme.c b/macosx/ttkMacOSXTheme.c index 4753a40..f9611c5 100644 --- a/macosx/ttkMacOSXTheme.c +++ b/macosx/ttkMacOSXTheme.c @@ -298,7 +298,7 @@ static void TabElementSize( void *clientData, void *elementRecord, Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) { - *heightPtr = GetThemeMetric(kThemeMetricLargeTabHeight, heightPtr); + GetThemeMetric(kThemeMetricLargeTabHeight, (SInt32 *)heightPtr); *paddingPtr = Ttk_MakePadding(0, 0, 0, 2); } diff --git a/tests/all.tcl b/tests/all.tcl index 7f57dc2..d15e5ca 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -9,9 +9,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -package require Tcl 8.5 -package require tcltest 2.2 package require Tk ;# This is the Tk test suite; fail early if no Tk! +package require tcltest 2.2 tcltest::configure {*}$argv tcltest::configure -testdir [file normalize [file dirname [info script]]] tcltest::configure -loadfile \ diff --git a/tests/bevel.tcl b/tests/bevel.tcl index 531def0..4af60f3 100644 --- a/tests/bevel.tcl +++ b/tests/bevel.tcl @@ -147,14 +147,12 @@ set ind [.t.t index end] xxxx} {} SSSSS sol100 {xxxx x} {} SSSSSSSSSSSSSSSSSS sol100 {x xxx} {} SSSSSSSSS sol100 xxxx {} -} .t.t insert end "\n\nA thinner border is continuous" .t.t insert end { xxxx} {} SSSSS sol12 {xxxx x} {} SSSSSSSSSSSSSSSSSS sol12 {x xxx} {} SSSSSSSSS sol12 xxxx {} -} .t.t tag add big $ind end diff --git a/tests/bind.test b/tests/bind.test index 474771d..892ba36 100644 --- a/tests/bind.test +++ b/tests/bind.test @@ -34,6 +34,14 @@ proc unsetBindings {} { bind .t <Enter> {} } +# move the mouse pointer away of the testing area +# otherwise some spurious events may pollute the tests +toplevel .top +wm geometry .top 50x50-50-50 +update +event generate .top <Button-1> -warp 1 +update +destroy .top test bind-1.1 {bind command} -body { bind @@ -6093,6 +6101,19 @@ test bind-31.7 {virtual event user_data field - unshared, asynch} -setup { destroy .t.f } -result {{} {} {TestUserData >b<}} +test bind-32 {-warp, window was destroyed before the idle callback DoWarp} -setup { + frame .t.f + pack .t.f + focus -force .t.f + update +} -body { + event generate .t.f <Button-1> -warp 1 + event generate .t.f <ButtonRelease-1> + destroy .t.f + update ; # shall simply not crash +} -cleanup { +} -result {} + # cleanup cleanupTests diff --git a/tests/button.test b/tests/button.test index 984fd43..708fc30 100644 --- a/tests/button.test +++ b/tests/button.test @@ -3750,7 +3750,7 @@ test button-12.1 {button widget vs hidden commands} -body { destroy .b } -result {1} -test button-13.1 {size behaviouor: label} -setup { +test button-13.1 {size behavior: label} -setup { label .a -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} label .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} label .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} @@ -3769,7 +3769,7 @@ test button-13.1 {size behaviouor: label} -setup { } -cleanup { destroy .a .b .c } -result {1 1 1} -test button-13.2 {size behaviouor: label} -setup { +test button-13.2 {size behavior: label} -setup { label .a -borderwidth 2 -highlightthickness 2 -font {Arial 20} label .b -borderwidth 2 -highlightthickness 2 -font {Arial 20} label .c -borderwidth 2 -highlightthickness 2 -font {Arial 20} @@ -3789,7 +3789,7 @@ test button-13.2 {size behaviouor: label} -setup { destroy .a .b .c } -result {1 1 1} -test button-13.3 {size behaviouor: button} -setup { +test button-13.3 {size behavior: button} -setup { button .a -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} button .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} button .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} @@ -3808,7 +3808,7 @@ test button-13.3 {size behaviouor: button} -setup { } -cleanup { destroy .a .b .c } -result {1 1 1} -test button-13.4 {size behaviouor: button} -setup { +test button-13.4 {size behavior: button} -setup { button .a -borderwidth 2 -highlightthickness 2 -font {Arial 20} button .b -borderwidth 2 -highlightthickness 2 -font {Arial 20} button .c -borderwidth 2 -highlightthickness 2 -font {Arial 20} @@ -3828,7 +3828,7 @@ test button-13.4 {size behaviouor: button} -setup { destroy .a .b .c } -result {1 1 1} -test button-13.5 {size behaviouor: radiobutton} -setup { +test button-13.5 {size behavior: radiobutton} -setup { radiobutton .a -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} radiobutton .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} radiobutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} @@ -3848,7 +3848,7 @@ test button-13.5 {size behaviouor: radiobutton} -setup { destroy .a .b .c } -result {1 1 1} -test button-13.6 {size behaviouor: radiobutton} -setup { +test button-13.6 {size behavior: radiobutton} -setup { radiobutton .a -borderwidth 2 -highlightthickness 2 -font {Arial 20} radiobutton .b -borderwidth 2 -highlightthickness 2 -font {Arial 20} radiobutton .c -borderwidth 2 -highlightthickness 2 -font {Arial 20} @@ -3868,7 +3868,7 @@ test button-13.6 {size behaviouor: radiobutton} -setup { destroy .a .b .c } -result {1 1 1} -test button-13.7 {size behaviouor: checkbutton} -setup { +test button-13.7 {size behavior: checkbutton} -setup { checkbutton .a -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} checkbutton .b -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold} @@ -3888,7 +3888,7 @@ test button-13.7 {size behaviouor: checkbutton} -setup { destroy .a .b .c } -result {1 1 1} -test button-13.8 {size behaviouor: checkbutton} -setup { +test button-13.8 {size behavior: checkbutton} -setup { checkbutton .a -borderwidth 2 -highlightthickness 2 -font {Arial 20} checkbutton .b -borderwidth 2 -highlightthickness 2 -font {Arial 20} checkbutton .c -borderwidth 2 -highlightthickness 2 -font {Arial 20} @@ -3908,6 +3908,24 @@ test button-13.8 {size behaviouor: checkbutton} -setup { destroy .a .b .c } -result {1 1 1} +test button-14.1 {bug fix: [011706ec42] tk::ButtonInvoke unsafe wrt widget destruction} -body { + proc destroy_button {} { + if {[winfo exists .top.b]} { + destroy .top.b + } + } + toplevel .top + button .top.b -text Foo -command destroy_button + bind .top.b <space> destroy_button + pack .top.b + focus -force .top.b + update + event generate .top.b <space> + update ; # shall not trigger error invalid command name ".top.b" +} -cleanup { + destroy .top.b .top +} -result {} + imageFinish cleanupTests return diff --git a/tests/constraints.tcl b/tests/constraints.tcl index 6402753..e0486ff 100644 --- a/tests/constraints.tcl +++ b/tests/constraints.tcl @@ -5,8 +5,6 @@ if {[namespace exists tk::test]} { return } -package require Tcl 8.4 - package require Tk 8.4 tk appname tktest wm title . tktest diff --git a/tests/entry.test b/tests/entry.test index 9c30b00..d27ffb5 100644 --- a/tests/entry.test +++ b/tests/entry.test @@ -1896,12 +1896,12 @@ test entry-6.12 {EntryComputeGeometry procedure} -constraints { fonts } -setup { catch {destroy .e} - entry .e -font $fixed -bd 2 -relief raised -width 20 + entry .e -font {Courier -12} -bd 2 -relief raised -width 20 pack .e } -body { .e insert end "012\t456\t" update - list [.e index @81] [.e index @82] [.e index @116] [.e index @117] + list [.e index @80] [.e index @81] [.e index @115] [.e index @116] } -cleanup { destroy .e } -result {6 7 7 8} diff --git a/tests/listbox.test b/tests/listbox.test index f50267e..407420c 100644 --- a/tests/listbox.test +++ b/tests/listbox.test @@ -57,6 +57,7 @@ proc mkPartial {{w .partial}} { # like border width have predictable values. option add *Listbox.borderWidth 2 +option add *Listbox.selectBorderWidth 1 option add *Listbox.highlightThickness 2 option add *Listbox.font {Helvetica -12 bold} @@ -203,6 +204,21 @@ test listbox-1.31 {configuration options} -body { } -cleanup { .l configure -highlightthickness [lindex [.l configure -highlightthickness] 3] } -result {0 0} +test listbox-1.32.1 {configuration options} -setup { + set res {} +} -body { + .l configure -justify left + set res [list [lindex [.l configure -justify] 4] [.l cget -justify]] + .l configure -justify center + lappend res [lindex [.l configure -justify] 4] [.l cget -justify] + .l configure -justify right + lappend res [lindex [.l configure -justify] 4] [.l cget -justify] +} -cleanup { + .l configure -justify [lindex [.l configure -justify] 3] +} -result {left left center center right right} +test listbox-1.32.2 {configuration options} -body { + .l configure -justify bogus +} -returnCodes error -result {bad justification "bogus": must be left, right, or center} test listbox-1.33 {configuration options} -body { .l configure -relief groove list [lindex [.l configure -relief] 4] [.l cget -relief] @@ -441,6 +457,58 @@ test listbox-3.18 {ListboxWidgetCmd procedure, "bbox" option, partial last line} mkPartial list [.partial.l bbox 3] [.partial.l bbox 4] } -result {{5 56 24 14} {5 73 23 14}} +test listbox-3.18a {ListboxWidgetCmd procedure, "bbox" option, justified} -constraints { + fonts +} -setup { + destroy .top.l .top + unset -nocomplain res +} -body { + toplevel .top + listbox .top.l -justify left + .top.l insert end Item1 LongerItem2 MuchLongerItem3 + pack .top.l + update + lappend res [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2] + .top.l configure -justify center + lappend res [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2] + .top.l configure -justify right + lappend res [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2] +} -cleanup { + destroy .top.l .top + unset -nocomplain res +} -result [list \ + {5 5 34 14} {5 22 74 14} {5 39 106 14} \ + {58 5 34 14} {38 22 74 14} {22 39 106 14} \ + {111 5 34 14} {71 22 74 14} {39 39 106 14} \ +] +test listbox-3.18b {ListboxWidgetCmd procedure, "bbox" option, justified, non-default borderwidth} -setup { + destroy .top.l .top + unset -nocomplain lres res +} -body { + # This test checks whether all "x" values from bbox for different size + # items with different justification settings are all positive or zero + # This checks a bit the calculation of this x value with non-default + # borders widths of the listbox + toplevel .top + listbox .top.l -justify left -borderwidth 17 -highlightthickness 19 -selectborderwidth 22 + .top.l insert end Item1 LongerItem2 MuchLongerItem3 + .top.l selection set 1 + pack .top.l + update + lappend lres [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2] + .top.l configure -justify center + lappend lres [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2] + .top.l configure -justify right + lappend lres [.top.l bbox 0] [.top.l bbox 1] [.top.l bbox 2] + set res 1 + for {set i 0} {$i < [llength $lres]} {incr i 4} { + set res [expr {$res * [expr {[lindex $lres $i] >= 0}] }] + } + set res +} -cleanup { + destroy .top.l .top + unset -nocomplain lres res +} -result {1} test listbox-3.19 {ListboxWidgetCmd procedure, "cget" option} -body { .l cget } -returnCodes error -result {wrong # args: should be ".l cget option"} @@ -455,7 +523,7 @@ test listbox-3.22 {ListboxWidgetCmd procedure, "cget" option} -body { } -result {0} test listbox-3.23 {ListboxWidgetCmd procedure, "configure" option} -body { llength [.l configure] -} -result {27} +} -result {28} test listbox-3.24 {ListboxWidgetCmd procedure, "configure" option} -body { .l configure -gorp } -returnCodes error -result {unknown option "-gorp"} @@ -3102,6 +3170,7 @@ test listbox-31.2 {<<ListboxSelect>> event on lost selection} -setup { focus -force .l event generate .l <1> -x 5 -y 5 ; # <<ListboxSelect>> fires selection clear ; # <<ListboxSelect>> fires again + update set res } -cleanup { destroy .l diff --git a/tests/option.file3 b/tests/option.file3 index 87f41ae..146cfd9 100755 --- a/tests/option.file3 +++ b/tests/option.file3 @@ -1,4 +1,4 @@ -! This file is a sample option (resource) database used to test +! This file is a sample option (resource) database used to test ! Tk's option-handling capabilities. ! Comment line \ diff --git a/tests/panedwindow.test b/tests/panedwindow.test index 666ed9c..ee184ce 100644 --- a/tests/panedwindow.test +++ b/tests/panedwindow.test @@ -4955,6 +4955,38 @@ test panedwindow-23.30 {ConfigurePanes, -hide works} -setup { } -cleanup { deleteWindows } -result {1 1 1 0 39 40 40 1 130 1 0 1 1 40 40 40 42 130} +test panedwindow-23.30a {ConfigurePanes, hidden panes are unmapped} -setup { + deleteWindows +} -body { + panedwindow .p1 -sashrelief raised + panedwindow .p2 -sashrelief raised + label .l1 -text Label1 + label .l2 -text Label2 + label .l3 -text Label3 + .p2 add .l2 -sticky nsew + .p2 add .l3 -sticky nsew + .p1 add .p2 -sticky nsew + .p1 add .l1 -sticky nsew + pack .p1 -side top -expand 1 -fill both + update + set result [list] + lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \ + [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]] + .p2 paneconfigure .l1 -hide 1 + update + lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \ + [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]] + .p1 paneconfigure .p2 -hide 1 + update + lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \ + [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]] + .p1 paneconfigure .p2 -hide 0 + update + lappend result [list [winfo ismapped .p1] [winfo ismapped .p2] \ + [winfo ismapped .l1] [winfo ismapped .l2] [winfo ismapped .l3]] +} -cleanup { + deleteWindows +} -result {{1 1 1 1 1} {1 1 0 1 1} {1 0 0 0 0} {1 1 0 1 1}} test panedwindow-23.31 {ConfigurePanes, -hide works, last pane stretches} -setup { deleteWindows } -body { diff --git a/tests/safe.test b/tests/safe.test index e7ed6c7..69a67ba 100644 --- a/tests/safe.test +++ b/tests/safe.test @@ -187,7 +187,7 @@ test safe-5.1 {loading Tk in safe interps without master's clearance} -body { interp eval $i {load {} Tk} } -cleanup { safe::interpDelete $i -} -returnCodes error -result {not allowed to start Tk by master's safe::TkInit} +} -returnCodes error -result {not allowed} test safe-5.2 {multi-level Tk loading with clearance} -setup { set safeParent [safe::interpCreate] } -body { diff --git a/tests/scale.test b/tests/scale.test index a8d08a8..8c14ed4 100644 --- a/tests/scale.test +++ b/tests/scale.test @@ -1396,6 +1396,114 @@ test scale-19 {Bug [3529885fff] - Click in through goes in wrong direction} \ } \ -result {1.0 1.0 1.0 1.0} +test scale-20.1 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 1} -setup { + catch {destroy .s} + set res {} + set commandedVar -1 +} -body { + scale .s -from 1 -to 50 -command {set commandedVar} + pack .s + update ; # -command callback shall NOT fire + set res [list [.s get] $commandedVar] +} -cleanup { + destroy .s +} -result {1 -1} +test scale-20.2 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 2} -setup { + catch {destroy .s} + set res {} + set commandedVar -1 + set scaleVar 7 +} -body { + scale .s -from 1 -to 50 -variable scaleVar -command {set commandedVar} + pack .s + update ; # -command callback shall NOT fire + set res [list [.s get] $commandedVar] +} -cleanup { + destroy .s +} -result {7 -1} +test scale-20.3 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 3} -setup { + catch {destroy .s} + set res {} + set commandedVar -1 +} -body { + scale .s -from 1 -to 50 + .s set 10 + .s configure -command {set commandedVar} + pack .s + update ; # -command callback shall NOT fire + set res [list [.s get] $commandedVar] +} -cleanup { + destroy .s +} -result {10 -1} +test scale-20.4 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 4} -setup { + catch {destroy .s} + set res {} + set commandedVar -1 +} -body { + scale .s -from 1 -to 50 -command {set commandedVar} + .s set 10 + pack .s + update ; # -command callback shall fire + set res [list [.s get] $commandedVar] +} -cleanup { + destroy .s +} -result {10 10} +test scale-20.5 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 5} -setup { + catch {destroy .s} + set res {} + set commandedVar -1 +} -body { + scale .s -from 1 -to 50 + pack .s + .s set 10 + .s configure -command {set commandedVar} + update ; # -command callback shall NOT fire + set res [list [.s get] $commandedVar] +} -cleanup { + destroy .s +} -result {10 -1} +test scale-20.6 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 6} -setup { + catch {destroy .s} + set res {} + set commandedVar -1 +} -body { + scale .s -from 1 -to 50 + pack .s + .s configure -command {set commandedVar} + .s set 10 + update ; # -command callback shall fire + set res [list [.s get] $commandedVar] +} -cleanup { + destroy .s +} -result {10 10} +test scale-20.7 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 7} -setup { + catch {destroy .s} + set res {} + set commandedVar -1 +} -body { + scale .s -from 1 -to 50 -command {set commandedVar} + pack .s + .s set 10 + update ; # -command callback shall fire + set res [list [.s get] $commandedVar] +} -cleanup { + destroy .s +} -result {10 10} +test scale-20.8 {Bug [2262543fff] - Scale widget unexpectedly fires command callback, case 8} -setup { + catch {destroy .s} + set res {} + set commandedVar -1 + set scaleVar 7 +} -body { + scale .s -from 1 -to 50 -variable scaleVar -command {set commandedVar} + pack .s + .s set 10 + update ; # -command callback shall fire + set res [list [.s get] $commandedVar] +} -cleanup { + destroy .s +} -result {10 10} + option clear # cleanup diff --git a/tests/scrollbar.test b/tests/scrollbar.test index 3b16821..bd14067 100644 --- a/tests/scrollbar.test +++ b/tests/scrollbar.test @@ -662,6 +662,43 @@ test scrollbar-10.2 {<MouseWheel> event on scrollbar} -constraints {win|unix} -s destroy .t .s } -result {1.4} +test scrollbar-11.1 {bug fix: [011706ec42] Scrollbar unsafe wrt widget destruction} -body { + proc destroy_scrollbar {} { + if {[winfo exists .top.s]} { + destroy .top.s + } + } + toplevel .top + scrollbar .top.s + bind .top.s <2> {destroy_scrollbar} + pack .top.s + focus -force .top.s + update + event generate .top.s <2> + update ; # shall not trigger error invalid command name ".top.s" +} -cleanup { + destroy .top.s .top +} -result {} +test scrollbar-11.2 {bug fix: [011706ec42] Scrollbar unsafe wrt widget destruction} -body { + proc destroy_scrollbar {{y 0}} { + if {[winfo exists .top.s]} { + destroy .top.s + } + } + toplevel .top + wm minsize .top 50 400 + update + scrollbar .top.s + bind .top.s <2> {after idle destroy_scrollbar} + pack .top.s -expand true -fill y + focus -force .top.s + update + event generate .top.s <2> -x 2 -y [expr {[winfo height .top.s] / 2}] + update ; # shall not trigger error invalid command name ".top.s" +} -cleanup { + destroy .top.s .top +} -result {} + catch {destroy .s} catch {destroy .t} diff --git a/tests/text.test b/tests/text.test index 52a21af..720afbe 100644 --- a/tests/text.test +++ b/tests/text.test @@ -3053,6 +3053,25 @@ test text-11a.41 {"sync" "pendingsync" and <<WidgetViewSync>>} -setup { destroy .top.yt .top } -result {Sync:0 Pending:1 Sync:1 Pending:0} +test text-11a.51 {<<WidgetViewSync>> calls TkSendVirtualEvent(), + NOT Tk_HandleEvent(). + Bug [b362182e45704dd7bbd6aed91e48122035ea3d16]} -setup { + destroy .top.t .top +} -body { + set res {} + toplevel .top + pack [text .top.t] + for {set i 1} {$i < 10000} {incr i} { + .top.t insert end "Hello world!\n" + } + bind .top.t <<WidgetViewSync>> {destroy .top.t} + .top.t tag add mytag 1.5 8000.8 ; # shall not crash + update + set res "Still doing fine!" +} -cleanup { + destroy .top.t .top +} -result {Still doing fine!} + test text-12.1 {TextWidgetCmd procedure, "index" option} -setup { text .t } -body { @@ -3673,10 +3692,9 @@ Line 4" list [.t tag ranges sel] [.t get 1.0 end] } -cleanup { destroy .t -} -result {{1.0 4.0} {Line 1 +} -result {{1.0 3.5} {Line 1 abcde 12345 - }} test text-19.9 {DeleteChars procedure} -body { text .t @@ -6189,7 +6207,7 @@ test text-27.2 {TextEditCmd procedure, argument parsing} -body { .t edit gorp } -cleanup { destroy .t -} -returnCodes {error} -result {bad edit option "gorp": must be modified, redo, reset, separator, or undo} +} -returnCodes {error} -result {bad edit option "gorp": must be canundo, canredo, modified, redo, reset, separator, or undo} test text-27.3 {TextEditUndo procedure, undoing changes} -body { text .t -undo 1 pack .t @@ -6281,7 +6299,7 @@ test text-27.11 {TextEditCmd procedure, set modified flag repeat} -setup { # Shouldn't require [update idle] to trigger event [Bug 1809538] lappend ::retval [.t edit modified] .t edit modified 1 - update idletasks + update lappend ::retval [.t edit modified] .t edit modified 1 ; # binding should only fire once [Bug 1799782] update idletasks @@ -6296,6 +6314,7 @@ test text-27.12 {<<Modified>> virtual event} -body { bind .t <<Modified>> "set ::retval modified" update idletasks .t insert end "nothing special\n" + update return $::retval } -cleanup { destroy .t @@ -6306,6 +6325,7 @@ test text-27.13 {<<Modified>> virtual event - insert before Modified} -body { bind .t <<Modified>> { set ::retval [.t get 1.0 end-1c] } update idletasks .t insert end "nothing special" + update return $::retval } -cleanup { destroy .t @@ -6318,10 +6338,26 @@ test text-27.14 {<<Modified>> virtual event - delete before Modified} -body { .t insert end "nothing special" .t edit modified 0 .t delete 1.0 1.2 + update set ::retval } -cleanup { destroy .t } -result {thing special} +test text-27.14a {<<Modified>> virtual event - propagation to peers} -body { +# Bug [fd3a4dc111], <<Modified>> event is not always sent to peers + set ::retval 0 + text .t -undo 1 + .t peer create .tt + pack .t .tt + bind .t <<Modified>> {incr ::retval} + bind .tt <<Modified>> {incr ::retval} + .t insert end "This increments ::retval once for each peer, i.e. twice." + .t edit modified 0 ; # shall increment twice as well, not just once + update + set ::retval +} -cleanup { + destroy .t .tt +} -result {4} test text-27.15 {<<Selection>> virtual event} -body { set ::retval no_selection pack [text .t -undo 1] @@ -6329,6 +6365,7 @@ test text-27.15 {<<Selection>> virtual event} -body { update idletasks .t insert end "nothing special\n" .t tag add sel 1.0 1.1 + update set ::retval } -cleanup { destroy .t @@ -6346,6 +6383,21 @@ test text-27.16 {-maxundo configuration option} -body { } -cleanup { destroy .t } -result "line 1\n\n" +test text-27.16a {undo configuration options with peers} -body { + text .t -undo 1 -autoseparators 0 -maxundo 100 + .t peer create .tt + set res [.t cget -undo] + lappend res [.tt cget -undo] + lappend res [.t cget -autoseparators] + lappend res [.tt cget -autoseparators] + lappend res [.t cget -maxundo] + lappend res [.tt cget -maxundo] + .t insert end "The undo stack is common between peers" + lappend res [.t edit canundo] + lappend res [.tt edit canundo] +} -cleanup { + destroy .t +} -result {1 1 0 0 100 100 1 1} test text-27.17 {bug fix 1536735 - undo with empty text} -body { text .t -undo 1 set r [.t edit modified] @@ -6368,7 +6420,7 @@ test text-27.18 {patch 1469210 - inserting after undo} -setup { } -cleanup { destroy .t } -result 1 -test text-25.19 {patch 1669632 (i) - undo after <Control-1>} -setup { +test text-27.19 {patch 1669632 (i) - undo after <Control-1>} -setup { destroy .t } -body { text .t -undo 1 @@ -6382,7 +6434,7 @@ test text-25.19 {patch 1669632 (i) - undo after <Control-1>} -setup { } -cleanup { destroy .t } -result WORLD -test text-25.20 {patch 1669632 (iv) - undo after <<SelectNone>>} -setup { +test text-27.20 {patch 1669632 (iv) - undo after <<SelectNone>>} -setup { destroy .top .top.t } -body { toplevel .top @@ -6401,7 +6453,7 @@ test text-25.20 {patch 1669632 (iv) - undo after <<SelectNone>>} -setup { } -cleanup { destroy .top.t .top } -result HELLO -test text-25.21 {patch 1669632 (vii) - <<Undo>> shall not remove separators} -setup { +test text-27.21 {patch 1669632 (vii) - <<Undo>> shall not remove separators} -setup { destroy .t } -body { text .t -undo 1 @@ -6417,7 +6469,7 @@ test text-25.21 {patch 1669632 (vii) - <<Undo>> shall not remove separators} -se } -cleanup { destroy .t } -result "This WORLD is an example text" -test text-25.22 {patch 1669632 (v) - <<Clear>> is atomic} -setup { +test text-27.22 {patch 1669632 (v) - <<Clear>> is atomic} -setup { destroy .t } -body { toplevel .top @@ -6437,7 +6489,7 @@ test text-25.22 {patch 1669632 (v) - <<Clear>> is atomic} -setup { } -cleanup { destroy .top.t .top } -result "This A an example text" - test text-25.23 {patch 1669632 (v) - <<Cut>> is atomic} -setup { + test text-27.23 {patch 1669632 (v) - <<Cut>> is atomic} -setup { destroy .t } -body { toplevel .top @@ -6457,6 +6509,75 @@ test text-25.22 {patch 1669632 (v) - <<Clear>> is atomic} -setup { } -cleanup { destroy .top.t .top } -result "This A an example text" +test text-27.24 {TextEditCmd procedure, canundo and canredo} -setup { + destroy .t + set res {} +} -body { + text .t -undo false -autoseparators false + lappend res [.t edit canundo] [.t edit canredo] + .t configure -undo true + lappend res [.t edit canundo] [.t edit canredo] + .t insert end "DO\n" + .t edit separator + .t insert end "IT\n" + .t insert end "YOURSELF\n" + .t edit separator + lappend res [.t edit canundo] [.t edit canredo] + .t edit undo + lappend res [.t edit canundo] [.t edit canredo] + .t configure -undo false + lappend res [.t edit canundo] [.t edit canredo] + .t configure -undo true + lappend res [.t edit canundo] [.t edit canredo] + .t edit redo + lappend res [.t edit canundo] [.t edit canredo] +} -cleanup { + destroy .t +} -result {0 0 0 0 1 0 1 1 0 0 1 1 1 0} +test text-27.25 {<<UndoStack>> virtual event} -setup { + destroy .t + set res {} + set nbUS 0 +} -body { + text .t -undo false -autoseparators false + bind .t <<UndoStack>> {incr nbUS} + update ; lappend res $nbUS + .t configure -undo true + update ; lappend res $nbUS + .t insert end "DO\n" + .t edit separator + .t insert end "IT\n" + .t insert end "YOURSELF\n" + .t edit separator + .t insert end "MAN\n" + .t edit separator + update ; lappend res $nbUS + .t edit undo + update ; lappend res $nbUS + .t edit redo + update ; lappend res $nbUS + .t edit undo + update ; lappend res $nbUS + .t edit undo + update ; lappend res $nbUS + .t edit undo + update ; lappend res $nbUS + .t edit redo + update ; lappend res $nbUS + .t edit redo + update ; lappend res $nbUS + .t edit redo + update ; lappend res $nbUS + .t edit undo + update ; lappend res $nbUS + .t edit undo + update ; lappend res $nbUS + .t edit reset + update ; lappend res $nbUS +} -cleanup { + destroy .t +} -result {0 0 1 2 3 4 4 5 6 6 7 8 8 9} + test text-28.1 {bug fix - 624372, ControlUtfProc long lines} -body { pack [text .t -wrap none] diff --git a/tests/textDisp.test b/tests/textDisp.test index caba769..99401c2 100644 --- a/tests/textDisp.test +++ b/tests/textDisp.test @@ -657,7 +657,7 @@ test textDisp-4.9 {UpdateDisplayInfo, filling in extra vertical space} {textfont update .t delete 15.0 end list [.t bbox 7.0] [.t bbox 12.0] -} [list [list [expr {$hlth + $px + $bw}] [expr {$hlth + $py + $bw + $fixedHeight}] $fixedWidth $fixedHeight] [list [expr {$hlth + $px + $bw}] [expr {$hlth + $py + $bw + 6 * $fixedHeight}] $fixedWidth $fixedHeight]] +} [list [list [expr {$hlth + $px + $bw}] [expr {$hlth + $py + $bw + 2 * $fixedHeight}] $fixedWidth $fixedHeight] [list [expr {$hlth + $px + $bw}] [expr {$hlth + $py + $bw + 7 * $fixedHeight}] $fixedWidth $fixedHeight]] test textDisp-4.10 {UpdateDisplayInfo, filling in extra vertical space} { .t delete 1.0 end .t insert end "1\n2\n3\n4\n5\nLine 6 is such a long line that it wraps around.\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17" @@ -666,7 +666,7 @@ test textDisp-4.10 {UpdateDisplayInfo, filling in extra vertical space} { .t delete 13.0 end update list [.t index @0,0] $tk_textRelayout $tk_textRedraw -} {6.0 {13.0 7.0 6.40 6.20 6.0} {6.0 6.20 6.40 7.0 13.0}} +} {5.0 {12.0 7.0 6.40 6.20 6.0 5.0} {5.0 6.0 6.20 6.40 7.0 12.0}} test textDisp-4.11 {UpdateDisplayInfo, filling in extra vertical space} { .t delete 1.0 end .t insert end "1\n2\n3\n4\n5\nLine 6 is such a long line that it wraps around, not once but really quite a few times.\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17" @@ -675,7 +675,7 @@ test textDisp-4.11 {UpdateDisplayInfo, filling in extra vertical space} { .t delete 14.0 end update list [.t index @0,0] $tk_textRelayout $tk_textRedraw -} {6.60 {14.0 7.0 6.80 6.60} {6.60 6.80 7.0 14.0}} +} {6.40 {13.0 7.0 6.80 6.60 6.40} {6.40 6.60 6.80 7.0 13.0}} test textDisp-4.12 {UpdateDisplayInfo, filling in extra vertical space} { .t delete 1.0 end .t insert end "1\n2\n3\n4\n5\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16" @@ -1181,16 +1181,15 @@ test textDisp-8.12 {TkTextChanged, moving the insert cursor redraws only past an .t mark set insert 3.8 ; # within the same line update lappend res $tk_textRedraw - # This last one is tricky: correct result really is {2.0 3.0} when - # calling .t mark set insert, two calls to TkTextChanged are done: - # (a) to redraw the line of the past position of the cursor - # (b) to redraw the line of the new position of the cursor - # During (a) the display line showing the cursor gets unlinked, - # which leads TkTextChanged in (b) to schedule a redraw starting - # one line _before_ the line containing the insert cursor. This is - # because during (b) findDLine cannot return the display line the - # cursor is in since this display line was just unlinked in (a). -} {{8.0 9.0} {8.0 12.0} {8.0 12.0} {3.0 8.0} {2.0 3.0}} +} {{8.0 9.0} {8.0 12.0} {8.0 12.0} {3.0 8.0} {3.0 4.0}} +test textDisp-8.13 {TkTextChanged, used to crash, see [06c1433906]} { + .t delete 1.0 end + .t insert 1.0 \nLine2\nLine3\n + update + .t insert 3.0 "" + .t delete 1.0 2.0 + update idletasks +} {} test textDisp-9.1 {TkTextRedrawTag} { .t configure -wrap char @@ -3698,7 +3697,7 @@ test textDisp-28.1 {"yview" option with bizarre scroll command} { set result [.t2.t index @0,0] update lappend result [.t2.t index @0,0] -} {6.0 2.0} +} {6.0 1.0} test textDisp-29.1 {miscellaneous: lines wrap but are still too long} {textfonts} { catch {destroy .t2} diff --git a/tests/textTag.test b/tests/textTag.test index fed073a..88081d0 100644 --- a/tests/textTag.test +++ b/tests/textTag.test @@ -168,6 +168,17 @@ test textTag-1.17 {configuration options} -constraints { } -cleanup { .t tag configure x -lmargin2 [lindex [.t tag configure x -lmargin2] 3] } -returnCodes error -result {bad screen distance "bad"} +test textTag-1.17a {tag configuration options} -body { + .t tag configure x -lmargincolor lightgreen + .t tag cget x -lmargincolor +} -cleanup { + .t tag configure x -lmargincolor [lindex [.t tag configure x -lmargincolor] 3] +} -result {lightgreen} +test textTag-1.17b {configuration options} -body { + .t tag configure x -lmargincolor non-existent +} -cleanup { + .t tag configure x -lmargincolor [lindex [.t tag configure x -lmargincolor] 3] +} -returnCodes error -result {unknown color name "non-existent"} test textTag-1.18 {tag configuration options} -constraints { haveCourier12 } -body { @@ -198,6 +209,17 @@ test textTag-1.21 {configuration options} -constraints { } -cleanup { .t tag configure x -overstrike [lindex [.t tag configure x -overstrike] 3] } -returnCodes error -result {expected boolean value but got "stupid"} +test textTag-1.21a {tag configuration options} -body { + .t tag configure x -overstrikefg red + .t tag cget x -overstrikefg +} -cleanup { + .t tag configure x -overstrikefg [lindex [.t tag configure x -overstrikefg] 3] +} -result {red} +test textTag-1.21b {configuration options} -body { + .t tag configure x -overstrikefg stupid +} -cleanup { + .t tag configure x -overstrikefg [lindex [.t tag configure x -overstrikefg] 3] +} -returnCodes error -result {unknown color name "stupid"} test textTag-1.22 {tag configuration options} -constraints { haveCourier12 } -body { @@ -228,6 +250,39 @@ test textTag-1.25 {configuration options} -constraints { } -cleanup { .t tag configure x -rmargin [lindex [.t tag configure x -rmargin] 3] } -returnCodes error -result {bad screen distance "bad"} +test textTag-1.25a {tag configuration options} -body { + .t tag configure x -rmargincolor darkblue + .t tag cget x -rmargincolor +} -cleanup { + .t tag configure x -rmargincolor [lindex [.t tag configure x -rmargincolor] 3] +} -result {darkblue} +test textTag-1.25b {configuration options} -body { + .t tag configure x -rmargincolor non-existent +} -cleanup { + .t tag configure x -rmargincolor [lindex [.t tag configure x -rmargincolor] 3] +} -returnCodes error -result {unknown color name "non-existent"} +test textTag-1.25c {tag configuration options} -body { + .t tag configure x -selectbackground #012345 + .t tag cget x -selectbackground +} -cleanup { + .t tag configure x -selectbackground [lindex [.t tag configure x -selectbackground] 3] +} -result {#012345} +test textTag-1.25d {configuration options} -body { + .t tag configure x -selectbackground non-existent +} -cleanup { + .t tag configure x -selectbackground [lindex [.t tag configure x -selectbackground] 3] +} -returnCodes error -result {unknown color name "non-existent"} +test textTag-1.25e {tag configuration options} -body { + .t tag configure x -selectforeground #012345 + .t tag cget x -selectforeground +} -cleanup { + .t tag configure x -selectforeground [lindex [.t tag configure x -selectforeground] 3] +} -result {#012345} +test textTag-1.25f {configuration options} -body { + .t tag configure x -selectforeground non-existent +} -cleanup { + .t tag configure x -selectforeground [lindex [.t tag configure x -selectforeground] 3] +} -returnCodes error -result {unknown color name "non-existent"} test textTag-1.26 {tag configuration options} -constraints { haveCourier12 } -body { @@ -303,6 +358,17 @@ test textTag-1.35 {configuration options} -constraints { } -cleanup { .t tag configure x -underline [lindex [.t tag configure x -underline] 3] } -returnCodes error -result {expected boolean value but got "stupid"} +test textTag-1.36 {tag configuration options} -body { + .t tag configure x -underlinefg red + .t tag cget x -underlinefg +} -cleanup { + .t tag configure x -underlinefg [lindex [.t tag configure x -underlinefg] 3] +} -result {red} +test textTag-1.37 {configuration options} -body { + .t tag configure x -underlinefg stupid +} -cleanup { + .t tag configure x -underlinefg [lindex [.t tag configure x -underlinefg] 3] +} -returnCodes error -result {unknown color name "stupid"} test textTag-2.1 {TkTextTagCmd - "add" option} -constraints { @@ -559,6 +625,13 @@ test textTag-5.4 {TkTextTagCmd - "configure" option} -constraints { } -cleanup { .t tag delete x } -result {-underline {} {} {} yes} +test textTag-5.4a {TkTextTagCmd - "configure" option} -body { + .t tag delete x + .t tag configure x -underlinefg lightgreen + .t tag configure x -underlinefg +} -cleanup { + .t tag delete x +} -result {-underlinefg {} {} {} lightgreen} test textTag-5.5 {TkTextTagCmd - "configure" option} -constraints { haveCourier12 } -body { @@ -568,6 +641,13 @@ test textTag-5.5 {TkTextTagCmd - "configure" option} -constraints { } -cleanup { .t tag delete x } -result {on} +test textTag-5.5a {TkTextTagCmd - "configure" option} -body { + .t tag delete x + .t tag configure x -overstrikefg lightgreen + .t tag configure x -overstrikefg +} -cleanup { + .t tag delete x +} -result {-overstrikefg {} {} {} lightgreen} test textTag-5.6 {TkTextTagCmd - "configure" option} -constraints { haveCourier12 } -body { @@ -625,16 +705,19 @@ test textTag-5.12 {TkTextTagCmd - "configure" option} -constraints { } -cleanup { .t tag delete x } -returnCodes error -result {bad screen distance "1.0q"} -test textTag-5.13 {TkTextTagCmd - "configure" option} -constraints { - haveCourier12 -} -body { +test textTag-5.13 {TkTextTagCmd - "configure" option} -body { .t tag delete x - .t tag configure x -lmargin1 2 -lmargin2 4 -rmargin 5 + .t tag configure x -lmargin1 2 -lmargin2 4 -rmargin 5 \ + -lmargincolor darkblue -rmargincolor lightgreen list [.t tag configure x -lmargin1] [.t tag configure x -lmargin2] \ - [.t tag configure x -rmargin] + [.t tag configure x -rmargin] [.t tag configure x -lmargincolor] \ + [.t tag configure x -rmargincolor] } -cleanup { .t tag delete x -} -result {{-lmargin1 {} {} {} 2} {-lmargin2 {} {} {} 4} {-rmargin {} {} {} 5}} +} -result [list {-lmargin1 {} {} {} 2} {-lmargin2 {} {} {} 4} \ + {-rmargin {} {} {} 5} \ + {-lmargincolor {} {} {} darkblue} {-rmargincolor {} {} {} lightgreen} \ + ] test textTag-5.14 {TkTextTagCmd - "configure" option} -constraints { haveCourier12 } -body { @@ -651,6 +734,12 @@ test textTag-5.15 {TkTextTagCmd - "configure" option} -constraints { } -cleanup { .t tag delete x } -returnCodes error -result {bad screen distance "gorp"} +test textTag-5.15a {TkTextTagCmd - "configure" option} -body { + .t tag delete x + .t tag configure x -lmargincolor rainbow +} -cleanup { + .t tag delete x +} -returnCodes error -result {unknown color name "rainbow"} test textTag-5.16 {TkTextTagCmd - "configure" option} -constraints { haveCourier12 } -body { @@ -659,6 +748,12 @@ test textTag-5.16 {TkTextTagCmd - "configure" option} -constraints { } -cleanup { .t tag delete x } -returnCodes error -result {bad screen distance "140.1.1"} +test textTag-5.16a {TkTextTagCmd - "configure" option} -body { + .t tag delete x + .t tag configure x -rmargincolor rainbow +} -cleanup { + .t tag delete x +} -returnCodes error -result {unknown color name "rainbow"} .t tag delete x test textTag-5.17 {TkTextTagCmd - "configure" option} -constraints { haveCourier12 @@ -713,7 +808,52 @@ test textTag-5.22 {TkTextTagCmd - "configure" option} -constraints { .t tag configure sel -borderwidth {} .t cget -selectborderwidth } -result {} - +test textTag-5.23 {TkTextTagCmd - "configure" option} -body { + set x {} + # when [.t tag cget sel -selectbackground] == "", mirroring happens between + # the text widget option -selectbackground + # and the tag option -background + .t tag configure sel -selectbackground {} + .t configure -selectbackground black + .t tag configure sel -background yellow + lappend x [.t cget -selectbackground] + .t tag configure sel -background orange + .t configure -selectbackground blue + lappend x [.t tag cget sel -background] + # when [.t tag cget sel -selectbackground] != "", mirroring happens between + # the text widget option -selectbackground + # and the tag option -selectbackground + .t tag configure sel -selectbackground green + .t configure -selectbackground red + lappend x [.t tag cget sel -selectbackground] + .t configure -selectbackground black + .t tag configure sel -selectbackground white + lappend x [.t cget -selectbackground] + return $x +} -result {yellow blue red white} +test textTag-5.24 {TkTextTagCmd - "configure" option} -body { + set x {} + # when [.t tag cget sel -selectforeground] == "", mirroring happens between + # the text widget option -selectforeground + # and the tag option -foreground + .t tag configure sel -selectforeground {} + .t configure -selectforeground black + .t tag configure sel -foreground yellow + lappend x [.t cget -selectforeground] + .t tag configure sel -foreground orange + .t configure -selectforeground blue + lappend x [.t tag cget sel -foreground] + # when [.t tag cget sel -selectforeground] != "", mirroring happens between + # the text widget option -selectforeground + # and the tag option -selectforeground + .t tag configure sel -selectforeground green + .t configure -selectforeground red + lappend x [.t tag cget sel -selectforeground] + .t configure -selectforeground black + .t tag configure sel -selectforeground white + lappend x [.t cget -selectforeground] + return $x +} -result {yellow blue red white} test textTag-6.1 {TkTextTagCmd - "delete" option} -constraints { haveCourier12 diff --git a/tests/ttk/all.tcl b/tests/ttk/all.tcl index da2e316..f03cd56 100644 --- a/tests/ttk/all.tcl +++ b/tests/ttk/all.tcl @@ -9,9 +9,8 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -package require Tcl 8.5 -package require tcltest 2.2 package require Tk ;# This is the Tk test suite; fail early if no Tk! +package require tcltest 2.2 tcltest::configure {*}$argv tcltest::configure -testdir [file normalize [file dirname [info script]]] tcltest::configure -loadfile \ diff --git a/tests/ttk/checkbutton.test b/tests/ttk/checkbutton.test index e18ff32..6b79287 100644 --- a/tests/ttk/checkbutton.test +++ b/tests/ttk/checkbutton.test @@ -45,4 +45,20 @@ test checkbutton-1.6 "Checkbutton default variable" -body { lappend result [info exists .cb] [set .cb] [.cb state] } -result [list .cb 0 alternate 1 on selected 1 off {}] +# Bug [109865fa01] +test checkbutton-1.7 "Button destroyed by click" -body { + proc destroy_button {} { + destroy .top + } + toplevel .top + ttk::menubutton .top.mb -text Button -style TLabel + bind .top.mb <ButtonRelease-1> destroy_button + pack .top.mb + focus -force .top.mb + update + event generate .top.mb <1> + event generate .top.mb <ButtonRelease-1> + update ; # shall not trigger error invalid command name ".top.b" +} -result {} + tcltest::cleanupTests diff --git a/tests/ttk/notebook.test b/tests/ttk/notebook.test index cdce020..3a2a6ff 100644 --- a/tests/ttk/notebook.test +++ b/tests/ttk/notebook.test @@ -468,6 +468,27 @@ test notebook-1817596-3 "insert/configure" -body { } -result [list [list .nb.l2 .nb.l0 .nb.l1] L2 L0 L1] -cleanup { destroy .nb } +test notebook-readd-1 "add same widget twice" -body { + pack [ttk::notebook .nb] + .nb add [ttk::button .nb.b1] -text "Button" + .nb add .nb.b1 + .nb tabs +} -result [list .nb.b1] -cleanup { destroy .nb } + +test notebook-readd-2 "add same widget twice, with options" -body { + pack [ttk::notebook .nb] + .nb add [ttk::button .nb.b1] -text "Tab label" + .nb add .nb.b1 -text "Changed tab label" + .nb tabs +} -result [list .nb.b1] -cleanup { destroy .nb } + +test notebook-readd-3 "insert same widget twice, with options" -body { + pack [ttk::notebook .nb] + .nb insert end [ttk::button .nb.b1] -text "Tab label" + .nb insert end .nb.b1 -text "Changed tab label" + .nb tabs +} -result [list .nb.b1] -cleanup { destroy .nb } + # See #1343984 test notebook-1343984-1 "don't autoselect on destroy - setup" -body { diff --git a/tests/wm.test b/tests/wm.test index 1aa0779..afcc2cd 100644 --- a/tests/wm.test +++ b/tests/wm.test @@ -2276,6 +2276,32 @@ test wm-forget-1.4 "pack into unmapped toplevel causes crash" -body { deleteWindows } -result {} +test wm-forget-2 {bug [e9112ef96e] - [wm forget] doesn't completely} -setup { + catch {destroy .l .f.b .f} + set res {} +} -body { + label .l -text "Top Dot" + frame .f + button .f.b -text Hello -command "puts Hello!" + pack .l -side top + pack .f.b + pack .f -side bottom + update + set res [winfo manager .f] + pack forget .f + update + lappend res [winfo manager .f] + wm manage .f + update + lappend res [winfo manager .f] + wm forget .f + update + lappend res [winfo manager .f] +} -cleanup { + destroy .l .f.b .f + unset res +} -result {pack {} wm {}} + # FIXME: # Test delivery of virtual events to the WM. We could check to see if the diff --git a/unix/configure b/unix/configure index 8f9a4ac..5ffc3fa 100755 --- a/unix/configure +++ b/unix/configure @@ -1338,7 +1338,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu TK_VERSION=8.6 TK_MAJOR_VERSION=8 TK_MINOR_VERSION=6 -TK_PATCH_LEVEL=".4" +TK_PATCH_LEVEL=".5" VERSION=${TK_VERSION} LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv" diff --git a/unix/configure.in b/unix/configure.in index 5a18d46..cb412af 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -25,7 +25,7 @@ m4_ifdef([SC_USE_CONFIG_HEADERS], [ TK_VERSION=8.6 TK_MAJOR_VERSION=8 TK_MINOR_VERSION=6 -TK_PATCH_LEVEL=".4" +TK_PATCH_LEVEL=".5" VERSION=${TK_VERSION} LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv" diff --git a/unix/tk.spec b/unix/tk.spec index af982f7..e43e28e 100644 --- a/unix/tk.spec +++ b/unix/tk.spec @@ -4,7 +4,7 @@ Name: tk Summary: Tk graphical toolkit for the Tcl scripting language. -Version: 8.6.4 +Version: 8.6.5 Release: 2 License: BSD Group: Development/Languages diff --git a/unix/tkUnixDefault.h b/unix/tkUnixDefault.h index d214aa5..2c3854d 100644 --- a/unix/tkUnixDefault.h +++ b/unix/tkUnixDefault.h @@ -221,6 +221,7 @@ #define DEF_LISTBOX_HIGHLIGHT_BG NORMAL_BG #define DEF_LISTBOX_HIGHLIGHT BLACK #define DEF_LISTBOX_HIGHLIGHT_WIDTH "1" +#define DEF_LISTBOX_JUSTIFY "left" #define DEF_LISTBOX_RELIEF "sunken" #define DEF_LISTBOX_SCROLL_COMMAND "" #define DEF_LISTBOX_LIST_VARIABLE "" diff --git a/unix/tkUnixRFont.c b/unix/tkUnixRFont.c index ab2ed4a..36e5462 100644 --- a/unix/tkUnixRFont.c +++ b/unix/tkUnixRFont.c @@ -14,6 +14,8 @@ #include <X11/Xft/Xft.h> #include <ctype.h> +#define MAX_CACHED_COLORS 16 + typedef struct { XftFont *ftFont; XftFont *ft0Font; @@ -23,6 +25,11 @@ typedef struct { } UnixFtFace; typedef struct { + XftColor color; + int next; +} UnixFtColorList; + +typedef struct { TkFont font; /* Stuff used by generic font package. Must be * first in structure. */ UnixFtFace *faces; @@ -33,7 +40,9 @@ typedef struct { Display *display; int screen; XftDraw *ftDraw; - XftColor color; + int ncolors; + int firstColor; + UnixFtColorList colors[MAX_CACHED_COLORS]; } UnixFtFont; /* @@ -289,11 +298,8 @@ InitFont( fontPtr->display = Tk_Display(tkwin); fontPtr->screen = Tk_ScreenNumber(tkwin); fontPtr->ftDraw = 0; - fontPtr->color.color.red = 0; - fontPtr->color.color.green = 0; - fontPtr->color.color.blue = 0; - fontPtr->color.color.alpha = 0xffff; - fontPtr->color.pixel = 0xffffffff; + fontPtr->ncolors = 0; + fontPtr->firstColor = -1; /* * Fill in platform-specific fields of TkFont. @@ -737,6 +743,89 @@ TkpMeasureCharsInContext( maxLength, flags, lengthPtr); } +/* + *---------------------------------------------------------------------- + * + * LookUpColor -- + * + * Convert a pixel value to an XftColor. This can be slow due to the + * need to call XQueryColor, which involves a server round-trip. To + * avoid that, a least-recently-used cache of up to MAX_CACHED_COLORS + * is kept, in the form of a linked list. The returned color is moved + * to the front of the list, so repeatedly asking for the same one + * should be fast. + * + * Results: + * A pointer to the XftColor structure for the requested color is + * returned. + * + * Side effects: + * The converted color is stored in a cache in the UnixFtFont structure. The cache + * can hold at most MAX_CACHED_COLORS colors. If no more slots are available, the least + * recently used color is replaced with the new one. + *---------------------------------------------------------------------- + */ + +static XftColor * +LookUpColor(Display *display, /* Display to lookup colors on */ + UnixFtFont *fontPtr, /* Font to search for cached colors */ + unsigned long pixel) /* Pixel value to translate to XftColor */ +{ + int i, last = -1, last2 = -1; + XColor xcolor; + + for (i = fontPtr->firstColor; + i >= 0; last2 = last, last = i, i = fontPtr->colors[i].next) { + + if (pixel == fontPtr->colors[i].color.pixel) { + /* + * Color found in cache. Move it to the front of the list and return it. + */ + if (last >= 0) { + fontPtr->colors[last].next = fontPtr->colors[i].next; + fontPtr->colors[i].next = fontPtr->firstColor; + fontPtr->firstColor = i; + } + + return &fontPtr->colors[i].color; + } + } + + /* + * Color wasn't found, so it needs to be added to the cache. + * If a spare slot is available, it can be put there. If not, last + * will now point to the least recently used color, so replace that one. + */ + + if (fontPtr->ncolors < MAX_CACHED_COLORS) { + last2 = -1; + last = fontPtr->ncolors++; + } + + /* + * Translate the pixel value to a color. Needs a server round-trip. + */ + xcolor.pixel = pixel; + XQueryColor(display, DefaultColormap(display, fontPtr->screen), &xcolor); + + fontPtr->colors[last].color.color.red = xcolor.red; + fontPtr->colors[last].color.color.green = xcolor.green; + fontPtr->colors[last].color.color.blue = xcolor.blue; + fontPtr->colors[last].color.color.alpha = 0xffff; + fontPtr->colors[last].color.pixel = pixel; + + /* + * Put at the front of the list. + */ + if (last2 >= 0) { + fontPtr->colors[last2].next = fontPtr->colors[last].next; + } + fontPtr->colors[last].next = fontPtr->firstColor; + fontPtr->firstColor = last; + + return &fontPtr->colors[last].color; +} + #define NUM_SPEC 1024 void @@ -760,7 +849,7 @@ Tk_DrawChars( const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */ UnixFtFont *fontPtr = (UnixFtFont *) tkfont; XGCValues values; - XColor xcolor; + XftColor *xftcolor; int clen, nspec, xStart = x; XftGlyphFontSpec specs[NUM_SPEC]; XGlyphInfo metrics; @@ -782,16 +871,7 @@ Tk_DrawChars( Tk_DeleteErrorHandler(handler); } XGetGCValues(display, gc, GCForeground, &values); - if (values.foreground != fontPtr->color.pixel) { - xcolor.pixel = values.foreground; - XQueryColor(display, DefaultColormap(display, fontPtr->screen), - &xcolor); - fontPtr->color.color.red = xcolor.red; - fontPtr->color.color.green = xcolor.green; - fontPtr->color.color.blue = xcolor.blue; - fontPtr->color.color.alpha = 0xffff; - fontPtr->color.pixel = values.foreground; - } + xftcolor = LookUpColor(display, fontPtr, values.foreground); if (tsdPtr->clipRegion != None) { XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion); } @@ -823,14 +903,14 @@ Tk_DrawChars( y += metrics.yOff; nspec++; if (nspec == NUM_SPEC) { - XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, + XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec); nspec = 0; } } } if (nspec) { - XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec); + XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec); } doUnderlineStrikeout: @@ -892,7 +972,7 @@ TkDrawAngledChars( const int minCoord = -1000; /* Should be good enough... */ UnixFtFont *fontPtr = (UnixFtFont *) tkfont; XGCValues values; - XColor xcolor; + XftColor *xftcolor; int xStart = x, yStart = y; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); @@ -919,16 +999,7 @@ TkDrawAngledChars( } XGetGCValues(display, gc, GCForeground, &values); - if (values.foreground != fontPtr->color.pixel) { - xcolor.pixel = values.foreground; - XQueryColor(display, DefaultColormap(display, fontPtr->screen), - &xcolor); - fontPtr->color.color.red = xcolor.red; - fontPtr->color.color.green = xcolor.green; - fontPtr->color.color.blue = xcolor.blue; - fontPtr->color.color.alpha = 0xffff; - fontPtr->color.pixel = values.foreground; - } + xftcolor = LookUpColor(display, fontPtr, values.foreground); if (tsdPtr->clipRegion != None) { XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion); } @@ -967,7 +1038,7 @@ TkDrawAngledChars( * this information... but we'll be ready when it does! */ - XftDrawGlyphs(fontPtr->ftDraw, &fontPtr->color, currentFtFont, + XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont, originX, originY, glyphs, nglyph); } originX = ROUND16(x); @@ -984,7 +1055,7 @@ TkDrawAngledChars( glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c); } if (nglyph) { - XftDrawGlyphs(fontPtr->ftDraw, &fontPtr->color, currentFtFont, + XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont, originX, originY, glyphs, nglyph); } #else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */ @@ -1008,16 +1079,7 @@ TkDrawAngledChars( Tk_DeleteErrorHandler(handler); } XGetGCValues(display, gc, GCForeground, &values); - if (values.foreground != fontPtr->color.pixel) { - xcolor.pixel = values.foreground; - XQueryColor(display, DefaultColormap(display, fontPtr->screen), - &xcolor); - fontPtr->color.color.red = xcolor.red; - fontPtr->color.color.green = xcolor.green; - fontPtr->color.color.blue = xcolor.blue; - fontPtr->color.color.alpha = 0xffff; - fontPtr->color.pixel = values.foreground; - } + xftcolor = LookUpColor(display, fontPtr, values.foreground); if (tsdPtr->clipRegion != None) { XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion); } @@ -1051,14 +1113,14 @@ TkDrawAngledChars( y += metrics.yOff*cosA - metrics.xOff*sinA; nspec++; if (nspec == NUM_SPEC) { - XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, + XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec); nspec = 0; } } } if (nspec) { - XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec); + XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec); } #endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */ diff --git a/unix/tkUnixWm.c b/unix/tkUnixWm.c index 612270c..19ac86c 100644 --- a/unix/tkUnixWm.c +++ b/unix/tkUnixWm.c @@ -1826,6 +1826,11 @@ WmForgetCmd( ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED); RemapWindows(winPtr, winPtr->parentPtr); + /* + * Make sure wm no longer manages this window + */ + Tk_ManageGeometry(frameWin, NULL, NULL); + /* * Flags (above) must be cleared before calling TkMapTopFrame (below). */ diff --git a/win/configure b/win/configure index 18efa23..cbac248 100755 --- a/win/configure +++ b/win/configure @@ -1312,7 +1312,7 @@ SHELL=/bin/sh TK_VERSION=8.6 TK_MAJOR_VERSION=8 TK_MINOR_VERSION=6 -TK_PATCH_LEVEL=".4" +TK_PATCH_LEVEL=".5" VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION #------------------------------------------------------------------------ diff --git a/win/configure.in b/win/configure.in index 709b97f..0ff9304 100644 --- a/win/configure.in +++ b/win/configure.in @@ -14,7 +14,7 @@ SHELL=/bin/sh TK_VERSION=8.6 TK_MAJOR_VERSION=8 TK_MINOR_VERSION=6 -TK_PATCH_LEVEL=".4" +TK_PATCH_LEVEL=".5" VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION #------------------------------------------------------------------------ diff --git a/win/makefile.vc b/win/makefile.vc index ae43eb6..6f61327 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -961,7 +961,7 @@ install-binaries: !if !$(STATIC_BUILD)
@echo creating package index
@type << > $(OUT_DIR)\pkgIndex.tcl
-if {[catch {package present Tcl $(TCL_PATCH_LEVEL)}]} { return }
+if {[catch {package present Tcl 8.6.0}]} { return }
if {($$::tcl_platform(platform) eq "unix") && ([info exists ::env(DISPLAY)]
|| ([info exists ::argv] && ("-display" in $$::argv)))} {
package ifneeded Tk $(TK_PATCH_LEVEL) [list load [file join $$dir .. .. bin libtk$(TK_DOTVERSION).dll] Tk]
diff --git a/win/tkWinDefault.h b/win/tkWinDefault.h index c52cc4d..f389075 100644 --- a/win/tkWinDefault.h +++ b/win/tkWinDefault.h @@ -224,6 +224,7 @@ #define DEF_LISTBOX_HIGHLIGHT_BG NORMAL_BG #define DEF_LISTBOX_HIGHLIGHT HIGHLIGHT #define DEF_LISTBOX_HIGHLIGHT_WIDTH "1" +#define DEF_LISTBOX_JUSTIFY "left" #define DEF_LISTBOX_RELIEF "sunken" #define DEF_LISTBOX_SCROLL_COMMAND "" #define DEF_LISTBOX_LIST_VARIABLE "" diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index d7f63fb..a7d8c7d 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -674,19 +674,25 @@ static void LoadShellProcs() * processing functions are used to cope with keyboard navigation of * controls.) * - * Here is one solution. After returning, we poll the message queue for - * 1/4s looking for WM_LBUTTON up messages. If we see one it's consumed. - * If we get a WM_LBUTTONDOWN message, then we exit early, since the user - * must be doing something new. This fix only works for the current - * application, so the problem will still occur if the open dialog - * happens to be over another applications button. However this is a - * fairly rare occurrance. + * Here is one solution. After returning, we flush all mouse events + * for 1/4 second. In 8.6.5 and earlier, the code used to + * poll the message queue consuming WM_LBUTTONUP messages. + * On seeing a WM_LBUTTONDOWN message, it would exit early, since the user + * must be doing something new. However this early exit does not work + * on Vista and later because the Windows sends both BUTTONDOWN and + * BUTTONUP after the DBLCLICK instead of just BUTTONUP as on XP. + * Rather than try and figure out version specific sequences, we + * ignore all mouse events in that interval. + * + * This fix only works for the current application, so the problem will + * still occur if the open dialog happens to be over another applications + * button. However this is a fairly rare occurrance. * * Results: * None. * * Side effects: - * Consumes an unwanted BUTTON messages. + * Consumes unwanted mouse related messages. * *------------------------------------------------------------------------- */ @@ -698,10 +704,7 @@ EatSpuriousMessageBugFix(void) DWORD nTime = GetTickCount() + 250; while (GetTickCount() < nTime) { - if (PeekMessageA(&msg, 0, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE)){ - break; - } - PeekMessageA(&msg, 0, WM_LBUTTONUP, WM_LBUTTONUP, PM_REMOVE); + PeekMessage(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE); } } @@ -1113,7 +1116,7 @@ ParseOFNOptions( if (strcmp(Tcl_GetString(objv[i]), "-xpstyle")) goto error_return; if (i + 1 == objc) { - Tcl_SetResult(interp, "value for \"-xpstyle\" missing", TCL_STATIC); + Tcl_SetObjResult(interp, Tcl_NewStringObj("value for \"-xpstyle\" missing", -1)); Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL); goto error_return; } @@ -1281,9 +1284,8 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, int oldMode; if (tsdPtr->newFileDialogsState != FDLG_STATE_USE_NEW) { - /* XXX - should be an assert but Tcl does not seem to have one? */ - Tcl_SetResult(interp, "Internal error: GetFileNameVista: IFileDialog API not available", TCL_STATIC); - return TCL_ERROR; + Tcl_Panic("Internal error: GetFileNameVista: IFileDialog API not available"); + return TCL_ERROR; } /* @@ -1425,6 +1427,7 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); hr = fdlgIf->lpVtbl->Show(fdlgIf, hWnd); Tcl_SetServiceMode(oldMode); + EatSpuriousMessageBugFix(); /* * Ensure that hWnd is enabled, because it can happen that we have updated @@ -3145,13 +3148,13 @@ HookProc( if (IsWindow(hwndCtrl)) { EnableWindow(hwndCtrl, FALSE); } - TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility"); + TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL); return 1; /* we handled the message */ } if (WM_DESTROY == msg) { phd->hwnd = NULL; - TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility"); + TkSendVirtualEvent(phd->parent, "TkFontchooserVisibility", NULL); return 0; } @@ -3169,7 +3172,7 @@ HookProc( ApplyLogfont(phd->interp, phd->cmdObj, hdc, &lf); } if (phd && phd->parent) { - TkSendVirtualEvent(phd->parent, "TkFontchooserFontChanged"); + TkSendVirtualEvent(phd->parent, "TkFontchooserFontChanged", NULL); } return 1; } @@ -3481,7 +3484,7 @@ FontchooserShowCmd( ApplyLogfont(hdPtr->interp, hdPtr->cmdObj, hdc, &lf); } if (hdPtr->parent) { - TkSendVirtualEvent(hdPtr->parent, "TkFontchooserFontChanged"); + TkSendVirtualEvent(hdPtr->parent, "TkFontchooserFontChanged", NULL); } } Tcl_SetServiceMode(oldMode); diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c index 4593928..8e14669 100644 --- a/win/tkWinMenu.c +++ b/win/tkWinMenu.c @@ -155,7 +155,7 @@ static void DrawWindowsSystemBitmap(Display *display, Drawable drawable, GC gc, const RECT *rectPtr, int bitmapID, int alignFlags); static void FreeID(WORD commandID); -static char * GetEntryText(TkMenuEntry *mePtr); +static char * GetEntryText(TkMenu *menuPtr, TkMenuEntry *mePtr); static void GetMenuAccelGeometry(TkMenu *menuPtr, TkMenuEntry *mePtr, Tk_Font tkfont, const Tk_FontMetrics *fmPtr, int *widthPtr, @@ -486,6 +486,7 @@ TkpDestroyMenuEntry( static char * GetEntryText( + TkMenu *menuPtr, /* The menu considered. */ TkMenuEntry *mePtr) /* A pointer to the menu entry. */ { char *itemText; @@ -506,7 +507,7 @@ GetEntryText( int i; const char *label = (mePtr->labelPtr == NULL) ? "" : Tcl_GetString(mePtr->labelPtr); - const char *accel = (mePtr->accelPtr == NULL) ? "" + const char *accel = ((menuPtr->menuType == MENUBAR) || (mePtr->accelPtr == NULL)) ? "" : Tcl_GetString(mePtr->accelPtr); const char *p, *next; Tcl_DString itemString; @@ -605,7 +606,7 @@ ReconfigureWindowsMenu( continue; } - itemText = GetEntryText(mePtr); + itemText = GetEntryText(menuPtr, mePtr); if ((menuPtr->menuType == MENUBAR) || (menuPtr->menuFlags & MENU_SYSTEM_MENU)) { Tcl_WinUtfToTChar(itemText, -1, &translatedText); @@ -1287,7 +1288,17 @@ TkWinHandleMenuEvent( if (menuPtr != NULL) { long entryIndex = LOWORD(*pwParam); - mePtr = NULL; + if ((menuPtr->menuType == MENUBAR) && menuPtr->tearoff) { + /* + * Windows passes the entry index starting at 0 for + * the first menu entry. However this entry #0 is the + * tearoff entry for Tk (the menu has -tearoff 1), + * which is ignored for MENUBAR menues on Windows. + */ + + entryIndex++; + } + mePtr = NULL; if (flags != 0xFFFF) { if ((flags&MF_POPUP) && (entryIndex<menuPtr->numEntries)) { mePtr = menuPtr->entries[entryIndex]; @@ -1502,12 +1513,12 @@ GetMenuAccelGeometry( *heightPtr = fmPtr->linespace; if (mePtr->type == CASCADE_ENTRY) { *widthPtr = 0; - } else if (mePtr->accelPtr == NULL) { - *widthPtr = 0; - } else { + } else if ((menuPtr->menuType != MENUBAR) && (mePtr->accelPtr != NULL)) { const char *accel = Tcl_GetString(mePtr->accelPtr); *widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength); + } else { + *widthPtr = 0; } } @@ -1763,6 +1774,10 @@ DrawMenuEntryAccelerator( int leftEdge = x + mePtr->indicatorSpace + mePtr->labelWidth; const char *accel; + if (menuPtr->menuType == MENUBAR) { + return; + } + if (mePtr->accelPtr != NULL) { accel = Tcl_GetString(mePtr->accelPtr); } else { diff --git a/win/tkWinWm.c b/win/tkWinWm.c index 768ee69..4e7618d 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -3673,6 +3673,12 @@ WmForgetCmd( winPtr->flags &= ~(TK_TOP_HIERARCHY|TK_TOP_LEVEL|TK_HAS_WRAPPER|TK_WIN_MANAGED); Tk_MakeWindowExist((Tk_Window)winPtr->parentPtr); RemapWindows(winPtr, Tk_GetHWND(winPtr->parentPtr->window)); + + /* + * Make sure wm no longer manages this window + */ + Tk_ManageGeometry(frameWin, NULL, NULL); + TkWmDeadWindow(winPtr); /* flags (above) must be cleared before calling */ /* TkMapTopFrame (below) */ diff --git a/xlib/X11/Xlib.h b/xlib/X11/Xlib.h index 667bdc7..8d8ec68 100644 --- a/xlib/X11/Xlib.h +++ b/xlib/X11/Xlib.h @@ -330,6 +330,9 @@ typedef struct _XImage { unsigned long green_mask; unsigned long blue_mask; XPointer obdata; /* hook for the object routines to hang on */ +#if defined(MAC_OSX_TK) + int pixelpower; /* n such that pixels are 2^n x 2^n blocks*/ +#endif struct funcs { /* image manipulation routines */ struct _XImage *(*create_image)(); #if NeedFunctionPrototypes |