Skip to content

Instantly share code, notes, and snippets.

@un-def
Last active July 15, 2024 21:02
Show Gist options
  • Save un-def/8362f2f95d4ece184d94453d8ceaada5 to your computer and use it in GitHub Desktop.
Save un-def/8362f2f95d4ece184d94453d8ceaada5 to your computer and use it in GitHub Desktop.
i3 persistent workspaces
from __future__ import annotations
import argparse
import json
import subprocess
from typing import Callable, Iterable, Iterator, TypedDict
class Workspace(TypedDict):
name: str
def print_workspaces(names: Iterable[str]) -> None:
workspace_iter: Iterator[Workspace] = iter(json.loads(
subprocess.check_output(['i3-msg', '-t', 'get_workspaces'])))
workspaces: list[Workspace] = []
workspace = next(workspace_iter, None)
for name in names:
if workspace and workspace['name'] == name:
workspaces.append(workspace)
workspace = next(workspace_iter, None)
else:
workspaces.append({'name': name})
print(json.dumps(workspaces), flush=True)
def subscribe(callback: Callable[[bytes], None]) -> None:
listener = subprocess.Popen(
['i3-msg', '-t', 'subscribe', '-m', '["workspace", "output"]'],
stdout=subprocess.PIPE,
)
assert listener.stdout is not None, 'makes typechecker happy'
for line in listener.stdout:
callback(line)
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument('workspaces', nargs='+', metavar='WORKSPACE')
args = parser.parse_args()
workspaces: list[str] = args.workspaces
print_workspaces(workspaces)
subscribe(lambda _: print_workspaces(workspaces))
if __name__ == '__main__':
main()
@un-def
Copy link
Author

un-def commented Jul 15, 2024

i3 version 4.23+ is required: https://i3wm.org/docs/i3bar-workspace-protocol.html

i3 config:

set $ws1 1:web
set $ws2 2:term
set $ws3 3:code
set $ws4 4:files

bar {
  workspace_command python3 /path/to/i3pws.py $ws1 $ws2 $ws3 $ws4
}

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