Skip to content

Instantly share code, notes, and snippets.

@hariseldon78
Created November 2, 2023 12:13
Show Gist options
  • Save hariseldon78/d0b91e584fa97e3efcbd280cf1703f5f to your computer and use it in GitHub Desktop.
Save hariseldon78/d0b91e584fa97e3efcbd280cf1703f5f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import subprocess
import sys
import json
def swap_workspaces(id1, name1, id2, name2):
# print("Swapping workspaces {}:{} and {}:{}".format(name1, id1, name2, id2))
# },{
# "address": "0x561521e76e10",
# "mapped": true,
# "hidden": false,
# "at": [1942, 52],
# "size": [1295, 1006],
# "workspace": {
# "id": -1352,
# "name": "hl4"
# },
# "floating": false,
# "monitor": 0,
# "class": "emacs",
# "title": "/home/roby/.config/hypr/sort-workspaces.py",
# "initialClass": "emacs",
# "initialTitle": "",
# "pid": 1628,
# "xwayland": false,
# "pinned": false,
# "fullscreen": false,
# "fullscreenMode": 0,
# "fakeFullscreen": false,
# "grouped": [],
# "swallowing": "0x0"
# }
# ]
clients_raw = subprocess.run(
["hyprctl", "clients", "-j"], stdout=subprocess.PIPE, text=True
).stdout.strip()
clients = json.loads(clients_raw)
hyprctl_batch = []
def print_clients(prefix, clients):
for client in clients:
wsid = client["workspace"]["id"]
# print(
# "{}: {},{} {} {}".format(
# prefix, client["title"], wsid, wsid == int(id1), wsid == int(id2)
# )
# )
# print_clients("all", clients)
clients1 = [client for client in clients if client["workspace"]["id"] == int(id1)]
# print_clients("1", clients1)
clients2 = [client for client in clients if client["workspace"]["id"] == int(id2)]
# print_clients("2", clients2)
for client in clients1:
hyprctl_batch.append(
" ".join(
[
"dispatch",
"movetoworkspacesilent",
"name:" + name2 + "," + "address:" + client["address"],
]
)
)
for client in clients2:
hyprctl_batch.append(
" ".join(
[
"dispatch",
"movetoworkspacesilent",
"name:" + name1 + "," + "address:" + client["address"],
]
)
)
hyprctl_batch.append(" ".join(["dispatch", "renameworkspace", str(id1), name2]))
hyprctl_batch.append(" ".join(["dispatch", "renameworkspace", str(id2), name1]))
return hyprctl_batch
def sort_workspaces():
# },{
# "id": 2,
# "name": "HDMI-A-1",
# "description": "Samsung Electric Company C27F390 HTQK500864 (HDMI-A-1)",
# "make": "Samsung Electric Company",
# "model": "C27F390",
# "serial": "HTQK500864",
# "width": 1920,
# "height": 1080,
# "refreshRate": 60.00000,
# "x": 3840,
# "y": 0,
# "activeWorkspace": {
# "id": -1344,
# "name": "ch1_"
# },
# "specialWorkspace": {
# "id": 0,
# "name": ""
# },
# "reserved": [0, 30, 0, 0],
# "scale": 1.00,
# "transform": 1,
# "focused": false,
# "dpmsStatus": true,
# "vrr": false,
# "activelyTearing": false
# }]
monitors_raw = subprocess.run(
["hyprctl", "monitors", "-j"], stdout=subprocess.PIPE, text=True
).stdout.strip()
monitors = json.loads(monitors_raw)
# current_monitor = [monitor for monitor in monitors if monitor["focused"]][0]
for monitor in monitors:
if monitor["focused"]:
focused_monitor = monitor
# print("Sorting monitor {}".format(monitor["name"]))
sorted_ = False
while not sorted_:
hyprctl_batch = []
sorted_ = True
workspaces_raw = subprocess.run(
["hyprctl", "workspaces", "-j"], stdout=subprocess.PIPE, text=True
).stdout.strip()
# {
# "id": -1355,
# "name": "bb1",
# "monitor": "DP-2",
# "windows": 1,
# "hasfullscreen": false,
# "lastwindow": "0x561521de42c0",
# "lastwindowtitle": "Google Chat Linux"
# }]
workspaces = json.loads(workspaces_raw)
monitor_workspaces = sorted(
[
workspace
for workspace in workspaces
if workspace["monitor"] == monitor["name"]
],
key=lambda k: k["id"],
)
workspaces_sorted = sorted(monitor_workspaces, key=lambda k: k["name"])
# print(
# [
# (workspace["name"], workspace["id"])
# for workspace in monitor_workspaces
# ]
# )
# print(
# [
# (workspace["name"], workspace["id"])
# for workspace in workspaces_sorted
# ]
# )
for i in range(len(workspaces_sorted) - 1):
if monitor_workspaces[i]["name"] != workspaces_sorted[i]["name"]:
hyprctl_batch += swap_workspaces(
monitor_workspaces[i]["id"],
monitor_workspaces[i]["name"],
workspaces_sorted[i]["id"],
workspaces_sorted[i]["name"],
)
sorted_ = False
break
hyprctl_batch.append(
" ".join(
[
"dispatch",
"workspace",
"name:" + monitor["activeWorkspace"]["name"],
]
)
)
subprocess.check_call(
[
"hyprctl",
"--batch",
" ; ".join(hyprctl_batch),
],
)
subprocess.check_call(
[
"hyprctl",
"dispatch",
"focusmonitor",
focused_monitor["name"],
],
)
def get_input_from_rofi():
rofi = subprocess.run(
["rofi", "-dmenu", "-p", "Workspace Name"], stdout=subprocess.PIPE, text=True
)
return rofi.stdout.strip()
def create_or_switch_workspace(name, output):
print("Creating workspace " + name + " on " + output)
hyprctl_batch = []
hyprctl_batch.append(" ".join(["dispatch", "focusmonitor", output]))
hyprctl_batch.append(
" ".join(["keyword", "workspace", "name:" + name + ",persistent:true"])
)
hyprctl_batch.append(" ".join(["dispatch", "workspace", "name:" + name]))
subprocess.check_call(
[
"hyprctl",
"--batch",
" ; ".join(hyprctl_batch),
]
)
def get_current_monitor():
hyprctl = subprocess.check_output(["hyprctl", "monitors", "-j"], text=True)
raw = hyprctl.strip()
list = json.loads(raw)
current = next((item for item in list if item["focused"]), None)
return current["name"]
def main():
if len(sys.argv) > 2:
workspace_name = sys.argv[2]
else:
workspace_name = get_input_from_rofi()
if workspace_name == "":
return
if len(sys.argv) > 1:
direction = sys.argv[1]
if direction == "right":
monitor = "HDMI-A-1"
elif direction == "center":
monitor = "DP-2"
elif direction == "left":
monitor = "DP-3"
else:
monitor = get_current_monitor()
if monitor == "HDMI-A-1":
suffix = "_"
elif monitor == "DP-2":
suffix = ""
elif monitor == "DP-3":
suffix = "+"
subprocess.call(["killall", "waybar"])
try:
create_or_switch_workspace(workspace_name + suffix, monitor)
sort_workspaces()
except subprocess.CalledProcessError as e:
print(e)
subprocess.Popen(["waybar"], start_new_session=True)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment