Tk Source Code

Changes On Branch bug-b68710aed6
Login

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

Changes In Branch bug-b68710aed6 Excluding Merge-Ins

This is equivalent to a diff from 8acca87b to 6e14c473

2018-01-28
15:45
Fix [b68710aed6]: Minor fixes to library/text.tcl bindings, and generation of <<Selection>> events. Legacy text widget. check-in: c53966de user: fvogel tags: core-8-6-branch
2018-01-18
00:42
Deal with the case of selection modification by insertion. All tests about <<Selection>> now pass, and no test is newly failing. Closed-Leaf check-in: 6e14c473 user: fvogel tags: bug-b68710aed6
00:29
Add more <<Selection>> event generation tests. check-in: 14510abd user: fvogel tags: bug-b68710aed6
2018-01-16
16:27
Make Tk 8.6 loadable in a TIP #484-enhanced Tcl 8.7. Backported from trunk. check-in: 93487383 user: jan.nijtmans tags: core-8-6-branch
2018-01-14
15:18
Take some proposals from kjnash in [b68710aed6], namely 1. Add test of -state normal to <Meta-d>, and 2. Don't add autoseparators when doing <<Cut>> if the widget is disabled and the operation is therefore only a <<Copy>>. check-in: b3f05000 user: fvogel tags: bug-b68710aed6
14:54
Fix [1821174fff] and [1938774fff]: RenderBadPicture (invalid Picture parameter) error returned on application exit when 'send' was renamed to {}. Patch from Christian Werner. check-in: a597a915 user: fvogel tags: bug-1938774fff, bug-1821174fff
2018-01-13
13:50
Fix [657c389120] and [b4214b4712]: Segfault when destroying menu with checkbutton entry Closed-Leaf check-in: 95cf2308 user: fvogel tags: bug-b4214b4712, bug-657c389120
2018-01-10
20:45
Fix [382712ade6]: X11: 'event generate . <KeyPress>' segfaults. Patch from Christian Werner. check-in: 2f691822 user: fvogel tags: bug-382712ade6
2018-01-08
11:22
merge core-8-6-branch check-in: 06baa487 user: jan.nijtmans tags: trunk
09:12
merge core-8-6-branch check-in: 72b54f9a user: jan.nijtmans tags: bug-00a27923ee
09:03
Some code cleanup, suggested by Christian Werner. Cherry-picked from bug-00a27923ee branch. check-in: 8acca87b user: jan.nijtmans tags: core-8-6-branch
2018-01-07
15:42
Complement fix for [84af709826] about alphabetical order of the widget-specific options of ttk:spinbox. check-in: 72cf11e4 user: fvogel tags: core-8-6-branch

Changes to generic/tkText.c.

2722
2723
2724
2725
2726
2727
2728
2729

2730
2731
2732



2733
2734
2735
2736
2737
2738
2739
	resetViewCount += 2;
    }
    if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
	ckfree(lineAndByteIndex);
    }

    /*
     * Invalidate any selection retrievals in progress.

     */

    for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {



	tPtr->abortSelections = 1;
    }

    /*
     * For convenience, return the length of the string.
     */








|
>



>
>
>







2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
	resetViewCount += 2;
    }
    if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
	ckfree(lineAndByteIndex);
    }

    /*
     * Invalidate any selection retrievals in progress, and send an event
     * that the selection changed if that is the case.
     */

    for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
        if (TkBTreeCharTagged(indexPtr, tPtr->selTagPtr)) {
            TkTextSelectionEvent(tPtr);
        }
	tPtr->abortSelections = 1;
    }

    /*
     * For convenience, return the length of the string.
     */

3065
3066
3067
3068
3069
3070
3071



