# TIP 321: Add a [tk busy] Command
	Author:         Jos Decoster <jos.decoster@gmail.com>
	State:          Final
	Type:           Project
	Vote:           Done
	Created:        26-Jun-2008
	Post-History:   
	Keywords:       Tk,BLT,busy
	Tcl-Version:    8.6
	Tk-Ticket:      1997907
-----

# Abstract

The **blt::busy** commands can be used to make Tk widget busy, with all user
interaction blocked and the cursor can be changed to e.g. a clock. This TIP
proposes to add this useful feature to Tk.

# Rationale

BLT has a lot of very useful commands: **bgexec**, **busy**, **vector**,
**graph** widget, **barchart** widget, ... But getting BLT to work with
the latest releases of Tcl and Tk becomes more and more difficult. Some of the
problems I experienced are:

 * internal Tk structures are mirrored

 * interaction with xft fails, so Tk has to be build without xft support

 * the build process is different from the one used in Tcl and Tk

Discussions on CLT and \#tcl indicated that extracting functionality from BLT
and add it to Tcl and Tk might be a good way to make the blt commands
available for every Tcl programmer.

This TIP proposes a way to add the **blt::busy** command to Tk, based on the code
as found in BLT2.4z and the code as found in busy.kit. While adding the code
to Tk, it was rewritten to use the Tcl\_Obj interface and the new option
interface. The interface has also been simplified. The **blt::release**
command was not withheld. Because often the same window is made busy again and
again, using **release** in stead of **forget** might be faster. But when
making an application busy, it's because it'll have to wait for another
operation and/or process to finish which will typically take a much longer
time than the time needed to \(re\)create the transparent window. The
**names** and **isbusy** commands were replaced by the new **current**
command. The confusing difference between a window which is busy, a window
which was busy but still has the associated transparent window allocated and a
window which was busy but no longer has its associated transparent window
allocated was removed.

The name of this new Tk command as currently implemented is **tk busy**,
part of the **tk** command ensemble. Adding it as an option to the
**grab** command might cause confusion as the **tk busy** command has the
opposite functionality of the **grab** command. It blocks all user
interaction rather than redirecting it to one widget.

# Specification

The **tk busy** command is an ensemble with a special feature that any
unrecognized subcommand that starts with a period is treated as an invokation
of the **hold** subcommand upon the widget with that name.

## Hold Subcommand

 > **tk busy** _window_ ?_option value_?

 > **tk busy hold** _window_ ?_option value_?

Makes the window \(and its descendants in the Tk window hierarchy\) appear busy by
ignoring all events sent to the window and its descendants. _Window_ must be a
valid path name of a Tk widget. A transparent window is put in front of the
specified window. This transparent window is mapped the next time idle tasks are
processed, and the specified window and its descendants will be blocked from
user interactions. Normally update should be called immediately afterward to
insure that the hold operation is in effect before the application starts its
processing. The following configuration options are valid:

 > **-cursor** _cursorName_ 

Specifies the cursor to be displayed when the widget is made busy. CursorName can be in any form accepted by Tk\_GetCursor. The default cursor is watch.

## Forget Subcommand

 > **tk busy forget** _window_

Releases resources allocated by the **tk busy** command for _window_,
including the transparent window. User events will again be received by the
specified window. Resources are also released when the specified window is
destroyed. _Window_ must be the name of a widget previously specified in a
**hold** operation, otherwise an error is reported.

## Current Subcommand

 > **tk busy current** ?_pattern_?

Returns the pathnames of all windows that are currently made busy. If a
_pattern_ is given, only the path names of busy windows matching _pattern_
are returned.

## Status Subcommand

 > **tk busy status** _window_

Returns the busy status of a _window_. If _window_ presently can not
receive user interactions, 1 is returned, otherwise 0.

## Configure Subcommand

 > **tk busy configure** _window_ ?_option_? ?_value ..._?

Queries or modifies the **tk busy** command configuration options for
_window_. _Window_ must be the path name of a widget previously made busy
by the **hold** operation. If no options are specified, a list describing
all of the available options for window \(see **Tk\_ConfigureInfo** for
information on the format of this list\) is returned. If _option_ is
specified with no _value_, then the command returns a list describing the
one named option \(this list will be identical to the corresponding sublist of
the value returned if no option is specified\). If one or more _option-value_
pairs are specified, then the command modifies the given widget option\(s\) to
have the given value\(s\); in this case the command returns the empty
string. Options may have any of the values accepted by the hold operation.

Please note that the option database is referenced through window. For
example, if the widget .frame is to be made busy, the busy cursor can be
specified for it by either option command:

	        option add *frame.busyCursor gumby
	        option add *Frame.BusyCursor gumby

## Cget Subcommand

 > **tk busy cget** _window option_

Queries the **tk busy** command configuration options for _window_.
_Window_ must be the path name of a widget previously made busy by the
**hold** operation. The command returns the present value of the specified
_option_. _Option_ may have any of the values accepted by the **hold**
operation.

# Reference Implementation

See SourceForge patch \#1997907
<https://sourceforge.net/support/tracker.php?aid=1997907> . There is no support
for Mac \+ Aqua in this patch. It compiles on Mac \+ Aqua and the command will
not return errors but will not resort in a _busy_ effect. Mac \+ X11 does
work.

# Compatibility

Because the command as proposed above has the same interface and behavior as
the **blt::busy** command, replacing **blt::busy** with **tk busy** is
all that's needed to switch to the Tk version of the busy command.

The **tk busy** command is not one-by-one compatible with the
**blt::busy** command, but typical use \(**hold** and **forget**\) will
not suffer a lot. Aliases or an ensemble could be used to make transition
easier.

# Alternatives

The busy command is available as starkit from <http://tcl.tk/starkits/busy.kit>

An alternative would have been to keep the interface from BLT. This would have
made transition easier, but would have kept the confusing difference between
_forgotten_ and _released_ busy windows.

# Copyright

This document has been placed in the public domain.

