I want to enable one more input language and I wonder is there any way to group similar languages? Suppose I have English, Russian and Ukranian. Russian and Ukranian are similar and it would be convenient to group them. To bind ctrl+shift — switching between cyrillic and latin groups, alt+shift — switching inside group between cyrillic languages. Is it possible?
Ubuntu – Input language groups switching windows style
command lineinput-languageshortcutsusability
Related Solutions
Keyboard layout in Xorg server session can be easily changed via setxkbmap
.
Usage is pretty simple. Just pass your locale as an argument for that command and your current input would be changed (works both for console apps and for UI apps):
SYNOPSIS
setxkbmap [ args ] [ layout [ variant [ option ... ] ] ]
The call you need is: setxkbmap us
. Or you may need more options which you can grab by running setxkbmap -query
while you are on some locale.
So to have your request done:
Alt+Shift+1 for English, Alt+Shift+2 for Russian, Alt+Shift+0 for Hebrew
you'd need to assign following commands to keyboard shortcuts:
- Alt+Shift+0 :
setxkbmap he
- Alt+Shift+1 :
setxkbmap us
- Alt+Shift+2 :
setxkbmap ru
Note on the answer below
The answer was originally written for 14.04, but rewritten January 6, 2017, to also work on (at least) 16.04 and 16.10. wmctrl
is no longer needed.
Script to automatically set a different language for a single application.
What it does
- Running the script in the background, the user can set a different language for a specific application (in this case
gnome-terminal
). Just run the script and, with the application in front, set the desired language. - The language will be remembered, in the script (while running) as well as in a hidden file, to be remembered on the next time the script runs (on restart of the computer).
- If the user sets focus to another application, the script switches back to the default language, whatever that was. Also the default language will be remembered, but user can change it any time (also the changed language is remembered)
Notes
- The script uses an extended set of tools (functions) to take into account that user should be able to change the set of used languages, and the languages should be remembered, as suggested in the comment(s). Nevertheless it is very "light", since it only uses the function(s) when it is needed.
The script
#!/usr/bin/env python3
import subprocess
import time
import os
import ast
#--- set the "targeted" exceptional application below
app = "gnome-terminal"
#---
l_file = os.path.join(os.environ["HOME"], app+"_lang")
def_lang = os.path.join(os.environ["HOME"], "def_lang")
k = ["org.gnome.desktop.input-sources", "current", "sources"]
def get(cmd):
# helper function
try:
return subprocess.check_output(cmd).decode("utf-8").strip()
except subprocess.CalledProcessError:
pass
def run(cmd):
# helper function
subprocess.Popen(cmd)
def front():
# see if app has active window
front = get(["xdotool", "getactivewindow"])
data = get(["xprop", "-id", front])
if all([front, data]):
return app in get(["xprop", "-id", front])
else:
pass
def getlang():
# get the currently set language (from index, in case the sources are changed)
currindex = int(get(["gsettings", "get", k[0], k[1]]).split()[-1])
return sources[currindex]
def get_stored(file):
# read the set language
return sources.index(ast.literal_eval(open(file).read().strip()))
def get_sources():
return ast.literal_eval(get(["gsettings", "get", k[0], k[2]]))
sources = get_sources()
appfront1 = None
currlang1 = getlang()
while True:
time.sleep(1)
appfront2 = front()
if appfront2 != None:
currlang2 = getlang()
# change of frontmost app (type)
if appfront2 != appfront1:
if appfront2:
try:
run(["gsettings", "set", k[0], k[1], str(get_stored(l_file))])
except FileNotFoundError:
open(l_file, "wt").write(str(currlang2))
elif not appfront2:
try:
run(["gsettings", "set", k[0], k[1], str(get_stored(def_lang))])
except FileNotFoundError:
open(def_lang, "wt").write(str(currlang2))
elif currlang2 != currlang1:
f = l_file if appfront2 else def_lang
open(f, "wt").write(str(currlang2))
appfront1 = appfront2
currlang1 = currlang2
How to use
The script uses
xdotool
:sudo apt-get install xdotool
Copy the script above into an empty file, save it as
set_language.py
Test-run it by the command:
python3 /path/to/set_language.py
While running the script:
- set the (default) language.
- open the (gnome-) terminal, set the language to be used with the terminal
- Switch between the two and see if the language automatically switches.
You can change both default language as the terminal language at any time. The set language(s) will be remembered.If all works as expected, add it to Startup Applications: Add to Startup Applications: Dash > Startup Applications > Add. Add the command:
python3 /path/to/set_language.py
Explanation, the short (conceptual) story:
The script uses two files, to store the set languages for both the default language and the language, used in the exceptional application (gnome-terminal
in this case, but you can set any application).
The script then periodically (once per second) does two tests:
- If the active window belongs to the exceptional application
- What is the currently set input language
The script compares the situation with the test(s) one second ago. Then if:
there was a change in application:
exceptional --> default: read language file for default language & set language. If the file does not exist (jet), create it, store the current language as default.
default --> exceptional: the other way around.If there was a change in language (but not in window class):
We may assume user set a different language for either the exceptional application or the default input language --> write the currently used input language into the according file (either for default language or the exceptional language).
Best Answer
Script to switch to the next language group, or to the next language inside the current group, depending on the argument.
Preparation
In a terminal, run:
This will output something like (in my case):
Now simply create a file inside your
$HOME
directory (exactly) named:where you group the languages to your liking. In my example, I will group
'us+intl'
together with'us'
, and'nl'
with'be'
. I group them by their order in the list, which results into a file:content of the file
~/home/langsets
:As you can see, on each line, I put the numbers of the index of the languages, separated by a space (where 1 is the first language in the output list).
You can set any combination of languages (as long as you don't place languages in multiple groups), and any number of language groups, simply create a new line with indices.
The script
Copy the script into an empty file, save it as
language_set.py
Test- run the script with the two commands:
an
to see if the script (subsequently) moves to the next language group or to the next language in the current group.
If all works fine, create two keyboard shortcuts. One to switch to the next group, one to switch inside the current group.
Choose: System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts". Click the "+" and add the commands below.
To change between language groups:
To change between languages inside a group: