diff options
author | culler <culler> | 2019-01-02 18:17:39 (GMT) |
---|---|---|
committer | culler <culler> | 2019-01-02 18:17:39 (GMT) |
commit | 19deb1cb04936981e905f5985497e4386dde5f9c (patch) | |
tree | 1e878f109941f4ceb2854b61c80bd653de20cfe4 | |
parent | 03dff5fd63941102495689b01b05bcea39d73912 (diff) | |
download | tk-19deb1cb04936981e905f5985497e4386dde5f9c.zip tk-19deb1cb04936981e905f5985497e4386dde5f9c.tar.gz tk-19deb1cb04936981e905f5985497e4386dde5f9c.tar.bz2 |
Make AsyncUpdateLineMetrics cancel any idle tasks for the afterSyncCmd before
running it, to protect against bug [0a9c91951b].
-rw-r--r-- | generic/tkText.c | 9 | ||||
-rw-r--r-- | generic/tkText.h | 4 | ||||
-rw-r--r-- | generic/tkTextDisp.c | 5 |
3 files changed, 10 insertions, 8 deletions
diff --git a/generic/tkText.c b/generic/tkText.c index 2dabe4c..6c1512d 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -406,7 +406,6 @@ static Tcl_Obj * TextGetText(const TkText *textPtr, 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, Tcl_Obj *undoString, int insert, const TkTextIndex *index1Ptr, @@ -1547,7 +1546,7 @@ TextWidgetObjCmd( textPtr->afterSyncCmd = cmd; } else { textPtr->afterSyncCmd = cmd; - Tcl_DoWhenIdle(RunAfterSyncCmd, (ClientData) textPtr); + Tcl_DoWhenIdle(TkTextRunAfterSyncCmd, (ClientData) textPtr); } break; } else if (objc != 2) { @@ -5506,7 +5505,7 @@ UpdateDirtyFlag( /* *---------------------------------------------------------------------- * - * RunAfterSyncCmd -- + * TkTextRunAfterSyncCmd -- * * This function is called by the event loop and executes the command * scheduled by [.text sync -command $cmd]. @@ -5520,8 +5519,8 @@ UpdateDirtyFlag( *---------------------------------------------------------------------- */ -static void -RunAfterSyncCmd( +void +TkTextRunAfterSyncCmd( ClientData clientData) /* Information about text widget. */ { register TkText *textPtr = (TkText *) clientData; diff --git a/generic/tkText.h b/generic/tkText.h index 5d88784..4703703 100644 --- a/generic/tkText.h +++ b/generic/tkText.h @@ -1070,7 +1070,7 @@ MODULE_SCOPE int TkTextGetObjIndex(Tcl_Interp *interp, TkText *textPtr, MODULE_SCOPE int TkTextSharedGetObjIndex(Tcl_Interp *interp, TkSharedText *sharedTextPtr, Tcl_Obj *idxPtr, TkTextIndex *indexPtr); -MODULE_SCOPE const TkTextIndex *TkTextGetIndexFromObj(Tcl_Interp *interp, +MODULE_SCOPE const TkTextIndex *TkTextGetIndexFromObj(Tcl_Interp *interp, TkText *textPtr, Tcl_Obj *objPtr); MODULE_SCOPE TkTextTabArray *TkTextGetTabs(Tcl_Interp *interp, TkText *textPtr, Tcl_Obj *stringPtr); @@ -1159,7 +1159,7 @@ MODULE_SCOPE int TkTextYviewCmd(TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE void TkTextWinFreeClient(Tcl_HashEntry *hPtr, TkTextEmbWindowClient *client); - +MODULE_SCOPE void TkTextRunAfterSyncCmd(ClientData clientData); #endif /* _TKTEXT */ /* diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 2bfb359..ecd2427 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -683,7 +683,7 @@ TkTextCreateDInfo( dInfoPtr->scanTotalYScroll = 0; dInfoPtr->scanMarkY = 0; dInfoPtr->dLinesInvalidated = 0; - dInfoPtr->flags = DINFO_OUT_OF_DATE; + dInfoPtr->flags = 0; dInfoPtr->topPixelOffset = 0; dInfoPtr->newTopPixelOffset = 0; dInfoPtr->currentMetricUpdateLine = -1; @@ -3072,9 +3072,12 @@ AsyncUpdateLineMetrics( * We have looped over all lines, so we're done. We must release our * refCount on the widget (the timer token was already set to NULL * above). If there is a registered aftersync command, run that first. + * Cancel any pending idle task which would try to run the command + * after the afterSyncCmd pointer had been set to NULL. */ if (textPtr->afterSyncCmd) { + Tcl_CancelIdleCall(TkTextRunAfterSyncCmd, textPtr); int code; Tcl_Preserve((ClientData) textPtr->interp); code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd, |