Shift+Space is not writing U+200c(ZWNJ) character in Persian layout

In Persian (with Persian layout) layout, Shift + Space must write U+200c Unicode character (also known as ZWNJ).
But it writes normal space character with Win + Space as the change layout key(it seems arbitrary but it works with Left Alt + Left Shift as change layout key)

Here is the output of xmodmap -pke command: Deleted

I’m not familiar with keymap settings and commands. Please tell me if there’s anything else you want me to share.

I’ve been playing around with it, and it seems that group(win_space_toggle) changes the key’s type to one that’s incompatible with a Space with more than one level (symbol).

Not surprising as it needs to fit into the standard type definitions, and there isn’t one for this situation. More info in the “Fix it” section below.

You have 3 options:

  1. Use another key/combo for change layout (recommended)
  2. Report an issue
  3. Fix it for your computer

What do you want to do?

Report an issue

I think this is the correct place:
Issues · xkbdesc / xkeyboard-config · GitLab

Fix it for your computer

The easiest way to get the config below is with xkbcomp $DISPLAY ~/.xkbmap. It will dump the combined config into a single file, which can be edited and then applied using xkbcomp ~/.xkbmap $DISPLAY.

I’m using gb as my primary layout and ir (aka Persian) as the secondary. These are the key definitions, from the 4th section (xkb_symbols):

# Win + Space changes layout
key <SPCE> {
        type= "PC_SUPER_LEVEL2",
        symbols[Group1]= [           space,  ISO_Next_Group ]
    };

# Caps Lock changes layout
key <SPCE> {
        type[group2]= "FOUR_LEVEL",
        symbols[Group1]= [           space ],
        symbols[Group2]= [           space,           U200C,    nobreakspace,           U202F ]
    };

These are the relevant types, from the 2nd section (xkb_types)

type "PC_SUPER_LEVEL2" {
        modifiers= Mod4;
        map[Mod4]= Level2;
        level_name[Level1]= "Base";
        level_name[Level2]= "Super";
    };

type "FOUR_LEVEL" {
        modifiers= Shift+LevelThree;
        map[Shift]= Level2;
        map[LevelThree]= Level3;
        map[Shift+LevelThree]= Level4;
        level_name[Level1]= "Base";
        level_name[Level2]= "Shift";
        level_name[Level3]= "AltGr";
        level_name[Level4]= "Shift AltGr";
    };

So one way to handle this, is to combine the types into a new type and merge the key definitions. Like so:

# create a new type
type "FOUR_LEVEL_WIN" {
        modifiers= Shift+LevelThree+Mod4;
        map[Shift]= Level2;
        map[LevelThree]= Level3;
        map[Shift+LevelThree]= Level4;
        map[Mod4]= Level5;
        level_name[Level1]= "Base";
        level_name[Level2]= "Shift";
        level_name[Level3]= "AltGr";
        level_name[Level4]= "Shift AltGr";
        level_name[Level5]= "Super";
    };


# replace the current definition
 key <SPCE> {
    type[Group1]= "PC_SUPER_LEVEL2",
    type[Group2]= "FOUR_LEVEL_WIN",
    symbols[Group1]= [  space,   ISO_Next_Group ],
    symbols[Group2]= [  space,   U200C,    nobreakspace,   U202F, ISO_Next_Group  ]
};

That would only be temporary. As you’re using X11, you’ll have to use a systemd service or similar to run the xkbcomp command on login. If the keyboard is external it would be a good idea to have a udev rule to also re-apply the layout if/when the keyboard re-connects (but you could do it manually with xkbcomp).

Obviously it may need adapting to your setup. Let me know if you want help with that or more detailed instructions. If you do, then post your current key definition for Space.

If you make changes to your keyboard setup, eg layout, options, then they may interfere with this configuration and vice versa. You should apply any layouts/options, etc, before dumping the config with xkbcomp, that way it will be included in your new “layout”. Afterwards it’s all managed manually in ~/.xkbmap.

You could create a new layout and use it, but you’d also have to edit the types file. Unfortunately your changes to the latter would be overwritten the next time xkeyboard-config was updated.

On wayland we can override the package owned files, which is a nicer way of doing it, but according to at least one xkeyboard-config maintainer, this won’t be backported to X11.

https://wiki.archlinux.org/title/X_keyboard_extension
https://wiki.archlinux.org/title/Systemd
https://wiki.archlinux.org/title/Udev