Назначение языка клавиатуры по умолчанию для каждого приложения

9

Можно ли назначить язык клавиатуры по умолчанию для определенных приложений? Я знаю, что есть возможность всегда запускать приложение с использованием языка клавиатуры по умолчанию, но это не то, что я хочу.

Я ищу что-то похожее на «фиксированные рабочие пространства», которые вы можете установить с помощью CompizConfig (вы всегда устанавливаете Chrome на X1Y1, терминал на X2Y1 и т. д.). Что-то, где я бы установил Chrome: чешский, терминал: английский, Spotify: английский, ...

    
задан grongor 02.08.2015 в 11:45
источник

3 ответа

6

Введение

Ниже приведенный ниже скрипт устанавливает язык для каждой пользовательской программы в соответствии с положением этого языка в меню языка. Например, если мой заказ: английский (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 

Файл Launcher (.desktop) для сценария set-lang.sh

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

Файл Launcher (.desktop) для set-lang-controller.sh

[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.sh и set-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. Затем добавьте соответствующую запись в структуру case.

Например, если я хочу добавить, LibreOffice Writer, я открываю окно LibreOffice Writer, перехожу на терминал и запускаю wmctrl -lx . Он скажет мне, что окно Writer имеет класс libreoffice.libreoffice-writer . Затем я перейду к скрипту, добавлю PROG_CLASS_4=libreoffice.libreoffice-writer и LANG4=3 в соответствующую область. Обратите внимание на соответствующее число 4. Затем перейдите к структуре case и добавьте следующую запись между последними ;; и 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 &

Небольшое примечание: еще один способ узнать класс окна для программы (тот материал, который предшествует одиночной круглой скобке в структуре случая) заключается в использовании этого xprop и awk oneliner: xprop | awk '/WM_CLASS/ {gsub(/"/," "); print $3"."$5}

    
ответ дан Sergiy Kolodyazhnyy 05.08.2015 в 01:52
источник
1

Вы можете установить gxneur для этого, запустив

sudo apt-get install gxneur

Это программное обеспечение может автоматически переключать макеты, но это не идеально.

Но у него очень хорошие инструменты для настройки ручных переключателей.

Вы можете делать именно то, что хотите. Чтобы установить конкретные макеты для определенных приложений.

    
ответ дан Pilot6 10.08.2015 в 21:53
источник
0

Ниже приведена отредактированная версия этого , которая была размещена как аналогичное решение для одно приложение ( 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. В сценарии используются как xdotool , так и wmctrl :

    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
    
ответ дан Jacob Vlijm 10.08.2015 в 21:50
источник

Ознакомьтесь с другими вопросами по меткам