summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tkText.c51
-rw-r--r--generic/tkText.h3
-rw-r--r--generic/tkTextDisp.c22
3 files changed, 62 insertions, 14 deletions
diff --git a/generic/tkText.c b/generic/tkText.c
index a2b7dde..0cb8431 100644
--- a/generic/tkText.c
+++ b/generic/tkText.c
@@ -397,6 +397,7 @@ static int TextSearchIndexInLine(const SearchSpec *searchSpecPtr,
static int TextPeerCmd(TkText *textPtr, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[]);
static TkUndoProc TextUndoRedoCallback;
+static void RunAfterSyncCmd(ClientData clientData);
/*
* Declarations of the three search procs required by the multi-line search
@@ -1512,8 +1513,8 @@ TextWidgetObjCmd(
}
textPtr->afterSyncCmd = cmd;
} else {
- result = Tcl_EvalObjEx(interp, cmd, TCL_EVAL_GLOBAL);
- Tcl_DecrRefCount(cmd);
+ textPtr->afterSyncCmd = cmd;
+ Tcl_DoWhenIdle(RunAfterSyncCmd, (ClientData) textPtr);
}
break;
} else if (objc != 2) {
@@ -6747,6 +6748,52 @@ TkpTesttextCmd(
}
/*
+ *----------------------------------------------------------------------
+ *
+ * RunAfterSyncCmd --
+ *
+ * This function is called by the event loop and excutes the command
+ * scheduled by [.text sync -command $cmd].
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Anything may happen, depending on $cmd contents.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RunAfterSyncCmd(
+ ClientData clientData) /* Information about text widget. */
+{
+ register TkText *textPtr = (TkText *) clientData;
+ int code;
+
+ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
+ /*
+ * The widget has been deleted. Don't do anything.
+ */
+
+ 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_Release((ClientData) textPtr->interp);
+ Tcl_DecrRefCount(textPtr->afterSyncCmd);
+ textPtr->afterSyncCmd = NULL;
+}
+
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
diff --git a/generic/tkText.h b/generic/tkText.h
index 49ee479..ea8ce07 100644
--- a/generic/tkText.h
+++ b/generic/tkText.h
@@ -782,7 +782,8 @@ typedef struct TkText {
* statements. */
int autoSeparators; /* Non-zero means the separators will be
* inserted automatically. */
- Tcl_Obj *afterSyncCmd; /* Command to be executed when lines are up to date */
+ Tcl_Obj *afterSyncCmd; /* Command to be executed when lines are up to
+ * date */
} TkText;
/*
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index ba584ac..39311a6 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -2958,18 +2958,18 @@ AsyncUpdateLineMetrics(
* above). If there is a registered aftersync command, run that first.
*/
- if (textPtr->afterSyncCmd != NULL) {
- int code;
- Tcl_Preserve((ClientData)textPtr->interp);
- code = Tcl_EvalObjEx(textPtr->interp, textPtr->afterSyncCmd, TCL_EVAL_GLOBAL);
- if (code != TCL_OK && code != TCL_CONTINUE
- && code != TCL_BREAK) {
- Tcl_AddErrorInfo(textPtr->interp, "\n (text sync)");
- Tcl_BackgroundError(textPtr->interp);
+ if (textPtr->afterSyncCmd) {
+ int code;
+ 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_Release((ClientData)textPtr->interp);
- Tcl_DecrRefCount(textPtr->afterSyncCmd);
- textPtr->afterSyncCmd = 0;
+ Tcl_Release((ClientData) textPtr->interp);
+ Tcl_DecrRefCount(textPtr->afterSyncCmd);
+ textPtr->afterSyncCmd = NULL;
}
/*