为每个应用程序分配默认键盘语言

为每个应用程序分配默认键盘语言

是否可以为特定应用程序指定默认键盘语言?我知道有一个选项可以始终使用默认键盘语言启动应用程序,但这不是我想要的。

我正在寻找类似于“固定工作区”的东西,您可以使用 CompizConfig 进行设置(您可以将 Chrome 设置为始终在 X1Y1 打开,将终端设置为始终在 X2Y1 打开等)。我会在其中设置 Chrome:捷克语、终端:英语、Spotify:英语……

答案1

介绍

下面的脚本根据语言菜单中语言的位置为每个用户定义的程序设置语言。例如,如果我的顺序是:英语 (1)、中文 (2) 和俄语 (3),我可以将 Firefox 设置为语言 2,将终端设置为语言 1,将 LibreOffice 设置为语言 3。

该脚本分为两部分:第一部分是执行该任务的实际脚本,第二部分脚本作为控制元素。其理念是将语言设置脚本作为启动应用程序每当您需要手动更改语言时 - 双击控制器脚本的快捷方式。

先决条件

  1. 使用安装wmctrl程序sudo apt-get install wmctrl

脚本

#!/bin/sh
# Author: Serg Kolo
# Date: August 4, 2015
# Description: This script forces assigned input languages
#              for specific windows
# Version:2

# Use this part to set programs and their respective languages
# PROG_CLASS or a running window can be found with the
# wmctrl -lx command
# If you want to add another program to the list, 
# follow the template PROG_CLASS_num=window.Class
# and bellow that $LANGnum=num


PROG_CLASS_1=gedit.Gedit
LANG1=2

PROG_CLASS_2=gnome-terminal-server.Gnome-terminal
LANG2=0

PROG_CLASS_3=Navigator.Firefox
LANG3=1


# While loop below gets the job done. 
# If you need to send languages for more programs -  copy  
# the first entry and replace  $PROG_CLASS_1 with $PROG_CLASS_num
# where num is respective number of a program
# Replace $LANGnum with the respective language number. After the "="
# post positional number of the language you want to use. 
# Remember the count starts from 0

while [ 1 ];do
  WM_CLASS=$(wmctrl -lx | awk -v search=$(printf %x $(xdotool getactivewindow)) '{ if($1~search) print $3 }' )
  CURRENT=$(gsettings get org.gnome.desktop.input-sources current| awk '{print $2}')
    case  $WM_CLASS in

      $PROG_CLASS_1)  
        if [ $CURRENT -ne  $LANG1 ];then
          gsettings set org.gnome.desktop.input-sources current $LANG1
        fi
      ;;

      $PROG_CLASS_2) 
        if [ $CURRENT -ne  $LANG2 ];then
          gsettings set org.gnome.desktop.input-sources current $LANG2
        fi  
      ;;

       $PROG_CLASS_3) 
         if [ $CURRENT -ne  $LANG3 ];then
           gsettings set org.gnome.desktop.input-sources current $LANG3
         fi  
        ;;
    esac

    sleep 0.250

done

控制器脚本

#!/bin/sh
# set -x
# Author: Serg Kolo
# Date: August 8, 2015
# Description: Controller script for set-lang.sh script
# Allows pausing and resuming execution of set-lang.sh
STATUS=$(ps -o stat -p $(pgrep -o  set-lang.sh) | awk '{getline;print }')

case $STATUS in
    T) kill -CONT $(pgrep set-lang.sh) 
       notify-send 'RESUMED'
    ;;

    S) kill -STOP $(pgrep set-lang.sh)
       notify-send 'STOPED'
    ;;

    *) exit ;;
esac 

set-lang.sh 脚本的启动器(.desktop)文件

[Desktop Entry]
Name=set-lang.sh
Comment=Script to set languages
Exec=/home/yourusername/bin/set-lang.sh
Type=Application
StartupNotify=true
Terminal=false

set-lang-controller.sh 的启动器(.desktop)文件

