Merge pull request #35 from KingMichaelPark/main

feat: Update script logic to exit gracefully and avoid unnecessary exceptions
This commit is contained in:
OdiousImp2604
2022-10-10 19:23:30 +01:00
committed by GitHub

View File

@@ -1,100 +1,119 @@
#!/bin/python3 #!/bin/python3
from argparse import ArgumentParser import json
import subprocess import subprocess
import json from argparse import ArgumentParser
ENTER = "\n"
enter="\n"
# Returns a list of all json window objects
def get_windows(): def get_windows():
command="swaymsg -t get_tree" command = "swaymsg -t get_tree"
process = subprocess.Popen(
active_outputs = [] command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process = subprocess.Popen(
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
data = json.loads(process.communicate()[0]) data = json.loads(process.communicate()[0])
# Select outputs that are active # Select outputs that are active
windows = [] windows = []
for output in data['nodes']: for output in data["nodes"]:
# The scratchpad (under __i3) is not supported # The scratchpad (under __i3) is not supported
if output.get('name') != '__i3' and output.get('type') == 'output': if output.get("name") != "__i3" and output.get("type") == "output":
workspaces = output.get('nodes') workspaces = output.get("nodes", [])
for ws in workspaces: for ws in workspaces:
if ws.get('type') == 'workspace': if ws.get("type") == "workspace":
windows += extract_nodes_iterative(ws) windows.extend(extract_nodes_iterative(ws))
return windows return windows
# Extracts all windows from a sway workspace json object
# Extracts all windows from a sway workspace json object
def extract_nodes_iterative(workspace): def extract_nodes_iterative(workspace):
all_nodes = [] all_nodes = []
floating_nodes = workspace.get('floating_nodes') floating_nodes = workspace.get("floating_nodes", [])
for floating_node in floating_nodes: for floating_node in floating_nodes:
all_nodes.append(floating_node) all_nodes.append(floating_node)
nodes = workspace.get('nodes') nodes = workspace.get("nodes", [])
for node in nodes: for node in nodes:
# Leaf node # Leaf node
if len(node.get('nodes')) == 0: if not node.get("nodes"):
all_nodes.append(node) all_nodes.append(node)
# Nested node, handled iterative # Nested node, handled iterative
else: else:
for inner_node in node.get('nodes'): for inner_node in node.get("nodes"):
nodes.append(inner_node) nodes.append(inner_node)
return all_nodes return all_nodes
# Returns an array of all windows # Returns an array of all windows
def parse_windows(windows): def parse_windows(windows):
parsed_windows = [] return [window.get("name") for window in windows]
for window in windows:
parsed_windows.append(window.get('name'))
return parsed_windows
# Returns a newline seperated UFT-8 encoded string of all windows for wofi # Returns a newline seperated UFT-8 encoded string of all windows for wofi
def build_wofi_string(windows): def build_wofi_string(windows):
return enter.join(windows).encode("UTF-8") return ENTER.join(windows).encode("UTF-8")
# Executes wofi with the given input string # Executes wofi with the given input string
def show_wofi(windows): def show_wofi(windows):
command="wofi -c ~/.config/wofi/menu -s ~/.config/wofi/style.css -p \"Windows: \" -d -i --hide-scroll" command = 'wofi -c ~/.config/wofi/menu -s ~/.config/wofi/style.css -p "Windows: " -d -i --hide-scroll'
process = subprocess.Popen(command,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE) process = subprocess.Popen(
command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE
)
return process.communicate(input=windows)[0] return process.communicate(input=windows)[0]
# Returns the sway window id of the window that was selected by the user inside wofi # Returns the sway window id of the window that was selected by the user inside wofi
def parse_id(windows, parsed_windows, selected): def parse_id(windows, parsed_windows, selected):
selected = (selected.decode("UTF-8"))[:-1] # Remove new line character if not selected:
window_index = int(parsed_windows.index(selected)) # Get index of selected window in the parsed window array return None
return str(windows[window_index].get('id')) # Get sway window id based on the index else:
selected = (selected.decode("UTF-8"))[:-1] # Remove new line character
window_index = int(
parsed_windows.index(selected)
) # Get index of selected window in the parsed window array
return str(
windows[window_index].get("id")
) # Get sway window id based on the index
# Switches the focus to the given id # Switches the focus to the given id
def switch_window(id): def switch_window(id):
command="swaymsg [con_id={}] focus".format(id) command = "swaymsg [con_id={}] focus".format(id)
process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE) process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
process.communicate()[0] process.communicate()[0]
# Entry point # Entry point
if __name__ == "__main__": if __name__ == "__main__":
parser = ArgumentParser(description="Wofi based window switcher") parser = ArgumentParser(description="Wofi based window switcher")
windows = get_windows() windows = get_windows()
parsed_windows = parse_windows(windows) parsed_windows = parse_windows(windows)
wofi_string = build_wofi_string(parsed_windows) wofi_string = build_wofi_string(parsed_windows)
selected = show_wofi(wofi_string) selected = show_wofi(wofi_string)
selected_id = parse_id(windows, parsed_windows, selected)
switch_window(selected_id) # Otherwise no point in running
if selected:
selected_id = parse_id(windows, parsed_windows, selected)
switch_window(selected_id)