Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

Is there any way to let the Shift, Ctrl and Alt keys behave as toggles under X? I know how one could do it under CLI (for example, by doing this) but found no reference for doing so under X.

Please note that this is not a question on sticky keys, which can be enabled by an accessibility option.

share|improve this question
    
Depends on what you are toggling for that would make a difference of the process. –  Casey Keller Oct 13 '10 at 4:11
    
@Casey Couldn't it be like caps lock (whose ON/OFF states are irrespective of incoming keys or mouse actions)? –  Gödel Oct 13 '10 at 6:22

3 Answers 3

This is implemented on the DE level AFAIK. KDE has the option to Lock Sticky Keys:

With Lock Sticky Keys enabled:

If you press the Shift key twice then press the F key, the computer interprets this as Shift+F. Now if you type a P, the computer interprets this as the letter P (Shift+P). To de-select the Shift key, press it again.

http://docs.kde.org/stable/en/kdebase-workspace/kcontrol/kcmaccess/index.html

share|improve this answer
    
That's a good answer for KDE users, though it isn't for GNOME users like myself. –  Gödel Oct 18 '10 at 21:04

Keys in X11 are remapped with xmodmap, but there is no Control_Lock in /usr/include/X11/keysymdef.h

If you have a few keys you could map Control to something like ISO_Next_Group_Lock and define your keys in this group with Control + Key.

I found some info here: https://bbs.archlinux.org/viewtopic.php?id=75771

share|improve this answer

This can be achieved using XKB compatibility component

  1. Check the compatibility variant you are using

    $ setxkbmap -v -query
    Trying to build keymap using the following components:
    keycodes:   evdev+aliases(qwerty)
    types:      complete
    compat:     complete
    symbols:    pc+us(altgr-intl)+us:2+inet(evdev)
    geometry:   pc(pc105)
    rules:      evdev
    model:      pc105
    layout:     us,us
    variant:    altgr-intl,
    
    $ more /usr/share/X11/xkb/compat/complete 
    default xkb_compatibility "complete"  {
        include "basic"
        augment "iso9995"
        augment "mousekeys"
        augment "accessx(full)"
        augment "misc"
        augment "xfree86"
        augment "level5"
        augment "caps(caps_lock)"
    };
    
  2. Modify misc file, the one which contains the needed modifiers interpretations

    sudo nano /usr/share/X11/xkb/compat/misc
    

    I have changed Shift_L, Alt_L & Alt_R action from SetMods to LockMods, added new Shift_R, Control_L & Control_R interpretation with LockMods and commented //setMods.clearLocks (not sure if it's needed). Here is the complete file:

    default partial xkb_compatibility "misc"  {
    
        virtual_modifiers   Alt,Meta,Super,Hyper,ScrollLock;
    
        // Interpretations for some other useful keys
    
        interpret Terminate_Server {
            action = Terminate();
        };
    
        //setMods.clearLocks= True;
    
        // Sets the "Alt" virtual modifier
    
        interpret Alt_L+Any     {
            //useModMapMods= level1;
        virtualModifier= Alt;
        action = LockMods(modifiers=modMapMods);
        };
    
        interpret Alt_L {
        action = LockMods(modifiers=Alt);
        };
    
        interpret Alt_R+Any     {
            //useModMapMods= level1;
        virtualModifier= Alt;
        action = LockMods(modifiers=modMapMods);
        };
    
        interpret Alt_R {
        action = LockMods(modifiers=Alt);
        };
    
        // Sets the "Meta" virtual modifier
    
        interpret Meta_L+Any     {
    //        useModMapMods= level1;
        virtualModifier= Meta;
        action = SetMods(modifiers=modMapMods);
        };
    
        interpret Meta_L    {
        action = SetMods(modifiers=Meta);
        };
    
        interpret Meta_R+Any     {
            //useModMapMods= level1;
        virtualModifier= Meta;
        action = SetMods(modifiers=modMapMods);
        };
    
        interpret Meta_R    {
        action = SetMods(modifiers=Meta);
        };
    
        // Sets the "Super" virtual modifier
    
        interpret Super_L+Any     {
    //        useModMapMods= level1;
        virtualModifier= Super;
        action = SetMods(modifiers=modMapMods);
        };
    
        interpret Super_L   {
        action = SetMods(modifiers=Super);
        };
    
        interpret Super_R+Any     {
            //useModMapMods= level1;
        virtualModifier= Super;
        action = SetMods(modifiers=modMapMods);
        };
    
        interpret Super_R   {
        action = SetMods(modifiers=Super);
        };
    
        // Sets the "Hyper" virtual modifier
    
        interpret Hyper_L+Any     {
    //        useModMapMods= level1;
        virtualModifier= Hyper;
        action = SetMods(modifiers=modMapMods);
        };
    
        interpret Hyper_L   {
        action = SetMods(modifiers=Hyper);
        };
    
        interpret Hyper_R+Any     {
            //useModMapMods= level1;
        virtualModifier= Hyper;
        action = SetMods(modifiers=modMapMods);
        };
    
        interpret Hyper_R   {
        action = SetMods(modifiers=Hyper);
        };
    
        // Sets the "ScrollLock" virtual modifier and
        // makes it actually lock when pressed.  Sets
        // up a map for the scroll lock indicator.
        interpret Scroll_Lock+Any   {
        virtualModifier= ScrollLock;
        action = LockMods(modifiers=modMapMods);
        };
    
        include "ledscroll"
    
        include "misc(assign_shift_left_action)"
    };
    
    partial xkb_compatibility "assign_shift_left_action"  {
        // Because of the irrevertable modifier mapping in symbols/pc <LFSH> is 
        // getting bound to the Lock modifier when using 
        // symbols/shift(both_capslock), creating unwanted behaviour. 
        // This is a quirk, to circumvent the problem.
        interpret Shift_L {
            action = LockMods(modifiers = Shift);
        };
    
        interpret Shift_R {
            action = LockMods(modifiers = Shift);
        };
    
        interpret Control_L {
            action = LockMods(modifiers = Control);
        };
    
        interpret Control_R {
            action = LockMods(modifiers = Control);
        };
    
    };
    
  3. Compile the change & update the initramfs images

    sudo dpkg-reconfigure xkb-data
    sudo update-initramfs -u -k all
    
  4. Reboot

References:

share|improve this answer

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.