[Desktop Entry]
Name=lang-control
Comment=Shortcut to controlling script
Exec=/home/yourusername/bin/set-lang-control.sh
Type=Application
StartupNotify=true
Terminal=false

让脚本发挥作用

  1. 在您的主目录中创建一个名为 的文件夹。您可以在文件管理器中执行此操作,也可以使用终端中的bin命令mkdir $HOME/bin
  2. bin文件夹中创建两个文件:set-lang.shset-lang-control.sh。将脚本保存到set-lang.sh,将控制器脚本保存到set-lang-control.sh。使用以下命令使两个脚本均可执行sudo chmod +x $HOME/bin/set-lang-control.sh $HOME/bin/set-lang.sh
  3. 创建两个.desktop文件。一个是set-lang.desktop。必须放在隐藏.config/autostart目录中。第二个是set-lang-controller.desktop,可以放在您的文件夹中bin。接下来将文件拖放到启动器上set-lang-controller.desktop。这将成为暂时停止和恢复脚本执行的快捷方式。

笔记必须修改此行,Exec=以便将实际用户名添加到脚本路径中(因为这是您的实际主目录)。例如,我的路径是Exec=/home/serg/bin/set-lang.sh

说明及定制:

脚本本身在无限 while 循环中运行并检查当前活动窗口。如果当前活动窗口与 case 结构中的某个选项匹配,我们将切换到相应的语言。为了避免不断设置,case 结构的每个部分都有 if 语句来检查语言是否已设置为所需值。

双击启动器set-lang-controller.sh将检查脚本的状态set-lang.sh;如果脚本正在运行 - 它将暂停,如果脚本暂停,它将恢复。将显示带有适当消息的通知。

为了自定义脚本,您可以打开所需的应用程序,运行wmctrl -lx并注意第三列 - 窗口类。示例输出:

$ wmctrl -lx | awk '$4="***" {print}'                                                                                                            
0x02c00007 0 gnome-terminal-server.Gnome-terminal *** Terminal
0x03a0000a 0 desktop_window.Nautilus *** Desktop
0x04a00002 0 N/A *** XdndCollectionWindowImp
0x04a00005 0 N/A *** unity-launcher
0x04a00008 0 N/A *** unity-panel
0x04a0000b 0 N/A *** unity-dash
0x04a0000c 0 N/A *** Hud
0x012000a6 0 Navigator.Firefox *** unity - Assign default keyboard language per-application - Ask Ubuntu - Mozilla Firefox

为每个程序选择适当的窗口类。接下来,转到允许自定义的脚本部分,并为 PROG_CLASS 和 LANG 添加两个条目。接下来在案例结构中添加适当的条目。

例如,如果我想添加 LibreOffice 的 Writer,我打开 LibreOffice Writer 窗口,转到终端并运行wmctrl -lx。它会告诉我 Writer 窗口有类libreoffice.libreoffice-writer。接下来我将转到脚本,在相应区域添加PROG_CLASS_4=libreoffice.libreoffice-writer和。注意匹配数字 4。接下来,转到案例结构,并在最后和LANG4=3之间添加以下条目:;;esac

$PROG_CLASS_4) 
  if [ $CURRENT -ne  $LANG4 ];then
    gsettings set org.gnome.desktop.input-sources current $LANG4
  fi  
;;

再次注意 $ 符号和匹配的数字 4。

此外,如果脚本作为自动启动项运行,而你想暂时停止它以进行自定义,请使用pkill set-lang.sh并恢复nohup set-lang.sh > /dev/null 2&>1 &

小提示:找出程序窗口类的另一种方法(在案例结构中单个圆括号之前的内容)是使用此方法xpropawk单行代码:xprop | awk '/WM_CLASS/ {gsub(/"/," "); print $3"."$5}

答案2

您可以gxneur通过运行来安装

sudo apt-get install gxneur

该软件可以自动切换布局,但是还不够完美。

但是它有非常好的工具来设置手动布局开关。

你可以做你想做的事。为特定应用程序设置特定布局。

答案3

下面的脚本是这个,这是针对单一应用gnome-terminal) 不久以前。

