Add ability to wait for signals between commands.

This commit is contained in:
redxef 2022-10-29 01:32:57 +02:00
parent 05dda652db
commit 6e10cd4e41
Signed by: redxef
GPG key ID: 7DAC3AA211CBD921

View file

@ -4,6 +4,8 @@
import collections.abc import collections.abc
import asyncio import asyncio
import signal
import os
import functools import functools
import json import json
@ -287,17 +289,33 @@ def window_new(configs: list[dict], debug: bool):
ipc.main_quit() ipc.main_quit()
return callback return callback
async def wait_signal(s):
event = asyncio.Event()
asyncio.get_running_loop().add_signal_handler(s, lambda: event.set())
await event.wait()
event.clear()
asyncio.get_running_loop().remove_signal_handler(s)
async def run(configs: list[dict], *, timeout: int, debug: bool): async def run(configs: list[dict], *, timeout: int, debug: bool):
ipc = await i3ipc.aio.Connection().connect() ipc = await i3ipc.aio.Connection().connect()
ipc.on('window::new', window_new(configs, debug=debug)) ipc.on('window::new', window_new(configs, debug=debug))
variables = {
'pid': os.getpid(),
}
coroutines = [] coroutines = []
for cfg in configs: for cfg in configs:
cfg['filter'] = parse(cfg['filter']) cfg['filter'] = parse(cfg['filter'])
p = cfg['program'] p = cfg['program']
if isinstance(p, collections.abc.Iterable) and not isinstance(p, str): if isinstance(p, collections.abc.Iterable) and not isinstance(p, str):
p = ' '.join(p) p = ' '.join(p)
coroutines += [ipc.command(f'exec {p}')] p = p.format(**variables)
coro = ipc.command(f'exec {p}')
if cfg.get('signal_continue', False):
await coro
await wait_signal(signal.Signals(cfg.get('signal_continue')))
else:
coroutines += [coro]
await asyncio.gather(*coroutines) await asyncio.gather(*coroutines)
try: try:
await asyncio.wait_for(ipc.main(), timeout=timeout/1000) await asyncio.wait_for(ipc.main(), timeout=timeout/1000)