i3-companion: turn polybar function into a decorator

This commit is contained in:
Vincent Bernat 2021-07-24 19:54:06 +02:00
parent 68496a33c6
commit a954b5ff57

View file

@ -228,6 +228,40 @@ def debounce(sleep, *, unless=None):
return decorator return decorator
def polybar(module):
"""Use returned string to update polybar module"""
def decorator(fn):
@functools.wraps(fn)
async def wrapper(*args, **kwargs):
content = await fn(*args, **kwargs)
if type(content) is not str or cache.get(module) == content:
return content
# Update cache file (for when polybar restarts)
with open(f"{os.getenv('XDG_RUNTIME_DIR')}/i3/{module}.txt", "w") as out:
out.write(content)
# Send it to polybar
for name in glob.glob("/tmp/polybar_mqueue.*"):
try:
with open(os.open(name, os.O_WRONLY | os.O_NONBLOCK), "w") as out:
cmd = f"action:#{module}.send.{content}"
out.write(cmd)
except OSError as e:
if e.errno != errno.ENXIO:
raise
logger.info(f"polybar/{module}: content updated")
cache[module] = content
return content
return wrapper
cache = {}
return decorator
# Other helpers # Other helpers
@ -249,23 +283,6 @@ async def notify(i3, **kwargs):
return await notifications.Notify(**parameters) return await notifications.Notify(**parameters)
def polybar(module, content):
"""Update Polybar module with the provided content."""
# Update cache file (for when polybar restarts)
with open(f"{os.getenv('XDG_RUNTIME_DIR')}/i3/{module}.txt", "w") as out:
out.write(content)
# Send it to polybar
for name in glob.glob("/tmp/polybar_mqueue.*"):
try:
with open(os.open(name, os.O_WRONLY | os.O_NONBLOCK), "w") as out:
cmd = f"action:#{module}.send.{content}"
out.write(cmd)
except OSError as e:
if e.errno != errno.ENXIO:
raise
async def create_new_workspace(i3): async def create_new_workspace(i3):
"""Create a new workspace and returns its number.""" """Create a new workspace and returns its number."""
workspaces = await i3.get_workspaces() workspaces = await i3.get_workspaces()
@ -637,17 +654,16 @@ async def bluetooth_notifications(i3, event, path, interface, changed, invalid):
), ),
), ),
) )
@static(last=None)
@retry(2) @retry(2)
@debounce(0.2) @debounce(0.2)
@polybar("bluetooth")
async def bluetooth_status(i3, event, *args): async def bluetooth_status(i3, event, *args):
"""Update bluetooth status for Polybar.""" """Update bluetooth status for Polybar."""
if event is StartEvent: if event is StartEvent:
# Do we have a bluetooth device? # Do we have a bluetooth device?
if not os.path.exists("/sys/class/bluetooth"): if not os.path.exists("/sys/class/bluetooth"):
logger.info("no bluetooth detected") logger.info("no bluetooth detected")
polybar("bluetooth", "") return ""
return
# OK, get the info # OK, get the info
conn = i3.system_bus["org.bluez"] conn = i3.system_bus["org.bluez"]
@ -714,13 +730,7 @@ async def bluetooth_status(i3, event, *args):
else: else:
icon = "unknown" icon = "unknown"
output.append(icon) output.append(icon)
output = "|".join(icons[o] for o in output) return "|".join(icons[o] for o in output)
# Update polybar
if bluetooth_status.last != output:
logger.info("updated bluetooth status")
polybar("bluetooth", output)
bluetooth_status.last = output
@on( @on(
@ -733,26 +743,22 @@ async def bluetooth_status(i3, event, *args):
onlyif=lambda args: args[0] == "org.dunstproject.cmd0" and "paused" in args[1], onlyif=lambda args: args[0] == "org.dunstproject.cmd0" and "paused" in args[1],
) )
) )
@polybar("dunst")
async def dunst_status_update(i3, event, path, interface, changed, invalid): async def dunst_status_update(i3, event, path, interface, changed, invalid):
"""Update notification status in Polybar.""" """Update notification status in Polybar."""
polybar( paused = changed["paused"][1]
"dunst", return icons[paused and "notifications-disabled" or "notifications-enabled"]
icons[
changed["paused"][1] and "notifications-disabled" or "notifications-enabled"
],
)
@on(StartEvent) @on(StartEvent)
@polybar("dunst")
async def dunst_status_check(i3, event): async def dunst_status_check(i3, event):
"""Display notification status for Polybar.""" """Display notification status for Polybar."""
conn = i3.session_bus["org.freedesktop.Notifications"] conn = i3.session_bus["org.freedesktop.Notifications"]
obj = conn["/org/freedesktop/Notifications"] obj = conn["/org/freedesktop/Notifications"]
dunst = await obj.get_async_interface("org.dunstproject.cmd0") dunst = await obj.get_async_interface("org.dunstproject.cmd0")
paused = await dunst.paused paused = await dunst.paused
polybar( return icons[paused and "notifications-disabled" or "notifications-enabled"]
"dunst", icons[paused and "notifications-disabled" or "notifications-enabled"]
)
@on( @on(
@ -809,7 +815,6 @@ async def network_manager_notifications(i3, event, path, state, reason):
signature="a{sv}", signature="a{sv}",
), ),
) )
@static(last=None)
@retry(2) @retry(2)
@debounce( @debounce(
1, 1,
@ -817,6 +822,7 @@ async def network_manager_notifications(i3, event, path, state, reason):
isinstance(event, DBusSignal) and event.interface.endswith(".Active") isinstance(event, DBusSignal) and event.interface.endswith(".Active")
), ),
) )
@polybar("network")
async def network_manager_status(i3, event, *args): async def network_manager_status(i3, event, *args):
"""Compute network manager status.""" """Compute network manager status."""
ofnm = "org.freedesktop.NetworkManager" ofnm = "org.freedesktop.NetworkManager"
@ -876,12 +882,7 @@ async def network_manager_status(i3, event, *args):
status.append(await nma.Id) status.append(await nma.Id)
# Final status line # Final status line
status = " ".join(status) return " ".join(status)
if status != network_manager_status.last:
logger.info("updated network status")
polybar("network", status)
network_manager_status.last = status
# Main function # Main function