web-dev-qa-db-fra.com

Attribuer la langue du clavier par application pour chaque application

Est-il possible d'attribuer une langue de clavier par défaut pour des applications spécifiques? Je sais qu'il existe une option pour toujours démarrer une application avec une langue de clavier par défaut, mais ce n'est pas ce que je veux.

Je recherche quelque chose de similaire aux "espaces de travail fixes" que vous pouvez définir à l'aide de CompizConfig (vous définissez Chrome pour qu'il soit toujours ouvert à X1Y1, terminal à X2Y1, etc.). Quelque chose où je placerais Chrome: tchèque, terminal: anglais, Spotify: anglais, ...

9
grongor

Introduction

Le script ci-dessous définit la langue de chaque programme défini par l'utilisateur, en fonction de la position de cette langue dans le menu Langue. Par exemple, si ma commande est la suivante: anglais (1), chinois (2) et russe (3), je peux configurer Firefox comme langue 2, le terminal comme langue 1 et LibreOffice comme langue 3.

Le script est composé de deux parties: la première est le script qui effectue le travail, le second sert d’élément de contrôle. L'idée est d'exécuter le script de paramétrage de la langue en tant que application de démarrage et chaque fois que vous devez modifier manuellement la langue - double-cliquez sur le raccourci du script du contrôleur.

Prérequis

  1. Installez le programme wmctrl avec Sudo apt-get install wmctrl.

Script

#!/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 de contrôleur

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

Fichier Launcher (.desktop) du script 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

Fichier Launcher (.desktop) pour 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

Faire fonctionner le script

  1. Créez un dossier dans votre répertoire personnel appelé bin. Vous pouvez le faire dans le gestionnaire de fichiers ou utiliser la commande mkdir $HOME/bin dans le terminal.
  2. Dans le dossier bin, créez deux fichiers: set-lang.sh et set-lang-control.sh. Enregistrez le script sur set-lang.sh et le script du contrôleur sur set-lang-control.sh. Rendre les deux scripts exécutables avec Sudo chmod +x $HOME/bin/set-lang-control.sh $HOME/bin/set-lang.sh
  3. Créez deux fichiers .desktop. L'un est set-lang.desktop. Doit être placé dans le répertoire caché .config/autostart. Le second est set-lang-controller.desktop, peut être placé dans votre dossier bin. Ensuite, faites glisser le fichier set-lang-controller.desktop sur le lanceur. Cela deviendra le raccourci pour arrêter et reprendre temporairement l'exécution du script.

NOTEZ que la ligne Exec= doit être modifiée pour que votre nom d'utilisateur actuel figure dans le chemin du script (car il s'agit de votre répertoire de base). Par exemple, le mien serait Exec=/home/serg/bin/set-lang.sh

Explication et personnalisation:

Le script lui-même s'exécute dans une boucle while infinie et vérifie la fenêtre active en cours. Si la fenêtre active actuelle correspond à l'une des options de la structure de cas, nous basculons vers la langue appropriée. Pour éviter la configuration constante, chaque partie de la structure de cas a une instruction if qui vérifie si la langue a déjà été définie sur la valeur souhaitée.

Un double-clic sur le lanceur pour set-lang-controller.sh vérifiera l’état du script set-lang.sh; si le script est en cours d'exécution, il sera suspendu et s'il est suspendu, il sera repris. Une notification sera affichée avec le message approprié.

Pour personnaliser le script, vous pouvez ouvrir les applications souhaitées, exécuter wmctrl -lx et noter la troisième colonne - la classe window. Exemple de sortie:

$ 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

Sélectionnez les classes de fenêtres appropriées pour chaque programme. Ensuite, accédez à la partie du script qui permet la personnalisation et ajoutez deux entrées pour PROG_CLASS et LANG. Ajoutez ensuite l'entrée appropriée dans la structure de cas.

Par exemple, si je veux ajouter Writer de LibreOffice, j'ouvre la fenêtre de LibreOffice Writer, allez au terminal et exécutez wmctrl -lx. Il me dira que la fenêtre Writer a la classe libreoffice.libreoffice-writer. Ensuite, je vais au script, ajouter PROG_CLASS_4=libreoffice.libreoffice-writer et LANG4=3 dans la zone appropriée. Avis correspondant numéro 4. Ensuite, accédez à la structure de cas et ajoutez l'entrée suivante entre le dernier ;; et le esac:

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

Encore une fois, notez le signe $ et le numéro correspondant 4.

De plus, si le script est exécuté en tant qu'élément de démarrage automatique et que vous souhaitez l'arrêter temporairement pour le personnaliser, utilisez pkill set-lang.sh et reprenez-le avec Nohup set-lang.sh > /dev/null 2&>1 &.

Petite remarque: une autre façon de connaître la classe de fenêtre d'un programme (ce qui se passe avant un crochet rond dans la structure de cas) consiste à utiliser ceci xprop et awk oneliner: xprop | awk '/WM_CLASS/ {gsub(/"/," "); print $3"."$5}

6

Vous pouvez installer gxneur pour cela en lançant

Sudo apt-get install gxneur

Ce logiciel peut changer automatiquement de disposition, mais ce n’est pas parfait avec ça.

Mais il dispose de très bons outils pour configurer des commutateurs de disposition manuels.

Vous pouvez faire exactement ce que vous voulez. Pour définir des dispositions spécifiques pour des applications spécifiques.

1
Pilot6

Le script ci-dessous est une version modifiée de this celui , qui a été publiée comme solution similaire pour une application unique (gnome-terminal) il y a un moment.

Le script a été partiellement réécrit pour cette question afin de pouvoir l'utiliser pour définir automatiquement les langues de plusieurs applications.

Comment utiliser en pratique; mémoriser automatiquement la langue définie par application

Si le script est démarré pour la première fois, la langue actuelle est supposée être la langue par défaut, qui est mémorisée dans un fichier caché: ~/.lang_set.

Ensuite, l’utilisation est simple: si vous exécutez, par exemple, gedit dans la fenêtre la plus à l'avant, et définissez une langue différente, cette langue est automatiquement connectée à gedit, jusqu'à ce que vous changiez de nouveau la langue avec gedit à l'avant.

Le nombre de langages/applications spécifiques est en principe illimité; Il suffit de lancer l'application et de définir la langue avec la fenêtre de l'application devant. L'application sera automatiquement définie et mémorisée sans modifier le code.

Event driven?

Bien que le script s'exécute en boucle, la consommation de ressources est minimale. Event driven signifie que l'événement est un changement dans la fenêtre au premier plan. Je ne vois pas d'autre option que "espionner" pour la fenêtre la plus en avant que de vérifier en boucle.

Le scénario

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

Comment mettre en place

  1. Le script utilise à la fois xdotool et wmctrl:

    Sudo apt-get install wmctrl xdotool
    
  2. Copiez le script ci-dessus dans un fichier vide, enregistrez-le sous le nom set_language.py

  3. Testez-le avec la commande:

    python3 /path/to/set_language.py
    
  4. Si tout fonctionne comme prévu, ajoutez-le à Applications de démarrage: Ajoutez à Applications de démarrage: Dash> Applications de démarrage> Ajouter. Ajoutez la commande:

    python3 /path/to/set_language.py
    
0
Jacob Vlijm