The Secondary Selection

by Charles Lindsey

For over 20 years, I have been using the secondary-selection (a standard feature of the X-Windows system) when editing texts, using the Solaris operating system on Sun Hardware. Recently, I have switched to Linux on i86 hardware, and have been horrified to find that this valuable feature is not supported by modern toolkits and editors. The world seems to have forgotten what it was meant for, and yet I believe it is the best thing since sliced bread.

So I set about hacking the source code of the GTK+ toolkit to remedy that omission – an uphill struggle, but now in a suitable state for the world to see and test it out. So in the following pages I shall explain what I have done, and provide an opportunity for you to download it and try it for yourself.

Table of Contents

So what will the Secondary Selection do for me?

Clearly, I first need to explain to the world what it is missing. So, for a textual explanation, click here,

or else, if you can bear my husky voice, watch my Video:

History

Once the basic X-Windows system was available, the first (to my knowledge) toolkit to use the secondary-selection was Xview, a product of Sun Microsystems for use in its Solaris OS. This was an excellent implementation - you could create secondary-selections by click-and-drag, or by double-clicking (for words) or triple-clicking (for lines) followed by dragging to include further word (lines). But the protocol that it used took some liberties with the basic X-Windows interface; moreover Xview fell out of favour (even in Solaris, which dropped it in favour of Motif) and even though some brave souls have implemented Xview in Linux, I thought it unwise to continue with its protocol.

Next came Motif, with a much more X-Windows-conformant protocol, but with an appalling human interface. You had (as I recall) to make a secondary-selection using the Middle Button whilst holding ctrl down, and all you could do was to press the button, drag it to where you wanted the secondary-selection to end, and let it go - no double- or triple-clicks at all. However, Motif being based on the Intrinsics, you could improve the interface slightly by writing an app-defaults file so that at least you could use ctrl+Left to do the job. Nevertheless, I have decided to use the Motif protocol in my experimental GTK+ version (which will, in fact, interwork with Motif).

The Motif Protocol

Follow that link to see all the Gory Details (it has to be documented somewhere, and nobody else seems to have done it ☹).

The Experimental GTK+ implementation

Instruction Manual

The secondary-selection is used when the cursor is in some focussed Recipient window, in order to grab some text (or whatever) from some Donor window (possibly the same window as the Recipient) and have that text pasted at the Recipient's insertion-point (overwriting any primary-selection in the Recipient).

  1. Be sure that you are in the intended Recipient, and that it has the focus;
  2. Press Ctrl (or alternatively some key in mod3), and keep it pressed until I tell you to release it;
  3. Move the cursor to the Donor, over the text to be grabbed;
  4. Make a secondary-selection covering that text
  5. As soon as you release Ctrl (or the mod3 key) you are committed, and the pasting (and maybe the cutting) will happen;
  6. Note that the precise rules for clicking/dragging/extending the secondary-selection are precisely the same as for clicking/dragging/extending the primary-selection.
  7. If Recipient and Donor are the same window and the primary- and secondary-selections overlap, you will get what you deserve (and with hindsight you might then be able to explain why).

Todo: Make a video showing further examples.

Special Keyboards

The convention that Ctrl-c, Ctrl-v and Ctrl-x are used for Copy, Paste and Cut comes from Microsoft, and is entirely unsuited to Unix systems (where Ctrl-c means 'interrupt' and Ctrl-x is heavily used in Emacs), and they are awkward to type with one hand. The alternative of using Ctrl-Insert, Shift-Insert and Ctrl-Delete is even worse. Why can't we have keyboards with dedicated Copy, Paste and Cut keys? There was a time when such keyboards were readily available, but in the interests of uniformity (with Microsoft) they have all but disappeared. The only ones left come from Sun (and offer other useful keys such as Open, Find, Cancel - aka Stop, Undo and Redo -aka Again). Linux is quite happy to recognise all these, assigning the correct keysyms to them.

So if you are able to arrange, using xmodmap, for Paste and Cut to be modifier keys (showing up as mod3), then holding Paste down will allow you to make a secondary-selection, and holding Cut down will do the same, but in addition will also delete the secondary-selection once it has been pasted to the Recipient. This means, however, that conventional Pasting and Cutting of the primary-selection has to be bound to the release of these keys (nobody will notice). On second thoughts, I might change that so that Copy rather than Paste is the modifier for mod3.

Changes to GTK