3072
3073
3074
3075
3076
3077
3078
{
    int line1, line2;
    TkTextIndex index1, index2;
    TkText *tPtr;
    int *lineAndByteIndex;
    int resetViewCount;
    int pixels[2*PIXEL_CLIENTS];




    if (sharedTextPtr == NULL) {
	sharedTextPtr = textPtr->sharedTextPtr;
    }

    /*
     * Prepare the starting and stopping indices.







>
>
>







3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
{
    int line1, line2;
    TkTextIndex index1, index2;
    TkText *tPtr;
    int *lineAndByteIndex;
    int resetViewCount;
    int pixels[2*PIXEL_CLIENTS];
    Tcl_HashSearch search;
    Tcl_HashEntry *hPtr;
    int i;

    if (sharedTextPtr == NULL) {
	sharedTextPtr = textPtr->sharedTextPtr;
    }

    /*
     * Prepare the starting and stopping indices.
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
	    for (i = 0; i < arraySize; i++) {
		TkBTreeTag(&index2, &oldIndex2, arrayPtr[i], 0);
	    }
	    ckfree(arrayPtr);
	}
    }

    if (line1 < line2) {
	/*
	 * We are deleting more than one line. For speed, we remove all tags
	 * from the range first. If we don't do this, the code below can (when
	 * there are many tags) grow non-linearly in execution time.
	 */

	Tcl_HashSearch search;
	Tcl_HashEntry *hPtr;
	int i;

	for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
		hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {
	    TkTextTag *tagPtr = Tcl_GetHashValue(hPtr);

	    TkBTreeTag(&index1, &index2, tagPtr, 0);
	}

	/*
	 * Special case for the sel tag which is not in the hash table. We
	 * need to do this once for each peer text widget.
	 */

	for (tPtr = sharedTextPtr->peers; tPtr != NULL ;
		tPtr = tPtr->next) {
	    if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) {
		/*
		 * Send an event that the selection changed. This is
		 * equivalent to:
		 *	event generate $textWidget <<Selection>>
		 */

		TkTextSelectionEvent(textPtr);
		tPtr->abortSelections = 1;
	    }
	}
    }

    /*
     * Tell the display what's about to happen so it can discard obsolete
     * display information, then do the deletion. Also, if the deletion
     * involves the top line on the screen, then we have to reset the view
     * (the deletion will invalidate textPtr->topIndex). Compute what the new







<
|
|
|
|
|

<
<
<
<
|
|
|

|
|

|
|
|
|

|
|
|
|
|
|
|
|

|
|
|
<







3136
3137
3138
3139
3140
3141
3142

3143
3144
3145
3146
3147
3148




3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172

3173
3174
3175
3176
3177
3178
3179
	    for (i = 0; i < arraySize; i++) {
		TkBTreeTag(&index2, &oldIndex2, arrayPtr[i], 0);
	    }
	    ckfree(arrayPtr);
	}
    }


    /*
     * For speed, we remove all tags from the range first. If we don't
     * do this, the code below can (when there are many tags) grow
     * non-linearly in execution time.
     */





    for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
	    hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {
        TkTextTag *tagPtr = Tcl_GetHashValue(hPtr);

        TkBTreeTag(&index1, &index2, tagPtr, 0);
    }

    /*
     * Special case for the sel tag which is not in the hash table. We
     * need to do this once for each peer text widget.
     */

    for (tPtr = sharedTextPtr->peers; tPtr != NULL ;
	    tPtr = tPtr->next) {
        if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) {
	    /*
	     * Send an event that the selection changed. This is
	     * equivalent to:
	     *	event generate $textWidget <<Selection>>
	     */

	    TkTextSelectionEvent(textPtr);
	    tPtr->abortSelections = 1;
        }

    }

    /*
     * Tell the display what's about to happen so it can discard obsolete
     * display information, then do the deletion. Also, if the deletion
     * involves the top line on the screen, then we have to reset the view
     * (the deletion will invalidate textPtr->topIndex). Compute what the new

Changes to library/text.tcl.

1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
# w -		Name of a text widget.

proc ::tk_textCut w {
    if {![catch {set data [$w get sel.first sel.last]}]} {
        # make <<Cut>> an atomic operation on the Undo stack,
        # i.e. separate it from other delete operations on either side
	set oldSeparator [$w cget -autoseparators]
	if {$oldSeparator} {
	    $w edit separator
	}
	clipboard clear -displayof $w
	clipboard append -displayof $w $data
	$w delete sel.first sel.last
	if {$oldSeparator} {
	    $w edit separator
	}
    }
}

# ::tk_textPaste --
# This procedure pastes the contents of the clipboard to the insertion







|





|







1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
# w -		Name of a text widget.

proc ::tk_textCut w {
    if {![catch {set data [$w get sel.first sel.last]}]} {
        # make <<Cut>> an atomic operation on the Undo stack,
        # i.e. separate it from other delete operations on either side
	set oldSeparator [$w cget -autoseparators]
	if {([$w cget -state] eq "normal") && $oldSeparator} {
	    $w edit separator
	}
	clipboard clear -displayof $w
	clipboard append -displayof $w $data
	$w delete sel.first sel.last
	if {([$w cget -state] eq "normal") && $oldSeparator} {
	    $w edit separator
	}
    }
}

# ::tk_textPaste --
# This procedure pastes the contents of the clipboard to the insertion

Changes to tests/text.test.

6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404













6405
6406
6407
6408
6409



























































































6410
6411
6412
6413
6414
6415
6416
    .t insert end "This increments ::retval once for each peer, i.e. twice."
    .t edit modified 0  ; # shall increment twice as well, not just once
    update
    set ::retval
} -cleanup {
    destroy .t .tt
} -result {4}
test text-27.15 {<<Selection>> virtual event} -body {
    set ::retval no_selection
    pack [text .t -undo 1]
    bind .t <<Selection>> "set ::retval selection_changed"
    update idletasks
    .t insert end "nothing special\n"
    .t tag add sel 1.0 1.1













    update
    set ::retval
} -cleanup {
    destroy .t
} -result {selection_changed}



























































































test text-27.16 {-maxundo configuration option} -body {
    text .t -undo 1  -autoseparators 1 -maxundo 2
    pack .t
    .t insert end "line 1\n"
    .t delete 1.4 1.6
    .t insert end "line 2\n"
    catch {.t edit undo}







|

|




>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
    .t insert end "This increments ::retval once for each peer, i.e. twice."
    .t edit modified 0  ; # shall increment twice as well, not just once
    update
    set ::retval
} -cleanup {
    destroy .t .tt
} -result {4}
test text-27.15 {<<Selection>> virtual event on sel tagging} -body {
    set ::retval no_selection
    pack [text .t]
    bind .t <<Selection>> "set ::retval selection_changed"
    update idletasks
    .t insert end "nothing special\n"
    .t tag add sel 1.0 1.1
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {selection_changed}
test text-27.15a {<<Selection>> virtual event on sel removal} -body {
    set ::retval no_selection
    pack [text .t]
    .t insert end "nothing special\n"
    .t tag add sel 1.0 1.1
    bind .t <<Selection>> "set ::retval selection_changed"
    update idletasks
    .t tag remove 1.0 end
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {selection_changed}
test text-27.15b {<<Selection>> virtual event on <<PasteSelection>> inside widget selection} -body {
    pack [text .t]
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "and it will be impacted by the <<PasteSelection>> event received.\n"
    .t insert end "Therefore a <<Selection>> event must fire back."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    event generate .t <<PasteSelection>> -x 15 -y 3
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {<<Selection>>_fired}
test text-27.15c {No <<Selection>> virtual event on <<PasteSelection>> outside widget selection} -body {
    pack [text .t]
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "but it will not be impacted by the <<PasteSelection>> event received."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    event generate .t <<PasteSelection>> -x 15 -y 80
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {no_<<Selection>>_event_fired}
test text-27.15d {<<Selection>> virtual event on <Delete> with cursor inside selection} -body {
    pack [text .t]
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "and it will be impacted by the <Delete> event received.\n"
    .t insert end "Therefore a <<Selection>> event must fire back."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    .t mark set insert 1.15
    focus .t
    event generate .t <Delete>
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {<<Selection>>_fired}
test text-27.15e {No <<Selection>> virtual event on <Delete> with cursor outside selection} -body {
    pack [text .t]
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "but it will not be impacted by the <Delete> event received."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    .t mark set insert 2.15
    focus .t
    event generate .t <Delete>
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {no_<<Selection>>_event_fired}
test text-27.15f {<<Selection>> virtual event on <<Cut>> with a widget selection} -body {
    pack [text .t]
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "and it will be impacted by the <<Cut>> event received.\n"
    .t insert end "Therefore a <<Selection>> event must fire back."
    .t tag add sel 1.0 1.28
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    event generate .t <<Cut>>
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {<<Selection>>_fired}
test text-27.15g {No <<Selection>> virtual event on <<Cut>> without widget selection} -body {
    pack [text .t]
    .t insert end "There is a selection in this text widget,\n"
    .t insert end "and it will be impacted by the <<Cut>> event received.\n"
    .t insert end "Therefore a <<Selection>> event must fire back."
    bind .t <<Selection>> "set ::retval <<Selection>>_fired"
    update
    set ::retval no_<<Selection>>_event_fired
    event generate .t <<Cut>>
    update
    set ::retval
} -cleanup {
    destroy .t
} -result {no_<<Selection>>_event_fired}
test text-27.16 {-maxundo configuration option} -body {
    text .t -undo 1  -autoseparators 1 -maxundo 2
    pack .t
    .t insert end "line 1\n"
    .t delete 1.4 1.6
    .t insert end "line 2\n"
    catch {.t edit undo}