from typing import Any
from libqtile import bar, hook
from libqtile.command.base import expose_command
from libqtile.layout import plasma
from libqtile.layout.plasma import AddMode
from libqtile.widget import base
[docs]
class Plasma(base._TextBox):
"""
A simple widget to indicate in which direction new windows will be
added in the Plasma layout.
"""
defaults: list[tuple[str, Any, str]] = [
("horizontal", "H", "Text to display if horizontal mode"),
("vertical", "V", "Text to display if horizontal mode"),
("split", "S", "Text to append to mode if ``horizontal/vertical_split`` not set"),
("horizontal_split", None, "Text to display for horizontal split mode"),
("vertical_split", None, "Text to display for horizontal split mode"),
("format", "{mode:>2}", "Format appearance of text"),
]
def __init__(self, text="", width=bar.CALCULATED, **config):
base._TextBox.__init__(self, text=text, width=width, **config)
self.add_defaults(Plasma.defaults)
self.add_callbacks({"Button1": self.next_mode})
if self.horizontal_split is None:
self.horizontal_split = self.horizontal + self.split
if self.vertical_split is None:
self.vertical_split = self.vertical + self.split
self.modes = [
AddMode.HORIZONTAL,
AddMode.HORIZONTAL | AddMode.SPLIT,
AddMode.VERTICAL,
AddMode.VERTICAL | AddMode.SPLIT,
]
self._mode = self.modes[0]
self._layout = None
def _configure(self, qtile, bar):
base._TextBox._configure(self, qtile, bar)
hook.subscribe.plasma_add_mode(self.mode_changed)
hook.subscribe.layout_change(self.layout_changed)
self.mode_changed(bar.screen.group.layout)
def mode_changed(self, layout):
"""Update text depending on add_mode of layout."""
if not isinstance(layout, plasma.Plasma):
self.update("")
self._layout = None
return
self._layout = layout
if layout.group and layout.group.screen is not self.bar.screen:
return
if layout.horizontal:
if layout.split:
mode = self.horizontal_split
self._mode = AddMode.HORIZONTAL | AddMode.SPLIT
else:
mode = self.horizontal
self._mode = AddMode.HORIZONTAL
else:
if layout.split:
mode = self.vertical_split
self._mode = AddMode.VERTICAL | AddMode.SPLIT
else:
mode = self.vertical
self._mode = AddMode.VERTICAL
self.update(self.format.format(mode=mode))
def layout_changed(self, layout, group):
"""Update widget when layout changes."""
if group.screen is self.bar.screen:
self.mode_changed(layout)
def finalize(self):
hook.unsubscribe.plasma_add_mode(self.mode_changed)
hook.unsubscribe.layout_change(self.layout_changed)
base._TextBox.finalize(self)
[docs]
@expose_command()
def next_mode(self):
"""Change the add mode for the Plasma layout."""
if self._layout is None:
return
index = self.modes.index(self._mode)
index = (index + 1) % len(self.modes)
self._layout.add_mode = self.modes[index]