Initial commit
This commit is contained in:
commit
fd68d9f463
10 changed files with 662 additions and 0 deletions
64
picker/window-picker.py
Executable file
64
picker/window-picker.py
Executable file
|
@ -0,0 +1,64 @@
|
|||
#!/bin/env python
|
||||
from argparse import ArgumentParser
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
# JSON object to represent a window in Niri
|
||||
type WindowJson = dict[str, int | str | bool]
|
||||
|
||||
# Get a list of open windows from Niri
|
||||
def get_windows():
|
||||
command = "niri msg -j windows"
|
||||
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
data: list[WindowJson] = json.loads(process.communicate()[0])
|
||||
|
||||
return data
|
||||
|
||||
# Generate a string representation for each window.
|
||||
# Map the string to its Niri window ID
|
||||
def get_string_id_mapping(window_list: list[WindowJson]):
|
||||
mapping: dict[str, int] = {}
|
||||
for idx, window in enumerate(window_list):
|
||||
s = f"{idx}: {window.get("app_id")}: {window.get("title")}"
|
||||
id = window.get("id")
|
||||
assert type(id) == int
|
||||
mapping[s] = id
|
||||
return mapping
|
||||
|
||||
# Generate the string to be sent to fuzzel
|
||||
def get_input_string(mapping: dict[str, int]):
|
||||
m = max([len(s) for s in mapping.keys()])
|
||||
return "\n".join(mapping.keys()), m
|
||||
|
||||
def spawn_picker(cmd, input_string, m):
|
||||
# cmd = "fuzzel --dmenu -I --placeholder=Select a window:"
|
||||
cmd = f"{cmd} --width {min(m, 120) + 1}"
|
||||
process = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
selection = process.communicate(input=input_string.encode("UTF-8"))
|
||||
if process.returncode != 2:
|
||||
return selection[0].decode("UTF-8").strip("\n")
|
||||
else:
|
||||
return None
|
||||
|
||||
def switch_window(id: int):
|
||||
cmd = f"niri msg action focus-window --id {id}"
|
||||
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
|
||||
process.communicate()
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("-p", "--picker", required=False, help="Set a picker command. Must take a newline delimited string on stdin and return the selection on stdout (default: %(default)s)", default="fuzzel --dmenu --placeholder=Select a window:", type=str, metavar="COMMAND")
|
||||
args = parser.parse_args()
|
||||
picker_cmd = args.picker
|
||||
# print("picker:", picker_cmd)
|
||||
wl = get_windows()
|
||||
mapping = get_string_id_mapping(wl)
|
||||
input_string, m= get_input_string(mapping)
|
||||
selection = spawn_picker(picker_cmd, input_string, m)
|
||||
if selection is None:
|
||||
exit(1)
|
||||
try:
|
||||
id = mapping[selection]
|
||||
except KeyError:
|
||||
exit(1)
|
||||
switch_window(id)
|
Loading…
Add table
Add a link
Reference in a new issue