.dotfiles/.config/bspwm/swallow.py

94 lines
2.7 KiB
Python
Executable file

#!/usr/bin/env python
import subprocess
from functools import partial
cmd_run = partial(subprocess.Popen, text=True, shell=True)
def cmd_output(cmd):
try:
out = subprocess.check_output(cmd, text=True, shell=True).strip()
except Exception:
out = ''
return out
def execute(cmd):
popen = subprocess.Popen(cmd, stdout=subprocess.PIPE,
universal_newlines=True, text=True, shell=True)
for stdout_line in iter(popen.stdout.readline, ""):
yield stdout_line
popen.stdout.close()
return_code = popen.wait()
if return_code:
raise subprocess.CalledProcessError(return_code, cmd)
def is_fullscreen(wid):
return cmd_output(f'bspc query -N -n {wid}.fullscreen').strip()
def is_floating(wid):
return cmd_output(f'bspc query -N -n {wid}.floating').strip()
def get_class(wid):
out = cmd_output(f'xprop -id {wid} | grep WM_CLASS')
if out:
out = out.split(' = ')[1].split(', ')
return (out[0].strip('"'), out[1].strip('"'))
else:
return ''
def get_pid(wid):
out = cmd_output(f'xprop -id {wid} | grep WM_PID')
if out:
return out.split(' = ')[1]
else:
return ''
def is_child(pid, child_pid):
tree = cmd_output(f'pstree -T -p {pid}')
for line in tree.split('\n'):
if child_pid in line:
return True
return False
def swallow():
swallowed = {}
for event in execute('bspc subscribe node'):
event = event.split()
if event[0] == 'node_add':
new_wid = event[-1]
last_wid = cmd_output('bspc query -N -d -n last.window')
if(get_class(last_wid)[0] != 'Alacritty'):
continue
if any([is_floating(new_wid), is_floating(last_wid),
is_fullscreen(new_wid), is_fullscreen(last_wid)]):
continue
new_pid = get_pid(new_wid)
last_pid = get_pid(last_wid)
if not all([new_pid, last_pid]):
continue
if is_child(last_pid, new_pid):
cmd_run(f'bspc node --swap {last_wid} --follow')
cmd_run(f'bspc node {new_wid} --flag private=on')
cmd_run(f'bspc node {last_wid} --flag hidden=on')
cmd_run(f'bspc node {last_wid} --flag private=on')
swallowed[new_wid] = last_wid
if event[0] == 'node_remove':
removed_wid = event[-1]
if removed_wid in swallowed.keys():
swallowed_id = swallowed[removed_wid]
cmd_run(f'bspc node {swallowed_id} --flag hidden=off')
cmd_run(f'bspc node --focus {swallowed_id}')
if __name__ == '__main__':
swallow()