By and large, everything that worked before will still work now. Nevertheless, there are a few niggling changes

  1. I find it annoying, when moving the focus to a new window, that clicking with Left not only changes the focus as intended, but also changes the insertion-point (which was formerly at some desired position in the new window, and is now at some random place). So I have fixed this. A first click in a window gives it the focus; a second and subsequent clicks sets the insertion-point. Sadly this does not work when the window manager changes the focus (using "focus-on-click" - it is fine if you have configured "focus on enter", which I much prefer myself).
  2. In Drag'n'Drop, pressing the Escape key abandoned the transfer. I now also us the Escape key (also the Cancel key) to clear a secondary-selection that has got out of hand. For good measure, this will also clear a primary-selection. When no selection is in progress, the Escape key will still do whatever (if anything) it would have done before.
    Todo: make Cancel work with original Drag'n'Drop.
  3. In gnome-terminal, pressing Ctrl whilst making a selection caused it to create a "column" primary-selection. I doubt this feature was often used, and I wanted Ctrl to initiate a secondary-selection, so now you have to us Ctrl+Alt to get a "column" selection.

Nuts and Bolts

What I provide in my tarball are three libraries

libgtk-3.so.0.1000.8-r1 with soft link from libgtk-3.so
libgdk-3.so.0.1000.8-r1 with soft link from libgdk-3.so
libvte2_90.so.9.3400.9-r1
with soft link from libvte2_90.so.9

where the "-r1" bit indicates Release 1 of my experimental implementation. All these libraries are unstripped, so you can use gdb on them and get usable backtraces

Now you could, of course, simply put these in place of the matching libraries in /usr/lib, but altering things in /usr/lib is usually considered bad practice since Linux vendors are in the habit of releasing updates, which can arbitrarily change stuff in there. So it is far better to choose which applications you want to use the new facilities (in my case that was gedit and gnome-terminal - it is surprising how few applications actually use gtk3.0 TextView). Then you write wrappers to call them which use the Environment Variable LOAD_PRELOAD to force-load those libraries as required (the wrappers should be placed in /usr/local/bin). So my tarball also includes

gedit
secgedit
gnome-terminal
secterminal

The difference between gedit and secgedit is that gedit will simply spawn a new window of an already running gedit (that is normal practice), whereas secgedit will force a new standalone process using the new libraries; so, for example, if you made the new gedit non-executable (so that it would use the original /usr/bin/gedit), you could then use secgedit to try out the new facilities. Likewise with gnome-terminal and secterminal.

There are also some .css files which should go in $HOME/.config/gtk-3.0 (ultimately, they belong in /usr/share/themes/some-theme/gtk-3.0)

gtk.css
gtk-keys.css

It is fairly obvious what these are trying to achieve, but some of them still don't work entirely as intended.

I have also resurrected the old SplitView plugin for gedit, and hacked it to work with modern gedits; this is very handy when using the secondary-selection to Copy/Cut stuff within the same file, where the positions of the Recipient and Donor are too far apart to be visible at the same time. These files should go in
$HOME/.local/share/gedit/plugins.

SplitView.plugin
SplitView.py

For debugging purposes, or for helping you to understand what is happing, there is a simple program

selections

which can be run in any terminal window and shows who (if anyone) owns each selection at any given moment (be patient, it only polls once a second). The numbers shown are actually the ids of the underlying x-windows, but these mostly correspond one-to-one to gtk widgets.

When you move the cursor from the Recipient to the Donor and start clicking there, the Window Manager is likely to move the focus to the Donor, which is a nuisance (you will have to move it back to the Recipient to continue editing there, and the Donor may have been moved to the front, obscuring what you were trying to edit). As regards compiz, I have reported this as a bug https://bugs.launchpad.net/compiz/+bug/1560679 wherein I also provided a fix; sadly compiz has a long queue of unread bugs, but hopefully something will happen some day. Meanwhile, the fix (a library and a LOAD_PRELOAD wrapper) are in the tarball

libcompiz_core.so.0.9.11.2-r1
compiz

Downloading

Click download to obtain the tarball.

Save it in some suitable place, gunzip it, and then unpack it in /usr/local. Note that the owner:group of all the files is bin:bin, and if you unpack it using sudo, that is what you will get. Alternatively, if you have write privileges in /usr/local and call tar without sudo, they will be owned (and grouped) by you. You will find everything in four directories

bin    lib    copy-these-to-HOME    secondary-selection-r1
                 |           |         |        |        |
              .local     .config   COPYRIGHT INVENTORY README

You will need ls -a (or even ls -aR) to see what is in copy-these-to-HOME. Everything in there is to be copied into the corresponding places in your $HOME.

Assuming /usr/local/bin comes early in your PATH, the stuff in bin that is executable will be immediately runnable. So try secgedit and secterminal to see it is all working, and then make gedit and gnome-terminal (and even compiz) executable to make them the defaults.

Feedback

Clearly, we need some place where people can express their opinions and experiences with trying out my system. Initially, I propose we meet in the Usenet Group comp.os.linux.x, but I am also on the lookout for some web forum that could host discussions, so watch this space!

Count of Downloads: