응용 프로그램 당 기본 키보드 언어 할당


11

특정 응용 프로그램에 기본 키보드 언어를 할당 할 수 있습니까? 항상 기본 키보드 언어로 응용 프로그램을 시작하는 옵션이 있지만 이것이 내가 원하는 것은 아닙니다.

CompizConfig를 사용하여 설정할 수있는 '고정 작업 공간'과 비슷한 것을 찾고 있습니다 (Chrome은 항상 X1Y1에서 열도록 설정하고 X2Y1의 터미널 등을 설정). Chrome을 설정할 위치 : 체코 어, 터미널 : 영어, Spotify : 영어, ...


"텍스트 입력"에는 "각 창마다 다른 소스 허용"옵션이 있습니다. 아마도 올바른 방향으로 나아가는 단계 일 것입니다.
Gunnar Hjalmarsson

예, 감사합니다. 알고 있습니다. 이것은 내가 말하고 싶은 단계이지만 불행히도 내가 달성하려는 것은 아닙니다. 어쨌든 고마워
grongor

스크립팅 방법이 있습니다. 이 3 개의 앱만 필요하거나 다른 앱이 있습니까? 스크립트의 유연성에 따라 스크립트를 작성하는 데 다소 시간이 걸릴 수 있습니다.
Sergiy Kolodyazhnyy

파이썬에 대한 또 다른 좋은 작업 같은 @JacobVlijm 사운드)
세르지 Kolodyazhnyy

답변을 게시했습니다. 당신의 생각을 알려주세요
Sergiy Kolodyazhnyy

답변:


6

소개

스크립트 벨로우즈는 언어 메뉴에서 해당 언어의 위치에 따라 각 사용자 정의 프로그램의 언어를 설정합니다. 예를 들어 주문이 영어 (1), 중국어 (2) 및 러시아어 (3) 인 경우 Firefox는 언어 2, 터미널은 언어 1, LibreOffice는 언어 3을 갖도록 Firefox를 설정할 수 있습니다.

스크립트는 두 부분으로 구성됩니다. 하나는 작업을 수행하는 실제 스크립트이고 두 번째는 제어 요소로 사용됩니다. 아이디어는 언어 설정 스크립트를 시작 응용 프로그램 으로 실행하고 수동으로 언어를 변경해야 할 때마다 컨트롤러 스크립트 바로 가기를 두 번 클릭하는 것입니다.

전제 조건

  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 루프로 실행되며 현재 활성 창을 확인합니다. 현재 활성 창이 사례 구조의 옵션 중 하나와 일치하면 적절한 언어로 전환됩니다. 지속적인 설정을 피하기 위해 케이스 구조의 각 부분에는 언어가 원하는 값으로 이미 설정되어 있는지 확인하는 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 창에 class가 있음을 알려줍니다 libreoffice.libreoffice-writer. 내가 스크립트로 이동합니다 다음으로, 추가 PROG_CLASS_4=libreoffice.libreoffice-writerLANG4=3해당 지역이다. 일치하는 숫자 4를 확인하십시오. 다음으로 케이스 구조로 이동하여 last ;;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 &

작은 참고 : 프로그램의 창 클래스를 찾는 또 다른 방법 (케이스 구조에서 단일 둥근 괄호 앞에 오는 것들)은 this xpropawkoneliner 를 사용하는 것입니다.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). 이렇게하면 일시 중지하고 언어를 정상적으로 전환 한 다음 다시 시작할 수 있습니다.
Sergiy Kolodyazhnyy

내가 가진 빠른 생각은 아마도 두 명령에 키보드 단축키를 사용하는 것이 방법 일지 모르지만 아직까지는 테스트하지 않았으며 지금까지는 이론이었습니다. 나는 충분한 수면 및 보고서 등을 일단 내일을 테스트합니다 :)이 허용 생각 될 경우 알려주세요
세르지 Kolodyazhnyy

1
위대하고 철저한 일을 위해 +1하십시오! 내가 말하고 싶은 두 가지 작은 것들 : 실행 파일에 ~/bin경로가 필요하지 않습니다 (확장자도 $PATH다시 로그인 한 후 이므로 lintian.debian.org/tags/script-with-language-extension 참조) .html ), 중지 / 시작을 하나의 .desktop파일로 결합 할 수 있습니다. 퀵리스트 또는 토글 기능 중 하나입니다. 나에게 완벽 해 보인다.
Jacob Vlijm

1

당신은 gxneur그것을 실행하여 설치할 수 있습니다

sudo apt-get install gxneur

이 소프트웨어는 자동으로 레이아웃을 전환 할 수 있지만 그 방법으로는 완벽하지 않습니다.

그러나 수동 레이아웃 스위치를 설정하는 매우 유용한 도구가 있습니다.

원하는 것을 정확하게 할 수 있습니다. 특정 응용 프로그램에 대한 특정 레이아웃을 설정합니다.


0

이 스크립트는 아래의 편집 된 버전 이 하나 A에 대한 유사한 솔루션으로 게시, 하나의 응용 프로그램 ( 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. 이 스크립트는 xdotooland를 모두 사용합니다 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
Fabby

이봐, 정말 고마워, 내가 곧 그것을보고 내가 그것에 대해 어떻게 생각하는지 알려드립니다 :)
grongor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.