Tk Source Code

Check-in [615bbce0]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Adjusted when <<WidgetViewSync>> fires. Also %d now only has boolean value. Implementation in sync with TIP #438 rev. 1.10
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tip-438
Files: files | file ages | folders
SHA1: 615bbce0fe5c243877ca0fa74e40ec5c46fa203d
User & Date: fvogel 2015-11-21 08:43:25
Context
2015-11-21
09:08
Improved the tests a bit check-in: 516a0cca user: fvogel tags: tip-438
08:43
Adjusted when <<WidgetViewSync>> fires. Also %d now only has boolean value. Implementation in sync with TIP #438 rev. 1.10 check-in: 615bbce0 user: fvogel tags: tip-438
2015-11-19
22:02
Rename "yupdate" to "sync" and fix various test-cases check-in: 625b52ac user: jan.nijtmans tags: tip-438
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tkTextDisp.c.

586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
....
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
....
2955
2956
2957
2958
2959
2960
2961








2962
2963
2964
2965
2966
2967
2968
....
2979
2980
2981
2982
2983
2984
2985
2986
2987

2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000

3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
....
3387
3388
3389
3390
3391
3392
3393

3394
3395
3396
3397
3398
3399
3400
....
5091
5092
5093
5094
5095
5096
5097

5098
5099
5100
5101
5102
5103
5104
static int		DlineXOfIndex(TkText *textPtr,
			    DLine *dlPtr, int byteIndex);
static int		TextGetScrollInfoObj(Tcl_Interp *interp,
			    TkText *textPtr, int objc,
			    Tcl_Obj *CONST objv[], double *dblPtr,
			    int *intPtr);
static void		AsyncUpdateLineMetrics(ClientData clientData);
static void		GenerateWidgetViewSyncEvent(TkText *textPtr);
static void		AsyncUpdateYScrollbar(ClientData clientData);
static int              IsStartOfNotMergedLine(TkText *textPtr,
                            CONST TkTextIndex *indexPtr);

/*
 * Result values returned by TextGetScrollInfoObj:
 */
................................................................................
    if (tkTextDebug) {
	char buffer[2 * TCL_INTEGER_SPACE + 1];

	sprintf(buffer, "%d %d", lineNum, dInfoPtr->lastMetricUpdateLine);
	LOG("tk_textInvalidateLine", buffer);
    }

    GenerateWidgetViewSyncEvent(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.
     */

    if (dInfoPtr->metricEpoch == -1
	    && lineNum == dInfoPtr->lastMetricUpdateLine) {
................................................................................
		    Tcl_BackgroundError(textPtr->interp);
	    }
	    Tcl_Release((ClientData)textPtr->interp);
	    Tcl_DecrRefCount(textPtr->afterSyncCmd);
	    textPtr->afterSyncCmd = 0;
	}









	textPtr->refCount--;
	if (textPtr->refCount == 0) {
	    ckfree((char *) textPtr);
	}
	return;
    }

................................................................................
 *----------------------------------------------------------------------
 *
 * GenerateWidgetViewSyncEvent --
 *
 *      Send the <<WidgetViewSync>> event related to the text widget
 *      line metrics asynchronous update.
 *      This is equivalent to:
 *         event generate $textWidget <<WidgetViewSync>> -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
GenerateWidgetViewSyncEvent(
    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("WidgetViewSync");
    event.virtual.user_data = Tcl_NewIntObj(TkTextPendingsync(textPtr));
    Tk_HandleEvent(&event.general);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkTextUpdateLineMetrics --
................................................................................
     * Now re-set the current update calculations.
     */

    if (dInfoPtr->lineUpdateTimer == NULL) {
	textPtr->refCount++;
	dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		AsyncUpdateLineMetrics, (ClientData) textPtr);

    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkTextFindDisplayLineEnd --
................................................................................

	dInfoPtr->metricEpoch = -1;

	if (dInfoPtr->lineUpdateTimer == NULL) {
	    textPtr->refCount++;
	    dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		    AsyncUpdateLineMetrics, (ClientData) textPtr);

	}
    }
}
 
