97 lines
3.1 KiB
Python
97 lines
3.1 KiB
Python
import subprocess
|
|
from itertools import zip_longest
|
|
|
|
from i3pystatus import IntervalModule
|
|
from xkbgroup import XKeyboard
|
|
|
|
|
|
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"])``
|
|
|
|
Requires xkbgroup (from PyPI)
|
|
|
|
.. rubric:: Available formatters
|
|
|
|
* `{num}` — current group number
|
|
* `{name}` — current group name
|
|
* `{symbol}` — current group symbol
|
|
* `{variant}` — current group variant
|
|
* `{count}` — number of all groups
|
|
* `{names}` — names of all groups
|
|
* `{symbols}` — symbols of all groups
|
|
* `{variants}` — variants of all groups
|
|
"""
|
|
|
|
interval = 1
|
|
color = "#FFFFFF"
|
|
format = "\u2328 {symbol}"
|
|
layouts = []
|
|
uppercase = True
|
|
settings = (
|
|
("color", "RGB hexadecimal color code specifuer, defaults to #FFFFFF"),
|
|
("format", "Format string"),
|
|
("layouts", "List of layouts"),
|
|
("uppercase", "Flag for uppercase output"),
|
|
)
|
|
|
|
on_leftclick = ["change_layout", 1]
|
|
on_upscroll = ["change_layout", 1]
|
|
on_downscroll = ["change_layout", -1]
|
|
|
|
def init(self):
|
|
if self.layouts:
|
|
self.set_layouts(self.layouts)
|
|
|
|
self._xkb = XKeyboard(auto_open=True)
|
|
|
|
def set_layouts(self, layouts):
|
|
self.layouts = layouts # Set, so that it could be used as a callback
|
|
|
|
layouts_parts = [x.split() for x in self.layouts]
|
|
symbols_variants_zipped = zip_longest(*layouts_parts, fillvalue="")
|
|
symbols_variants_str = [",".join(x) for x in symbols_variants_zipped]
|
|
assert len(symbols_variants_str) > 0
|
|
|
|
if len(symbols_variants_str) == 1:
|
|
symbols = symbols_variants_str[0]
|
|
args = "setxkbmap -layout {}".format(symbols)
|
|
elif len(symbols_variants_str) == 2:
|
|
(symbols, variants) = symbols_variants_str
|
|
args = "setxkbmap -layout {} -variant {}".format(symbols, variants)
|
|
else:
|
|
raise ValueError("Wrong layouts value: {}".format(self.layouts))
|
|
|
|
subprocess.check_call(args.split())
|
|
|
|
def change_layout(self, increment=1):
|
|
self._xkb.group_num += increment
|
|
|
|
def run(self):
|
|
cdict = {
|
|
"num": self._xkb.group_num,
|
|
"name": self._xkb.group_name,
|
|
"symbol": self._xkb.group_symbol,
|
|
"variant": self._xkb.group_variant,
|
|
"count": self._xkb.groups_count,
|
|
"names": self._xkb.groups_names,
|
|
"symbols": self._xkb.groups_symbols,
|
|
"variants": self._xkb.groups_variants,
|
|
}
|
|
|
|
full_text = self.format.format(**cdict)
|
|
full_text = full_text.upper() if self.uppercase else full_text
|
|
|
|
self.data = cdict
|
|
self.output = {
|
|
"full_text": full_text,
|
|
"color": self.color,
|
|
}
|