分类: LINUX
2009-09-13 14:32:02
(June 2001)
This documents how to get your delete and backspace keys working correctly under X by configuring it correctly. There are many FAQs out there that tell you to do stupid things like swap your Delete and BackSpace keysyms or alter your stty erase character. Ignore them all.
Delete sequences
There are three character sequences for deleting characters:
character | aka | meaning |
---|---|---|
^H | Ctrl-H aka C-h aka ASCII 8 aka Backspace | delete left |
^? | Ctrl-? aka C-? aka ASCII 127 aka Delete | delete left or right |
ESC [ 3 ~ | VT 220 remove | delete right |
The transition from punched tape to CRTs with keyboards resulted in a number of decisions. One decision was what to use to represent a newline, and another was what to use to represent a delete.
On a punch card when you wanted to delete you would have gone left with a backspace control character (^H) and then punched out the card with the delete control character (^?). The keyboard only needs to generate one character for each key, so a choice had to be made as to which key to output.
The unix community had many different terminals where some used ^H for delete left and some used ^?. However, the VT-terminals from DEC became so popular that over time the unix community standarised on ^? to mean delete left.
These days people come from a variety of backgrounds - many home computer systems use the DOS method of ^H for the backspace key and ^? for the delete key. This is not appropriate in unix systems. Many people try and configure their systems to be like DOS, but this will only lead to problems. In unix ^H is not delete, infact many programs - emacs being the most notable - use ^H to bring up a help screen.
VT220 | Backspace key produces ^? (delete left) Delete key produces ESC [ 3 ~ (delete right) |
---|---|
DOS | Backspace key produces ^H (delete left) Delete key produces ^? (delete right) |
X systems
We now live in a multi-national world where there are a wide variety of keyboard layouts. X deals with this by assigning each physical key on the keyboard a unique keycode (which infact is derived from the kernel which in turn by the keyboard itself).
X applications receive keycodes but they won't know what that means until they ask X what that keycode represents. This is managed by the keycode<>keysym table. A keysym is supposed to represent a common symbol that might appear on a keyboard whose function is well known.
There are two keysyms that interest us, they are defined as:
A properly setup system will generate the keysym BackSpace for the physical backspace key and will generate the keysym Delete for the physical delete key. The BackSpace keysym means delete left and the Delete keysym means delete right. If you agree with that, and most people do, then the above settings are what you want - ignore any FAQ that tells you to swap them.
My system generates keycode 22 for the backspace key and 107 for the delete key. Run xmodmap -pk and look at key codes 22 and 107. If you want your physical backspace key to delete left and your physical delete key to delete right, then this is the correct mapping (and is the default):
Netscape
Netscape is an X application. When it receives keycode 22 it will look it up in the keycode<>keysym map and see that it is a BackSpace keysym. Netscape will then know you want to delete left. If it looks it up and sees a Delete keysym, it will know you want to delete right. All X applications should work this way. If you press backspace and you get a space then in all likelyhood the keycode that represents your backspace has been configured incorrectly - FAQs sometimes (stupidly) say that xmodmap -e 'keycode 22 = 0177' is a good idea (or other such hard-coded number). The reason behind them doing this is that it forces xterm to send a ^? when the backspace is pressed, but by doing that normal X applications won't know what the keys mean anymore. You need to get Netscape working first, and then fix xterm. Your backspace keycode should generate the BackSpace keysym, don't change that!
Xterm
Xterm is a normal X application and will receive keycodes just like Netscape does. It will then look up the corresponding keysym and find BackSpace for your backspace key and Delete for your delete key. So, what does xterm send to the remote end? There is no provision in X for translating these codes into ASCII sequences. Xterm has to handle this itself...
Unfortunately xterm comes setup wrong (perhaps from only xfree86 4 onwards). There is a X resource called backarrowKey that specifies whether or not the BackSpace keysym generates a backspace or not. This is set to true by default but it should be false. To fix this add/create the following line in your .Xdefaults file: xterm.*.backarrowKey: false. This will make your backspace key generate the ^? code. The Delete keysym always generates the VT220 delete sequence, so that will be correct.
Emacs
Emacs receives your input via Xterm and expects ^? for delete left and the VT220 delete sequence for delete right. If you have followed the above you will find emacs will work correctly - both locally and remotely. There is no reason at all for altering emacs' configuration files. If you get the help file when you try and delete then xterm is sending the wrong character. If you find your backspace deletes right then this means you've got your keysyms the wrong way around, more than likely this is the cause of following some FAQ that tells you to swap them - don't. The backspace keycode should generate the BackSpace keysym. Do not alter emacs' configuration files to fix keyboard problems!
Other notes
Your stty erase character should be ^?. Type stty -a to see what erase is currently set to, if it is wrong, type stty erase '^?'.