针对这个问题,脚本被部分重写,以便能够使用它来自动设置多个应用程序的语言。

如何在实践中使用;自动记住每个应用程序设置的语言

如果首次启动脚本,则当前语言将被假定为默认语言,该语言被保存在一个隐藏文件中:~/.lang_set

然后使用很简单:如果您gedit在最前面的窗口中运行例如,并设置不同的语言,则gedit从那时起该语言就会自动连接到该语言,直到您再次使用gedit前面的语言更改语言。

特定语言/应用程序的数量原则上不受限制;只需运行应用程序并在应用程序窗口前面设置语言即可。应用程序将自动设置并记住,无需编辑代码。

事件驱动?

虽然脚本确实循环运行,但资源消耗却很小。事件驱动意味着事件是最前面窗口的变化。我认为除了“监视”最前面的窗口之外,没有其他选择,只能在循环中检查。

剧本

#!/usr/bin/env python3
import subprocess
import os
import time

key = [
    "org.gnome.desktop.input-sources",
    "gsettings get ", "gsettings set ",
    " sources", " current",
    ]

prev = os.environ["HOME"]+"/.lang_set"

def get(cmd):
    return subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")

def get_front():
    # produce the frontmost application
    try:
        focus = str(hex(int(get("xdotool getwindowfocus").strip())))
        front = focus[:2]+"0"+focus[2:]
        cmd = "wmctrl -lp"
        w_list = subprocess.check_output(["/bin/bash", "-c",cmd]).decode("utf-8")
        w_match = [w for w in w_list.splitlines() if front in w][0].split()[2]
        application = get("ps -p "+w_match+" -o comm=").strip()
        # fix for 15.04, where the process name of gnome-terminal varies
        application = "gnome-terminal" if "gnome-terminal" in application else application
        return application
    except subprocess.CalledProcessError:
        return None

def get_lang():
    # get the currently running language (output = string)
    curr_n = int(get(key[1]+key[0]+key[4]).strip().split()[-1])
    return str(eval(get(key[1]+key[0]+key[3]))[curr_n])

def read_prev(application):
    # reads the possibly set languages for general and specific use (list)
    if not os.path.exists(prev):
        currlang = get_lang()
        open(prev, "wt").write("default "+currlang+"\n"+application+" "+currlang)
        return [currlang, currlang]
    else:
        return [l.strip() for l in open(prev).readlines()]

def write_changed(application, lang):
    changelist = read_prev(front_2)
    try:
        match = changelist.index([l for l in changelist if application in l][0])
        changelist[match] = application+" "+lang+"\n"
    except IndexError:
        changelist.append(application+" "+lang+"\n")
    open(prev, "wt").write(("\n").join(changelist))

def set_lang(lang):
    # set the currently used language (input = string)
    lang_i = eval(get(key[1]+key[0]+key[3])).index(eval(lang))  
    cmd = key[2]+key[0]+key[4]+" "+str(lang_i)
    subprocess.Popen(["/bin/bash", "-c", cmd])

front_1 = get_front(); lang_1 = get_lang()

while True:
    time.sleep(1)
    front_2 = get_front(); lang_2 = get_lang()
    if front_2 != None:
        if front_2 != front_1:
            try:
                setlist = read_prev(front_2)
                match = [l for l in setlist if front_2 in l][0]
            except IndexError:
                match = [l for l in setlist if "default" in l][0]
                set_lang(match[match.find(" ")+1:])            
        elif lang_2 != lang_1:
            write_changed(front_2, lang_2)
    front_1 = front_2; lang_1 = lang_2

如何设置

  1. 该脚本同时使用了xdotoolwmctrl

    sudo apt-get install wmctrl xdotool
    
  2. 将上述脚本复制到一个空文件中,另存为set_language.py

  3. 通过命令测试运行:

    python3 /path/to/set_language.py
    
  4. 如果一切正常,请将其添加到启动应用程序:添加到启动应用程序:Dash > 启动应用程序 > 添加。添加命令:

    python3 /path/to/set_language.py
    

相关内容