Tk Source Code

View Ticket
Login
Ticket UUID: 991849
Title: removal/optimization of scrollbar events?
Type: Bug Version: 8.4.6, 8.6.18, 9.0.5, 9.1b1
Submitter: jfontain Created on: 2004-07-15 19:52:07
Subsystem: 48. Geometry Management Assigned To: aku
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2026-10-05 13:18:49
Resolution: Fixed Closed By: nemethi
    Closed on: 2026-10-05 13:18:49
Description:
While developing my application, I noticed that in some
cases, I got scroll commands invocations with
exceedingly small first and last range.
For example:

proc echo {args} {
  foreach argument $args {puts -nonewline "$argument "}
  puts {}
}
.canvas configure -xscrollcommand echo

would, in some cases, give:
0 0.00201613

Since I use this type of code to automatically manage
scrollbars (displayed only when needed), I end up with
scrollbars displayed when they should not, as the event
above implies that a scrollbar is needed (last - first
< 1).

At the time these events happen, and after looking at
the 8.4.6 tkCanvas.c source code, [winfo width .canvas]
= 1, which means that these events are not really
valid, in the sense that the canvas is not really
"displayed" yet (my interpretation).

I traced the problem (if that is indeed one) using
printf() calls, in ConfigureCanvas():

  ...
    printf("canvasPtr->xOrigin = %d,
Tk_Width(canvasPtr->tkwin) = %d\n",  
canvasPtr->xOrigin, Tk_Width(canvasPtr->tkwin));
    Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
      canvasPtr->xOrigin, canvasPtr->yOrigin,
      canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
      canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
    return TCL_OK;
  }

which gives:

  canvasPtr->xOrigin = 0, Tk_Width(canvasPtr->tkwin) = 1

followed by, in Tk_CanvasEventuallyRedraw():

  ...
  if (!(canvasPtr->flags & REDRAW_PENDING)) {
    printf("canvasPtr->redrawX1 = %d,
canvasPtr->redrawX2 = %d\n", canvasPtr->redrawX1,
canvasPtr->redrawX2);
    Tcl_DoWhenIdle(DisplayCanvas, (ClientData) canvasPtr);
    canvasPtr->flags |= REDRAW_PENDING;
  }
}

which gives:

  canvasPtr->redrawX1 = 0, canvasPtr->redrawX2 = 1

followed by the invocation of the X scroll command with
first = 0, last = 0.00201613, as described before.

Now there are quite many "invalid" events of this sort,
which invoke commands at the Tcl level. Filtering these
out at the C code level (when [winfo width/height] = 1,
as I now do at the Tcl level in my automatic scrollbar
code) would possibly improve Tk display performance and
remove some display errors.

What do you think? 

Best regards,

Jean-Luc
User Comments: nemethi (claiming to be Csaba Nemethi) added on 2026-10-05 13:18:49:

Serhiy, many thanks for fixing this very long-standing bug! Merged into main, core-9-0-branch, and core-8-6-branch by commits [aa35622f], [9ec29de9], and [d23599f1].


serhiy.storchaka added on 2026-09-28 18:56:25:

Still reproducible with 9.1: the canvas and the text call the scroll commands before the window is mapped, when it has size 1x1 (e.g. 0.004 0.004 for a canvas whose scroll region fits in it). A ttk::treeview does the same if xview or yview is called before mapping. The listbox postpones the call until the window is mapped.

Proposed fix in branch scroll-command-unmapped: the canvas, the text and ttk scrollable widgets postpone the call in the same way. This also fixes the error in [a137728410] (the scroll command is called before the scrollbar is created).

Related: [7d8d10e4a9] is the performance side of this (proposed fix: use the requested size for the layout).


dgp added on 2005-06-02 02:31:17:
Logged In: YES 
user_id=80530


must have been a slip of
the mouse that assigned
this to me.