Skip to content

Instantly share code, notes, and snippets.

@stecman
Last active October 15, 2023 21:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stecman/764da404d32edcdd7960457117da8c6e to your computer and use it in GitHub Desktop.
Save stecman/764da404d32edcdd7960457117da8c6e to your computer and use it in GitHub Desktop.
Scripts to make i3 more natural to use
# Move workspace left and right (swap if conflicting)
bindsym $mod+Ctrl+Shift+Left exec $HOME/.i3/i3-swap.py left
bindsym $mod+Ctrl+Shift+Right exec $HOME/.i3/i3-swap.py right
# Make the next free workspace number, whatever that is
bindsym $mod+Ctrl+Return exec $HOME/.i3/i3-makews.py
# Rotate focus through visible workspaces on different monitors
bindsym $mod+x exec $HOME/.i3/i3-nextoutput.py
#!/usr/bin/env python3
"""
Move to the next unused workspace number, without needing to think
"""
import json
import subprocess
import sys
def get_workspaces():
result = subprocess.run(["i3-msg", "-t", "get_workspaces"], check=True, capture_output=True)
return json.loads(result.stdout.decode())
workspaces = get_workspaces()
# Find the first free workspace number (leaving workspace 0 for comms)
existing = set([ws['num'] for ws in workspaces])
target = 2
while target in existing:
target += 1
subprocess.run(['i3-msg', 'workspace', str(target)], check=True)
#!/usr/bin/env python3
"""
Move all workspaces to the specified output
"""
import json
import subprocess
import sys
def get_workspaces():
result = subprocess.run(["i3-msg", "-t", "get_workspaces"], check=True, capture_output=True)
return json.loads(result.stdout.decode())
for ws in get_workspaces():
subprocess.run(['i3-msg', '[workspace="%s"]' % ws['num'], 'move', 'workspace', 'to', 'output', sys.argv[1]], check=True)
#!/usr/bin/env python3
"""
Focus the visible workspace on the next output
A reliable way to switch to the other monitor you're looking at, without
needing to prime or keep track of the "back_and_forth" buffer.
"""
import json
import subprocess
import sys
def get_workspaces():
result = subprocess.run(["i3-msg", "-t", "get_workspaces"], check=True, capture_output=True)
return json.loads(result.stdout.decode())
display_workspace = {}
current_display = None
for ws in get_workspaces():
if ws['visible']:
display_workspace[ws['output']] = ws['num']
if ws['focused']:
current_display = ws['output']
displays = list(display_workspace.keys())
current_index = displays.index(current_display)
next_index = (current_index + 1) % len(displays)
next_display = displays[next_index]
next_ws = display_workspace[next_display]
subprocess.run(['i3-msg', 'workspace', str(next_ws)], check=True)
#!/usr/bin/env python3
"""
Increment or decrement the workspace number, shifting other workspaces out of the way
"""
import argparse
import json
import subprocess
import sys
def rename_workspace(name, new_name):
subprocess.run(["i3-msg", "rename", "workspace", name, "to", new_name], check=True)
def get_workspaces():
result = subprocess.run(["i3-msg", "-t", "get_workspaces"], check=True, capture_output=True)
return json.loads(result.stdout.decode())
parser = argparse.ArgumentParser()
parser.add_argument("direction")
args = parser.parse_args()
workspaces = get_workspaces()
# Find focused workspace
for index, ws in enumerate(workspaces):
if ws['focused']:
focused = ws['num']
break
# Get next workspace number
if args.direction == 'left':
target = focused - 1
if target < 0:
print("Can't move any further left")
sys.exit(1)
elif args.direction == 'right':
target = focused + 1
else:
raise AttributeError("Direction must be 'left' or 'right'. Got '%s'" % args.direction)
# Find any conflicting workspace to swap with
conflicting = [ws for ws in workspaces if ws['name'] == str(target)]
if len(conflicting):
# Swap with conflicting workspace
rename_workspace(str(target), 'tmp')
rename_workspace(str(focused), str(target))
rename_workspace('tmp', str(focused))
else:
# Just rename as there's no conflict
rename_workspace(str(focused), str(target))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment