47 lines
1.5 KiB
Python
Executable File
47 lines
1.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import subprocess
|
|
|
|
import i3ipc
|
|
import psutil
|
|
import pulsectl
|
|
|
|
|
|
def main():
|
|
i3 = i3ipc.Connection()
|
|
window = i3.get_tree().find_focused()
|
|
cmd = ['xprop', '-id', str(window.window), '_NET_WM_PID']
|
|
o = subprocess.run(cmd, encoding='utf-8', capture_output=True)
|
|
# _NET_WM_PID(CARDINAL) = 418472
|
|
pid = int(o.stdout.strip().split(' = ')[1])
|
|
|
|
pulse = pulsectl.Pulse('Focused sink switcher')
|
|
sink_input_by_pid = {}
|
|
for i in pulse.sink_input_list():
|
|
sink_pid = int(i.proplist['application.process.id'])
|
|
sink_input_by_pid[sink_pid] = i
|
|
|
|
if pid in sink_input_by_pid:
|
|
sink_input = sink_input_by_pid[pid]
|
|
else:
|
|
# try the childprocesses of our process, because this might be a
|
|
# terminal having started an mpv or something
|
|
p = psutil.Process(pid)
|
|
for child in p.children(recursive=True):
|
|
if child.pid in sink_input_by_pid:
|
|
sink_input = sink_input_by_pid[child.pid]
|
|
break
|
|
else:
|
|
msg = 'Did not find a pulse client for pid {} or its children.'
|
|
raise RuntimeError(msg.format(pid))
|
|
|
|
sink_index_list = [s.index for s in pulse.sink_list()]
|
|
old_sink = sink_input.sink
|
|
old_sink_index = sink_index_list.index(old_sink)
|
|
new_sink_index = sink_index_list[(old_sink_index + 1) % len(sink_index_list)]
|
|
|
|
pulse.sink_input_move(sink_input.index, new_sink_index)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|