/*
 *----------------------------------------------------------------------
 *






|







 







<
<







 







>
>
>
>
>
>
>
>







 







|
|
>












|
>










|







 







>







 







>







586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
....
2926
2927
2928
2929
2930
2931
2932


2933
2934
2935
2936
2937
2938
2939
....
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
....
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
....
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
....
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
static int		DlineXOfIndex(TkText *textPtr,
			    DLine *dlPtr, int byteIndex);
static int		TextGetScrollInfoObj(Tcl_Interp *interp,
			    TkText *textPtr, int objc,
			    Tcl_Obj *CONST objv[], double *dblPtr,
			    int *intPtr);
static void		AsyncUpdateLineMetrics(ClientData clientData);
static void		GenerateWidgetViewSyncEvent(TkText *textPtr, Bool InSync);
static void		AsyncUpdateYScrollbar(ClientData clientData);
static int              IsStartOfNotMergedLine(TkText *textPtr,
                            CONST TkTextIndex *indexPtr);

/*
 * Result values returned by TextGetScrollInfoObj:
 */
................................................................................
    if (tkTextDebug) {
	char buffer[2 * TCL_INTEGER_SPACE + 1];

	sprintf(buffer, "%d %d", lineNum, dInfoPtr->lastMetricUpdateLine);
	LOG("tk_textInvalidateLine", buffer);
    }



    /*
     * 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.
     */

    if (dInfoPtr->metricEpoch == -1
	    && lineNum == dInfoPtr->lastMetricUpdateLine) {
................................................................................
		    Tcl_BackgroundError(textPtr->interp);
	    }
	    Tcl_Release((ClientData)textPtr->interp);
	    Tcl_DecrRefCount(textPtr->afterSyncCmd);
	    textPtr->afterSyncCmd = 0;
	}

        /*
         * Fire the <<WidgetViewSync>> event since the widget view is in sync
         * with its internal data (actually it will be after the next trip
         * through the event loop, because the widget redraws at idle-time).
         */

        GenerateWidgetViewSyncEvent(textPtr, 1);

	textPtr->refCount--;
	if (textPtr->refCount == 0) {
	    ckfree((char *) textPtr);
	}
	return;
    }

................................................................................
 *----------------------------------------------------------------------
 *
 * GenerateWidgetViewSyncEvent --
 *
 *      Send the <<WidgetViewSync>> event related to the text widget
 *      line metrics asynchronous update.
 *      This is equivalent to:
 *         event generate $textWidget <<WidgetViewSync>> -detail $s
 *      where $s is the sync status: true (when the widget view is in
 *      sync with its internal data) or false (when it is not).
 *
 * Results:
 *      None
 *
 * Side effects:
 *      If corresponding bindings are present, they will trigger.
 *
 *----------------------------------------------------------------------
 */

static void
GenerateWidgetViewSyncEvent(
    TkText *textPtr,		/* Information about text widget. */
    Bool InSync)                /* True if in sync, false otherwise */
{
    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("WidgetViewSync");
    event.virtual.user_data = Tcl_NewBooleanObj(InSync);
    Tk_HandleEvent(&event.general);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkTextUpdateLineMetrics --
................................................................................
     * Now re-set the current update calculations.
     */

    if (dInfoPtr->lineUpdateTimer == NULL) {
	textPtr->refCount++;
	dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		AsyncUpdateLineMetrics, (ClientData) textPtr);
        GenerateWidgetViewSyncEvent(textPtr, 0);
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkTextFindDisplayLineEnd --
................................................................................

	dInfoPtr->metricEpoch = -1;

	if (dInfoPtr->lineUpdateTimer == NULL) {
	    textPtr->refCount++;
	    dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		    AsyncUpdateLineMetrics, (ClientData) textPtr);
            GenerateWidgetViewSyncEvent(textPtr, 0);
	}
    }
}
 
/*
 *----------------------------------------------------------------------
 *

Changes to tests/text.test.

1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
    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 <<WidgetViewSync>> { if {%d == 0} {set yud(%W) 1} }
    # wait for end of line metrics calculation to get correct $fraction1
    # as a reference
    if {[.top.yt pendingsync]} {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






|







1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
    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 <<WidgetViewSync>> { if {%d} {set yud(%W) 1} }
    # wait for end of line metrics calculation to get correct $fraction1
    # as a reference
    if {[.top.yt pendingsync]} {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