Действительно ли возможно присвоить язык клавиатуры по умолчанию для определенных приложений? Я знаю, что существует опция всегда запустить приложение с языком клавиатуры по умолчанию, но это не то, что я хочу.
Я ищу что-то подобное "фиксированным рабочим областям", которые можно установить использование CompizConfig (Вы устанавливаете Chrome, чтобы всегда открыться в X1Y1, терминале в X2Y1 и т.д.). Что-то, где я установил бы Chrome: чешский язык, терминал: английский, Spotify: английский язык...
Вы можете установить gxneur
для этого, запустив
sudo apt-get install gxneur
Это программное обеспечение может автоматически переключать раскладки, но с этим не идеально.
Но в нем есть очень хорошие инструменты для настройки ручных переключателей раскладки
Вы можете делать именно то, что хотите. Для настройки конкретных макетов для конкретных приложений.
Введение
Приведенный ниже сценарий устанавливает язык для каждой пользовательской программы в соответствии с положением этого языка в языковом меню. Например, если мой заказ: английский (1), китайский (2) и русский (3), я могу настроить Firefox на язык 2, терминал на язык 1 и LibreOffice на язык 3.
Сценарий состоит из двух частей: первая часть - это сам скрипт, выполняющий работу, вторая часть служит управляющим элементом. Идея состоит в том, чтобы запустить сценарий настройки языка как приложение запуска , и всякий раз, когда вам нужно вручную изменить язык, дважды щелкните ярлык для сценария контроллера.
Предварительные требования
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
Файл программы запуска (.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
Файл программы запуска (.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
Обеспечение работы сценария
bin
. Вы можете сделать это в файловом менеджере или использовать команду mkdir $ HOME / bin
в терминале 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
.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. Затем перейдите к структуре дела,и добавьте следующую запись между последними ;;
и 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 &
Небольшое примечание: еще один способ узнать класс окна для программы (то, что стоит перед одиночной круглой скобкой в структуре case) - использовать этот xprop
и awk
oneliner: xprop | awk '/ WM_CLASS / {gsub (/ "/," "); print $ 3". "$ 5}
Приведенный ниже сценарий является отредактированной версией этого , который был опубликован как аналогичное решение для отдельного приложения ( 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
Сценарий использует как xdotool
, так и wmctrl
:
sudo apt-get install wmctrl xdotool
Скопируйте приведенный выше сценарий в пустой файл, сохраните его как set_language.py
Протестируйте и запустите его с помощью команды:
python3 /path/to/set_language.py
Если все работает, как ожидалось, добавьте его в Автозагрузку приложений: Добавить в Автозагрузку приложений: Dash> Автозагрузка приложений> Добавить. Добавьте команду:
python3 /path/to/set_language.py