Gán ngôn ngữ bàn phím mặc định cho mỗi ứng dụng


11

Có thể gán ngôn ngữ bàn phím mặc định cho các ứng dụng cụ thể không? Tôi biết rằng có một tùy chọn để luôn khởi động một ứng dụng với ngôn ngữ bàn phím mặc định nhưng đây không phải là điều tôi muốn.

Tôi đang tìm kiếm một cái gì đó tương tự như "không gian làm việc cố định" mà bạn có thể đặt bằng CompizConfig (Bạn đặt Chrome luôn mở ở X1Y1, thiết bị đầu cuối tại X2Y1, v.v.). Một cái gì đó nơi tôi sẽ đặt Chrome: Séc, thiết bị đầu cuối: Tiếng Anh, Spotify: Tiếng Anh, ...


Trong "Nhập văn bản" có tùy chọn "Cho phép các nguồn khác nhau cho mỗi cửa sổ". Có thể là một bước đi đúng hướng cho bạn.
Gunnar Hjalmarsson

Vâng, cảm ơn bạn, tôi biết về điều đó. Đây là bước cần thiết tôi sẽ nói nhưng thật không may, đó không phải là điều tôi muốn đạt được. Dẫu sao cũng xin cảm ơn.
grongor

Có một cách viết kịch bản. Bạn chỉ cần 3 ứng dụng đó hoặc có những ứng dụng khác? Tùy thuộc vào mức độ linh hoạt mà bạn muốn kịch bản trở thành, tôi có thể mất ít nhiều thời gian để viết nó
Sergiy Kolodyazhnyy

@JacobVlijm Nghe giống như một công việc tốt khác cho trăn;)
Sergiy Kolodyazhnyy

Đăng một câu trả lời. Hãy cho tôi biết những gì bạn nghĩ
Sergiy Kolodyazhnyy

Câu trả lời:


6

Giới thiệu

Tập lệnh dưới đây đặt ngôn ngữ cho từng chương trình do người dùng xác định, theo vị trí của ngôn ngữ đó trong menu ngôn ngữ. Chẳng hạn, nếu đơn hàng của tôi là: tiếng Anh (1), tiếng Trung (2) và tiếng Nga (3), tôi có thể đặt Firefox có ngôn ngữ 2, thiết bị đầu cuối có ngôn ngữ 1 và LibreOffice có ngôn ngữ 3.

Kịch bản có hai phần: phần một là kịch bản thực tế thực hiện công việc, tập lệnh thứ hai đóng vai trò là yếu tố kiểm soát. Ý tưởng là để chạy tập lệnh cài đặt ngôn ngữ như một ứng dụng khởi động và bất cứ khi nào bạn cần thay đổi ngôn ngữ theo cách thủ công - nhấp đúp vào phím tắt đến tập lệnh điều khiển.

Điều kiện tiên quyết

  1. Cài đặt wmctrlchương trình với sudo apt-get install wmctrl.

Kịch bản

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

Script điều khiển

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

Tệp trình khởi chạy (.desktop) cho tập lệnh 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

Tệp trình khởi chạy (.desktop) cho set-lang-controll.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

Làm cho kịch bản hoạt động

  1. Tạo một thư mục trong thư mục nhà của bạn được gọi là bin. Bạn có thể làm điều đó trong trình quản lý tệp hoặc sử dụng lệnh mkdir $HOME/bintrong thiết bị đầu cuối
  2. Trong binthư mục tạo hai tệp: set-lang.shset-lang-control.sh. Lưu tập lệnh set-lang.shvà tập lệnh điều khiển vào set-lang-control.sh. Làm cho cả hai tập lệnh thực thi vớisudo chmod +x $HOME/bin/set-lang-control.sh $HOME/bin/set-lang.sh
  3. Tạo hai .desktoptập tin. Một là set-lang.desktop. Phải được đặt trong .config/autostartthư mục ẩn . Thứ hai là set-lang-controller.desktop, có thể được đặt trong binthư mục của bạn . Tiếp theo kéo và ghim vào trình khởi chạy set-lang-controller.desktoptệp. Điều này sẽ trở thành lối tắt để tạm thời dừng và tiếp tục thực thi tập lệnh.

LƯU Ý rằng dòng Exec=phải được thay đổi để có tên người dùng thực tế của bạn trong đường dẫn đến tập lệnh (vì đó là thư mục chính thực tế của bạn). Ví dụ, của tôi sẽ làExec=/home/serg/bin/set-lang.sh

