Shimmering in Tk

Tk has its own shimmering. It is when you have widgets with dark backrounds and try to switch between the widgets' shows. Another road to the shimmering hell is paved with intentions to have a toplevel window of a certain geometry which can be easily obtained with a shimmering ghost alongside.

For example, in TKE editor when you set a dark theme and try to switch between tabs of the tab bar, you see a short flash of light background before showing a text, as a rule (but not as a strict rule) seen at the first presentation of the text.

But even when you have ttk::frame styled so that it has a dark background, you can see (though mild, yet seen) shimmering. Example of this is presented by alited editor's versions before 1.3.5 (when black themed too): in its "Preferences" when you switched between tabs, you could see shimmering of two dark backgrounds. It's related to the fact that alited uses two main backgrounds: one for the base, one for the fields like entry, text etc. And you can style ttk::frame to have only one of them.

In complex layouts, overcoming this annoyance can become a tricky task, because the problem can reveal itself in most unusual places.

Perhaps, it would be nice for Tk to have a couple of commands like freeze widget / unfreeze widget, so that you might to do all you need with a "frozen" widget and its children and then unfreeze it to show the result only, without the intermediate changes being seen.

Still, I'd like to share my tiny experience about this "fight against shimmering".

1. Immediately after loading Tk, hide its generic window, i.e. the following pair should be a must for your GUI apps:

    package require Tk
    wm withdraw .

2. For the same reason, never rely on wish as a starter of your applications. wish is good as a Tcl/Tk shell only. In particular, never use Unix's shebangs like this:

    #! /usr/bin/env wish

Otherwise, at start of your applications, you will enjoy a little window flashing in the screen center.

3. When a toplevel window has to be shown, hide it immediately after creation and show after GUI done (setting its geometry before deiconifying):

    toplevel $wtop {*}$options
    wm withdraw $wtop
    # ... then populating $wtop
    wm geometry $wtop $geom
    wm deiconify $wtop

4. When a toplevel window has to be centered over a parent window, use ::tk::PlaceWindow this way

    ::tk::PlaceWindow $win widget $parent

5. You might smile but label and ttk::label both can be used as containers instead of frame and ttk::frame, though not replacing them in other aspects. At that, in my opinion, label is a more flexible type as it allows to configure a specific widget without touching others. The use of labels can solve problems with shimmering in some specific cases. For example, in alited, only a label container removed shimmering of embedded calendar (no other means helped).

6. Also, frame can be used instead of ttk::frame for the same reason: it allows to configure a specific widget without touching others.

7. A toplevel window (notebook tabs etc.) can have a base frame to include all other widgets, so that the base frame will define the background. Thus it will remove the shimmering backgrounds:

    toplevel $wtop ...
    set base [frame $wtop.baseframe ...]
    set lab1 [ttk::label $base.lab1 ...]
    set ent1 [ttk::entry $base.ent1 ...]
    ...