Search code examples
tcltk-toolkit

Tcl/TK: how to prevent screen tearing?


I am messing around with canvases in TK, and have this small example of a black rectangle that follows the cursor:

package require Tk
package require Thread
ttk::frame .c
canvas .c.card
.c.card create rectangle 0 0 1000 1000 -fill green
.c.card create rectangle 0 0 100 200 -fill black -tags card
pack .c .c.card -fill both -expand 1
proc moveCard {x y} { .c.card moveto card $x $y  }
set mouseDown 0
bind . <ButtonPress> { set mouseDown 1 }
bind . <ButtonRelease> { set mouseDown 0 }
bind . <Motion> { if { $mouseDown }  {  moveCard %x %y; } }

However, when I move the rectangle fast, it "tears" - it seems like the position of rectangle is updating mid-drawing top to bottom, and so the top and bottom are in different places! By my understanding this is screen tearing, which is occuring due to the events redrawing out of sync with the screen refresh rate. However, I can't find how to enable vsync/otherwise prevent this from happening. Have I accurately diagnosed the problem, and if so how could I fix it?


Solution

  • Tk already does double buffering internally for all widgets (except perhaps menus), but knows nothing about when to do blitting of the buffer to avoid tearing; it's dependent on the lower level systems (e.g., the Xserver) handling all that.

    It sounds like this could be improved. I'm not sure what sort of notifications would be involved, if any, but they would not normally be exposed to scripts as they are things that really are the domain of the drawing engine.