diff options
-rw-r--r-- | generic/tkTextDisp.c | 40 | ||||
-rw-r--r-- | tests/text.test | 28 |
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. |