diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tk.h | 4 | ||||
-rw-r--r-- | generic/tkEntry.c | 156 | ||||
-rw-r--r-- | generic/tkEvent.c | 6 | ||||
-rw-r--r-- | generic/tkFont.c | 4 | ||||
-rw-r--r-- | generic/tkImgPhoto.c | 6 | ||||
-rw-r--r-- | generic/tkInt.decls | 2 | ||||
-rw-r--r-- | generic/tkIntPlatDecls.h | 7 | ||||
-rw-r--r-- | generic/tkListbox.c | 46 | ||||
-rw-r--r-- | generic/tkMenu.c | 7 | ||||
-rw-r--r-- | generic/tkOldConfig.c | 6 | ||||
-rw-r--r-- | generic/tkOption.c | 2 | ||||
-rw-r--r-- | generic/tkPanedWindow.c | 19 | ||||
-rw-r--r-- | generic/tkScrollbar.c | 2 | ||||
-rw-r--r-- | generic/tkStubInit.c | 2 | ||||
-rw-r--r-- | generic/tkText.c | 34 | ||||
-rw-r--r-- | generic/tkTextBTree.c | 2 | ||||
-rw-r--r-- | generic/tkTextDisp.c | 152 | ||||
-rw-r--r-- | generic/tkTextIndex.c | 2 | ||||
-rw-r--r-- | generic/tkTextTag.c | 8 | ||||
-rw-r--r-- | generic/tkTextWind.c | 16 | ||||
-rw-r--r-- | generic/ttk/ttkButton.c | 4 | ||||
-rw-r--r-- | generic/ttk/ttkNotebook.c | 2 |
22 files changed, 349 insertions, 140 deletions
diff --git a/generic/tk.h b/generic/tk.h index e356ce5..bf43b41 100644 --- a/generic/tk.h +++ b/generic/tk.h @@ -59,10 +59,10 @@ extern "C" { #define TK_MAJOR_VERSION 8 #define TK_MINOR_VERSION 5 #define TK_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TK_RELEASE_SERIAL 18 +#define TK_RELEASE_SERIAL 19 #define TK_VERSION "8.5" -#define TK_PATCH_LEVEL "8.5.18" +#define TK_PATCH_LEVEL "8.5.19" /* * A special definition used to allow this header file to be included from diff --git a/generic/tkEntry.c b/generic/tkEntry.c index 6683cdc..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,8 +390,8 @@ static const char *selElementNames[] = { */ static int ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr, - int objc, Tcl_Obj *const objv[], int flags); -static void DeleteChars(Entry *entryPtr, int index, int count); + 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); static void EntryBlinkProc(ClientData clientData); @@ -417,7 +417,7 @@ static int EntryValidateChange(Entry *entryPtr, char *change, static void ExpandPercents(Entry *entryPtr, const char *before, const char *change, const char *newStr, int index, int type, Tcl_DString *dsPtr); -static void EntryValueChanged(Entry *entryPtr, +static int EntryValueChanged(Entry *entryPtr, const char *newValue); static void EntryVisibleRange(Entry *entryPtr, double *firstPtr, double *lastPtr); @@ -427,7 +427,7 @@ static int EntryWidgetObjCmd(ClientData clientData, static void EntryWorldChanged(ClientData instanceData); static int GetEntryIndex(Tcl_Interp *interp, Entry *entryPtr, char *string, int *indexPtr); -static void InsertChars(Entry *entryPtr, int index, char *string); +static int InsertChars(Entry *entryPtr, int index, char *string); /* * These forward declarations are the spinbox specific ones: @@ -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,12 +658,12 @@ EntryWidgetObjCmd( Tcl_SetObjResult(interp, objPtr); } } else { - result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0); + result = ConfigureEntry(interp, entryPtr, objc-2, objv+2); } break; case COMMAND_DELETE: { - int first, last; + int first, last, code; if ((objc < 3) || (objc > 4)) { Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?"); @@ -680,7 +680,10 @@ EntryWidgetObjCmd( goto error; } if ((last >= first) && (entryPtr->state == STATE_NORMAL)) { - DeleteChars(entryPtr, first, last - first); + code = DeleteChars(entryPtr, first, last - first); + if (code != TCL_OK) { + goto error; + } } break; } @@ -721,7 +724,7 @@ EntryWidgetObjCmd( } case COMMAND_INSERT: { - int index; + int index, code; if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "index text"); @@ -732,7 +735,10 @@ EntryWidgetObjCmd( goto error; } if (entryPtr->state == STATE_NORMAL) { - InsertChars(entryPtr, index, Tcl_GetString(objv[3])); + code = InsertChars(entryPtr, index, Tcl_GetString(objv[3])); + if (code != TCL_OK) { + goto error; + } } break; } @@ -1080,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; @@ -1096,6 +1101,7 @@ ConfigureEntry( int valuesChanged = 0; /* lint initialization */ double oldFrom = 0.0; /* lint initialization */ double oldTo = 0.0; /* lint initialization */ + int code; /* * Eliminate any existing trace on a variable monitored by the entry. @@ -1298,6 +1304,17 @@ ConfigureEntry( value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY); if (value == NULL) { + + /* + * Since any trace on the textvariable was eliminated above, + * the only possible reason for EntryValueChanged to return + * an error is that the textvariable lives in a namespace + * that does not (yet) exist. Indeed, namespaces are not + * automatically created as needed. Don't trap this error + * here, better do it below when attempting to trace the + * variable. + */ + EntryValueChanged(entryPtr, NULL); } else { EntrySetValue(entryPtr, value); @@ -1316,7 +1333,13 @@ ConfigureEntry( */ Tcl_ListObjIndex(interp, sbPtr->listObj, 0, &objPtr); - EntryValueChanged(entryPtr, Tcl_GetString(objPtr)); + + /* + * No check for error return here as well, because any possible + * error will be trapped below when attempting tracing. + */ + + EntryValueChanged(entryPtr, Tcl_GetString(objPtr)); } else if ((sbPtr->valueStr == NULL) && !DOUBLES_EQ(sbPtr->fromValue, sbPtr->toValue) && (!DOUBLES_EQ(sbPtr->fromValue, oldFrom) @@ -1341,6 +1364,12 @@ ConfigureEntry( } } sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue); + + /* + * No check for error return here as well, because any possible + * error will be trapped below when attempting tracing. + */ + EntryValueChanged(entryPtr, sbPtr->formatBuf); } } @@ -1352,10 +1381,13 @@ ConfigureEntry( if ((entryPtr->textVarName != NULL) && !(entryPtr->flags & ENTRY_VAR_TRACED)) { - Tcl_TraceVar(interp, entryPtr->textVarName, + code = Tcl_TraceVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, EntryTextVarProc, (ClientData) entryPtr); - entryPtr->flags |= ENTRY_VAR_TRACED; + if (code != TCL_OK) { + return TCL_ERROR; + } + entryPtr->flags |= ENTRY_VAR_TRACED; } EntryWorldChanged((ClientData) entryPtr); @@ -1675,7 +1707,7 @@ DisplayEntry( Tk_CharBbox(entryPtr->textLayout, entryPtr->insertPos, &cursorX, NULL, NULL, NULL); cursorX += entryPtr->layoutX; - cursorX -= (entryPtr->insertWidth)/2; + cursorX -= (entryPtr->insertWidth == 1) ? 1 : (entryPtr->insertWidth)/2; Tk_SetCaretPos(entryPtr->tkwin, cursorX, baseY - fm.ascent, fm.ascent + fm.descent); if (entryPtr->insertPos >= entryPtr->leftIndex && cursorX < xBound) { @@ -1990,7 +2022,8 @@ EntryComputeGeometry( * Add new characters to an entry widget. * * Results: - * None. + * A standard Tcl result. If an error occurred then an error message is + * left in the interp's result. * * Side effects: * New information gets added to entryPtr; it will be redisplayed soon, @@ -1999,7 +2032,7 @@ EntryComputeGeometry( *---------------------------------------------------------------------- */ -static void +static int InsertChars( Entry *entryPtr, /* Entry that is to get the new elements. */ int index, /* Add the new elements before this character @@ -2017,7 +2050,7 @@ InsertChars( byteIndex = Tcl_UtfAtIndex(string, index) - string; byteCount = strlen(value); if (byteCount == 0) { - return; + return TCL_OK; } newByteCount = entryPtr->numBytes + byteCount + 1; @@ -2031,7 +2064,7 @@ InsertChars( EntryValidateChange(entryPtr, value, newStr, index, VALIDATE_INSERT) != TCL_OK) { ckfree(newStr); - return; + return TCL_OK; } ckfree((char *)string); @@ -2079,7 +2112,7 @@ InsertChars( if (entryPtr->insertPos >= index) { entryPtr->insertPos += charsAdded; } - EntryValueChanged(entryPtr, NULL); + return EntryValueChanged(entryPtr, NULL); } /* @@ -2090,7 +2123,8 @@ InsertChars( * Remove one or more characters from an entry widget. * * Results: - * None. + * A standard Tcl result. If an error occurred then an error message is + * left in the interp's result. * * Side effects: * Memory gets freed, the entry gets modified and (eventually) @@ -2099,7 +2133,7 @@ InsertChars( *---------------------------------------------------------------------- */ -static void +static int DeleteChars( Entry *entryPtr, /* Entry widget to modify. */ int index, /* Index of first character to delete. */ @@ -2113,7 +2147,7 @@ DeleteChars( count = entryPtr->numChars - index; } if (count <= 0) { - return; + return TCL_OK; } string = entryPtr->string; @@ -2135,7 +2169,7 @@ DeleteChars( VALIDATE_DELETE) != TCL_OK) { ckfree(newStr); ckfree(toDelete); - return; + return TCL_OK; } ckfree(toDelete); @@ -2194,7 +2228,7 @@ DeleteChars( entryPtr->insertPos = index; } } - EntryValueChanged(entryPtr, NULL); + return EntryValueChanged(entryPtr, NULL); } /* @@ -2207,7 +2241,8 @@ DeleteChars( * is one, and does other bookkeeping such as arranging for redisplay. * * Results: - * None. + * A standard Tcl result. If an error occurred then an error message is + * left in the interp's result. * * Side effects: * None. @@ -2215,7 +2250,7 @@ DeleteChars( *---------------------------------------------------------------------- */ -static void +static int EntryValueChanged( Entry *entryPtr, /* Entry whose value just changed. */ const char *newValue) /* If this value is not NULL, we first force @@ -2229,7 +2264,7 @@ EntryValueChanged( newValue = NULL; } else { newValue = Tcl_SetVar(entryPtr->interp, entryPtr->textVarName, - entryPtr->string, TCL_GLOBAL_ONLY); + entryPtr->string, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); } if ((newValue != NULL) && (strcmp(newValue, entryPtr->string) != 0)) { @@ -2251,6 +2286,19 @@ EntryValueChanged( EntryComputeGeometry(entryPtr); EventuallyRedraw(entryPtr); } + + /* + * An error may have happened when setting the textvariable in case there + * is a trace on that variable and the trace proc triggered an error. + * Another possibility is that the textvariable is in a namespace that + * does not (yet) exist. + * Signal this error. + */ + + if ((entryPtr->textVarName != NULL) && (newValue == NULL)) { + return TCL_ERROR; + } + return TCL_OK; } /* @@ -3588,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; } @@ -3698,12 +3746,12 @@ SpinboxWidgetObjCmd( Tcl_SetObjResult(interp, objPtr); } } else { - result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0); + result = ConfigureEntry(interp, entryPtr, objc-2, objv+2); } break; case SB_CMD_DELETE: { - int first, last; + int first, last, code; if ((objc < 3) || (objc > 4)) { Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?"); @@ -3722,7 +3770,10 @@ SpinboxWidgetObjCmd( } } if ((last >= first) && (entryPtr->state == STATE_NORMAL)) { - DeleteChars(entryPtr, first, last - first); + code = DeleteChars(entryPtr, first, last - first); + if (code != TCL_OK) { + goto error; + } } break; } @@ -3782,7 +3833,7 @@ SpinboxWidgetObjCmd( } case SB_CMD_INSERT: { - int index; + int index, code; if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "index text"); @@ -3793,7 +3844,10 @@ SpinboxWidgetObjCmd( goto error; } if (entryPtr->state == STATE_NORMAL) { - InsertChars(entryPtr, index, Tcl_GetString(objv[3])); + code = InsertChars(entryPtr, index, Tcl_GetString(objv[3])); + if (code != TCL_OK) { + goto error; + } } break; } @@ -4001,16 +4055,22 @@ SpinboxWidgetObjCmd( break; } - case SB_CMD_SET: + case SB_CMD_SET: { + int code = TCL_OK; + if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?string?"); goto error; } if (objc == 3) { - EntryValueChanged(entryPtr, Tcl_GetString(objv[2])); + code = EntryValueChanged(entryPtr, Tcl_GetString(objv[2])); + if (code != TCL_OK) { + goto error; + } } Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1); break; + } case SB_CMD_VALIDATE: { int code; @@ -4151,7 +4211,7 @@ GetSpinboxElement( * TCL_OK. * * Side effects: - * An background error condition may arise when invoking the callback. + * A background error condition may arise when invoking the callback. * The widget value may change. * *-------------------------------------------------------------- @@ -4182,6 +4242,7 @@ SpinboxInvoke( return TCL_OK; } + code = TCL_OK; if (fabs(sbPtr->increment) > MIN_DBL_VAL) { if (sbPtr->listObj != NULL) { Tcl_Obj *objPtr; @@ -4227,7 +4288,7 @@ SpinboxInvoke( } } Tcl_ListObjIndex(interp, sbPtr->listObj, sbPtr->eIndex, &objPtr); - EntryValueChanged(entryPtr, Tcl_GetString(objPtr)); + code = EntryValueChanged(entryPtr, Tcl_GetString(objPtr)); } else if (!DOUBLES_EQ(sbPtr->fromValue, sbPtr->toValue)) { double dvalue; @@ -4274,9 +4335,12 @@ SpinboxInvoke( } } sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue); - EntryValueChanged(entryPtr, sbPtr->formatBuf); + code = EntryValueChanged(entryPtr, sbPtr->formatBuf); } } + if (code != TCL_OK) { + return TCL_ERROR; + } if (sbPtr->command != NULL) { Tcl_DStringInit(&script); diff --git a/generic/tkEvent.c b/generic/tkEvent.c index 03e7283..747555e 100644 --- a/generic/tkEvent.c +++ b/generic/tkEvent.c @@ -2047,6 +2047,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/tkFont.c b/generic/tkFont.c index 5d2ad43..7ff1ae9 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -2069,14 +2069,14 @@ Tk_ComputeTextLayout( NewChunk(&layoutPtr, &maxChunks, start, 1, curX, newX, baseline)->numDisplayChars = -1; start++; + curX = newX; + flags &= ~TK_AT_LEAST_ONE; if ((start < end) && ((wrapLength <= 0) || (newX <= wrapLength))) { /* * More chars can still fit on this line. */ - curX = newX; - flags &= ~TK_AT_LEAST_ONE; continue; } } else { diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 780b0c2..47aa523 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -2454,7 +2454,11 @@ ImgPhotoGet( } XFree((char *) visInfoPtr); - sprintf(buf, ((mono) ? "%d": "%d/%d/%d"), nRed, nGreen, nBlue); + if (mono) { + sprintf(buf, "%d", nRed); + } else { + sprintf(buf, "%d/%d/%d", nRed, nGreen, nBlue); + } instancePtr->defaultPalette = Tk_GetUid(buf); /* diff --git a/generic/tkInt.decls b/generic/tkInt.decls index 7921852..f24d48c 100644 --- a/generic/tkInt.decls +++ b/generic/tkInt.decls @@ -957,7 +957,7 @@ declare 51 aqua { void TkGenWMDestroyEvent(Tk_Window tkwin) } declare 52 aqua { - TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag); + void TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag) } # removed duplicate from tkPlat table (tk.decls) diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h index 7654b5d..86127fe 100644 --- a/generic/tkIntPlatDecls.h +++ b/generic/tkIntPlatDecls.h @@ -723,7 +723,7 @@ typedef struct TkIntPlatStubs { Window (*tkGetTransientMaster) (TkWindow *winPtr); /* 49 */ int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */ void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */ - VOID *reserved52; + void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */ unsigned long (*tkpGetMS) (void); /* 53 */ VOID * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */ int (*tkpScanWindowId) (Tcl_Interp *interp, CONST char *string, Window *idPtr); /* 55 */ @@ -1129,7 +1129,10 @@ extern TkIntPlatStubs *tkIntPlatStubsPtr; #define TkGenWMDestroyEvent \ (tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */ #endif -/* Slot 52 is reserved */ +#ifndef TkMacOSXSetDrawingEnabled +#define TkMacOSXSetDrawingEnabled \ + (tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */ +#endif #ifndef TkpGetMS #define TkpGetMS \ (tkIntPlatStubsPtr->tkpGetMS) /* 53 */ 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/tkMenu.c b/generic/tkMenu.c index 49b5935..b35be24 100644 --- a/generic/tkMenu.c +++ b/generic/tkMenu.c @@ -934,9 +934,14 @@ MenuWidgetObjCmd( * Tearoff menus are posted differently on Mac and Windows than * non-tearoffs. TkpPostMenu does not actually map the menu's window * on those platforms, and popup menus have to be handled specially. + * Also, menubar menues are not intended to be posted (bug 1567681, + * 2160206). */ - if (menuPtr->menuType != TEAROFF_MENU) { + if (menuPtr->menuType == MENUBAR) { + Tcl_AppendResult(interp, "a menubar menu cannot be posted", NULL); + return TCL_ERROR; + } else if (menuPtr->menuType != TEAROFF_MENU) { result = TkpPostMenu(interp, menuPtr, x, y); } else { result = TkPostTearoffMenu(interp, menuPtr, x, y); diff --git a/generic/tkOldConfig.c b/generic/tkOldConfig.c index 97ad5cb..d7a33f7 100644 --- a/generic/tkOldConfig.c +++ b/generic/tkOldConfig.c @@ -112,6 +112,10 @@ Tk_ConfigureWidget( specs = GetCachedSpecs(interp, specs); + for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) { + specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED; + } + /* * Pass one: scan through all of the arguments, processing those that * match entries in the specs. @@ -167,7 +171,6 @@ Tk_ConfigureWidget( if ((specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED) || (specPtr->argvName == NULL) || (specPtr->type == TK_CONFIG_SYNONYM)) { - specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED; continue; } if (((specPtr->specFlags & needFlags) != needFlags) @@ -1128,7 +1131,6 @@ GetCachedSpecs( specPtr->defValue = Tk_GetUid(specPtr->defValue); } } - specPtr->specFlags &= ~TK_CONFIG_OPTION_SPECIFIED; } } else { cachedSpecs = (Tk_ConfigSpec *) Tcl_GetHashValue(entryPtr); diff --git a/generic/tkOption.c b/generic/tkOption.c index 91a6cc0..95b140d 100644 --- a/generic/tkOption.c +++ b/generic/tkOption.c @@ -559,7 +559,7 @@ Tk_GetOption( count -= levelPtr[-1].bases[currentStack]; } - if (currentStack && CLASS) { + if (currentStack & CLASS) { nodeId = winClassId; } else { nodeId = winNameId; diff --git a/generic/tkPanedWindow.c b/generic/tkPanedWindow.c index 6a3766b..99ed179 100644 --- a/generic/tkPanedWindow.c +++ b/generic/tkPanedWindow.c @@ -147,6 +147,10 @@ typedef struct PanedWindow { GC gc; /* Graphics context for copying from * off-screen pixmap onto screen. */ int proxyx, proxyy; /* Proxy x,y coordinates. */ + Tk_3DBorder proxyBackground;/* Background color used to draw proxy. If NULL, use background. */ + Tcl_Obj *proxyBorderWidthPtr; /* Tcl_Obj rep for proxyBorderWidth */ + int proxyBorderWidth; /* Borderwidth used to draw proxy. */ + int proxyRelief; /* Relief used to draw proxy, if TK_RELIEF_NULL then use relief. */ Slave **slaves; /* Pointer to array of Slaves. */ int numSlaves; /* Number of slaves. */ int sizeofSlaves; /* Number of elements in the slaves array. */ @@ -298,6 +302,15 @@ static const Tk_OptionSpec optionSpecs[] = { {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", DEF_PANEDWINDOW_ORIENT, -1, Tk_Offset(PanedWindow, orient), 0, (ClientData) orientStrings, GEOMETRY}, + {TK_OPTION_BORDER, "-proxybackground", "proxyBackground", "ProxyBackground", + 0, -1, Tk_Offset(PanedWindow, proxyBackground), TK_OPTION_NULL_OK, + (ClientData) DEF_PANEDWINDOW_BG_MONO}, + {TK_OPTION_PIXELS, "-proxyborderwidth", "proxyBorderWidth", "ProxyBorderWidth", + DEF_PANEDWINDOW_PROXYBORDER, Tk_Offset(PanedWindow, proxyBorderWidthPtr), + Tk_Offset(PanedWindow, proxyBorderWidth), 0, 0, GEOMETRY}, + {TK_OPTION_RELIEF, "-proxyrelief", "proxyRelief", "Relief", + 0, -1, Tk_Offset(PanedWindow, proxyRelief), + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", DEF_PANEDWINDOW_RELIEF, -1, Tk_Offset(PanedWindow, relief), 0, 0, 0}, {TK_OPTION_CURSOR, "-sashcursor", "sashCursor", "Cursor", @@ -2769,8 +2782,10 @@ DisplayProxyWindow( * Redraw the widget's background and border. */ - Tk_Fill3DRectangle(tkwin, pixmap, pwPtr->background, 0, 0, - Tk_Width(tkwin), Tk_Height(tkwin), 2, pwPtr->sashRelief); + Tk_Fill3DRectangle(tkwin, pixmap, + pwPtr->proxyBackground ? pwPtr->proxyBackground : pwPtr->background, + 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), pwPtr->proxyBorderWidth, + (pwPtr->proxyRelief != TK_RELIEF_NULL) ? pwPtr->proxyRelief : pwPtr->sashRelief); #ifndef TK_NO_DOUBLE_BUFFERING /* 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/tkStubInit.c b/generic/tkStubInit.c index 3ee54dd..90a124f 100644 --- a/generic/tkStubInit.c +++ b/generic/tkStubInit.c @@ -588,7 +588,7 @@ TkIntPlatStubs tkIntPlatStubs = { TkGetTransientMaster, /* 49 */ TkGenerateButtonEvent, /* 50 */ TkGenWMDestroyEvent, /* 51 */ - NULL, /* 52 */ + TkMacOSXSetDrawingEnabled, /* 52 */ TkpGetMS, /* 53 */ TkMacOSXDrawable, /* 54 */ TkpScanWindowId, /* 55 */ diff --git a/generic/tkText.c b/generic/tkText.c index eb2d77a..8edf82d 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}, @@ -566,14 +566,6 @@ CreateWidget( textPtr->end = NULL; } - /* - * Register with the B-tree. In some sense it would be best if we could do - * this later (after configuration options), so that any changes to - * start,end do not require a total recalculation. - */ - - TkBTreeAddClient(sharedPtr->tree, textPtr, textPtr->charHeight); - textPtr->state = TK_TEXT_STATE_NORMAL; textPtr->relief = TK_RELIEF_FLAT; textPtr->cursor = None; @@ -584,6 +576,14 @@ CreateWidget( textPtr->prevHeight = Tk_Height(newWin); /* + * Register with the B-tree. In some sense it would be best if we could do + * this later (after configuration options), so that any changes to + * start,end do not require a total recalculation. + */ + + TkBTreeAddClient(sharedPtr->tree, textPtr, textPtr->charHeight); + + /* * This will add refCounts to textPtr. */ @@ -2319,6 +2319,7 @@ TextWorldChanged( { Tk_FontMetrics fm; int border; + int oldCharHeight = textPtr->charHeight; textPtr->charWidth = Tk_TextWidth(textPtr->tkfont, "0", 1); if (textPtr->charWidth <= 0) { @@ -2330,6 +2331,9 @@ TextWorldChanged( if (textPtr->charHeight <= 0) { textPtr->charHeight = 1; } + if (textPtr->charHeight != oldCharHeight) { + TkBTreeClientRangeChanged(textPtr, textPtr->charHeight); + } border = textPtr->borderWidth + textPtr->highlightWidth; Tk_GeometryRequest(textPtr->tkwin, textPtr->width * textPtr->charWidth + 2*textPtr->padX + 2*border, @@ -4205,7 +4209,11 @@ TextSearchFoundMatch( matchOffset += Tcl_NumUtfChars(segPtr->body.chars, -1); } } else { - leftToScan -= segPtr->size; + if (searchSpecPtr->exact) { + leftToScan -= segPtr->size; + } else { + leftToScan -= Tcl_NumUtfChars(segPtr->body.chars, -1); + } } curIndex.byteIndex += segPtr->size; } diff --git a/generic/tkTextBTree.c b/generic/tkTextBTree.c index 36f0ef3..58fc645 100644 --- a/generic/tkTextBTree.c +++ b/generic/tkTextBTree.c @@ -1117,7 +1117,7 @@ TkBTreeInsertChars( /* * I don't believe it's possible for either of the two lines passed to * this function to be the last line of text, but the function is robust - * to that case anyway. (We must never re-calculated the line height of + * to that case anyway. (We must never re-calculate the line height of * the last line). */ diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index fc7b46b..1f39112 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -658,17 +658,8 @@ TkTextCreateDInfo( dInfoPtr->metricEpoch = -1; dInfoPtr->metricIndex.textPtr = NULL; dInfoPtr->metricIndex.linePtr = NULL; - - /* - * Add a refCount for each of the idle call-backs. - */ - - textPtr->refCount++; - dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(0, - AsyncUpdateLineMetrics, (ClientData) textPtr); - textPtr->refCount++; - dInfoPtr->scrollbarTimer = Tcl_CreateTimerHandler(200, - AsyncUpdateYScrollbar, (ClientData) textPtr); + dInfoPtr->lineUpdateTimer = NULL; + dInfoPtr->scrollbarTimer = NULL; textPtr->dInfoPtr = dInfoPtr; } @@ -1647,7 +1638,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 @@ -2225,7 +2216,7 @@ UpdateDisplayInfo( * Here's a problem: see the tests textDisp-29.2.1-4 * * If the widget is being created, but has not yet been configured it will - * have a maxY of 1 above, and we we won't have examined all the lines + * have a maxY of 1 above, and we won't have examined all the lines * (just the first line, in fact), and so maxOffset will not be a true * reflection of the widget's lines. Therefore we must not overwrite the * original newXPixelOffset in this case. @@ -2540,7 +2531,7 @@ DisplayLineBackground( * current x coordinate? */ int matchRight; /* Does line's style match its neighbor just * to the right of the current x-coord? */ - int minX, maxX, xOffset; + int minX, maxX, xOffset, bw; StyleValues *sValuePtr; Display *display; #ifndef TK_NO_DOUBLE_BUFFERING @@ -2611,16 +2602,25 @@ DisplayLineBackground( rightX = leftX + 32767; } + /* + * Prevent the borders from leaking on adjacent characters, + * which would happen for too large border width. + */ + + bw = sValuePtr->borderWidth; + if (leftX + sValuePtr->borderWidth > rightX) { + bw = rightX - leftX; + } + XFillRectangle(display, pixmap, chunkPtr->stylePtr->bgGC, leftX + xOffset, y, (unsigned int) (rightX - leftX), (unsigned int) dlPtr->height); if (sValuePtr->relief != TK_RELIEF_FLAT) { Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, - leftX + xOffset, y, sValuePtr->borderWidth, - dlPtr->height, 1, sValuePtr->relief); + leftX + xOffset, y, bw, dlPtr->height, 1, + sValuePtr->relief); Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, - rightX - sValuePtr->borderWidth + xOffset, - y, sValuePtr->borderWidth, dlPtr->height, 0, + rightX - bw + xOffset, y, bw, dlPtr->height, 0, sValuePtr->relief); } } @@ -2717,22 +2717,29 @@ DisplayLineBackground( matchRight = (nextPtr2 != NULL) && SAME_BACKGROUND(nextPtr2->stylePtr, chunkPtr->stylePtr); if (matchLeft && !matchRight) { + bw = sValuePtr->borderWidth; + if (rightX2 - sValuePtr->borderWidth < leftX) { + bw = rightX2 - leftX; + } if (sValuePtr->relief != TK_RELIEF_FLAT) { Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, - rightX2 - sValuePtr->borderWidth + xOffset, y, - sValuePtr->borderWidth, sValuePtr->borderWidth, 0, - sValuePtr->relief); + rightX2 - bw + xOffset, y, bw, + sValuePtr->borderWidth, 0, sValuePtr->relief); } - leftX = rightX2 - sValuePtr->borderWidth; + leftX = rightX2 - bw; leftXIn = 0; } else if (!matchLeft && matchRight && (sValuePtr->relief != TK_RELIEF_FLAT)) { + bw = sValuePtr->borderWidth; + if (rightX2 + sValuePtr->borderWidth > rightX) { + bw = rightX - rightX2; + } Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, - rightX2 + xOffset, y, sValuePtr->borderWidth, - sValuePtr->borderWidth, 1, sValuePtr->relief); + rightX2 + xOffset, y, bw, sValuePtr->borderWidth, + 1, sValuePtr->relief); Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border, - leftX + xOffset, y, rightX2 + sValuePtr->borderWidth - - leftX, sValuePtr->borderWidth, leftXIn, 0, 1, + leftX + xOffset, y, rightX2 + bw - leftX, + sValuePtr->borderWidth, leftXIn, 0, 1, sValuePtr->relief); } @@ -2764,7 +2771,7 @@ DisplayLineBackground( chunkPtr2 = NULL; if (dlPtr->nextPtr != NULL && dlPtr->nextPtr->chunkPtr != NULL) { /* - * Find the chunk in the previous line that covers leftX. + * Find the chunk in the next line that covers leftX. */ nextPtr2 = dlPtr->nextPtr->chunkPtr; @@ -2820,26 +2827,33 @@ DisplayLineBackground( matchRight = (nextPtr2 != NULL) && SAME_BACKGROUND(nextPtr2->stylePtr, chunkPtr->stylePtr); if (matchLeft && !matchRight) { + bw = sValuePtr->borderWidth; + if (rightX2 - sValuePtr->borderWidth < leftX) { + bw = rightX2 - leftX; + } if (sValuePtr->relief != TK_RELIEF_FLAT) { Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, - rightX2 - sValuePtr->borderWidth + xOffset, + rightX2 - bw + xOffset, y + dlPtr->height - sValuePtr->borderWidth, - sValuePtr->borderWidth, sValuePtr->borderWidth, 0, - sValuePtr->relief); + bw, sValuePtr->borderWidth, 0, sValuePtr->relief); } - leftX = rightX2 - sValuePtr->borderWidth; + leftX = rightX2 - bw; leftXIn = 1; } else if (!matchLeft && matchRight && (sValuePtr->relief != TK_RELIEF_FLAT)) { + bw = sValuePtr->borderWidth; + if (rightX2 + sValuePtr->borderWidth > rightX) { + bw = rightX - rightX2; + } Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, - rightX2 + xOffset, y + dlPtr->height - - sValuePtr->borderWidth, sValuePtr->borderWidth, + rightX2 + xOffset, + y + dlPtr->height - sValuePtr->borderWidth, bw, sValuePtr->borderWidth, 1, sValuePtr->relief); Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border, - leftX + xOffset, y + dlPtr->height - - sValuePtr->borderWidth, rightX2 + sValuePtr->borderWidth - - leftX, sValuePtr->borderWidth, leftXIn, 1, 0, - sValuePtr->relief); + leftX + xOffset, + y + dlPtr->height - sValuePtr->borderWidth, + rightX2 + bw - leftX, sValuePtr->borderWidth, leftXIn, + 1, 0, sValuePtr->relief); } nextChunk2b: @@ -2889,9 +2903,10 @@ AsyncUpdateLineMetrics( dInfoPtr->lineUpdateTimer = NULL; - if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) { + if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED) + || !Tk_IsMapped(textPtr->tkwin)) { /* - * The widget has been deleted. Don't do anything. + * The widget has been deleted, or is not mapped. Don't do anything. */ if (--textPtr->refCount == 0) { @@ -5151,7 +5166,10 @@ TkTextSetYView( dInfoPtr->newTopPixelOffset = 0; goto scheduleUpdate; - } + } + /* + * The line is already on screen, with no need to scroll. + */ return; } } @@ -5214,6 +5232,15 @@ TkTextSetYView( } /* + * If the window height is smaller than the line height, prefer to make + * the top of the line visible. + */ + + if (dInfoPtr->maxY - dInfoPtr->y < lineHeight) { + bottomY = lineHeight; + } + + /* * Our job now is to arrange the display so that indexPtr appears as low * on the screen as possible but with its bottom no lower than bottomY. * BottomY is the bottom of the window if the desired line is just below @@ -6563,6 +6590,7 @@ FindDLine( CONST TkTextIndex *indexPtr)/* Index of desired character. */ { DLine *dlPtrPrev; + TkTextIndex indexPtr2; if (dlPtr == NULL) { return NULL; @@ -6587,24 +6615,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; } } diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index 6a60faf..b886975 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -1695,7 +1695,7 @@ IndexCountBytesOrdered( byteCount += segPtr->size; } - linePtr = indexPtr1->linePtr->nextPtr; + linePtr = TkBTreeNextLine(textPtr, indexPtr1->linePtr); while (linePtr != indexPtr2->linePtr) { for (segPtr = linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { 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/tkTextWind.c b/generic/tkTextWind.c index 8d1f850..5b511d2 100644 --- a/generic/tkTextWind.c +++ b/generic/tkTextWind.c @@ -1123,6 +1123,16 @@ TkTextEmbWinDisplayProc( &lineX, &windowY, &width, &height); windowX = lineX - chunkPtr->x + x; + /* + * Mark the window as displayed so that it won't get unmapped. + * This needs to be done before the next instruction block because + * Tk_MaintainGeometry/Tk_MapWindow will run event handlers, in + * particular for the <Map> event, and if the bound script deletes + * the embedded window its clients will get freed. + */ + + client->displayed = 1; + if (textPtr->tkwin == Tk_Parent(tkwin)) { if ((windowX != Tk_X(tkwin)) || (windowY != Tk_Y(tkwin)) || (Tk_ReqWidth(tkwin) != Tk_Width(tkwin)) @@ -1134,12 +1144,6 @@ TkTextEmbWinDisplayProc( Tk_MaintainGeometry(tkwin, textPtr->tkwin, windowX, windowY, width, height); } - - /* - * Mark the window as displayed so that it won't get unmapped. - */ - - client->displayed = 1; } /* 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/generic/ttk/ttkNotebook.c b/generic/ttk/ttkNotebook.c index 551f4a6..dd757cb 100644 --- a/generic/ttk/ttkNotebook.c +++ b/generic/ttk/ttkNotebook.c @@ -902,7 +902,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; } |