frobar: Gracefully handle zelbar exists
Before it would just spam logs with "Unknown command: "
This commit is contained in:
parent
356186de7c
commit
465c2347cb
2 changed files with 48 additions and 36 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
zelbarnixpkgs ? builtins.getFlake "github:wlcx/nixpkgs/zelbar",
|
zelbarnixpkgs ? builtins.getFlake "github:wlcx/nixpkgs/zelbar",
|
||||||
# nixpkgs ? <nixpkgs>,
|
nixpkgs ? <nixpkgs>,
|
||||||
nixpkgs ? builtins.getFlake "nixpkgs/nixos-25.11",
|
# nixpkgs ? builtins.getFlake "nixpkgs/nixos-25.11",
|
||||||
pkgs ? import nixpkgs {
|
pkgs ? import nixpkgs {
|
||||||
overlays = [
|
overlays = [
|
||||||
(self: super: {
|
(self: super: {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import datetime
|
||||||
import enum
|
import enum
|
||||||
import logging
|
import logging
|
||||||
import signal
|
import signal
|
||||||
import sys
|
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
import gi
|
import gi
|
||||||
|
|
@ -361,29 +360,32 @@ class Screen(ComposableText):
|
||||||
self.output,
|
self.output,
|
||||||
]
|
]
|
||||||
print(" ".join(cmd))
|
print(" ".join(cmd))
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
while True:
|
||||||
|
last_start_time = loop.time()
|
||||||
proc = await asyncio.create_subprocess_exec(
|
proc = await asyncio.create_subprocess_exec(
|
||||||
*cmd,
|
*cmd,
|
||||||
stdout=asyncio.subprocess.PIPE,
|
stdout=asyncio.subprocess.PIPE,
|
||||||
stdin=asyncio.subprocess.PIPE,
|
stdin=asyncio.subprocess.PIPE,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def refresher() -> None:
|
async def refresher(proc: asyncio.subprocess.Process) -> None:
|
||||||
assert proc.stdin
|
assert proc.stdin
|
||||||
while True:
|
while proc.returncode is None:
|
||||||
await self.refresh.wait()
|
|
||||||
self.refresh.clear()
|
|
||||||
markup = self.get_markup()
|
markup = self.get_markup()
|
||||||
# sys.stdout.write(markup) # DEBUG
|
# sys.stdout.write(markup) # DEBUG
|
||||||
proc.stdin.write(markup.encode())
|
proc.stdin.write(markup.encode())
|
||||||
|
await self.refresh.wait()
|
||||||
|
self.refresh.clear()
|
||||||
|
|
||||||
async def action_handler() -> None:
|
async def action_handler(proc: asyncio.subprocess.Process) -> None:
|
||||||
assert proc.stdout
|
assert proc.stdout
|
||||||
while True:
|
while proc.returncode is None:
|
||||||
line = await proc.stdout.readline()
|
line = await proc.stdout.readline()
|
||||||
try:
|
try:
|
||||||
command = line.decode().strip()
|
command = line.decode().strip()
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
# FIXME zelbar seems to have some memory issues
|
# TODO zelbar seems to have some memory issues
|
||||||
log.exception("Not unicode: %s", str(line))
|
log.exception("Not unicode: %s", str(line))
|
||||||
continue
|
continue
|
||||||
callback = self.actions.get(command)
|
callback = self.actions.get(command)
|
||||||
|
|
@ -392,8 +394,17 @@ class Screen(ComposableText):
|
||||||
continue
|
continue
|
||||||
callback()
|
callback()
|
||||||
|
|
||||||
self.bar.add_long_running_task(refresher())
|
refresher_task = self.bar.add_long_running_task(refresher(proc))
|
||||||
self.bar.add_long_running_task(action_handler())
|
action_handler_task = self.bar.add_long_running_task(action_handler(proc))
|
||||||
|
|
||||||
|
await proc.wait()
|
||||||
|
log.error("zelbar exited with code %d", proc.returncode)
|
||||||
|
refresher_task.cancel()
|
||||||
|
action_handler_task.cancel()
|
||||||
|
|
||||||
|
# Delay restart if it's been less than 5 seconds to prevent infinite loops
|
||||||
|
time_since_start = loop.time() - last_start_time
|
||||||
|
await asyncio.sleep(max(0, 5 - time_since_start))
|
||||||
|
|
||||||
def add_action(self, callback: typing.Callable) -> str:
|
def add_action(self, callback: typing.Callable) -> str:
|
||||||
command = f"com{self.actionIndex:x}"
|
command = f"com{self.actionIndex:x}"
|
||||||
|
|
@ -434,14 +445,15 @@ class Bar(ComposableText):
|
||||||
continue
|
continue
|
||||||
Screen(parent=self, output=output.name)
|
Screen(parent=self, output=output.name)
|
||||||
|
|
||||||
def add_long_running_task(self, coro: typing.Coroutine) -> None:
|
def add_long_running_task(self, coro: typing.Coroutine) -> asyncio.Task:
|
||||||
task = self.taskGroup.create_task(coro)
|
task = self.taskGroup.create_task(coro)
|
||||||
self.longRunningTasks.append(task)
|
self.longRunningTasks.append(task)
|
||||||
|
return task
|
||||||
|
|
||||||
async def run(self) -> None:
|
async def run(self) -> None:
|
||||||
async with self.taskGroup:
|
async with self.taskGroup:
|
||||||
for screen in self.children:
|
for screen in self.children:
|
||||||
await screen.run()
|
self.add_long_running_task(screen.run())
|
||||||
for provider in self.providers:
|
for provider in self.providers:
|
||||||
self.add_long_running_task(provider.run())
|
self.add_long_running_task(provider.run())
|
||||||
|
|
||||||
|
|
@ -630,7 +642,7 @@ class PeriodicProvider(Provider):
|
||||||
while True:
|
while True:
|
||||||
# TODO Block bar update during the periodic update of the loops
|
# TODO Block bar update during the periodic update of the loops
|
||||||
loops = [provider.loop() for provider in providers]
|
loops = [provider.loop() for provider in providers]
|
||||||
asyncio.gather(*loops)
|
await asyncio.gather(*loops)
|
||||||
|
|
||||||
now = datetime.datetime.now(datetime.UTC)
|
now = datetime.datetime.now(datetime.UTC)
|
||||||
# Hardcoded to 1 second... not sure if we want some more than that,
|
# Hardcoded to 1 second... not sure if we want some more than that,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue