Last active
February 14, 2019 16:47
-
-
Save alliefitter/a6d0cd4e8142d1628e164412b9cefd10 to your computer and use it in GitHub Desktop.
Useful lil' script to page through i3wm workspaces.
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
from collections import defaultdict | |
from sys import argv | |
from typing import Dict | |
from i3ipc import Connection | |
''' | |
Pages left or right through workspaces in i3wm, and also moves windows to left or right workspaces. | |
Add the following lines to ~/.config/i3/config to use with Page Up and Page Down: | |
bindsym $mod+Next exec python /path/to/script/change_workspace.py next | |
bindsym $mod+Prior exec python /path/to/script/change_workspace.py previous | |
bindsym $mod+Shift+Next exec python /path/to/script/change_workspace.py move_next | |
bindsym $mod+Shift+Prior exec python /path/to/script/change_workspace.py move_previous | |
''' | |
def get_args(command: str): | |
return { | |
'next': ('workspace {workspace}', 1), | |
'previous': ('workspace {workspace}', -1), | |
'move_next': ('move container to workspace {workspace}; workspace {workspace}', 1), | |
'move_previous': ('move container to workspace {workspace}; workspace {workspace}', -1) | |
}.get(command) | |
def parse_workspaces(workspaces: Dict): | |
focused_output = None | |
focused_workspace = None | |
outputs = defaultdict(list) | |
for workspace in workspaces: | |
if workspace.get('focused') is True: | |
focused_output = workspace.get('output') | |
focused_workspace = workspace.get('num') | |
outputs[workspace['output']].append(workspace.get('num')) | |
return { | |
'outputs': outputs, | |
'focused_output': focused_output, | |
'focused_workspace': focused_workspace | |
} | |
def change_workspace(i3: Connection, command: str, modifier: int): | |
parsed_workspaces = parse_workspaces(i3.get_workspaces()) | |
focused_workspace = parsed_workspaces.get('focused_workspace') | |
focused_output = parsed_workspaces.get('focused_output') | |
outputs = parsed_workspaces.get('outputs') | |
workspaces_for_focused_output = outputs.get(focused_output) | |
non_focused_outputs = {o: w for o, w in outputs.items() if o != focused_output} | |
occupied_workspaces = [w for o, ws in non_focused_outputs.items() for w in ws] | |
max_workspace_for_focused_output = max(workspaces_for_focused_output) | |
max_workspace = max(occupied_workspaces + workspaces_for_focused_output) | |
default = max_workspace_for_focused_output if modifier < 0 else max_workspace + 1 | |
if modifier > 0: | |
max_workspace_for_focused_output += modifier | |
end_of_range = 0 if modifier < 0 else max_workspace + 1 | |
success = False | |
for x in range(focused_workspace + modifier, end_of_range, modifier): | |
if success is False and (x in workspaces_for_focused_output or x not in occupied_workspaces): | |
success = i3.command(command.format(workspace=x)) | |
success or i3.command(command.format(workspace=default)) | |
if __name__ == '__main__': | |
change_workspace(Connection(), *get_args(argv[1])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment