LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   Non cyclic switching between keyboard layouts (https://www.linuxquestions.org/questions/linux-general-1/non-cyclic-switching-between-keyboard-layouts-789057/)

alexbrui 02-14-2010 12:12 PM

Non cyclic switching between keyboard layouts
 
Hi all.

I have three keyboard layouts: en, ru and ua. Now I switch between layouts by pressing Ctrl+Shift (en->ru->ua->en->ru...). Here is part of my xorg.conf
Code:

Option "XkbRules"        "xorg"
Option "XkbModel"        "pc101"
Option "XkbLayout"        "us,ru,ua(winkeys)"
Option "XkbOptions"    "grp:ctrl_shift_toggle,lv3:none,ctrl:caps,grp_led:scroll,caps:internal,compose:ralt"

I want to setup non cyclic switching with next sheme:
CapsLock - switch to en
CapsLock+Shift - switch to ru
CapsLock+Ctrl - switch to ua

I've read an xkb manuals and some articles about it but can't understand how I can setup xkb for non cyclic switching. Can anyone help me?

David the H. 02-15-2010 08:13 AM

I'm not sure if it can be done with any regular keyboard mapping tool. The standard X switching mechanism seems to be a simple rotate.

It appears, however, that you can instead use one of the input method frameworks, uim or scim, to work with languages that have different keboard mappings, and these can be configured with separate shortcuts for each layout. I've never personally tried either of them for languages like that though.

See here for more on Linux language support.

http://www.jw-stumpel.nl/stestu.html

neonsignal 02-15-2010 08:26 AM

Here is one way to do it, which involves hacking the files in /usr/share/X11/xkb (alternatively you could set up your own keymap files). This is to select four keyboard layouts, but it will work for three.

First, add in a CapsLock selector type to the default xkb_types section in xkb/types/extra (this will be used to allow the CapsLock to select up to 4 different actions)
Code:

    type "FOUR_LEVEL_CAPS" {
        modifiers = Shift+Control;
        map[None] = Level1;
        map[Shift] = Level2;
        map[Control] = Level3;
        map[Shift+Control] = Level4;
        level_name[Level1] = "Base";
        level_name[Level2] = "Shift";
        level_name[Level3] = "Ctrl"; 
        level_name[Level4] = "Shift Ctrl"; 
    };

Then add in group set actions to the default xkb_compatibility section in xkb/compat/iso9995 (reinterpreting these somewhat so that they set a fixed group number)
Code:

    interpret ISO_First_Group_Lock {
        action= LockGroup(group=1);
    };
    interpret ISO_Prev_Group_Lock {
        action= LockGroup(group=2);
    };
    interpret ISO_Next_Group_Lock {
        action= LockGroup(group=3);
    };
    interpret ISO_Last_Group_Lock {
        action= LockGroup(group=4);
    };

Then add in the switch map to xkb/symbols/group
Code:

partial modifier_keys
xkb_symbols "shift_ctrl_caps_switch" {
    key <CAPS> { type = "FOUR_LEVEL_CAPS", [ ISO_First_Group_Lock, ISO_Prev_Group_Lock, ISO_Next_Group_Lock, ISO_Last_Group_Lock ] };
};

Now add in the group command to the option symbols in xkb/rules/base
Code:

  grp:shift_ctrl_caps_switch = +group(shift_ctrl_caps_switch)
Then you can set up your xorg.conf to make use of the new group change option, and restart X.

The four layouts are selected using 'capslock', 'shift-capslock', 'ctrl-capslock', and 'shift-ctrl-capslock' (as defined in the switch map).

alexbrui 02-15-2010 11:32 AM

Many thanks, neonsignal! This is what I need.
But I have a small problem with this. When I switch first layout by pressing CapsLock it switches correctly, then I press CapsLock+Shift to switch to the second layout and it switches correctly too. But when I press CapsLock again I get third layout instead of first. When I switch from third layot to first all works fine.
This is because I have only three layouts I'm right?

neonsignal 02-15-2010 04:07 PM

Quote:

But I have a small problem with this. When I switch first layout by pressing CapsLock it switches correctly, then I press CapsLock+Shift to switch to the second layout and it switches correctly too. But when I press CapsLock again I get third layout instead of first.
It isn't because of only three layouts (I tested that case). It is more likely to be a problem with the "FOUR_LEVEL_CAPS" not being right, or not getting loaded. The way to test this is to see if ctrl-CapsLock is working.

I'm assuming that you didn't make any changes to the above. It would be worth looking at the Xorg log to see if there were any errors (these may also appear on the ctrl-alt-F1 terminal window).

lumak 02-15-2010 09:05 PM

... If you work only in GUI, then why can't you just bind "setxkbmap en" "setxkbmap ru" and "setxkbmap ua" to any key combo you want?

alexbrui 02-16-2010 11:39 AM

Quote:

Originally Posted by neonsignal (Post 3864866)
It isn't because of only three layouts (I tested that case). It is more likely to be a problem with the "FOUR_LEVEL_CAPS" not being right, or not getting loaded. The way to test this is to see if ctrl-CapsLock is working.

Ctrl+CapsLock is working, I can switch to third layout.
Switching from first to second layout works. Switching from first to third and from third to first works too.
When I switch from second layout to first I get third layout and need to press CapsLock again to perform switching.

Quote:

Originally Posted by neonsignal (Post 3864866)
I'm assuming that you didn't make any changes to the above. It would be worth looking at the Xorg log to see if there were any errors (these may also appear on the ctrl-alt-F1 terminal window).

I made changes in xkb files as you tell. When I discover this problem I check my changes twice and seems all edits are correct. Here is files with my edits.
Also I've look in Xorg.log and as I can see there are no errors related to the keyboard

Xorg log: http://www.4shared.com/file/22332535.../Xorg0log.html
xkb files with edits: http://www.4shared.com/file/22332503...ed/xkbtar.html

neonsignal 02-16-2010 07:54 PM

Quote:

Ctrl+CapsLock is working, I can switch to third layout. Switching from first to second layout works. Switching from first to third and from third to first works too.
When I switch from second layout to first I get third layout and need to press CapsLock again to perform switching.
I've been able to replicate the problem. On my system, running setxkbmap after X windows starts (even without any parameters) fixes the problem (ie, CapsLock switches back to the first layout immediately).

This explains why I didn't see it earlier, because I was running setxkbmap to try out different combinations.

I don't know why setxkbmap would make a difference. My guess is that the setup order must be slightly different when X windows first starts, and something else is adding a definition to the capslock.

==EDIT==

Looking at the keymap (using xkbcomp) after X windows starts, CAPS is set to:
Code:

    key <CAPS> {
        type[group1]= "FOUR_LEVEL_CAPS",
        symbols[Group1]= [ ISO_First_Group_Lock, ISO_Prev_Group_Lock, ISO_Next_Group_Lock, ISO_Last_Group_Lock ],
        symbols[Group2]= [ ISO_Next_Group_Lock, ISO_Last_Group_Lock ]
    };

Which makes it look like the first group is wrapping into the second (perhaps because it was originally allocated only 2 entries by the pc keymap?). Running setxkbmap changes this to the way it should be:
[CODE]
Code:

    key <CAPS> {
        type[group1]= "FOUR_LEVEL_CAPS",
        symbols[Group1]= [ ISO_First_Group_Lock, ISO_Prev_Group_Lock, ISO_Next_Group_Lock, ISO_Last_Group_Lock ]
    };


alexbrui 02-17-2010 12:54 AM

Many thanks neonsignal!
Now all works and my understanding was much better


All times are GMT -5. The time now is 12:21 AM.