diff options
author | fvogel <fvogelnew1@free.fr> | 2019-05-08 08:41:10 (GMT) |
---|---|---|
committer | fvogel <fvogelnew1@free.fr> | 2019-05-08 08:41:10 (GMT) |
commit | 590aacc76691cd115ffcd3a0b4643f5f53941cb8 (patch) | |
tree | 1383c68084b65eb1f480c669b2f696460a830db2 | |
parent | c4bbfb925fae272f474e5c33bf19fd2107821838 (diff) | |
parent | d843a7eadb157bca482e150f7298e9cf3007c85c (diff) | |
download | tk-590aacc76691cd115ffcd3a0b4643f5f53941cb8.zip tk-590aacc76691cd115ffcd3a0b4643f5f53941cb8.tar.gz tk-590aacc76691cd115ffcd3a0b4643f5f53941cb8.tar.bz2 |
Fix [2513186fff], [f9343d8f72] and [8261c517af]: ttk scrolling (xview/yview commands) is incorrect until idle tasks are run
-rw-r--r-- | doc/GetScroll.3 | 4 | ||||
-rw-r--r-- | doc/ttk_entry.n | 41 | ||||
-rw-r--r-- | doc/ttk_treeview.n | 13 | ||||
-rw-r--r-- | doc/ttk_widget.n | 78 | ||||
-rw-r--r-- | generic/ttk/ttkEntry.c | 3 | ||||
-rw-r--r-- | generic/ttk/ttkScroll.c | 26 | ||||
-rw-r--r-- | generic/ttk/ttkTreeview.c | 4 | ||||
-rw-r--r-- | generic/ttk/ttkWidget.h | 3 | ||||
-rw-r--r-- | library/ttk/entry.tcl | 1 | ||||
-rw-r--r-- | tests/ttk/entry.test | 29 | ||||
-rw-r--r-- | tests/ttk/treeview.test | 12 |
11 files changed, 157 insertions, 57 deletions
diff --git a/doc/GetScroll.3 b/doc/GetScroll.3 index 70145aa..c0b302d 100644 --- a/doc/GetScroll.3 +++ b/doc/GetScroll.3 @@ -15,10 +15,10 @@ Tk_GetScrollInfoObj, Tk_GetScrollInfo \- parse arguments for scrolling commands \fB#include <tk.h>\fR .sp int -\fBTk_GetScrollInfoObj(\fIinterp, objc, objv, dblPtr, intPtr\fB)\fR +\fBTk_GetScrollInfoObj(\fIinterp, objc, objv, fractionPtr, stepsPtr\fB)\fR .sp int -\fBTk_GetScrollInfo(\fIinterp, argc, argv, dblPtr, intPtr\fB)\fR +\fBTk_GetScrollInfo(\fIinterp, argc, argv, fractionPtr, stepsPtr\fB)\fR .SH ARGUMENTS .AS "Tcl_Interp" *fractionPtr .AP Tcl_Interp *interp in diff --git a/doc/ttk_entry.n b/doc/ttk_entry.n index 1c182ff..cb58005 100644 --- a/doc/ttk_entry.n +++ b/doc/ttk_entry.n @@ -222,52 +222,13 @@ by the \fB\-validate\fR option. Returns 0 if validation fails, 1 if it succeeds. Sets or clears the \fBinvalid\fR state accordingly. See \fBVALIDATION\fR below for more details. -.TP -\fIpathName \fBxview \fIargs\fR -This command is used to query and change the horizontal position of the -text in the widget's window. It can take any of the following -forms: -.RS -.TP -\fIpathName \fBxview\fR -Returns a list containing two elements. -Each element is a real fraction between 0 and 1; together they describe -the horizontal span that is visible in the window. -For example, if the first element is .2 and the second element is .6, -20% of the entry's text is off-screen to the left, the middle 40% is visible -in the window, and 40% of the text is off-screen to the right. -These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR -option. -.TP -\fIpathName \fBxview\fR \fIindex\fR -Adjusts the view in the window so that the character given by \fIindex\fR -is displayed at the left edge of the window. -.TP -\fIpathName \fBxview moveto\fI fraction\fR -Adjusts the view in the window so that the character \fIfraction\fR of the -way through the text appears at the left edge of the window. -\fIFraction\fR must be a fraction between 0 and 1. -.TP -\fIpathName \fBxview scroll \fInumber what\fR -This command shifts the view in the window left or right according to -\fInumber\fR and \fIwhat\fR. -\fINumber\fR must be an integer. -\fIWhat\fR must be either \fBunits\fR or \fBpages\fR. -'\" or an abbreviation of one of these, but we don't document that. -If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by -\fInumber\fR average-width characters on the display; if it is -\fBpages\fR then the view adjusts by \fInumber\fR screenfuls. -If \fInumber\fR is negative then characters farther to the left -become visible; if it is positive then characters farther to the right -become visible. -.RE .PP The entry widget also supports the following generic \fBttk::widget\fR widget subcommands (see \fIttk::widget(n)\fR for details): .DS .ta 5.5c 11c \fBcget\fR \fBconfigure\fR \fBidentify\fR -\fBinstate\fR \fBstate\fR +\fBinstate\fR \fBstate\fR \fBxview\fR .DE .SH VALIDATION .PP diff --git a/doc/ttk_treeview.n b/doc/ttk_treeview.n index 96565a3..5fd5e6d 100644 --- a/doc/ttk_treeview.n +++ b/doc/ttk_treeview.n @@ -388,12 +388,13 @@ If \fIitems\fR is omitted, removes \fItag\fR from each item in the tree. If \fItag\fR is not present for a particular item, then the \fB\-tags\fR for that item are unchanged. .RE -.TP -\fIpathName \fBxview \fIargs\fR -Standard command for horizontal scrolling; see \fIwidget(n)\fR. -.TP -\fIpathName \fByview \fIargs\fR -Standard command for vertical scrolling; see \fIttk::widget(n)\fR. +.PP +The treeview widget also supports the following generic \fBttk::widget\fR +widget subcommands (see \fIttk::widget(n)\fR for details): +.DS +.ta 5.5c 11c +\fBxview\fR \fByview\fR +.DE .SH "ITEM OPTIONS" .PP The following item options may be specified for items diff --git a/doc/ttk_widget.n b/doc/ttk_widget.n index 9e9f3db..b1c280d 100644 --- a/doc/ttk_widget.n +++ b/doc/ttk_widget.n @@ -224,6 +224,84 @@ will restore \fIpathName\fR to the original state. If \fIstateSpec\fR is not specified, returns a list of the currently-enabled state flags. .RE +.TP +\fIpathName \fBxview \fIargs\fR +This command is used to query and change the horizontal position of the +content in the widget's window. It can take any of the following +forms: +.RS +.TP +\fIpathName \fBxview\fR +Returns a list containing two elements. +Each element is a real fraction between 0 and 1; together they describe +the horizontal span that is visible in the window. +For example, if the first element is .2 and the second element is .6, +20% of the widget's content is off-screen to the left, the middle 40% is visible +in the window, and 40% of the content is off-screen to the right. +These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR +option. +.TP +\fIpathName \fBxview\fR \fIindex\fR +Adjusts the view in the window so that the content given by \fIindex\fR +is displayed at the left edge of the window. +.TP +\fIpathName \fBxview moveto\fI fraction\fR +Adjusts the view in the window so that the character \fIfraction\fR of the +way through the content appears at the left edge of the window. +\fIFraction\fR must be a fraction between 0 and 1. +.TP +\fIpathName \fBxview scroll \fInumber what\fR +This command shifts the view in the window left or right according to +\fInumber\fR and \fIwhat\fR. +\fINumber\fR must be an integer. +\fIWhat\fR must be either \fBunits\fR or \fBpages\fR. +'\" or an abbreviation of one of these, but we don't document that. +If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by +\fInumber\fR average-width characters on the display; if it is +\fBpages\fR then the view adjusts by \fInumber\fR screenfuls. +If \fInumber\fR is negative then characters farther to the left +become visible; if it is positive then characters farther to the right +become visible. +.RE +.TP +\fIpathName \fByview \fIargs\fR +This command is used to query and change the vertical position of the +content in the widget's window. It can take any of the following +forms: +.RS +.TP +\fIpathName \fByview\fR +Returns a list containing two elements. +Each element is a real fraction between 0 and 1; together they describe +the vertical span that is visible in the window. +For example, if the first element is .2 and the second element is .6, +20% of the widget's content is off-screen to the top, the middle 40% is visible +in the window, and 40% of the content is off-screen to the bottom. +These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR +option. +.TP +\fIpathName \fByview\fR \fIindex\fR +Adjusts the view in the window so that the content given by \fIindex\fR +is displayed at the top edge of the window. +.TP +\fIpathName \fByview moveto\fI fraction\fR +Adjusts the view in the window so that the item \fIfraction\fR of the +way through the content appears at the top edge of the window. +\fIFraction\fR must be a fraction between 0 and 1. +.TP +\fIpathName \fByview scroll \fInumber what\fR +This command shifts the view in the window up or down according to +\fInumber\fR and \fIwhat\fR. +\fINumber\fR must be an integer. +\fIWhat\fR must be either \fBunits\fR or \fBpages\fR. +'\" or an abbreviation of one of these, but we don't document that. +If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by +\fInumber\fR average-width characters on the display; if it is +\fBpages\fR then the view adjusts by \fInumber\fR screenfuls. +If \fInumber\fR is negative then items farther to the top +become visible; if it is positive then items farther to the bottom +become visible. +.RE .SH "WIDGET STATES" The widget state is a bitmap of independent state flags. Widget state flags include: diff --git a/generic/ttk/ttkEntry.c b/generic/ttk/ttkEntry.c index 4e702be..bde3a0c 100644 --- a/generic/ttk/ttkEntry.c +++ b/generic/ttk/ttkEntry.c @@ -1403,6 +1403,7 @@ EntryIndex( *indexPtr = Tk_PointToChar(entryPtr->entry.textLayout, x - entryPtr->entry.layoutX, 0); + TtkUpdateScrollInfo(entryPtr->entry.xscrollHandle); if (*indexPtr < entryPtr->entry.xscroll.first) { *indexPtr = entryPtr->entry.xscroll.first; } @@ -1697,7 +1698,7 @@ static int EntryXViewCommand( if (EntryIndex(interp, entryPtr, objv[2], &newFirst) != TCL_OK) { return TCL_ERROR; } - TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst); + TtkScrollTo(entryPtr->entry.xscrollHandle, newFirst, 1); return TCL_OK; } return TtkScrollviewCommand(interp, objc, objv, entryPtr->entry.xscrollHandle); diff --git a/generic/ttk/ttkScroll.c b/generic/ttk/ttkScroll.c index 184f5f2..47db6ac 100644 --- a/generic/ttk/ttkScroll.c +++ b/generic/ttk/ttkScroll.c @@ -181,6 +181,19 @@ void TtkScrollbarUpdateRequired(ScrollHandle h) h->flags |= SCROLL_UPDATE_REQUIRED; } +/* TtkUpdateScrollInfo -- + * Call the layoutProc to update the scroll info first, last, and total. + * Do it only if needed, that is when a redisplay is pending (which + * indicates scroll info are possibly out of date). + */ + +void TtkUpdateScrollInfo(ScrollHandle h) +{ + if (h->corePtr->flags & REDISPLAY_PENDING) { + h->corePtr->widgetSpec->layoutProc(h->corePtr); + } +} + /* TtkScrollviewCommand -- * Widget [xy]view command implementation. * @@ -193,7 +206,10 @@ int TtkScrollviewCommand( Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle h) { Scrollable *s = h->scrollPtr; - int newFirst = s->first; + int newFirst; + + TtkUpdateScrollInfo(h); + newFirst = s->first; if (objc == 2) { Tcl_Obj *result[2]; @@ -226,15 +242,19 @@ int TtkScrollviewCommand( } } - TtkScrollTo(h, newFirst); + TtkScrollTo(h, newFirst, 0); return TCL_OK; } -void TtkScrollTo(ScrollHandle h, int newFirst) +void TtkScrollTo(ScrollHandle h, int newFirst, int updateScrollInfo) { Scrollable *s = h->scrollPtr; + if (updateScrollInfo) { + TtkUpdateScrollInfo(h); + } + if (newFirst >= s->total) newFirst = s->total - 1; if (newFirst > s->first && s->last >= s->total) /* don't scroll past end */ diff --git a/generic/ttk/ttkTreeview.c b/generic/ttk/ttkTreeview.c index cc2c9e1..64e25aa 100644 --- a/generic/ttk/ttkTreeview.c +++ b/generic/ttk/ttkTreeview.c @@ -2843,10 +2843,10 @@ static int TreeviewSeeCommand( */ rowNumber = RowNumber(tv, item); if (rowNumber < tv->tree.yscroll.first) { - TtkScrollTo(tv->tree.yscrollHandle, rowNumber); + TtkScrollTo(tv->tree.yscrollHandle, rowNumber, 1); } else if (rowNumber >= tv->tree.yscroll.last) { TtkScrollTo(tv->tree.yscrollHandle, - tv->tree.yscroll.first + (1+rowNumber - tv->tree.yscroll.last)); + tv->tree.yscroll.first + (1+rowNumber - tv->tree.yscroll.last), 1); } return TCL_OK; diff --git a/generic/ttk/ttkWidget.h b/generic/ttk/ttkWidget.h index 798bcce..6cd691b 100644 --- a/generic/ttk/ttkWidget.h +++ b/generic/ttk/ttkWidget.h @@ -195,7 +195,8 @@ MODULE_SCOPE void TtkFreeScrollHandle(ScrollHandle); MODULE_SCOPE int TtkScrollviewCommand( Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], ScrollHandle); -MODULE_SCOPE void TtkScrollTo(ScrollHandle, int newFirst); +MODULE_SCOPE void TtkUpdateScrollInfo(ScrollHandle h); +MODULE_SCOPE void TtkScrollTo(ScrollHandle, int newFirst, int updateScrollInfo); MODULE_SCOPE void TtkScrolled(ScrollHandle, int first, int last, int total); MODULE_SCOPE void TtkScrollbarUpdateRequired(ScrollHandle); diff --git a/library/ttk/entry.tcl b/library/ttk/entry.tcl index c123bc9..e9f249c 100644 --- a/library/ttk/entry.tcl +++ b/library/ttk/entry.tcl @@ -211,7 +211,6 @@ proc ttk::entry::ClosestGap {w x} { ## See $index -- Make sure that the character at $index is visible. # proc ttk::entry::See {w {index insert}} { - update idletasks ;# ensure scroll data up-to-date set c [$w index $index] # @@@ OR: check [$w index left] / [$w index right] if {$c < [$w index @0] || $c >= [$w index @[winfo width $w]]} { diff --git a/tests/ttk/entry.test b/tests/ttk/entry.test index d303446..0ff0f2f 100644 --- a/tests/ttk/entry.test +++ b/tests/ttk/entry.test @@ -103,10 +103,37 @@ test entry-3.1 "bbox widget command" -body { test entry-3.2 "xview" -body { .e delete 0 end; .e insert end [string repeat "0" 40] - update idletasks set result [.e xview] } -result {0.0 0.5} +test entry-3.3 "xview" -body { + .e delete 0 end; + .e insert end abcdefghijklmnopqrstuvwxyz + .e xview end + set result [.e index @0] +} -result {7} + +test entry-3.4 "xview" -body { + .e delete 0 end; + .e insert end abcdefghijklmnopqrstuvwxyz + .e xview moveto 1.0 + set result [.e index @0] +} -result {7} + +test entry-3.5 "xview" -body { + .e delete 0 end; + .e insert end abcdefghijklmnopqrstuvwxyz + .e xview scroll 5 units + set result [.e index @0] +} -result {5} + +test entry-3.6 "xview" -body { + .e delete 0 end; + .e insert end [string repeat abcdefghijklmnopqrstuvwxyz 5] + .e xview scroll 2 pages + set result [.e index @0] +} -result {40} + test entry-3.last "Series 3 cleanup" -body { destroy .e } diff --git a/tests/ttk/treeview.test b/tests/ttk/treeview.test index be82f68..a36e3d1 100644 --- a/tests/ttk/treeview.test +++ b/tests/ttk/treeview.test @@ -471,6 +471,18 @@ test treeview-9.0 "scroll callback - empty tree" -body { set ::scrolldata } -result [list 0.0 1.0] +test treeview-9.1 "scrolling" -setup { + pack [ttk::treeview .tree -show tree] -fill y + for {set i 1} {$i < 100} {incr i} { + .tree insert {} end -text $i + } +} -body { + .tree yview scroll 5 units + .tree identify item 2 2 +} -cleanup { + destroy .tree +} -result {I006} + ### identify tests: # proc identify* {tv comps args} { |