Uygulama başına varsayılan klavye dilini atama


11

Belirli uygulamalar için varsayılan klavye dilini atamak mümkün müdür? Her zaman varsayılan bir klavye dili ile bir uygulama başlatmak için bir seçenek olduğunu biliyorum ama istediğim bu değil.

CompizConfig kullanarak ayarlayabileceğiniz "sabit çalışma alanlarına" benzer bir şey arıyorum (Chrome'u her zaman X1Y1'de, terminal X2Y1'de açılacak şekilde ayarladınız). Chrome: Çekçe, terminal: İngilizce, Spotify: İngilizce, ...


"Metin Girişi" seçeneğinde "Her pencere için farklı kaynaklara izin ver" seçeneği vardır. Muhtemelen sizin için doğru yönde bir adım.
Gunnar Hjalmarsson

Evet, teşekkürler, bunu biliyorum. Söylemek istediğim bu adım ama maalesef başarmak istediğim şey bu değil. Yine de teşekkürler.
grongor

Senaryo yazmanın bir yolu var. Sadece bu 3 uygulamaya ihtiyacınız var mı yoksa başkaları mı var? Betiğin ne kadar esnek olmasını istediğinize bağlı olarak, yazmak için daha fazla veya daha az zaman alabilir
Sergiy Kolodyazhnyy

@JacobVlijm Python için başka bir iyi iş gibi geliyor;)
Sergiy Kolodyazhnyy

Bir cevap gönderdi. Ne düşündüğünüzü söyleyin
Sergiy Kolodyazhnyy

Yanıtlar:


6

Giriş

Aşağıdaki komut dosyası, dil menüsünde dilin konumuna göre, kullanıcı tanımlı her program için dili ayarlar. Örneğin, siparişim: İngilizce (1), Çince (2) ve Rusça (3) ise, Firefox'u dil 2'ye, terminal dil 1'e ve LibreOffice dil 3'e ayarlayabilirim.

Komut dosyası iki kısımdan oluşur: birinci kısım işi yapan gerçek komut dosyasıdır, ikinci komut dosyası kontrol elemanı olarak işlev görür. Fikir, dil ayarı komut dosyasını bir başlangıç ​​uygulaması olarak çalıştırmak ve dili el ile değiştirmeniz gerektiğinde - denetleyici komut dosyasının kısayolunu çift tıklatın.

Ön koşul

  1. İle wmctrlprogramı yükleyin sudo apt-get install wmctrl.

Senaryo

#!/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

Denetleyici Komut Dosyası

#!/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 komut dosyası için başlatıcı (.desktop) dosyası

