73 lines
1.7 KiB
Python
73 lines
1.7 KiB
Python
import subprocess
|
|
import pydbus
|
|
from dataclasses import dataclass
|
|
from typing import Optional
|
|
|
|
|
|
@dataclass
|
|
class RofiResult:
|
|
"""Data returned from Rofi.
|
|
|
|
Attributes
|
|
----------
|
|
index
|
|
Index within entries of the selected entry.
|
|
`None` if nothing was selected.
|
|
value
|
|
Selected entry's string value.
|
|
`None` if the value is not in the list or nothing was selected.
|
|
custom_bind
|
|
ID of custom bind used to select entry. None if no custom bind was used.
|
|
"""
|
|
|
|
index: Optional[int]
|
|
value: str
|
|
custom_bind: Optional[int]
|
|
|
|
|
|
def rofi(
|
|
entries: list[str], prompt: str = "> ", fuzzy=True, extra_args=[]
|
|
) -> Optional[RofiResult]:
|
|
"""Start a Rofi prompt.
|
|
|
|
Returns
|
|
-------
|
|
None if the prompt was cancelled, or a `RofiResult`.
|
|
"""
|
|
args = ["rofi", "-dmenu", "-sep", "\\0"]
|
|
args += ["-p", prompt]
|
|
|
|
if fuzzy:
|
|
args += ["-matching", "fuzzy"]
|
|
|
|
args += extra_args
|
|
|
|
ret = RofiResult(None, "", None)
|
|
|
|
res = subprocess.run(
|
|
args, input="\0".join(entries), stdout=subprocess.PIPE, text=True
|
|
)
|
|
match res.returncode:
|
|
case 0:
|
|
pass
|
|
case 1:
|
|
return None
|
|
case x if x >= 10 and x <= 28:
|
|
ret.custom_bind = x - 9
|
|
case _ as retc:
|
|
raise RuntimeError(f"Rofi returned an unexpected return code `{retc}`.")
|
|
ret.value = res.stdout.strip()
|
|
try:
|
|
ret.index = entries.index(ret.value)
|
|
except ValueError:
|
|
pass
|
|
|
|
return ret
|
|
|
|
|
|
def notify(title: str, txt: str) -> None:
|
|
"""Send a text notification."""
|
|
bus = pydbus.SessionBus()
|
|
notifs = bus.get(".Notifications")
|
|
notifs.Notify("instantref", 0, "dialog-information", title, txt, [], {}, 5000)
|