Source code for libqtile.extension.dmenu
import shlex
from libqtile.extension import base
[docs]
class Dmenu(base.RunCommand):
"""
Python wrapper for dmenu
http://tools.suckless.org/dmenu/
"""
defaults = [
("dmenu_font", None, "override the default 'font' and 'fontsize' options for dmenu"),
# NOTE: Do not use a list as a default value, since it would be shared
# among all the objects inheriting this class, and if one of them
# modified it, all the other objects would see the modified list;
# use a string or a tuple instead, which are immutable
("dmenu_command", "dmenu", "the dmenu command to be launched"),
("dmenu_bottom", False, "dmenu appears at the bottom of the screen"),
("dmenu_ignorecase", False, "dmenu matches menu items case insensitively"),
("dmenu_lines", None, "dmenu lists items vertically, with the given number of lines"),
(
"dmenu_prompt",
None,
"defines the prompt to be displayed to the left of the input field",
),
("dmenu_height", None, "defines the height (only supported by some dmenu forks)"),
]
def __init__(self, **config):
base.RunCommand.__init__(self, **config)
self.add_defaults(Dmenu.defaults)
def _configure(self, qtile):
base.RunCommand._configure(self, qtile)
dmenu_command = self.dmenu_command or self.command
if isinstance(dmenu_command, str):
self.configured_command = shlex.split(dmenu_command)
else:
# Create a clone of dmenu_command, don't use it directly since
# it's shared among all the instances of this class
self.configured_command = list(dmenu_command)
if self.dmenu_bottom:
self.configured_command.append("-b")
if self.dmenu_ignorecase:
self.configured_command.append("-i")
if self.dmenu_lines:
self.configured_command.extend(("-l", str(self.dmenu_lines)))
if self.dmenu_prompt:
self.configured_command.extend(("-p", self.dmenu_prompt))
if self.dmenu_font:
font = self.dmenu_font
elif self.font:
if self.fontsize:
font = f"{self.font}-{self.fontsize}"
else:
font = self.font
self.configured_command.extend(("-fn", font))
if self.background:
self.configured_command.extend(("-nb", self.background))
if self.foreground:
self.configured_command.extend(("-nf", self.foreground))
if self.selected_background:
self.configured_command.extend(("-sb", self.selected_background))
if self.selected_foreground:
self.configured_command.extend(("-sf", self.selected_foreground))
# NOTE: The original dmenu doesn't support the '-h' option
if self.dmenu_height:
self.configured_command.extend(("-h", str(self.dmenu_height)))
def run(self, items=None):
if items and self.dmenu_lines:
lines = min(len(items), int(self.dmenu_lines))
self.configured_command.extend(("-l", str(lines)))
proc = super().run()
if items:
input_str = "\n".join([i for i in items]) + "\n"
return proc.communicate(str.encode(input_str))[0].decode("utf-8")
return proc
[docs]
class DmenuRun(Dmenu):
"""
Special case to run applications.
config.py should have something like:
.. code-block:: python
from libqtile import extension
keys = [
Key(['mod4'], 'r', lazy.run_extension(extension.DmenuRun(
dmenu_prompt=">",
dmenu_font="Andika-8",
background="#15181a",
foreground="#00ff00",
selected_background="#079822",
selected_foreground="#fff",
dmenu_height=24, # Only supported by some dmenu forks
))),
]
"""
defaults = [
("dmenu_command", "dmenu_run", "the dmenu command to be launched"),
]
def __init__(self, **config):
Dmenu.__init__(self, **config)
self.add_defaults(DmenuRun.defaults)
[docs]
class J4DmenuDesktop(Dmenu):
"""
Python wrapper for j4-dmenu-desktop
https://github.com/enkore/j4-dmenu-desktop
"""
defaults = [
("j4dmenu_command", "j4-dmenu-desktop", "the dmenu command to be launched"),
(
"j4dmenu_use_xdg_de",
False,
"read $XDG_CURRENT_DESKTOP to determine the desktop environment",
),
("j4dmenu_display_binary", False, "display binary name after each entry"),
("j4dmenu_generic", True, "include the generic name of desktop entries"),
("j4dmenu_terminal", None, "terminal emulator used to start terminal apps"),
("j4dmenu_usage_log", None, "file used to sort items by usage frequency"),
]
def __init__(self, **config):
Dmenu.__init__(self, **config)
self.add_defaults(J4DmenuDesktop.defaults)
def _configure(self, qtile):
Dmenu._configure(self, qtile)
self.configured_command = [
self.j4dmenu_command,
"--dmenu",
" ".join(shlex.quote(arg) for arg in self.configured_command),
]
if self.j4dmenu_use_xdg_de:
self.configured_command.append("--use-xdg-de")
if self.j4dmenu_display_binary:
self.configured_command.append("--display-binary")
if not self.j4dmenu_generic:
self.configured_command.append("--no-generic")
if self.j4dmenu_terminal:
self.configured_command.extend(("--term", self.j4dmenu_terminal))
if self.j4dmenu_usage_log:
self.configured_command.extend(("--usage-log", self.j4dmenu_usage_log))