[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 için Başlatıcı (.desktop) dosyası

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

Senaryoyu çalıştırma

  1. Ana dizininizde adlı bir klasör oluşturun bin. Dosya yöneticisinden yapabilir veya mkdir $HOME/binterminaldeki komutu kullanabilirsiniz
  2. Gelen binklasörüne iki dosya oluşturun: set-lang.shve set-lang-control.sh. Komut dosyasını şuraya set-lang.shve denetleyici komut dosyasını şuraya kaydedin set-lang-control.sh. Her iki betiği de ile çalıştırılabilir yapsudo chmod +x $HOME/bin/set-lang-control.sh $HOME/bin/set-lang.sh
  3. İki .desktopdosya oluşturun . Bir tanesi set-lang.desktop. Gizli .config/autostartdizine yerleştirilmelidir . İkincisi set-lang-controller.desktop, binklasörünüze yerleştirilebilir . Sonra set-lang-controller.desktopdosyayı sürükleyip başlatıcıya sabitleyin . Bu, komut dosyası yürütmesini geçici olarak durdurmak ve sürdürmek için kısayol olacaktır.

NOT hattı olduğunu Exec=(yani gerçek ev dizini çünkü) komut yolunda gerçek kullanıcı adı olması değişmiş olması gerekir. Örneğin, benimkiExec=/home/serg/bin/set-lang.sh

Açıklama ve özelleştirme:

Komut dosyasının kendisi sonsuz while döngüsünde çalışır ve geçerli etkin pencereyi denetler. Geçerli etkin pencere, vaka yapısındaki seçeneklerden biriyle eşleşiyorsa, uygun dile geçeriz. Sabit ayardan kaçınmak için, vaka yapısının her bir parçası, dilin önceden istenen değere ayarlanıp ayarlanmadığını kontrol eden if ifadesine sahiptir.

Başlatıcıyı çift tıklatmak komut dosyasının set-lang-controller.shdurumunu kontrol eder set-lang.sh; komut dosyası çalışıyorsa - duraklatılır ve komut dosyası duraklatılırsa devam ettirilir. Uygun mesajla birlikte bir bildirim gösterilir.

Komut dosyasını özelleştirmek için, istediğiniz uygulamaları açabilir wmctrl -lx, üçüncü sütunu (pencere sınıfı ) çalıştırabilir ve not edebilirsiniz. Örnek çıktı:

$ 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

Her program için uygun pencere sınıflarını seçin. Ardından, komut dosyasının özelleştirmeye izin veren bölümüne gidin ve PROG_CLASS ve LANG için iki giriş ekleyin. Daha sonra vaka yapısına uygun girişi ekleyin.

Örneğin, LibreOffice'in Yazarını eklemek istersem, LibreOffice Writer penceresini açar, terminale gider ve çalıştırırım wmctrl -lx. Bana Writer penceresinin sınıfı olduğunu söyleyecek libreoffice.libreoffice-writer. Daha sonra senaryoya gideceğim PROG_CLASS_4=libreoffice.libreoffice-writerve LANG4=3uygun alana ekleyeceğim . Eşleştirme numarası 4'e dikkat edin. Ardından, vaka yapısına gidin ve son ;;ile arasına aşağıdaki girişi ekleyin esac:

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

Yine, $ işaretine ve eşleşen 4 numarasına dikkat edin.

Ayrıca, komut dosyası otomatik başlatma öğesi olarak çalışıyorsa ve bunu özelleştirmek için geçici olarak durdurmak istiyorsanız pkill set-lang.sh,nohup set-lang.sh > /dev/null 2&>1 &

Küçük not: Bir programın pencere sınıfını bulmanın başka bir yolu (vaka yapısında tek yuvarlak köşeli parantezden önce gidenler) bunu xpropve awkoneliner'ı kullanmaktır :xprop | awk '/WM_CLASS/ {gsub(/"/," "); print $3"."$5}


Teşekkür ederim, bu oldukça iyi bir başlangıç. Tek (ama büyük) sorun, bu uygulamalarda dili değiştiremeyeceğim. Komut dosyası ayarlarımı her zaman geçersiz kılacaktır. Bu pencerelerdeki dili de değiştirmek istiyorum. Yani belki uygulama pid ve biraz dilini kontrol etmek için ilk kez veya böyle bir şey eklemek biraz?
grongor

Ayrıca bu komut dosyasının döngü tabanlı değil, olay odaklı olmasını tercih ederim. Bu büyük bir anlaşma değil ama bu mümkün (eğer mümkünse) dbus veya bir şey ile çalışmak için küçük bir nasıl-ebilmek tedarik eğer takdir ediyorum.
grongor

@ GRONGoR bu yüzden biraz düşündüm ve şimdiye kadar komut dosyası duraklatmak kill -STOP $(pgrep set-lang.sh)ve sonra komut dosyası ile devam etmek için bir yol görmüyorum kill -CONT $(pgrep set-lang.sh). Bu şekilde duraklatabilir, dilleri normal şekilde değiştirebilir ve sonra devam edebilirsiniz.
Sergiy Kolodyazhnyy

Sahip olduğum kısa bir düşünce, belki de iki komut için bir klavye kısayolu kullanmak, bunu yapmanın yolu olabilir, ancak henüz test etmedim, sadece bir teori. Ben yeterli uyku almak ve geri rapor kez yarın test edecek :) Bu kabul edilebilir bir fikir olacağını bildirin
Sergiy Kolodyazhnyy

1
Harika ve kapsamlı çalışma için +1! Bahsetmek istediğim iki küçük şey: içindeki yürütülebilir dosyaların ~/binyola ihtiyacı yoktur (ne de $PATHyeniden giriş yaptıktan sonra uzantıdır ), bkz: lintian.debian.org/tags/script-with-language-extension .html ) ve durdur / başlat işlevlerini tek bir .desktopdosyada birleştirebilirsiniz ; hızlı listede veya açma / kapatma işlevinde. benim için mükemmel görünüyor.
Jacob Vlijm

1

Bunu gxneurçalıştırarak kurabilirsiniz

sudo apt-get install gxneur

Bu yazılım düzenleri otomatik olarak değiştirebilir, ancak bununla mükemmel değildir.

Ancak manuel düzen anahtarları ayarlamak için çok güzel araçlara sahiptir.

Tam olarak istediğinizi yapabilirsiniz. Belirli uygulamalar için belirli düzenler ayarlamak için.


0

Script aşağıda düzenlenmiş bir versiyonudur bu bir bir için benzer bir çözüm olarak gönderilmiş, tek bir uygulama ( gnome-terminalbir süre önce).

Komut dosyası, birden çok uygulama için dilleri otomatik olarak ayarlamak üzere kullanabilmek için bu soru için kısmen yeniden yazılmıştır.

Pratikte nasıl kullanılır; Uygulama başına ayarlanan dili otomatik olarak hatırla

Komut ilk kez başlatıldığında, geçerli dil gizli dosyada hatırlanır varsayılan dil, olduğu varsayılır: ~/.lang_set.

Daha sonra kullanımı basittir: örneğin gediten ön pencerede çalıştırır ve farklı bir dil ayarlarsanız gedit, dili tekrar geditönden değiştirinceye kadar bu dil o andan itibaren otomatik olarak bağlanır .

Belirli dillerin / uygulamaların sayısı prensipte sınırsızdır; uygulamayı çalıştırın ve dili uygulama penceresinin önündeyken ayarlayın. Uygulama kodu düzenlemeden otomatik olarak ayarlanır ve hatırlanır.

Olay güdümlü mü?

Komut dosyası bir döngü halinde çalışmasına rağmen, kaynak tüketimi minimum düzeydedir. Olay güdümlüdür, olayın en ön pencerede bir değişiklik olduğu anlamına gelir . Ben bir döngüde kontrol daha en ön pencere için "casus" başka bir seçenek görmüyorum.

Senaryo

#!/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

Nasıl kurulur

  1. Senaryo hem kullanır xdotoolve wmctrl:

    sudo apt-get install wmctrl xdotool
    
  2. Yukarıdaki komut dosyasını boş bir dosyaya kopyalayın, set_language.py

  3. Komut ile test çalıştırın:

    python3 /path/to/set_language.py
    
  4. Tümü beklendiği gibi çalışıyorsa Başlangıç ​​Uygulamalarına ekleyin: Başlangıç ​​Uygulamalarına Ekle: Çizgi> Başlangıç ​​Uygulamaları> Ekle. Komutu ekleyin:

    python3 /path/to/set_language.py
    

Tek beden herkese uyar! +1
Fabby

Hey bunun için çok teşekkür ederim, yakında içine bakacağım ve bu konuda nasıl hissettiğimi size bildireceğim :)
grongor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.