Created
March 13, 2021 17:54
-
-
Save nfraprado/484a0dfe60c49b7d2e9dfb45c3c4a4b5 to your computer and use it in GitHub Desktop.
Windowswitcher for sway using rofi. Adapted from https://github.com/tobiaspc/wofi-scripts/blob/master/windows.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/python3 | |
# Source: https://github.com/tobiaspc/wofi-scripts/blob/master/windows.py | |
from argparse import ArgumentParser | |
import subprocess | |
import json | |
enter="\n" | |
# Returns a list of all json window objects | |
def get_windows(): | |
command="swaymsg -t get_tree" | |
active_outputs = [] | |
process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
data = json.loads(process.communicate()[0]) | |
# Select outputs that are active | |
windows = [] | |
for output in data['nodes']: | |
# The scratchpad (under __i3) is not supported | |
if output.get('name') != '__i3' and output.get('type') == 'output': | |
workspaces = output.get('nodes') | |
for ws in workspaces: | |
if ws.get('type') == 'workspace': | |
windows += extract_nodes_iterative(ws) | |
return windows | |
# Extracts all windows from a sway workspace json object | |
def extract_nodes_iterative(workspace): | |
all_nodes = [] | |
floating_nodes = workspace.get('floating_nodes') | |
for floating_node in floating_nodes: | |
all_nodes.append(floating_node) | |
nodes = workspace.get('nodes') | |
for node in nodes: | |
# Leaf node | |
if len(node.get('nodes')) == 0: | |
all_nodes.append(node) | |
# Nested node, handled iterative | |
else: | |
for inner_node in node.get('nodes'): | |
nodes.append(inner_node) | |
return all_nodes | |
# Returns an array of all windows | |
def parse_windows(windows): | |
parsed_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 rofi | |
def build_rofi_string(windows): | |
return enter.join(windows).encode("UTF-8") | |
# Executes rofi with the given input string | |
def show_rofi(windows): | |
command="rofi -p \"windows\" -dmenu -i" | |
process = subprocess.Popen(command,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE) | |
return process.communicate(input=windows)[0] | |
# Returns the sway window id of the window that was selected by the user inside rofi | |
def parse_id(windows, parsed_windows, selected): | |
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 | |
def switch_window(id): | |
command="swaymsg [con_id={}] focus".format(id) | |
process = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE) | |
process.communicate()[0] | |
# Entry point | |
if __name__ == "__main__": | |
parser = ArgumentParser(description="Rofi based window switcher") | |
windows = get_windows() | |
parsed_windows = parse_windows(windows) | |
rofi_string = build_rofi_string(parsed_windows) | |
selected = show_rofi(rofi_string) | |
selected_id = parse_id(windows, parsed_windows, selected) | |
switch_window(selected_id) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment