Previous section   Next section

Practical Programming in Tcl & Tk, Third Edition
By Brent B. Welch

Table of Contents
Chapter 35.  Selections and the Clipboard

The Selection Model

The Windows and Macintosh selection model is simpler than the selection model used in X windows. In the Macintosh and Windows there is one selection, although that selection may store different types of data like text or images. Users copy data from an application into a clipboard, and later they paste it into another application.

In X windows the selection model is generalized to support more than one selection, and they are identified by names like PRIMARY and CLIPBOARD. The CLIPBOARD selection is used for copy and paste as in Macintosh and Windows. The PRIMARY selection is described later. You could use other selection names, like SECONDARY or FOOBAR, but that only works if the other applications know about that selection name. The selection data has both a type and a format. These are described briefly later.

Data is not copied into a selection. Instead, an application asserts ownership of a selection, and other applications request the value of the selection from that owner. This model is used on all platforms. The window system keeps track of ownership, and applications are informed when some other application takes away ownership. Several of the Tk widgets implement selections and take care of asserting ownership and returning its value.

The X PRIMARY selection is used in a way that eliminates the explicit copy step in copy and paste user actions. Whenever you select an object in your application, your application automatically puts that value into the PRIMARY selection. The Tk entry, listbox, and text widgets do this with their text selections, although you can turn this off with the exportSelection widget attribute. Users typically insert the value of the PRIMARY selection by clicking with the middle mouse button. There is only one instance of the PRIMARY selection across all widgets and all applications. If the user makes a new selection it automatically overwrites the previous value of the PRIMARY selection.


The CLIPBOARD is cross-platform.

If you want a mechanism that works on all platforms, use the CLIPBOARD selection. The PRIMARY selection is implemented by Tk on all platforms, and you can use it within an application, but on Windows and Macintosh the non-Tk applications do not know about the PRIMARY selection. The main goal of copy and paste is to provide general interoperability among all applications, so stick with the CLIPBOARD.

Tk 3.6 and earlier only supported the PRIMARY selection. When Tk 4.0 added support for the CLIPBOARD, I tried to merge the two selections to "simplify" things for my users. Example 35-1 implements a Paste function that inserts either the PRIMARY or CLIPBOARD selection into a text widget. The selection get command is used to retrieve the selection value:

Example 35-1 Paste the PRIMARY or CLIPBOARD selection.
proc Paste { text } {
   if [catch {selection get}sel] {
      if [catch {selection get -selection CLIPBOARD}sel] {
         # no selection or clipboard data
   $text insert insert $sel

This Paste function can be convenient, but it turns out that users still need to keep track of the difference between the two selections. If a user only understands the CLIPBOARD, then the use of PRIMARY is only surprising. I learned that it is best to have a separate paste user action for the two selections. The convention is that <ButtonRelease-2> sets the insert point and inserts the PRIMARY selection. (This convention is awkward with the one- and two-button mice on Macintosh and Windows.) The <<Paste>> event (e.g., the Paste key) simply inserts the CLIPBOARD selection at the current insert point. This convention is shown in Example 35-2, although these bindings are defined automatically for the text and entry widgets:

Example 35-2 Separate paste actions.
bind Text <<Paste>> {
   catch {%W insert insert \
      [selection get -selection CLIPBOARD]
bind Text <ButtonRelease-2> {
   %W mark set insert @%x,%y
   catch {%W insert insert \
      [selection get -selection PRIMARY]

      Previous section   Next section