Compare commits
No commits in common. "ba5d560a010e979b0a45af847a5661f57850a211" and "c10b9fdb668be712630f76073ae385fdf213b749" have entirely different histories.
ba5d560a01
...
c10b9fdb66
1 changed files with 8 additions and 27 deletions
29
i3toolwait
29
i3toolwait
|
@ -6,7 +6,6 @@ import collections.abc
|
||||||
import asyncio
|
import asyncio
|
||||||
import signal
|
import signal
|
||||||
import os
|
import os
|
||||||
import time
|
|
||||||
import functools
|
import functools
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
@ -273,7 +272,7 @@ def parse(s: str) -> Expression:
|
||||||
tokens = tokenize(s)
|
tokens = tokenize(s)
|
||||||
return build_expression(tokens)
|
return build_expression(tokens)
|
||||||
|
|
||||||
def window_new(configs: list[dict], debug: bool, *, lock):
|
def window_new(configs: list[dict], debug: bool):
|
||||||
async def callback(ipc: i3ipc.aio.Connection, e: i3ipc.WorkspaceEvent):
|
async def callback(ipc: i3ipc.aio.Connection, e: i3ipc.WorkspaceEvent):
|
||||||
assert e.change == 'new'
|
assert e.change == 'new'
|
||||||
if debug:
|
if debug:
|
||||||
|
@ -283,10 +282,8 @@ def window_new(configs: list[dict], debug: bool, *, lock):
|
||||||
workspace = cfg['workspace']
|
workspace = cfg['workspace']
|
||||||
if filter.reduce(e.ipc_data):
|
if filter.reduce(e.ipc_data):
|
||||||
container_id = e.ipc_data['container']['id']
|
container_id = e.ipc_data['container']['id']
|
||||||
async with lock:
|
|
||||||
await ipc.command(f'for_window [con_id="{container_id}"] focus')
|
await ipc.command(f'for_window [con_id="{container_id}"] focus')
|
||||||
await ipc.command(f'move container to workspace {workspace}')
|
await ipc.command(f'move container to workspace {workspace}')
|
||||||
await asyncio.sleep(1)
|
|
||||||
configs.pop(i)
|
configs.pop(i)
|
||||||
if not configs:
|
if not configs:
|
||||||
ipc.main_quit()
|
ipc.main_quit()
|
||||||
|
@ -298,49 +295,33 @@ async def wait_signal(s):
|
||||||
await event.wait()
|
await event.wait()
|
||||||
event.clear()
|
event.clear()
|
||||||
asyncio.get_running_loop().remove_signal_handler(s)
|
asyncio.get_running_loop().remove_signal_handler(s)
|
||||||
asyncio.get_running_loop().add_signal_handler(s, lambda: None)
|
|
||||||
|
|
||||||
async def coro_wait_signal(coro, s):
|
|
||||||
await coro
|
|
||||||
await wait_signal(s)
|
|
||||||
|
|
||||||
async def run(configs: list[dict], *, timeout: int, debug: bool):
|
async def run(configs: list[dict], *, timeout: int, debug: bool):
|
||||||
window_configs = [c for c in configs if c.get('workspace') is not None]
|
window_configs = [c for c in configs if c.get('workspace') is not None]
|
||||||
lock = asyncio.Lock()
|
|
||||||
ipc = await i3ipc.aio.Connection().connect() # we only wait for configs which spawn a window
|
ipc = await i3ipc.aio.Connection().connect() # we only wait for configs which spawn a window
|
||||||
ipc.on('window::new', window_new(window_configs, debug=debug, lock=lock))
|
ipc.on('window::new', window_new(window_configs, debug=debug))
|
||||||
|
|
||||||
variables = {
|
variables = {
|
||||||
'pid': os.getpid(),
|
'pid': os.getpid(),
|
||||||
}
|
}
|
||||||
coroutines = []
|
coroutines = []
|
||||||
timeouts = [timeout]
|
|
||||||
started_at = time.monotonic_ns()
|
|
||||||
for cfg in configs:
|
for cfg in configs:
|
||||||
cfg['filter'] = parse(cfg['filter'])
|
cfg['filter'] = parse(cfg['filter'])
|
||||||
p = cfg['program']
|
p = cfg['program']
|
||||||
t = cfg.get('timeout', timeout)
|
|
||||||
timeouts += [t]
|
|
||||||
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)
|
||||||
p = p.format(**variables)
|
p = p.format(**variables)
|
||||||
coro = ipc.command(f'exec {p}')
|
coro = ipc.command(f'exec {p}')
|
||||||
if cfg.get('signal_continue', False):
|
if cfg.get('signal_continue', False):
|
||||||
sig = signal.Signals(cfg.get('signal_continue'))
|
await coro
|
||||||
coro = coro_wait_signal(coro, sig)
|
await wait_signal(signal.Signals(cfg.get('signal_continue')))
|
||||||
try:
|
|
||||||
await asyncio.wait_for(coro, timeout=t/1000)
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
coroutines += [coro]
|
coroutines += [coro]
|
||||||
await asyncio.gather(*coroutines)
|
await asyncio.gather(*coroutines)
|
||||||
try:
|
try:
|
||||||
if window_configs:
|
if window_configs:
|
||||||
# run main loop only if we wait for something
|
# run main loop only if we wait for something
|
||||||
diff = (time.monotonic_ns() - started_at) / (1000*1000)
|
await asyncio.wait_for(ipc.main(), timeout=timeout/1000)
|
||||||
new_timeout = max(max(*timeouts) - diff, 0)
|
|
||||||
await asyncio.wait_for(ipc.main(), timeout=new_timeout/1000)
|
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
Loading…
Reference in a new issue