Source code for i3pystatus.xkblayout
from i3pystatus import IntervalModule
import subprocess
[docs]class Xkblayout(IntervalModule):
"""Displays and changes current keyboard layout.
``change_layout`` callback finds the current layout in the
``layouts`` setting and enables the layout following it. If the
current layout is not in the ``layouts`` setting the first layout
is enabled.
``layouts`` can be stated with or without variants,
e.g.: status.register("xkblayout", layouts=["de neo", "de"])
"""
interval = 1
format = u"\u2328 {name}"
uppercase = True
settings = (
("format", "Format string"),
("layouts", "List of layouts"),
("uppercase", "Flag for uppercase output"),
)
layouts = []
on_leftclick = "change_layout"
def run(self):
kblayout = self.kblayout()
full_text = self.format.format(name=kblayout)
if self.uppercase:
full_text = full_text.upper()
self.output = {
"full_text": full_text,
"color": "#ffffff"
}
def change_layout(self):
layouts = self.layouts
kblayout = self.kblayout()
if kblayout in layouts:
position = layouts.index(kblayout)
try:
subprocess.check_call(["setxkbmap"] +
layouts[position + 1].split())
except IndexError:
subprocess.check_call(["setxkbmap"] + layouts[0].split())
else:
subprocess.check_call(["setxkbmap"] + layouts[0].split())
def kblayout(self):
kblayout = subprocess.check_output("setxkbmap -query", shell=True)\
.decode("utf-8").splitlines()
kblayout = [l.split() for l in kblayout]
kblayout = [l[1].strip() for l in kblayout
if l[0].startswith(("layout", "variant"))]
return (" ").join(kblayout)