Giải thích và tùy biến:

Kịch bản lệnh tự chạy trong một vòng lặp vô hạn và kiểm tra cửa sổ hiện hoạt. Nếu cửa sổ hiện hoạt phù hợp với một trong các tùy chọn trong cấu trúc trường hợp, chúng tôi sẽ chuyển sang ngôn ngữ phù hợp. Để tránh cài đặt không đổi, mỗi phần của cấu trúc trường hợp có câu lệnh if kiểm tra xem ngôn ngữ đã được đặt thành giá trị mong muốn chưa.

Nhấp đúp chuột vào launcher cho set-lang-controller.shsẽ kiểm tra trạng thái của set-lang.shtập lệnh; nếu tập lệnh đang chạy - nó sẽ bị tạm dừng và nếu tập lệnh bị tạm dừng, nó sẽ được tiếp tục. Một thông báo sẽ được hiển thị với thông điệp thích hợp.

Để tùy chỉnh tập lệnh, bạn có thể mở (các) ứng dụng mong muốn, chạy wmctrl -lxvà ghi chú cột thứ ba - lớp cửa sổ. Đầu ra mẫu:

$ 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

Chọn các lớp cửa sổ thích hợp cho mỗi chương trình. Tiếp theo, đi đến phần của tập lệnh cho phép tùy chỉnh và thêm hai mục nhập cho PROG_CLASS và LANG. Tiếp theo thêm mục thích hợp trong cấu trúc trường hợp.

Chẳng hạn, nếu tôi muốn thêm, Nhà văn của LibreOffice, tôi mở cửa sổ LibreOffice Writer, đi đến terminal và chạy wmctrl -lx. Nó sẽ cho tôi biết rằng cửa sổ Nhà văn có lớp libreoffice.libreoffice-writer. Tiếp theo tôi sẽ đi đến kịch bản, thêm PROG_CLASS_4=libreoffice.libreoffice-writerLANG4=3trong khu vực thích hợp. Thông báo khớp số 4. Tiếp theo, đi đến cấu trúc trường hợp và thêm mục sau đây giữa cuối ;;esac:

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

Một lần nữa, hãy chú ý dấu $ và khớp số 4.

Ngoài ra, nếu tập lệnh đang chạy như một mục tự khởi động và bạn muốn tạm thời dừng nó để tùy chỉnh nó, hãy sử dụng pkill set-lang.shvà tiếp tục vớinohup set-lang.sh > /dev/null 2&>1 &

Lưu ý nhỏ: một cách khác để tìm ra lớp cửa sổ cho một chương trình (thứ đó đi trước dấu ngoặc tròn đơn trong cấu trúc trường hợp) là sử dụng cái này xpropawkoneliner:xprop | awk '/WM_CLASS/ {gsub(/"/," "); print $3"."$5}


Cảm ơn bạn, đây là một khởi đầu khá tốt. Vấn đề duy nhất (nhưng chính) là tôi sẽ không thể chuyển đổi ngôn ngữ trong các ứng dụng đó. Kịch bản đơn giản sẽ ghi đè cài đặt của tôi mọi lúc. Tôi cũng muốn có thể chuyển đổi ngôn ngữ trong các cửa sổ đó. Vì vậy, có thể thêm một số kiểm tra cho ứng dụng pid và buộc ngôn ngữ chỉ lần đầu tiên hoặc một cái gì đó như thế?
grongor

Tôi cũng thích kịch bản này sẽ dựa trên sự kiện, không phải dựa trên vòng lặp. Đó không phải là một vấn đề lớn nhưng tôi thực sự sẽ đánh giá cao nếu bạn có thể cung cấp một cách nhỏ để làm việc này với dbus hoặc một cái gì đó (nếu có thể).
grongor

@GRoNGoR vì vậy tôi đã suy nghĩ về nó một chút và cho đến nay tôi không thấy cách nào để tạm dừng tập lệnh ngoại trừ kill -STOP $(pgrep set-lang.sh)và sau đó tiếp tục tập lệnh với kill -CONT $(pgrep set-lang.sh). Bằng cách đó bạn có thể tạm dừng nó, chuyển đổi ngôn ngữ bình thường và sau đó tiếp tục.
Sergiy Kolodyazhnyy

Một suy nghĩ nhanh mà tôi có là có lẽ sử dụng phím tắt cho hai lệnh có thể là cách để thực hiện, nhưng tôi chưa thử nghiệm nó, chỉ là một lý thuyết cho đến nay. Sẽ kiểm tra vào ngày mai khi tôi ngủ đủ giấc và báo cáo lại :) Hãy cho tôi biết nếu đây sẽ là một ý tưởng có thể chấp nhận được
Sergiy Kolodyazhnyy

1
+1 cho công việc tuyệt vời và kỹ lưỡng! Hai điều nhỏ mà tôi muốn đề cập: các tệp thực thi ~/binkhông cần đường dẫn (cũng không phải phần mở rộng, vì nó nằm $PATHsau khi đăng nhập lại, xem: lintian.debian.org/tags/script-with-lingu-extension .html ) và bạn có thể kết hợp dừng / bắt đầu trong một .desktoptệp; hoặc trong một danh sách nhanh hoặc một chức năng chuyển đổi. trông khá hoàn hảo với tôi
Jacob Vlijm

1

Bạn có thể cài đặt gxneurcho nó bằng cách chạy

sudo apt-get install gxneur

Phần mềm này có thể tự động chuyển đổi bố cục, nhưng nó không hoàn hảo với điều đó.

Nhưng nó có các công cụ rất đẹp để thiết lập các công tắc bố trí thủ công.

Bạn có thể làm chính xác những gì bạn muốn. Để thiết lập bố cục cụ thể cho các ứng dụng cụ thể.


0

Kịch bản dưới đây là phiên bản chỉnh sửa của cái này , đã được đăng dưới dạng một giải pháp tương tự cho một ứng dụng ( gnome-terminal) cách đây một thời gian.

Kịch bản được viết lại một phần cho câu hỏi này, để có thể sử dụng nó để tự động thiết lập ngôn ngữ cho nhiều ứng dụng.

Cách sử dụng trong thực tế; tự động ghi nhớ thiết lập ngôn ngữ cho mỗi ứng dụng

Nếu tập lệnh được bắt đầu lần đầu tiên, ngôn ngữ hiện tại được coi là ngôn ngữ mặc định, được ghi nhớ trong một tệp ẩn : ~/.lang_set.

Sau đó, cách sử dụng rất đơn giản: nếu bạn chạy ví dụ geditở cửa sổ phía trước và đặt một ngôn ngữ khác, ngôn ngữ đó sẽ tự động được kết nối gedittừ đó trở đi, cho đến khi bạn thay đổi lại ngôn ngữ geditở phía trước.

Số lượng ngôn ngữ / ứng dụng cụ thể về nguyên tắc là không giới hạn; chỉ cần chạy ứng dụng và đặt ngôn ngữ với cửa sổ ứng dụng ở phía trước. Ứng dụng sẽ được tự động thiết lập và ghi nhớ mà không cần chỉnh sửa mã.

Sự kiện thúc đẩy?

Mặc dù tập lệnh không chạy trong một vòng lặp, việc tiêu thụ tài nguyên là tối thiểu. Sự kiện hướng đến có nghĩa là sự kiện là một sự thay đổi trong cửa sổ ngoài cùng. Tôi không thấy lựa chọn nào khác ngoài "gián điệp" cho hầu hết các cửa sổ phía trước ngoài việc kiểm tra một vòng lặp.

Kịch bản

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

Làm thế nào để thiết lập

  1. Kịch bản sử dụng cả hai xdotoolwmctrl:

    sudo apt-get install wmctrl xdotool
    
  2. Sao chép tập lệnh ở trên vào một tệp trống, lưu nó dưới dạng set_language.py

  3. Chạy thử nó bằng lệnh:

    python3 /path/to/set_language.py
    
  4. Nếu tất cả đều hoạt động như mong đợi, hãy thêm nó vào Ứng dụng khởi động: Thêm vào Ứng dụng khởi động: Dấu gạch ngang> Ứng dụng khởi động> Thêm. Thêm lệnh:

    python3 /path/to/set_language.py
    

Một kích thước phù hợp với tất cả! +1
Fabby 10/08/2015

Xin chân thành cảm ơn bạn rất nhiều vì điều này, tôi sẽ xem xét nó sớm và cho bạn biết tôi cảm thấy thế nào về nó :)
grongor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.