summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tkTextDisp.c40
-rw-r--r--tests/text.test28
2 files changed, 68 insertions, 0 deletions
diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c
index d740181..ff90520 100644
--- a/generic/tkTextDisp.c
+++ b/generic/tkTextDisp.c
@@ -590,6 +590,7 @@ static int TextGetScrollInfoObj(Tcl_Interp *interp,
Tcl_Obj *CONST objv[], double *dblPtr,
int *intPtr);
static void AsyncUpdateLineMetrics(ClientData clientData);
+static void GenerateTextLineHeightsInvalidEvent(TkText *textPtr);
static void AsyncUpdateYScrollbar(ClientData clientData);
static int IsStartOfNotMergedLine(TkText *textPtr,
CONST TkTextIndex *indexPtr);
@@ -2929,6 +2930,8 @@ AsyncUpdateLineMetrics(
LOG("tk_textInvalidateLine", buffer);
}
+ GenerateTextLineHeightsInvalidEvent(textPtr);
+
/*
* If we're not in the middle of a long-line calculation (metricEpoch==-1)
* and we've reached the last line, then we're done.
@@ -2961,6 +2964,43 @@ AsyncUpdateLineMetrics(
/*
*----------------------------------------------------------------------
*
+ * GenerateTextLineHeightsInvalidEvent --
+ *
+ * Send the <<TextLineHeightsInvalid>> event related to the text widget
+ * line metrics asynchronous update.
+ * This is equivalent to:
+ * event generate $textWidget <<TextLineHeightsInvalid>> -detail $N
+ * where $N is the number of lines for which the height is outdated.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * If corresponding bindings are present, they will trigger.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GenerateTextLineHeightsInvalidEvent(
+ TkText *textPtr) /* Information about text widget. */
+{
+ union {XEvent general; XVirtualEvent virtual;} event;
+
+ memset(&event, 0, sizeof(event));
+ event.general.xany.type = VirtualEvent;
+ event.general.xany.serial = NextRequest(Tk_Display(textPtr->tkwin));
+ event.general.xany.send_event = False;
+ event.general.xany.window = Tk_WindowId(textPtr->tkwin);
+ event.general.xany.display = Tk_Display(textPtr->tkwin);
+ event.virtual.name = Tk_GetUid("TextLineHeightsInvalid");
+ event.virtual.user_data = Tcl_NewIntObj(TkTextPendingyupdate(textPtr));
+ Tk_HandleEvent(&event.general);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TkTextUpdateLineMetrics --
*
* This function updates the pixel height calculations of a range of
diff --git a/tests/text.test b/tests/text.test
index d8ed533..7e754e2 100644
--- a/tests/text.test
+++ b/tests/text.test
@@ -1025,6 +1025,34 @@ test text-11a.12 {TextWidgetCmd procedure, "pendingyupdate" option} {
set fraction2 [lindex [.top.yt yview] 0]
lappend res [expr {$fraction1 == $fraction2}]
} {1 1 1}
+test text-11a.21 {"<<TextLineHeightsInvalid>>" event} {
+ destroy .top.yt .top
+ toplevel .top
+ pack [text .top.yt]
+ set content {}
+ for {set i 1} {$i < 300} {incr i} {
+ append content [string repeat "$i " 15] \n
+ }
+ .top.yt insert 1.0 $content
+ update
+ bind .top.yt <<TextLineHeightsInvalid>> { if {%d == 0} {set yud(%W) 1} }
+ # wait for end of line metrics calculation to get correct $fraction1
+ # as a reference
+ if {[.top.yt pendingyupdate]} {vwait yud(.top.yt)}
+ .top.yt yview moveto 1
+ set fraction1 [lindex [.top.yt yview] 0]
+ set res [expr {$fraction1 > 0}]
+ .top.yt delete 1.0 end
+ .top.yt insert 1.0 $content
+ # synchronously wait for completion of line metrics calculation
+ # and ensure the test is relevant
+ set waited 0
+ if {[.top.yt pendingyupdate]} {set waited 1 ; vwait yud(.top.yt)}
+ lappend res $waited
+ .top.yt yview moveto $fraction1
+ set fraction2 [lindex [.top.yt yview] 0]
+ lappend res [expr {$fraction1 == $fraction2}]
+} {1 1 1}
# edit, mark, scan, search, see, tag, window, xview and yview actions are tested elsewhere.