summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/SetOptions.350
-rw-r--r--doc/colors.n26
-rw-r--r--doc/listbox.n9
-rw-r--r--generic/tkEntry.c25
-rw-r--r--generic/tkListbox.c46
-rw-r--r--generic/tkScrollbar.c2
-rw-r--r--generic/tkText.c8
-rw-r--r--generic/tkTextDisp.c9
-rw-r--r--generic/tkTextTag.c8
-rw-r--r--generic/ttk/ttkButton.c4
-rw-r--r--library/listbox.tcl36
-rw-r--r--library/scrlbar.tcl7
-rw-r--r--macosx/README2
-rw-r--r--macosx/tkMacOSXDialog.c22
-rw-r--r--macosx/tkMacOSXInit.c9
-rw-r--r--macosx/tkMacOSXWindowEvent.c10
-rw-r--r--macosx/tkMacOSXWm.c2
-rw-r--r--tests/listbox.test39
-rw-r--r--tests/scrollbar.test30
-rw-r--r--tests/textDisp.test26
-rw-r--r--tests/winButton.test8
-rw-r--r--win/tkWinScrlbr.c4
22 files changed, 290 insertions, 92 deletions
diff --git a/doc/SetOptions.3 b/doc/SetOptions.3
index 028467a..f12a00f 100644
--- a/doc/SetOptions.3
+++ b/doc/SetOptions.3
@@ -129,19 +129,21 @@ option table is no longer needed \fBTk_DeleteOptionTable\fR should be
called to free all of its resources. All of the option tables
for a Tcl interpreter are freed automatically if the interpreter is deleted.
.PP
-\fBTk_InitOptions\fR is invoked when a new widget is created to set
-the default values for all of the widget's configuration options.
-\fBTk_InitOptions\fR is passed a token for an option table (\fIoptionTable\fR)
-and a pointer to a widget record (\fIrecordPtr\fR), which is the C
-structure that holds information about this widget. \fBTk_InitOptions\fR
-uses the information in the option table to
-choose an appropriate default for each option, then it stores the default
-value directly into the widget record, overwriting any information that
-was already present in the widget record. \fBTk_InitOptions\fR normally
-returns \fBTCL_OK\fR. If an error occurred while setting the default values
-(e.g., because a default value was erroneous) then \fBTCL_ERROR\fR is returned
-and an error message is left in \fIinterp\fR's result if \fIinterp\fR
-is not NULL.
+\fBTk_InitOptions\fR is invoked when a new widget is created to set the
+default values for all of the widget's configuration options that do not
+have \fBTK_OPTION_DONT_SET_DEFAULT\fR set in their \fIflags\fR field.
+\fBTk_InitOptions\fR is passed a token for an option table
+(\fIoptionTable\fR) and a pointer to a widget record (\fIrecordPtr\fR),
+which is the C structure that holds information about this widget.
+\fBTk_InitOptions\fR uses the information in the option table to choose an
+appropriate default for each option, except those having
+\fBTK_OPTION_DONT_SET_DEFAULT\fR set, then it stores the default value
+directly into the widget record, overwriting any information that was
+already present in the widget record. \fBTk_InitOptions\fR normally
+returns \fBTCL_OK\fR. If an error occurred while setting the default
+values (e.g., because a default value was erroneous) then \fBTCL_ERROR\fR
+is returned and an error message is left in \fIinterp\fR's result if
+\fIinterp\fR is not NULL.
.PP
\fBTk_SetOptions\fR is invoked to modify configuration options based
on information specified in a Tcl command. The command might be one that
@@ -306,19 +308,27 @@ given by \fIinternalOffset\fR. For example, if the option's type is
value is not stored in that form. At least one of the offsets must be
greater than or equal to zero.
.PP
-The \fIflags\fR field consists of one or more bits ORed together. At
-present only a single flag is supported: \fBTK_OPTION_NULL_OK\fR. If
-this bit is set for an option then an empty string will be accepted as
-the value for the option and the resulting internal form will be a
-NULL pointer, a zero value, or \fBNone\fR, depending on the type of
-the option. If the flag is not set then empty strings will result
-in errors.
+The \fIflags\fR field consists of one or more bits ORed together. The
+following flags are supported:
+.TP
+\fBTK_OPTION_NULL_OK\fR
+If this bit is set for an option then an empty string will be accepted as
+the value for the option and the resulting internal form will be a NULL
+pointer, a zero value, or \fBNone\fR, depending on the type of the option.
+If the flag is not set then empty strings will result in errors.
\fBTK_OPTION_NULL_OK\fR is typically used to allow a
feature to be turned off entirely, e.g. set a cursor value to
\fBNone\fR so that a window simply inherits its parent's cursor.
Not all option types support the \fBTK_OPTION_NULL_OK\fR
flag; for those that do, there is an explicit indication of that fact
in the descriptions below.
+.TP
+\fBTK_OPTION_DONT_SET_DEFAULT\fR
+If this bit is set for an option then no default value will be set in
+\fBTk_InitOptions\fR for this option. Neither the option database, nor any
+system default value, nor \fIoptionTable\fR are used to give a default
+value to this option. Instead it is assumed that the caller has already
+supplied a default value in the widget code.
.PP
The \fItype\fR field of each Tk_OptionSpec structure determines
how to parse the value of that configuration option. The
diff --git a/doc/colors.n b/doc/colors.n
index 46c35aa..584e0ca 100644
--- a/doc/colors.n
+++ b/doc/colors.n
@@ -933,19 +933,19 @@ On Windows, the following additional system colors are available
.RS
.DS
.ta 6c
-3dDarkShadow Highlight
-3dLight HighlightText
-ActiveBorder InactiveBorder
-ActiveCaption InactiveCaption
-AppWorkspace InactiveCaptionText
-Background InfoBackground
-ButtonFace InfoText
-ButtonHighlight Menu
-ButtonShadow MenuText
-ButtonText Scrollbar
-CaptionText Window
-DisabledText WindowFrame
-GrayText WindowText
+system3dDarkShadow systemHighlight
+system3dLight systemHighlightText
+systemActiveBorder systemInactiveBorder
+systemActiveCaption systemInactiveCaption
+systemAppWorkspace systemInactiveCaptionText
+systemBackground systemInfoBackground
+systemButtonFace systemInfoText
+systemButtonHighlight systemMenu
+systemButtonShadow systemMenuText
+systemButtonText systemScrollbar
+systemCaptionText systemWindow
+systemDisabledText systemWindowFrame
+systemGrayText systemWindowText
.DE
.RE
.SH "SEE ALSO"
diff --git a/doc/listbox.n b/doc/listbox.n
index 642e1f0..aecc8e2 100644
--- a/doc/listbox.n
+++ b/doc/listbox.n
@@ -431,9 +431,12 @@ Most people will probably want to use \fBbrowse\fR mode for
single selections and \fBextended\fR mode for multiple selections;
the other modes appear to be useful only in special situations.
.PP
-Any time the selection changes in the listbox, the virtual event
-\fB<<ListboxSelect>>\fR will be generated. It is easiest to bind
-to this event to be made aware of any changes to listbox selection.
+Any time the set of selected item(s) in the listbox is updated by the
+user through the keyboard or mouse, the virtual event
+\fB<<ListboxSelect>>\fR will be generated. This virtual event will not
+be generated when adjusting the selection with the \fIpathName
+\fBselection\fR command. It is easiest to bind to this event to be
+made aware of any user changes to listbox selection.
.PP
In addition to the above behavior, the following additional behavior
is defined by the default bindings:
diff --git a/generic/tkEntry.c b/generic/tkEntry.c
index 338652b..9f43f90 100644
--- a/generic/tkEntry.c
+++ b/generic/tkEntry.c
@@ -133,7 +133,7 @@ static const Tk_OptionSpec entryOptSpec[] = {
0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0},
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr),
- TK_CONFIG_NULL_OK, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0},
+ TK_OPTION_NULL_OK, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0},
{TK_OPTION_STRING, "-show", "show", "Show",
DEF_ENTRY_SHOW, -1, Tk_Offset(Entry, showChar),
TK_OPTION_NULL_OK, 0, 0},
@@ -279,23 +279,23 @@ static const Tk_OptionSpec sbOptSpec[] = {
0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0},
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr),
- TK_CONFIG_NULL_OK, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0},
+ TK_OPTION_NULL_OK, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0},
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state),
0, (ClientData) stateStrings, 0},
{TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus),
- TK_CONFIG_NULL_OK, 0, 0},
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(Entry, textVarName),
- TK_CONFIG_NULL_OK, 0, 0},
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_DOUBLE, "-to", "to", "To",
DEF_SPINBOX_TO, -1, Tk_Offset(Spinbox, toValue), 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
0, (ClientData) validateStrings, 0},
{TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
- NULL, -1, Tk_Offset(Entry, validateCmd), TK_CONFIG_NULL_OK, 0, 0},
+ NULL, -1, Tk_Offset(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_STRING, "-values", "values", "Values",
DEF_SPINBOX_VALUES, -1, Tk_Offset(Spinbox, valueStr),
TK_OPTION_NULL_OK, 0, 0},
@@ -307,7 +307,7 @@ static const Tk_OptionSpec sbOptSpec[] = {
DEF_SPINBOX_WRAP, -1, Tk_Offset(Spinbox, wrap), 0, 0, 0},
{TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
DEF_ENTRY_SCROLL_COMMAND, -1, Tk_Offset(Entry, scrollCmd),
- TK_CONFIG_NULL_OK, 0, 0},
+ TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};
@@ -390,7 +390,7 @@ static const char *selElementNames[] = {
*/
static int ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr,
- int objc, Tcl_Obj *const objv[], int flags);
+ int objc, Tcl_Obj *const objv[]);
static int DeleteChars(Entry *entryPtr, int index, int count);
static void DestroyEntry(char *memPtr);
static void DisplayEntry(ClientData clientData);
@@ -553,7 +553,7 @@ Tk_EntryObjCmd(
if ((Tk_InitOptions(interp, (char *) entryPtr, optionTable, tkwin)
!= TCL_OK) ||
- (ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0) != TCL_OK)) {
+ (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK)) {
Tk_DestroyWindow(entryPtr->tkwin);
return TCL_ERROR;
}
@@ -658,7 +658,7 @@ EntryWidgetObjCmd(
Tcl_SetObjResult(interp, objPtr);
}
} else {
- result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0);
+ result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
}
break;
@@ -1086,8 +1086,7 @@ ConfigureEntry(
Entry *entryPtr, /* Information about widget; may or may not
* already have values for some fields. */
int objc, /* Number of valid entries in argv. */
- Tcl_Obj *const objv[], /* Argument objects. */
- int flags) /* Flags to pass to Tk_ConfigureWidget. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
{
Tk_SavedOptions savedOptions;
Tk_3DBorder border;
@@ -3637,7 +3636,7 @@ Tk_SpinboxObjCmd(
Tk_DestroyWindow(entryPtr->tkwin);
return TCL_ERROR;
}
- if (ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0) != TCL_OK) {
+ if (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK) {
goto error;
}
@@ -3747,7 +3746,7 @@ SpinboxWidgetObjCmd(
Tcl_SetObjResult(interp, objPtr);
}
} else {
- result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0);
+ result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
}
break;
diff --git a/generic/tkListbox.c b/generic/tkListbox.c
index 248dd7b..86fb671 100644
--- a/generic/tkListbox.c
+++ b/generic/tkListbox.c
@@ -278,7 +278,7 @@ static const Tk_OptionSpec optionSpecs[] = {
Tk_Offset(Listbox, selBorderWidth), 0, 0, 0},
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
DEF_LISTBOX_SELECT_FG_COLOR, -1, Tk_Offset(Listbox, selFgColorPtr),
- TK_CONFIG_NULL_OK, (ClientData) DEF_LISTBOX_SELECT_FG_MONO, 0},
+ TK_OPTION_NULL_OK, (ClientData) DEF_LISTBOX_SELECT_FG_MONO, 0},
{TK_OPTION_STRING, "-selectmode", "selectMode", "SelectMode",
DEF_LISTBOX_SELECT_MODE, -1, Tk_Offset(Listbox, selectMode),
TK_OPTION_NULL_OK, 0, 0},
@@ -379,7 +379,7 @@ enum indices {
static void ChangeListboxOffset(Listbox *listPtr, int offset);
static void ChangeListboxView(Listbox *listPtr, int index);
static int ConfigureListbox(Tcl_Interp *interp, Listbox *listPtr,
- int objc, Tcl_Obj *const objv[], int flags);
+ int objc, Tcl_Obj *const objv[]);
static int ConfigureListboxItem(Tcl_Interp *interp,
Listbox *listPtr, ItemAttr *attrs, int objc,
Tcl_Obj *const objv[], int index);
@@ -401,6 +401,7 @@ static void ListboxEventProc(ClientData clientData,
static int ListboxFetchSelection(ClientData clientData,
int offset, char *buffer, int maxBytes);
static void ListboxLostSelection(ClientData clientData);
+static void GenerateListboxSelectEvent(Listbox *listPtr);
static void EventuallyRedrawRange(Listbox *listPtr,
int first, int last);
static void ListboxScanTo(Listbox *listPtr, int x, int y);
@@ -563,7 +564,7 @@ Tk_ListboxObjCmd(
return TCL_ERROR;
}
- if (ConfigureListbox(interp, listPtr, objc-2, objv+2, 0) != TCL_OK) {
+ if (ConfigureListbox(interp, listPtr, objc-2, objv+2) != TCL_OK) {
Tk_DestroyWindow(listPtr->tkwin);
return TCL_ERROR;
}
@@ -699,7 +700,7 @@ ListboxWidgetObjCmd(
result = TCL_OK;
}
} else {
- result = ConfigureListbox(interp, listPtr, objc-2, objv+2, 0);
+ result = ConfigureListbox(interp, listPtr, objc-2, objv+2);
}
break;
}
@@ -1543,8 +1544,7 @@ ConfigureListbox(
register Listbox *listPtr, /* Information about widget; may or may not
* already have values for some fields. */
int objc, /* Number of valid entries in argv. */
- Tcl_Obj *const objv[], /* Arguments. */
- int flags) /* Flags to pass to Tk_ConfigureWidget. */
+ Tcl_Obj *const objv[]) /* Arguments. */
{
Tk_SavedOptions savedOptions;
Tcl_Obj *oldListObj = NULL;
@@ -3177,12 +3177,46 @@ ListboxLostSelection(
if ((listPtr->exportSelection) && (listPtr->nElements > 0)) {
ListboxSelect(listPtr, 0, listPtr->nElements-1, 0);
+ GenerateListboxSelectEvent(listPtr);
}
}
/*
*----------------------------------------------------------------------
*
+ * GenerateListboxSelectEvent --
+ *
+ * Send an event that the listbox selection was updated. This is
+ * equivalent to event generate $listboxWidget <<ListboxSelect>>
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Any side effect possible, depending on bindings to this event.
+ *
+ *----------------------------------------------------------------------
+ */
+
+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);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* EventuallyRedrawRange --
*
* Ensure that a given range of elements is eventually redrawn on the
diff --git a/generic/tkScrollbar.c b/generic/tkScrollbar.c
index 3fff58d..ba42c20 100644
--- a/generic/tkScrollbar.c
+++ b/generic/tkScrollbar.c
@@ -627,6 +627,8 @@ TkScrollbarEventProc(
TkScrollbarEventuallyRedraw(scrollPtr);
}
}
+ } else if (eventPtr->type == MapNotify) {
+ TkScrollbarEventuallyRedraw(scrollPtr);
}
}
diff --git a/generic/tkText.c b/generic/tkText.c
index 6e982b0..341ec0f 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -197,18 +197,18 @@ static const Tk_OptionSpec optionSpecs[] = {
TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_BD_MONO, 0},
{TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
DEF_TEXT_SELECT_FG_COLOR, -1, Tk_Offset(TkText, selFgColorPtr),
- TK_CONFIG_NULL_OK, (ClientData) DEF_TEXT_SELECT_FG_MONO, 0},
+ TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_FG_MONO, 0},
{TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
DEF_TEXT_SET_GRID, -1, Tk_Offset(TkText, setGrid), 0, 0, 0},
{TK_OPTION_PIXELS, "-spacing1", "spacing1", "Spacing",
DEF_TEXT_SPACING1, -1, Tk_Offset(TkText, spacing1),
- TK_OPTION_DONT_SET_DEFAULT, 0 , TK_TEXT_LINE_GEOMETRY },
+ 0, 0 , TK_TEXT_LINE_GEOMETRY },
{TK_OPTION_PIXELS, "-spacing2", "spacing2", "Spacing",
DEF_TEXT_SPACING2, -1, Tk_Offset(TkText, spacing2),
- TK_OPTION_DONT_SET_DEFAULT, 0 , TK_TEXT_LINE_GEOMETRY },
+ 0, 0 , TK_TEXT_LINE_GEOMETRY },
{TK_OPTION_PIXELS, "-spacing3", "spacing3", "Spacing",
DEF_TEXT_SPACING3, -1, Tk_Offset(TkText, spacing3),
- TK_OPTION_DONT_SET_DEFAULT, 0 , TK_TEXT_LINE_GEOMETRY },
+ 0, 0 , TK_TEXT_LINE_GEOMETRY },
{TK_OPTION_CUSTOM, "-startline", NULL, NULL,
NULL, -1, Tk_Offset(TkText, start), TK_OPTION_NULL_OK,
(ClientData) &lineOption, TK_TEXT_LINE_RANGE},
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index ef8d6f4..133a7d7 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -4803,9 +4803,16 @@ 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).
+ * 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.
*/
+ if (dInfoPtr->flags & DINFO_OUT_OF_DATE) {
+ UpdateDisplayInfo(textPtr);
+ }
dlPtr = dInfoPtr->dLinePtr;
if (dlPtr == NULL) {
return;
diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c
index dad03bf..a310dd7 100644
--- a/generic/tkTextTag.c
+++ b/generic/tkTextTag.c
@@ -44,11 +44,11 @@ static const Tk_OptionSpec tagOptionSpecs[] = {
{TK_OPTION_BITMAP, "-bgstipple", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, bgStipple), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-borderwidth", NULL, NULL,
- "0", Tk_Offset(TkTextTag, borderWidthPtr), Tk_Offset(TkTextTag, borderWidth),
- TK_OPTION_DONT_SET_DEFAULT|TK_OPTION_NULL_OK, 0, 0},
+ NULL, Tk_Offset(TkTextTag, borderWidthPtr), Tk_Offset(TkTextTag, borderWidth),
+ TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
{TK_OPTION_STRING, "-elide", NULL, NULL,
- "0", -1, Tk_Offset(TkTextTag, elideString),
- TK_OPTION_DONT_SET_DEFAULT|TK_OPTION_NULL_OK, 0, 0},
+ NULL, -1, Tk_Offset(TkTextTag, elideString),
+ TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
{TK_OPTION_BITMAP, "-fgstipple", NULL, NULL,
NULL, -1, Tk_Offset(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_FONT, "-font", NULL, NULL,
diff --git a/generic/ttk/ttkButton.c b/generic/ttk/ttkButton.c
index 2954184..bc44f25 100644
--- a/generic/ttk/ttkButton.c
+++ b/generic/ttk/ttkButton.c
@@ -413,8 +413,8 @@ typedef struct
static Tk_OptionSpec CheckbuttonOptionSpecs[] =
{
{TK_OPTION_STRING, "-variable", "variable", "Variable",
- "", Tk_Offset(Checkbutton, checkbutton.variableObj), -1,
- TK_OPTION_DONT_SET_DEFAULT,0,0},
+ NULL, Tk_Offset(Checkbutton, checkbutton.variableObj), -1,
+ TK_OPTION_NULL_OK,0,0},
{TK_OPTION_STRING, "-onvalue", "onValue", "OnValue",
"1", Tk_Offset(Checkbutton, checkbutton.onValueObj), -1,
0,0,0},
diff --git a/library/listbox.tcl b/library/listbox.tcl
index 2d9af20..5087786 100644
--- a/library/listbox.tcl
+++ b/library/listbox.tcl
@@ -118,7 +118,7 @@ bind Listbox <Control-Home> {
%W see 0
%W selection clear 0 end
%W selection set 0
- event generate %W <<ListboxSelect>>
+ tk::FireListboxSelectEvent %W
}
bind Listbox <Shift-Control-Home> {
tk::ListboxDataExtend %W 0
@@ -128,7 +128,7 @@ bind Listbox <Control-End> {
%W see end
%W selection clear 0 end
%W selection set end
- event generate %W <<ListboxSelect>>
+ tk::FireListboxSelectEvent %W
}
bind Listbox <Shift-Control-End> {
tk::ListboxDataExtend %W [%W index end]
@@ -163,7 +163,7 @@ bind Listbox <Control-slash> {
bind Listbox <Control-backslash> {
if {[%W cget -selectmode] ne "browse"} {
%W selection clear 0 end
- event generate %W <<ListboxSelect>>
+ tk::FireListboxSelectEvent %W
}
}
@@ -243,7 +243,7 @@ proc ::tk::ListboxBeginSelect {w el {focus 1}} {
set Priv(listboxSelection) {}
set Priv(listboxPrev) $el
}
- event generate $w <<ListboxSelect>>
+ tk::FireListboxSelectEvent $w
# check existence as ListboxSelect may destroy us
if {$focus && [winfo exists $w] && [$w cget -state] eq "normal"} {
focus $w
@@ -271,7 +271,7 @@ proc ::tk::ListboxMotion {w el} {
$w selection clear 0 end
$w selection set $el
set Priv(listboxPrev) $el
- event generate $w <<ListboxSelect>>
+ tk::FireListboxSelectEvent $w
}
extended {
set i $Priv(listboxPrev)
@@ -302,7 +302,7 @@ proc ::tk::ListboxMotion {w el} {
incr i -1
}
set Priv(listboxPrev) $el
- event generate $w <<ListboxSelect>>
+ tk::FireListboxSelectEvent $w
}
}
}
@@ -353,7 +353,7 @@ proc ::tk::ListboxBeginToggle {w el} {
} else {
$w selection set $el
}
- event generate $w <<ListboxSelect>>
+ tk::FireListboxSelectEvent $w
}
}
@@ -405,7 +405,7 @@ proc ::tk::ListboxUpDown {w amount} {
browse {
$w selection clear 0 end
$w selection set active
- event generate $w <<ListboxSelect>>
+ tk::FireListboxSelectEvent $w
}
extended {
$w selection clear 0 end
@@ -413,7 +413,7 @@ proc ::tk::ListboxUpDown {w amount} {
$w selection anchor active
set Priv(listboxPrev) [$w index active]
set Priv(listboxSelection) {}
- event generate $w <<ListboxSelect>>
+ tk::FireListboxSelectEvent $w
}
}
}
@@ -501,7 +501,7 @@ proc ::tk::ListboxCancel w {
}
incr first
}
- event generate $w <<ListboxSelect>>
+ tk::FireListboxSelectEvent $w
}
# ::tk::ListboxSelectAll
@@ -521,5 +521,19 @@ proc ::tk::ListboxSelectAll w {
} else {
$w selection set 0 end
}
- event generate $w <<ListboxSelect>>
+ tk::FireListboxSelectEvent $w
+}
+
+# ::tk::FireListboxSelectEvent
+#
+# Fire the <<ListboxSelect>> event if the listbox is not in disabled
+# state.
+#
+# Arguments:
+# w - The listbox widget.
+
+proc ::tk::FireListboxSelectEvent w {
+ if {[$w cget -state] eq "normal"} {
+ event generate $w <<ListboxSelect>>
+ }
}
diff --git a/library/scrlbar.tcl b/library/scrlbar.tcl
index 4b25325..43ce4ae 100644
--- a/library/scrlbar.tcl
+++ b/library/scrlbar.tcl
@@ -141,6 +141,13 @@ if {[tk windowingsystem] eq "aqua"} {
bind Scrollbar <Shift-Option-MouseWheel> {
tk::ScrollByUnits %W h [expr {-10 * (%D)}]
}
+} else {
+ bind Scrollbar <MouseWheel> {
+ tk::ScrollByUnits %W v [expr {- (%D /120 ) * 4}]
+ }
+ bind Scrollbar <Shift-MouseWheel> {
+ tk::ScrollByUnits %W h [expr {- (%D /120 ) * 4}]
+ }
}
# tk::ScrollButtonDown --
# This procedure is invoked when a button is pressed in a scrollbar.
diff --git a/macosx/README b/macosx/README
index 7b17fb8..8940ee6 100644
--- a/macosx/README
+++ b/macosx/README
@@ -399,7 +399,7 @@ The main program in a typical OSX application looks like this (see *)
}
The run method implements the event loop for the application. There
-are three key steps in the run method. First it calls
+are three key steps in the run method. First it calls
[NSApp finishLaunching], which creates the bouncing application icon
and does other mysterious things. Second it creates an
NSAutoreleasePool. Third, it starts an event loop which drains the
diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c
index eebff3c..67f17be 100644
--- a/macosx/tkMacOSXDialog.c
+++ b/macosx/tkMacOSXDialog.c
@@ -398,6 +398,7 @@ Tk_GetOpenFileObjCmd(
TkInitFileFilters(&fl);
for (i = 1; i < objc; i += 2) {
+ BOOL parentIsKey = NO;
if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings,
sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
goto end;
@@ -513,6 +514,7 @@ Tk_GetOpenFileObjCmd(
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
[panel beginSheetForDirectory:directory
file:filename
+ parentIsKey = [parent isKeyWindow];
types:fileTypes
modalForWindow:parent
modalDelegate:NSApp
@@ -544,6 +546,9 @@ Tk_GetOpenFileObjCmd(
if (typeVariablePtr && result == TCL_OK) {
/*
* The -typevariable option is not really supported.
+ if (parentIsKey) {
+ [parent makeKeyWindow];
+ }
*/
Tcl_SetVar2(interp, Tcl_GetString(typeVariablePtr), NULL,
@@ -596,6 +601,7 @@ Tk_GetSaveFileObjCmd(
TkInitFileFilters(&fl);
for (i = 1; i < objc; i += 2) {
+ BOOL parentIsKey = NO;
if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings,
sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
goto end;
@@ -712,6 +718,7 @@ Tk_GetSaveFileObjCmd(
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
[panel beginSheetForDirectory:directory
file:filename
+ parentIsKey = [parent isKeyWindow];
modalForWindow:parent
modalDelegate:NSApp
didEndSelector:
@@ -737,7 +744,9 @@ Tk_GetSaveFileObjCmd(
contextInfo:callbackInfo];
}
result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
-
+ if (parentIsKey) {
+ [parent makeKeyWindow];
+ }
end:
TkFreeFileFilters(&fl);
return result;
@@ -780,6 +789,7 @@ Tk_ChooseDirectoryObjCmd(
NSWindow *parent;
NSOpenPanel *panel = [NSOpenPanel openPanel];
NSInteger modalReturnCode = modalError;
+ BOOL parentIsKey = NO;
for (i = 1; i < objc; i += 2) {
if (Tcl_GetIndexFromObjStruct(interp, objv[i], chooseOptionStrings,
@@ -847,6 +857,7 @@ Tk_ChooseDirectoryObjCmd(
callbackInfo->multiple = 0;
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
+ parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
[panel beginSheetForDirectory:directory
file:filename
@@ -874,7 +885,9 @@ Tk_ChooseDirectoryObjCmd(
contextInfo:callbackInfo];
}
result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
-
+ if (parentIsKey) {
+ [parent makeKeyWindow];
+ }
end:
return result;
}
@@ -1013,6 +1026,7 @@ Tk_MessageBoxObjCmd(
NSArray *buttons;
NSAlert *alert = [NSAlert new];
NSInteger modalReturnCode = 1;
+ BOOL parentIsKey = NO;
iconIndex = ICON_INFO;
typeIndex = TYPE_OK;
@@ -1139,6 +1153,7 @@ Tk_MessageBoxObjCmd(
callbackInfo->typeIndex = typeIndex;
parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
if (haveParentOption && parent && ![parent attachedSheet]) {
+ parentIsKey = [parent isKeyWindow];
#if MAC_OS_X_VERSION_MIN_REQUIRED > 1090
[alert beginSheetModalForWindow:parent
completionHandler:^(NSModalResponse returnCode)
@@ -1161,6 +1176,9 @@ Tk_MessageBoxObjCmd(
result = (modalReturnCode >= NSAlertFirstButtonReturn) ? TCL_OK : TCL_ERROR;
end:
[alert release];
+ if (parentIsKey) {
+ [parent makeKeyWindow];
+ }
return result;
}
diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c
index cb97f47..26eb3f5 100644
--- a/macosx/tkMacOSXInit.c
+++ b/macosx/tkMacOSXInit.c
@@ -72,11 +72,13 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt
_mainPool = [NSAutoreleasePool new];
}
}
+
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
- (void)_postedNotification:(NSNotification *)notification {
TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}
#endif
+
- (void)_setupApplicationNotifications {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
#define observe(n, s) [nc addObserver:self selector:@selector(s) name:(n) object:nil]
@@ -91,18 +93,19 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt
CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(), NULL, &keyboardChanged, kTISNotifySelectedKeyboardInputSourceChanged, NULL, CFNotificationSuspensionBehaviorCoalesce);
#endif
}
+
- (void)_setupEventLoop {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
[self finishLaunching];
[self setWindowsNeedUpdate:YES];
[pool drain];
}
+
- (void)_setup:(Tcl_Interp *)interp {
_eventInterp = interp;
- _mainPool = nil;
+ _mainPool = [NSAutoreleasePool new];
[NSApp setPoolProtected:NO];
_defaultMainMenu = nil;
- NSAutoreleasePool *pool = [NSAutoreleasePool new];
[self _setupMenus];
[self setDelegate:self];
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
@@ -111,8 +114,8 @@ static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFSt
#endif
[self _setupWindowNotifications];
[self _setupApplicationNotifications];
- [pool drain];
}
+
- (NSString *)tkFrameworkImagePath:(NSString*)image {
NSString *path = nil;
NSAutoreleasePool *pool = [NSAutoreleasePool new];
diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c
index 91cc348..fce3801 100644
--- a/macosx/tkMacOSXWindowEvent.c
+++ b/macosx/tkMacOSXWindowEvent.c
@@ -165,6 +165,10 @@ extern BOOL opaqueTag;
if (winPtr) {
TkGenWMDestroyEvent((Tk_Window) winPtr);
+ if (_windowWithMouse == w) {
+ _windowWithMouse = nil;
+ [w release];
+ }
}
/*
@@ -862,12 +866,9 @@ ConfigureRestrictProc(
/*
* Try to prevent flickers and flashes.
- *
- * This stops the flickers, but on OSX 10.11 flashes still occur when
- * the width of the window is 16, 32, 48, 64, 80, 96, 112, 256, 512,
- * 768, ...
*/
[w disableFlushWindow];
+ NSDisableScreenUpdates();
/* Disable Tk drawing until the window has been completely configured.*/
TkMacOSXSetDrawingEnabled(winPtr, 0);
@@ -891,6 +892,7 @@ ConfigureRestrictProc(
while (Tk_DoOneEvent(TK_ALL_EVENTS|TK_DONT_WAIT)) {}
[w enableFlushWindow];
[w flushWindowIfNeeded];
+ NSEnableScreenUpdates();
[NSApp setPoolProtected:NO];
}
}
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 50cac20..5df72f0 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -907,6 +907,8 @@ TkWmDeadWindow(
[front makeKeyAndOrderFront:NSApp];
}
}
+ [NSApp _resetAutoreleasePool];
+
#if DEBUG_ZOMBIES > 0
fprintf(stderr, "================= Pool dump ===================\n");
[NSAutoreleasePool showPools];
diff --git a/tests/listbox.test b/tests/listbox.test
index b4046b6..62b8cc1 100644
--- a/tests/listbox.test
+++ b/tests/listbox.test
@@ -2169,6 +2169,45 @@ test listbox-30.1 {Bug 3607326} -setup {
unset -nocomplain a
} -result * -match glob -returnCodes error
+test listbox-31.1 {<<ListboxSelect>> event} -setup {
+ destroy .l
+ unset -nocomplain res
+} -body {
+ pack [listbox .l -state normal]
+ update
+ bind .l <<ListboxSelect>> {lappend res [%W curselection]}
+ .l insert end a b c
+ focus -force .l
+ event generate .l <1> -x 5 -y 5 ; # <<ListboxSelect>> fires
+ .l configure -state disabled
+ focus -force .l
+ event generate .l <Control-Home> ; # <<ListboxSelect>> does NOT fire
+ .l configure -state normal
+ focus -force .l
+ event generate .l <Control-End> ; # <<ListboxSelect>> fires
+ .l selection clear 0 end ; # <<ListboxSelect>> does NOT fire
+ .l selection set 1 1 ; # <<ListboxSelect>> does NOT fire
+ lappend res [.l curselection]
+} -cleanup {
+ destroy .l
+ unset -nocomplain res
+} -result {0 2 1}
+
+test listbox-31.2 {<<ListboxSelect>> event on lost selection} -setup {
+ destroy .l
+} -body {
+ pack [listbox .l -exportselection true]
+ update
+ bind .l <<ListboxSelect>> {lappend res [list [selection own] [%W curselection]]}
+ .l insert end a b c
+ focus -force .l
+ event generate .l <1> -x 5 -y 5 ; # <<ListboxSelect>> fires
+ selection clear ; # <<ListboxSelect>> fires again
+ set res
+} -cleanup {
+ destroy .l
+} -result {{.l 0} {{} {}}}
+
resetGridInfo
deleteWindows
option clear
diff --git a/tests/scrollbar.test b/tests/scrollbar.test
index 5d4334f..35f48bd 100644
--- a/tests/scrollbar.test
+++ b/tests/scrollbar.test
@@ -632,6 +632,36 @@ test scrollbar-9.1 {scrollbar widget vs hidden commands} {
list [winfo children .] [interp hidden]
} [list {} $l]
+test scrollbar-10.1 {<MouseWheel> event on scrollbar} -constraints {win|unix} -setup {
+ destroy .t .s
+} -body {
+ pack [text .t -yscrollcommand {.s set}] -side left
+ for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
+ pack [scrollbar .s -command {.t yview}] -fill y -expand 1 -side left
+ update
+ focus -force .s
+ event generate .s <MouseWheel> -delta -120
+ after 200 {set eventprocessed 1} ; vwait eventprocessed
+ .t index @0,0
+} -cleanup {
+ destroy .t .s
+} -result {5.0}
+
+test scrollbar-10.2 {<MouseWheel> event on scrollbar} -constraints {win|unix} -setup {
+ destroy .t .s
+} -body {
+ pack [text .t -xscrollcommand {.s set} -wrap none] -side top
+ for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
+ pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
+ update
+ focus -force .s
+ event generate .s <Shift-MouseWheel> -delta -120
+ after 200 {set eventprocessed 1} ; vwait eventprocessed
+ .t index @0,0
+} -cleanup {
+ destroy .t .s
+} -result {1.4}
+
catch {destroy .s}
catch {destroy .t}
diff --git a/tests/textDisp.test b/tests/textDisp.test
index 038eccd..ac3aee0 100644
--- a/tests/textDisp.test
+++ b/tests/textDisp.test
@@ -1333,6 +1333,30 @@ test textDisp-9.13 {TkTextRedrawTag} {
update
list $tk_textRelayout $tk_textRedraw
} {{2.0 6.0 7.0} {2.0 6.0 7.0}}
+test textDisp-9.14 {TkTextRedrawTag} {
+ pack [text .tnocrash]
+ for {set i 1} {$i < 6} {incr i} {
+ .tnocrash insert end \nfoo$i
+ }
+ .tnocrash tag configure mytag1 -relief raised
+ .tnocrash tag configure mytag2 -relief solid
+ update
+ proc doit {} {
+ .tnocrash tag add mytag1 4.0 5.0
+ .tnocrash tag add mytag2 4.0 5.0
+ after idle {
+ .tnocrash tag remove mytag1 1.0 end
+ .tnocrash tag remove mytag2 1.0 end
+ }
+ .tnocrash delete 1.0 2.0
+ }
+ doit ; # must not crash
+ after 500 {
+ destroy .tnocrash
+ set done 1
+ }
+ vwait done
+} {}
test textDisp-10.1 {TkTextRelayoutWindow} {
.t configure -wrap char
@@ -2021,9 +2045,9 @@ test textDisp-16.18 {TkTextYviewCmd procedure, "moveto" roundoff} {textfonts} {
wm geometry .top1 +0+0
text .top1.t -height 3 -width 4 -wrap none -setgrid 1 -padx 6 \
-spacing3 6
- .top1.t insert end "1\n2\n3\n4\n5\n6"
pack .top1.t
update
+ .top1.t insert end "1\n2\n3\n4\n5\n6"
.top1.t yview moveto 0.3333
set result [.top1.t yview]
destroy .top1
diff --git a/tests/winButton.test b/tests/winButton.test
index 5bf6867..5e3dcfb 100644
--- a/tests/winButton.test
+++ b/tests/winButton.test
@@ -29,7 +29,9 @@ radiobutton .r -text Radiobutton
pack .l .b .c .r
update
-test winbutton-1.1 {TkpComputeButtonGeometry procedure} {testImageType win} {
+test winbutton-1.1 {TkpComputeButtonGeometry procedure} {testImageType win nonPortable} {
+ # nonPortable because of [3e3e25f483]: on Win7 first started with a high DPI screen
+ # the smallest size (i.e. 8) is not available for "MS Sans Serif" font
deleteWindows
image create test image1
image1 changed 0 0 0 0 60 40
@@ -46,7 +48,9 @@ test winbutton-1.1 {TkpComputeButtonGeometry procedure} {testImageType win} {
[winfo reqwidth .b3] [winfo reqheight .b3] \
[winfo reqwidth .b4] [winfo reqheight .b4]
} {68 48 70 50 90 52 90 52}
-test winbutton-1.2 {TkpComputeButtonGeometry procedure} win {
+test winbutton-1.2 {TkpComputeButtonGeometry procedure} {win nonPortable} {
+ # nonPortable because of [3e3e25f483]: on Win7 first started with a high DPI screen
+ # the smallest size (i.e. 8) is not available for "MS Sans Serif" font
deleteWindows
label .b1 -bitmap question -bd 3 -padx 0 -pady 2
button .b2 -bitmap question -bd 3 -padx 0 -pady 2
diff --git a/win/tkWinScrlbr.c b/win/tkWinScrlbr.c
index 46aad58..fc9685d 100644
--- a/win/tkWinScrlbr.c
+++ b/win/tkWinScrlbr.c
@@ -218,10 +218,10 @@ CreateProc(
if (scrollPtr->info.vertical) {
style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
- | SBS_VERT | SBS_RIGHTALIGN;
+ | SBS_VERT;
} else {
style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS
- | SBS_HORZ | SBS_BOTTOMALIGN;
+ | SBS_HORZ;
}
scrollPtr->hwnd = CreateWindow("SCROLLBAR", NULL, style,