Skip to content

Instantly share code, notes, and snippets.

@phwelo
Last active September 10, 2022 17:11
Show Gist options
  • Save phwelo/55bebedf5b2352c43b43dc878d5916ef to your computer and use it in GitHub Desktop.
Save phwelo/55bebedf5b2352c43b43dc878d5916ef to your computer and use it in GitHub Desktop.
Per-Display Workspace Toggler
[
{"name": "eDP-1", "workspaces": [1, 5]},
{"name": "DP-1", "workspaces": [3, 4]},
{"name": "HDMI-A-1", "workspaces": [2, 6, 7]}
]
#!/usr/bin/python3
from subprocess import check_output
from json import loads, load
from os import path
WS_CMD = "i3-msg -t get_workspaces -r"
MON_CMD = "i3-msg -t get_outputs -r"
SET_CMD = "i3-msg workspace"
CONFIG = "config.json"
# get the active workspace & switch to the next workspace on same monitor
def workspace_info(cmd):
return loads(check_output(cmd.split(" ")))
def active_query(ws_info):
for workspace in ws_info:
if workspace["focused"] == True:
return workspace["output"], workspace["num"]
def load_config():
script_path = path.dirname(path.realpath(__file__))
return load(open(f"{script_path}/{CONFIG}"))
def get_display_workspaces(config, active):
for display in config:
if active == display["name"]:
return display["workspaces"]
def next_workspace(current_workspace, workspaces):
if current_workspace in workspaces:
print("branch 1")
index = workspaces.index(current_workspace)
else:
return workspaces[0]
if len(workspaces) == index + 1: return workspaces[0]
return workspaces[index + 1]
def switch_workspace_to(ws):
command = SET_CMD + " " + str(ws)
check_output(command.split(" "))
def main():
active_display, active_workspace = active_query(workspace_info(WS_CMD))
config = load_config()
workspace_options = get_display_workspaces(config, active_display)
next = next_workspace(active_workspace, workspace_options)
switch_workspace_to(next)
main()
#!/usr/bin/python3
from subprocess import check_output
from json import loads, load
from os import path
CMD = "swaymsg -t get_outputs -r"
CMD2 = "swaymsg workspace"
CONFIG = "config.json"
class Display:
def __init__(self, display):
self.current_workspace = int(display["current_workspace"].split(" ")[0])
self.name = display["name"]
self.config = self.load_config()
self.focused = bool(display["focused"])
self.workspaces = self.get_mapped_workspaces()
def get_mapped_workspaces(self):
return [ i["workspaces"] for i in self.config if i["name"] == self.name ][0]
def load_config(self):
script_path = path.dirname(path.realpath(__file__))
return load(open(f"{script_path}/{CONFIG}"))
def next_workspace(self):
if self.current_workspace in self.workspaces:
index = self.workspaces.index(self.current_workspace)
else:
index = self.workspaces[0]
if len(self.workspaces) == index + 1: return self.workspaces[0]
return self.workspaces[index+1]
def list_of_displays():
displays = [find_active_display(i) for i in loads(check_output(CMD.split(' ')))]
return [ i for i in displays if i ]
def find_active_display(display):
if display["active"] == True: return Display(display)
def set_workspace(workspace_index):
command = CMD2 + " " + str(workspace_index)
check_output(command.split(" "))
def find_focused_display(display_list):
return [i for i in display_list if i.focused][0]
def main():
display_list = list_of_displays()
current_display = find_focused_display(display_list)
set_workspace(current_display.next_workspace())
if __name__ == "__main__":
main()
@phwelo
Copy link
Author

phwelo commented Sep 10, 2022

Where I kind of used that class to unify the get workspace and get outputs on sway, i3 gave all of that info via get workspace - so the same version couldn't be used as previously expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment