TIP 765: Support for off-screen rendering in macOS

Login
Author:         Marc Culler
State:          Draft
Type:           Project
Created:        2026-10-13
Tcl-Version:    9.1
Tcl-Branch:     tip_765
Keywords:       hidden off-screen
Vote:           
Vote-Summary:   
Votes-For:      
Votes-Against:  
Votes-Present:  

Abstract

This TIP proposes to add support for off-screen rendering of toplevel windows in the macOS Aqua port of Tk. It adds one attribute (-hidden) to the list of attributes supported by the wm attributes command.

Target

This TIP targets version 9.1 of Tk.

Rationale

It is a useful feature in any GUI toolkit to be able to render a complex window off screen and show it only after it hss been completely rendered. The alternative is to make the user watch the flashes and incremental changes as widgets are laid out and drawn into the window. Rendering the window off screen and presenting it in a single display cycle is a much better user experience.

A common paradigm in Tk, to accomplish this, is:

wm withdraw .
renderWindow
wm deiconify .
Unfortunately, this does not really work on macOS if it takes more than 200 milliseconds to render the window. Even when the withdraw command runs before the root window is displayed, avoiding a flash, the rendering takes place after the wm deiconify command has shown the window on the screen.

The primary issue is that when a window is withdrawn, it and all of its widgets are not mapped, and display procs are not generated as idle tasks for a widget that is not mapped. So, even if the geometry managers have computed the size and positions of all of the widgets, the actual rendering does not happen until the window and its widgets get mapped during the wm deiconify command.

At the language level, the proposed replacement for this paradigm is:

wm attributes . -hidden 1
renderWindow
wm attributes . -hidden 0

The key idea which makes this work is that the state of the -hidden attribute has no effect at all on any of the Tk data structures describing the window or the operations which Tk can perform on it. A window whose -hidden attribute is 1 can be resized, reconfigured, withdrawn, iconified, deiconified or drawn in exactly the same way, with exactly the same code as a window whose -hidden attribute is 0.

The key technical feature which makes this work is that, starting with Tk 9.0, each window has a CGImage backing store which holds the current image of the window. Drawing to the backing store is identical whether the window is displayed on the screen or not. This make the implementation very simple. An AppKit NSWindow has methods orderFront and orderOut which have the effect of showing or hiding the window. These have no effect on the graphics state of the window, but only determine whether the compositor displays that graphics state at the current time. So the main thing that is needed is to replace orderFront by a different method which calls orderFront if the -hidden attribute is 0 and does nothing if the attribute is 1. I don't think this would have been possible with Tk 8.6 because the dsrawRect method used in 8.6 did not give Tk control of the window backing store. The implementaiona also calls orderOut if the -hidden attribute is changed from 0 to 1 and may, depending on the Tk state of the window, call orderFront if the value of the -hidden attribute is changed from 1 to 0.

Specification

The following command will be made available on macOS.

Compatibility

This TIP does not propose to implement the -hidden attribute for Window or linux. But the identical language feature should be usable on any platform. The key step for an implementation would be identifying or creating the analogues of orderFront and orderOut. This will be straightforward for Wayland and may also be straightforward for X11 and Windows.

Reference Implementation

The TIP is implemented in the branch tip_765 in the Tk fossil repository.

Copyright

This document has been placed in the public domain.