Comment puis-je écrire un «idempotent» .Xmodmap

14

Actuellement, j'ai un .Xmodmapfichier qui change mon Commanden Ctrl, puis change mon Ctrlen Super(j'utilise Linux sur un Mac).

Cela fonctionne assez bien, lorsqu'il n'est exécuté qu'une seule fois mais lors d'exécutions successives (par exemple lorsque je redémarre mon environnement de bureau (Cinnamon), il recharge le .Xmodmapfichier), il réinitialise essentiellement les paramètres en annulant les modifications. Basculer efficacement entre ma configuration souhaitée et la configuration d'origine.

Comment puis-je écrire un .Xmodmapfichier qui ne définit les paramètres qu'une seule fois, mais ne les modifie pas lors des exécutions successives? Voici mon .Xmodmapfichier existant :

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
coteyr
la source
Je ne comprends pas la question. Je n'ai aucune idée de ce que signifie «modal» ici. Cela .Xmodmapn'affecte que les clés que vous modifiez, que voulez-vous faire différemment?
Gilles 'SO- arrête d'être méchant'
Lorsque j'utilise le .Xmodmap, il définit les clés, si je le relance, il les rétablit. Je veux créer un .Xmodmap qui, peu importe ce qui se traduit par les touches de contrôle et de commande échangées. Parfois, au redémarrage, le DE .Xmodmap est à nouveau exécuté, ce qui entraîne une gêne.
coteyr
2
@coteyr Je pense que le mot que vous recherchez est " idempotent "
Joseph R.

Réponses:

7

Réinitialisez la carte à son état d'origine avant d'appliquer vos mods. Une réinitialisation complète prend une éternité, donc le mieux que je puisse trouver est différent.

Ce code utilise .Xmodmap{.orig,.reset,.mods}où s'il .orign'existe pas, il est défini sur l'état actuel et calcule .resetpour restaurer cet état où qu'il se trouve. avant de postuler .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

(modifier: nettoyage)

jthill
la source
J'essaie. Jusqu'ici tout va bien.
coteyr
@coteyr - est-ce que ça marche pour vous?
slm
Pas vraiment j'expérimente toujours.
coteyr
Upadate: cela semble fonctionner, pour la plupart, je dois encore modifier un peu les choses, mais au moins les paramètres ne sont pas réinitialisés lors des exécutions successives.
coteyr
@coteyr - si cela ne fonctionne pas, je pense que j'ai une autre méthode qui pourrait fonctionner, mais elle est plus impliquée, donc je ne veux pas vraiment l'écrire si cela fait le travail. Lorsque vous répondez, veuillez inclure le signe @ en face de mon nom d'utilisateur afin que je sache que vous avez répondu, sinon je dois revenir et vérifier et j'oublierai très probablement.
slm
0

Accédez à système> Préférences> Applications de démarrage et ajoutez xmodmap ~/.Xmodmap. ajouter la commande xmodmap

PMint
la source
Cela provoque l'exécution de xmodmap à chaque redémarrage du DE, cela fonctionne déjà et entraîne la définition des paramètres, puis la réinitialisation. Par exemple, Démarrer l'ordinateur, se connecter, DE est lancé, xmodmap est exécuté, DE se bloque, DE démarre, xmodmap est exécuté. Maintenant, mon clavier est de nouveau en désordre.
coteyr
0

Je suis encore un peu confus quant à ce que vous voulez, mais je le pense:

Si vous mettez cela dans votre ~/.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

puis à chaque fois xmodmap ~/.Xmodmapest exécuté, puis l' échange de touches gauche Ctrlet gauche . Ainsi, lors de la première invocation, la Ctrltouche agit comme si vous aviez appuyé , mais lors de la deuxième invocation, elle reprend à nouveau sa fonction de Ctrltouche.

billyjmc
la source
C'est exactement ce que je ne veux pas
coteyr
Je veux exactement le contraire, je veux que chaque invocation, peu importe ce qui se traduit par un commandement agissant comme un contrôle et un contrôle agissant comme un commandement.
coteyr
Bon, eh bien, c'est pourquoi je suis confus, car votre message d'origine semble faire exactement ce que vous voulez ...
billyjmc
Mais ce n'est pas le cas.
coteyr
Eh bien, le comportement que j'observe est que votre code est idempotent, alors que mon code est avec état. Êtes-vous en train de me dire que votre code et le mien se comportent de manière identique pour vous? Si c'est le cas, je pense que vous devez rencontrer un bug quelconque. J'ai une suggestion: essayez d'exécuter explicitement à xmodmap ~/.Xmodmappartir d'un xterm et voyez si votre code échange vraiment les clés avec une application répétée. Peut-être que vos clés reviennent à leur comportement d'origine lorsque Cinnamon redémarre n'est pas pour la raison que vous pensez que c'est le cas?
billyjmc