You are not logged in.
Pages: 1
I've trying to use xmodmap to map keys such as CAPS LOCK to something more useful, but it is not working as I had hoped. I mapped Menu to Hyper_R, but is still gets treated as Alt by "Window Manager" under the keyboard tab. I am left with three questions:
1) Is there a way to make Xfce distinguish between the left and right versions of modifier keys (e.g. Shift_L and Shift_R)?
2) Is there a way for me to add new modifier keys (or for me to map to a key such as XF86WebCam, and use that as a modifier key)?
3) Am I stuck with only Control, Shift, Super, and Alt as modifier keys? I keep on seeing Mod, Meta, Hyper, Lock, but I know neither what they do nor what they are.
Offline
1.) Yes. E.g. with
xmodmap - <<EOF
clear shift
add shift = Shift_L
add control = Shift_R
EOF
Now Shift_R + a selects all the text in most text editors while Shift_L + a still prints a capital 'A'.
2.) Yes. This works the same as above. There is no discerning between 'normal keycodes' and 'modifier keycodes'.
xmodmap <( echo 'add control = F1' )
Now F1+a selects all text in my favorite editor. (tested)
3.) Isn't this the same question as 2.? X provides 8 modifier keys. They can be shown with `xmodmap -pm`. They are sent to X programs in a state byte with 8 bits which can be set or not set. The X client has to map "bit (un)set + key" to corresponding actions. The only mappings which can be done globally are:
shift + key
Mode_switch + key
shift + Mode_switch + key
mod5 + key
shift + mod5 + key
Mode_switch seems to be the only weird one here, because it is not read from a modifier state like shift or mod5.
Meta, Hyper and Super are basically the same. The refer to the key with the Windows, Mac or Linux logo on it. In my long rant below I do many things with Super_R.
If you want to understand a bit more about everything you could retrace my steps below:
| |
The first thing I would do, is trying to understand the current keyboard mapping. For that you can use xev, press keys and look at the output:
xev
left control : keycode 37 (keysym 0xffe3, Control_L ), Hex: 0x25
right control : keycode 105 (keysym 0xffe4, Control_R ), Hex: 0x69
left alt : keycode 64 (keysym 0xffe9, Alt_L ), Hex: 0x40
right alt : keycode 108 (keysym 0xfe03, ISO_Level3_Shift), Hex: 0x6C
left shift : keycode 50 (keysym 0xffe1, Shift_L ), Hex: 0x32
right shift : keycode 62 (keysym 0xffe2, Shift_R ), Hex: 0x3E
left meta : keycode 133 (keysym 0xffeb, Super_L ), Hex: 0x85
right meta : keycode 134 (keysym 0xffec, Super_R ), Hex: 0x86
num lock : keycode 77 (keysym 0xff7f, Num_Lock ), Hex: 0x4D
caps lock : keycode 66 (keysym 0xffe5, Caps_Lock ), Hex: 0x42
scroll lock : keycode 78 (keysym 0xff14, Scroll_Lock ), Hex: 0x4E
pause / break : keycode 127 (keysym 0xff13, Pause ), Hex: 0x7F
menu key : keycode 135 (keysym 0xff67, Menu ), Hex: 0x87
(right of meta_r)
convert keycodes to hexadecimal (needed later):
echo "obase=16; 37; 105; 64; 108; 50; 62; 133; 134; 77; 66; 78; 127; 135" | bc
I use a USB-keyboard, meaning the keycodes should be universal for all other USB-keyboards
-> `man setkeycodes`
> USB keyboards have standardized keycodes and setkeycodes doesn't affect them at all.
https://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html
Next you can assert that these outputs are correct. For that you can output the current keycode->keysym mapping with xmodmap:
xmodmap -pke > ~/.Xmodmaprc.org
keycode 37 = Control_L NoSymbol Control_L
keycode 105 = Control_R NoSymbol Control_R
keycode 64 = Alt_L Meta_L Alt_L Meta_L
keycode 108 = ISO_Level3_Shift NoSymbol ISO_Level3_Shift
keycode 50 = Shift_L NoSymbol Shift_L
keycode 62 = Shift_R NoSymbol Shift_R
keycode 66 = Caps_Lock NoSymbol Caps_Lock
[...]
So, yes the mapping we saw is of course correct
Now we can assert how the modifier keys work. For that we can rewrite some test key to some dummy values on all columns, because very column should map to a different modifier key. The first column being no modifier keys, the second column shift and the rest I can't say yet:
# create a new xmodmap containing the following two lines after the next line
vim ~/.Xmodmap
!keycode 13 = 4 dollar 4 dollar onequarter currency
keycode 13 = a b c d e f g h i j k l m
xmodmap ~/.Xmodmap
Now we can try out what modifier key + '4'-key prints. To make this easier we can grep for only 'KeyPress' events and then only for keycode. For me KeyPress events are 6 or 7 lines long. In order to see the output in real time instead of only when closing the program we need to add '--line-buffered'
xev | grep 'KeyPress' --line-buffered -A7 | grep --line-buffered 'keycode'
no modifier + 4 : keycode 13 (keysym 0x61, a)
left control + 4 : state 0x10, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
state 0x14, keycode 13 (keysym 0x61, a), same_screen YES,
right control + 4 : state 0x10, keycode 105 (keysym 0xffe4, Control_R), same_screen YES,
state 0x14, keycode 13 (keysym 0x61, a), same_screen YES,
left alt + 4 : state 0x10, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
state 0x18, keycode 13 (keysym 0x61, a), same_screen YES,
right alt + 4 : state 0x10, keycode 108 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES,
XKeysymToKeycode returns keycode: 92
state 0x90, keycode 13 (keysym 0x65, e), same_screen YES,
left shift + 4 : state 0x10, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
state 0x11, keycode 13 (keysym 0x62, b), same_screen YES,
XKeysymToKeycode returns keycode: 56
right shift + 4 : state 0x10, keycode 62 (keysym 0xffe2, Shift_R), same_screen YES,
state 0x11, keycode 13 (keysym 0x62, b), same_screen YES,
XKeysymToKeycode returns keycode: 56
left meta + 4 : state 0x0, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
right meta + 4 : state 0x0, keycode 134 (keysym 0xffec, Super_R), same_screen YES,
num lock + 4 : state 0x10, keycode 77 (keysym 0xff7f, Num_Lock), same_screen YES,
state 0x10, keycode 13 (keysym 0x61, a), same_screen YES,
caps lock + 4 : state 0x12, keycode 66 (keysym 0xffe5, Caps_Lock), same_screen YES,
state 0x12, keycode 13 (keysym 0x41, A), same_screen YES,
XKeysymToKeycode returns keycode: 38
scroll lock + 4 : state 0x10, keycode 78 (keysym 0xff14, Scroll_Lock), same_screen YES,
state 0x10, keycode 13 (keysym 0x61, a), same_screen YES,
pause / break + 4 : state 0x10, keycode 127 (keysym 0xff13, Pause), same_screen YES,
state 0x10, keycode 13 (keysym 0x61, a), same_screen YES,
menu key + 4 : state 0x10, keycode 135 (keysym 0xff67, Menu), same_screen YES,
state 0x10, keycode 13 (keysym 0x61, a), same_screen YES,
The following thought on the output:
I'm not sure why there is mapping from Alt_R (108) to 92
keycode 92 = ISO_Level3_Shift NoSymbol ISO_Level3_Shift
The same XKeysymToKeycode message appears for left and right shift
keycode 56 = b B b B leftdoublequotemark leftsinglequotemark
But in this case it is the correct mapped output we wanted.
The same is true for all other working modifier+4 combinations
The only columns we can actually reproduce are:
'a' : [no modifier keys]
'b' : Shift_L Shift_R
'e' : ISO_Level3_Shift [right alt]
Basically non-working modifier keys:
Alt_L Ctrl_L Ctrl_R Num_Lock Pause Menu Scroll_Lock
Super_L and Super_R produce no symbol for some reason, but looking at the full output of xev they seem to produce some kind of window control sequence:
KeyPress event, serial 37, synthetic NO, window 0x5c00001,
root 0x29e, subw 0x0, time 252830107, (76,-166), root:(947,276),
state 0x0, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
FocusOut event, serial 37, synthetic NO, window 0x5c00001,
mode NotifyGrab, detail NotifyAncestor
FocusIn event, serial 37, synthetic NO, window 0x5c00001,
mode NotifyUngrab, detail NotifyAncestor
KeymapNotify event, serial 37, synthetic NO, window 0x0,
keys: 4294967198 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
KeyRelease event, serial 37, synthetic NO, window 0x5c00001,
root 0x29e, subw 0x0, time 252830844, (76,-166), root:(947,276),
state 0x40, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
Now let's take a look at the current modifier mapping to see if this output is what it should be:
xmodmap -pm
xmodmap: up to 4 keys per modifier, (keycodes in parentheses):
shift Shift_L (0x32), Shift_R (0x3e)
lock
control Control_L (0x25), Caps_Lock (0x42), Control_R (0x69)
mod1 Alt_L (0x40), Meta_L (0xcd)
mod2 Num_Lock (0x4d)
mod3
mod4 Super_L (0x85), Super_R (0x86), Super_L (0xce), Hyper_L (0xcf)
mod5 ISO_Level3_Shift (0x5c), Mode_switch (0xcb)
Observations:
modifier 'shift' returns correctly column 2 with 'b' and 'mod5' column 5 with 'e'
The above observation gives neither an ordering for the columns nor does it explain, why all other modifiers don't seem to map to a column
The assigned keycodes for shift, control, mod1, mod2, mod4 look correct, althoughthere seem to be some dupes like 'Super_L (0xce)'
mod5 looks weird, but it seems 0x6C is somehow translated to 0x5C, but I can't see where !!
To restore the original setting you can load the output of the earlier xmodmap-call
xmodmap ~/.Xmodmaprc.org
man xmodmap
keycode NUMBER = KEYSYMNAME ...
The list of keysyms is assigned to the indicated keycode (which may be specified in decimal, hex or octal and can be determined by running the xev program). Up to eight keysyms may be attached to a key, however the last four are not used in any major X server implementation. The first keysym is used when no modifier key is pressed in conjunction with this key, the second with Shift, the third when the Mode_switch key is used with this key and the fourth when both the Mode_switch and Shift keys are used.
Look at the manual above I have forgotten to try out multiple modifier key combinations:
CtrlL+Alt+4:
state 0x10, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
state 0x14, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
state 0x1c, keycode 13 (keysym 0x61, a), same_screen YES,
CtrlL+Shift+4
state 0x10, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
state 0x14, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
state 0x15, keycode 13 (keysym 0x62, b), same_screen YES,
XKeysymToKeycode returns keycode: 56
CtrlL+AltR+4
state 0x10, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
state 0x14, keycode 108 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES,
XKeysymToKeycode returns keycode: 92
state 0x94, keycode 13 (keysym 0x65, e), same_screen YES,
XKeysymToKeycode returns keycode: 26
CtrlL+ShiftR+4
state 0x10, keycode 37 (keysym 0xffe3, Control_L), same_screen YES,
state 0x14, keycode 62 (keysym 0xffe2, Shift_R), same_screen YES,
state 0x15, keycode 13 (keysym 0x62, b), same_screen YES,
XKeysymToKeycode returns keycode: 56
CtrlR+*+a has the same effect as CtrlL+...
Shift+AltR+4
state 0x10, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
state 0x11, keycode 108 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES,
XKeysymToKeycode returns keycode: 92
state 0x91, keycode 13 (keysym 0x66, f), same_screen YES,
XKeysymToKeycode returns keycode: 41
The only new keystroke I could reproduce with all these combinations is 'f', the 6th column when pressing Shift_L + right alt. The manual says this should be the 4th column ... So either something is wrong or AltGr is not the Mode_switch key the manual speaks of, http://unix.stackexchange.com/questions … difier-for
This site https://wiki.ubuntuusers.de/Xmodmap/ says that the second and third are for Alt and Shift+Alt. I can't reproduce that.
But we could map some other key like Ctrl_R to modeswitch, for that add the following line to ~/.Xmodmap
keycode 37 = Mode_switch NoSymbol Mode_switch
Now I can actually produce the output of column 3 and 4 with xev!
Strg_R + 4:
state 0x10, keycode 105 (keysym 0xff7e, Mode_switch), same_screen YES,
state 0x2010, keycode 13 (keysym 0x63, c), same_screen YES,
XKeysymToKeycode returns keycode: 54
Strg_R + Shift + a:
state 0x10, keycode 105 (keysym 0xff7e, Mode_switch), same_screen YES,
state 0x2010, keycode 50 (keysym 0xffe1, Shift_L), same_screen YES,
state 0x2011, keycode 13 (keysym 0x64, d), same_screen YES,
XKeysymToKeycode returns keycode: 40
I think one important thing to understand is from this link: https://en.wikipedia.org/wiki/X_Window_ … l#Mappings
"The server therefore sends the keycode and the modifier state without attempting to translate them into a specific character. It is a responsibility of the client to do this conversion."
"The X server works with at most eight modifiers. However, each modifier can be associated with more than one key."
What I am deducing from all this, is that normally Ctrl+key and Alt+Key is something the client itself has to convert to the wanted actions and/or (escape) codes. That's why it's not easily possible to remap Ctrl+Backspace for xfce4-terminal using xmodmap ?!
The modifier keys http://unix.stackexchange.com/questions … super-keys can be seen with xev in the 'state' variable:
xev | grep --line-buffer 'state'
Shift_L : state 0x01 bit 0
Shift_R : state 0x01
Caps_Lock: state 0x02 bit 1
Ctrl_L : state 0x04 bit 2
Ctrl_R : state 0x04
Alt_L : state 0x08 bit 3
Num_Lock : state 0x10 bit 4
? : state 0x20 bit 5 # nothing assigned to mod3
Meta_L : state 0x40 bit 6
Meta_R : state 0x40
Alt_R : state 0x80 bit 7
Bit 8 is always set if Num_lock is on, even if it is not pressed. Similar is Caps_Lock with bit 2. Now we see what mod1 to mod5 are for. They map to bit 3 to 7. These modifiers have nothing to do with the columns in a key assignment, with the notable exception of 'shift'.
There are 3 basic commands for modifier keys (man xmodmap):
clear MODIFIERNAME
This removes all entries in the modifier map for the given modifier,
where valid name are: Shift, Lock, Control, Mod1, Mod2, Mod3, Mod4,
and Mod5 (case does not matter in modifier names, although it does
matter for all other names). For example, ``clear Lock'' will remove
all any keys that were bound to the shift lock modifier.
add MODIFIERNAME = KEYSYMNAME ...
This adds all keys containing the given keysyms to the indicated modi-
fier map. The keysym names are evaluated after all input expressions
are read to make it easy to write expressions to swap keys (see the
EXAMPLES section).
remove MODIFIERNAME = KEYSYMNAME ...
This removes all keys containing the given keysyms from the indicated
modifier map. Unlike add, the keysym names are evaluated as the line
is read in. This allows you to remove keys from a modifier without
having to worry about whether or not they have been reassigned.
You can produce the 2nd column with capslock+key by adding capslock to the shift-modifier:
xmodmap <(echo 'remove mod4 = Super_R')
xmodmap <(echo 'add shift = Super_R')
Now pressing Super_R+'t' produces 'T'. (Super_R+4 = b.)
xmodmap <(echo 'remove shift = Super_R')
xmodmap <(echo 'add mod5 = Super_R')
Now Super_R+4 = e, the same as AltGr.
xmodmap <(echo 'remove mod5 = Super_R')
xmodmap <(echo 'add control = Super_R')
About mod1 to 6:
mod1 is interpreted by programs as alt. E.g. Alt+F to open the file menu
mod2 is num lock
mod3 ? this is not set by default so it may not have any function
mod4 is super key
mod5 is AltGr key, e.g. for printing { and ~ on German keyboards. Assigning Super_R to this makes those symbols printable with Super_R+7 and Super_R+'+'
Note: Adding Super_R to mod2 is a very bad idea. For some reason it seems that then Super_R is always assumed as being pressed, meaning if you have shortcuts like Super+'d' to show the desktop you can't print 'd' anymore, which is needed to input 'xmodmap' so yeah. Also for some reason Super_R will only turn the Num_Lock LED off, but it can't turn it on when pressing it again. Turning it on still works with Num_Lock though.
xmodmap <(printf 'remove control = Super_R\nadd mod2 = Super_R')
xmodmap <(printf 'remove mod2 = Super_R')
When trying to assign Super_R to multiple modifiers I get the following error message:
X Error of failed request: BadValue (integer parameter out of range for operation)
Major opcode of failed request: 118 (X_SetModifierMapping)
Value in failed request: 0x17
Serial number of failed request: 11
Current serial number in output stream: 11
Last edited by xyzdragon (2016-02-13 19:08:17)
Offline
Pages: 1
[ Generated in 0.008 seconds, 10 queries executed - Memory usage: 611.98 KiB (Peak: 669.46 KiB) ]