summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorculler <culler>2019-01-02 18:17:39 (GMT)
committerculler <culler>2019-01-02 18:17:39 (GMT)
commit19deb1cb04936981e905f5985497e4386dde5f9c (patch)
tree1e878f109941f4ceb2854b61c80bd653de20cfe4
parent03dff5fd63941102495689b01b05bcea39d73912 (diff)
downloadtk-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.c9
-rw-r--r--generic/tkText.h4
-rw-r--r--generic/tkTextDisp.c5
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,