Призначте мову клавіатури за замовчуванням для програми


11

Чи можливо призначити мову клавіатури за замовчуванням для конкретних програм? Я знаю, що є можливість завжди запускати програму з мовою клавіатури за замовчуванням, але це не те, що я хочу.

Я шукаю щось подібне до "фіксованих робочих просторів", які можна встановити за допомогою CompizConfig (Ви налаштовуєте Chrome завжди відкриватись на X1Y1, термінал у X2Y1 тощо). Щось я б встановив Chrome: чеський, термінал: англійський, Spotify: англійський, ...


У "Введенні тексту" є опція "Дозволити різні джерела для кожного вікна". Можливо, крок у правильному для вас напрямку.
Gunnar Hjalmarsson

Так, дякую, я знаю про це. Я б сказав, що це необхідний крок, але, на жаль, це не те, чого я хочу досягти. Все одно, дякую.
grongor

Існує сценарій способу. Вам потрібні лише ці 3 програми чи є інші? Залежно від того, наскільки гнучким ви хочете бути сценарієм, на його написання може знадобитися більше чи менше часу
Сергій Колодяжний,

@JacobVlijm Звучить як ще одна хороша робота для python;)
Сергій Колодяжний

Опублікував відповідь. Дайте мені знати, що ви думаєте
Сергій Колодяжний

Відповіді:


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 

Файл запуску (.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

Здійснення роботи сценарію

  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

Пояснення та налаштування:

Сам скрипт працює в нескінченному циклі і перевіряє поточне активне вікно. Якщо поточне активне вікно відповідає одному з варіантів структури справи, ми переходимо на відповідну мову. Щоб уникнути постійного налаштування, у кожній частині структури корпусу є оператор 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's 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 &

Невелика примітка: ще один спосіб дізнатися клас вікна для програми (той матеріал, який знаходиться перед однією круглою дужкою у структурі випадку) - використовувати цей xpropта awkoneliner:xprop | awk '/WM_CLASS/ {gsub(/"/," "); print $3"."$5}


Дякую, це досить вдалий початок. Єдина (але основна) проблема полягає в тому, що я не зможу переключити мову в цих додатках. Сценарій буде просто змінювати мої налаштування весь час. Я також хотів би мати можливість переключити мову в цих вікнах. Тож, можливо, додайте перевірку на додаток pid та примушуйте мову лише з першого разу чи щось подібне?
grongor

Я також вважаю за краще, щоб цей сценарій був керований подіями, а не циклами. Це не велика справа, але я дуже вдячний, якби ви могли запропонувати невелику практичну роботу, щоб налагодити цю роботу з dbus чи іншим (якщо це можливо).
grongor

@GRoNGoR, тому я трохи про це подумав, і поки що я не бачу способу призупинити сценарій, окрім, kill -STOP $(pgrep set-lang.sh)а потім відновити сценарій kill -CONT $(pgrep set-lang.sh). Таким чином ви можете призупинити, перемкнути мови, а потім відновити.
Сергій Колодяжний

Швидка думка, яку я мав, - це те, що, можливо, використання комбінації клавіш для двох команд може бути способом це зробити, але я ще не перевіряв її, лише теорія поки що. Попробую завтра, як тільки я виспаюся і доповім назад :) Повідомте, чи це буде прийнятна ідея
Сергій Колодяжний

1
+1 за велику і ретельну роботу! Дві крихітні речі, які я хотів би зазначити: виконуваним файлам~/bin не потрібен шлях (ні розширення, оскільки він знаходиться $PATHпісля повторного входу, див.: Lintian.debian.org/tags/script-with-language-extension .html ), і ви могли поєднати зупинку / запуск в одному .desktopфайлі; або у швидкому списку, або у функції перемикання. мені виглядає досить ідеально.
Яків Влійм

1

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

sudo apt-get install gxneur

Це програмне забезпечення може автоматично перемикати макети, але це не ідеально.

Але у нього є дуже приємні інструменти для встановлення ручних вимикачів компонування.

Ви можете робити саме те, що хочете. Встановлення конкретних макетів для конкретних програм.


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. Якщо все працює, як очікувалося, додайте його до програм запуску: Додати до програм запуску: тире> програми запуску> Додати. Додайте команду:

    python3 /path/to/set_language.py
    

Один розмір підходить всім! +1
Фабі

Гей, дякую вам за це, я незабаром
розберуся
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.