Linux 中的 2 个及以上键盘布局组可通过不同的热键进行更改

Linux 中的 2 个及以上键盘布局组可通过不同的热键进行更改

所以,这是我多年来一直梦想的事情。我偶尔在 Google 上寻找解决方案,但从未真正找到任何东西。有人在 IRC 上告诉我这是可能的,但我从未真正看到过如何做到这一点。

这就是我想要的。

我使用 en 和 ru 键盘布局作为日常工作中两种主要的输入语言。我使用Shift+Caps_Lock来切换这些布局。有时我需要输入 ua 和 pl,我希望将它们放在单独的布局组中,可以通过按L_Win+来切换Caps_Lock

因此,每当我按下L_Win+Caps_Lock时,我就会开始在 ua 和 pl 之间循环,而当我需要回到我的标准 en 和 ru 组时,我会按Shift+ Caps_Lock

这种描述与对现有键盘布局切换框架如何工作的真正理解没有任何联系。这只是我想象的理想情况。

那么,亲爱的超级用户,这可以在 Linux 上完成吗?如果可以,怎么做?

答案1

我对这个脚本做了一些改进。现在它不会破坏 WM 键盘切换器。它的工作方式与 TS 想要的略有不同,但我认为这样至少对我来说更方便

如果需要,您应该更改键盘型号和选项

#!/bin/sh
current=`setxkbmap -query | grep layout|cut  -d ',' -f 2`
if [ "$current" == 'pl' ]
then 
    notify-send -t 1500 -i keyboard "Keyboard layouts: EN / RU"
    setxkbmap -model logitech_base -layout en,ru -variant , -option grp:caps_toggle,compose:rwin
else 
    notify-send -t 1500 -i keyboard "Keyboard layouts: UA / PL"
    setxkbmap -model logitech_base -layout ua,pl -variant , -option grp:caps_toggle,compose:rwin
fi

答案2

最简单的方法可能是使用窗口管理器的键盘布局切换器作为主布局(en 和 ru),然后使用映射到L_Win+ 的以下脚本Caps_Lock

#!/bin/bash 

current=`setxkbmap -query | grep layout | fold -s2 | tail -n 1`
if [ "$current" == 'ua' ]
then
    setxkbmap -layout pl
else
    setxkbmap -layout ua
fi

如果您将脚本另存为toggle_layout.sh,使其可执行,并使用窗口管理器的工具将其映射到所需的键盘快捷键,它应该会满足您的需要。脚本只会检查您当前是否正在使用布局ua,如果没有,则切换到pl


更新:

我按照以下方式让它工作:

  1. 将上面的脚本映射到Ctrl+ 8(即键盘8)。
  2. 制作另一个脚本来在主布局之间切换:

    #!/bin/bash 
    
    current=`setxkbmap -query | grep layout | fold -s2 | tail -n 1`
    if [ "$current" == 'en' ]
    then
        setxkbmap -layout ru
    else
        setxkbmap -layout en
    fi
    
  3. 将步骤 2 中的脚本映射到Ctrl+ 2(即键盘2)。

确保使用的键不会随布局变化而变化(这就是我在本例中使用键盘的原因)。我不知道您是否可以在不破坏 WM 更改布局的本机方式的情况下做到这一点,但至少这应该可行。

答案3

还有另一种解决方案,基于已提供的解决方案。

将其绑定到一个键并提供所需的布局作为参数:

Super+ Lkeyboard-keyout-switch en,ua en,ru

#!/bin/bash

set -e

if [[ $# -lt 2 ]]; then
  echo 'Expected at least 2 arguments, specifying layout groups to switch.'
  echo 'Got:' "$@"
  exit 1
fi

declare -a groups
groups=( "$@" )

current=$( setxkbmap -query | grep layout | cut  -d ':' -f 2 | tr -d ' ' )

for currentI in "${!groups[@]}"; do
  if [[ "${groups[$currentI]}" = "$current" ]]; then
    nextI=$(( (currentI + 1) % ${#groups[@]} ))
    notify-send -t 1500 -i keyboard "Layout: ${groups[nextI]}" || true
    setxkbmap -layout "${groups[nextI]}"
    exit 0
  fi
done

echo 'Currently active layout is not preset in the configuration.'
echo 'Current layout:' "$current"
echo 'Configuration layouts:' "${groups[@]}"
exit 1

相关内容