Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Currently I have an .Xmodmap file that changes my Command to Ctrl, then changes my Ctrl to Super (I'm running Linux on a Mac).

It works quite well, when only run once but on successive runs (for example when I restart my desktop environment (Cinnamon) it reloads the .Xmodmap file) it basically resets the settings by reverting the changes. Effectively toggling between my desired setup and the original setup.

How can I write an .Xmodmap file that only sets the settings one time, but doesn't change them back on successive runs? Here is my existing .Xmodmap file:

clear control
clear mod4

keycode 105 =
keycode 206 =

keycode 133 = Control_L NoSymbol Control_L
keycode 134 = Control_R NoSymbol Control_R
keycode 37 = Super_L NoSymbol Super_L

add control = Control_L
add control = Control_R
share|improve this question
    
I don't understand the question. I have no idea what “modal” means here. This .Xmodmap only affects the keys that you're changing, what do you want to do differently? –  Gilles Nov 4 '13 at 22:12
    
When I use the .Xmodmap it sets the keys, if I run it again it switches them back. I want create a .Xmodmap that no matter what results in the swapped control and command keys. Sometimes when restart the DE .Xmodmap is run again resulting in an annoyance. –  coteyr Nov 5 '13 at 1:34
2  
@coteyr I think the word you're looking for is "idempotent" –  Joseph R. Nov 6 '13 at 22:33

3 Answers 3

up vote 6 down vote accepted
+200

Reset the map to its original state before applying your mods. A full reset takes forever, so best I can come up with is diffing.

This code uses .Xmodmap{.orig,.reset,.mods} where if .orig doesn't exist it's set to the current state, and calculates .reset to restore that state from wherever it's got to. before applying .mods.

#!/bin/sh
# file xmodmap-reset

#     rm ~/.Xmodmap.orig
# beforehand to take current setup as baseline for Xmodmap.mods changes

stem=~/.Xmodmap
orig=${stem}.orig
reset=${stem}.reset
mods=${stem}.mods

# implement -pme like -pke
#
xmodmap-pme () {
  xmodmap -pm \
  | sed '
        1d
        / [^ ]/!d
        s/^[^ ][^ ]*/clear &\nadd & =/
        s/([^ ]*//g
    '
}

# save baseline if none atm
test -a $orig || {
    xmodmap  -pke
    xmodmap-pme
} > $orig

# payload, diff for commands to reset to baseline from current
{
    xmodmap  -pke
    xmodmap-pme
} \
| {
    diff -u0 $orig - \
    | sed -n '
        1,/^@@/d
        s/^[^+]clear/clear/p
        s/^-//p
      '
} > $reset
xmodmap $reset

# finally ready to apply the mods
test -a $mods && xmodmap $mods

(edit: cleanup)

share|improve this answer
    
I am giving this a try. So far so good. –  coteyr Nov 8 '13 at 20:56
    
@coteyr - is this working out for you? –  slm Nov 9 '13 at 6:12
    
Not really I am still experimenting. –  coteyr Nov 9 '13 at 7:37
    
Upadate: this seems to be working, for the most part I still have to tweak things a bit but at least the settings are not be reset on successive runs. –  coteyr Nov 9 '13 at 19:22
    
@coteyr - if this doesn't pan out I think I have another method which might work, but it's more involved, so I don't really want to write it up if this does the job. When replying please include the @ sign infront of my username so I know you replied, otherwise I have to come back and check and will most probably forget. –  slm Nov 9 '13 at 21:01

Go to system > Preferences > Startup Applications and add xmodmap ~/.Xmodmap. add xmodmap command

share|improve this answer
    
This causes xmodmap to run every time the DE is restarted, this already works, and causes the settings to be set, then set back. For example Start computer, log in, DE is launched, xmodmap is run, DE crashes, DE starts, xmodmap is run. Now my keyboard is messed up again. –  coteyr Nov 7 '13 at 19:07
    
What about Xev? crunchbanglinux.org/wiki/xev-determine_custom_keybindings –  PMint Nov 7 '13 at 19:11

I'm still confused a little bit as to what you want, but I think this it:

If you put this in your ~/.Xmodmap,

clear control
clear mod4

keysym Super_L = Control_L
keysym Control_L = Super_L

add control = Control_L
add control = Control_R
add mod4 = Super_L
add mod4 = Super_R

then every time xmodmap ~/.Xmodmap is executed, then the left Ctrl and left key swap. So, on the first invocation, the Ctrl key acts as though you pressed , but on the second invocation, it resumes acting as a Ctrl key again.

share|improve this answer
    
This is exactly what I don't want –  coteyr Nov 8 '13 at 20:43
    
I want the exact opposite, I want every invocation, no matter what to result in command acting like control and control acting like command. –  coteyr Nov 8 '13 at 20:44
    
Okay, well, this is why I'm confused, because your original posting appears to do exactly what you want... –  billyjmc Nov 8 '13 at 22:20
    
But it doesn't. –  coteyr Nov 8 '13 at 23:20
    
Well, the behavior I observe is that your code is idempotent, whereas my code is stateful. Are you telling me that both your code and mine behave identically for you? If that's the case, then I think you must be experiencing a bug of some sort. I have a suggestion: try explicitly running xmodmap ~/.Xmodmap from an xterm, and see if your code really does swap the keys with repeated application. Maybe your keys reverting to original behavior when Cinnamon restarts isn't for the reason you think it is? –  billyjmc Nov 9 '13 at 5:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.