Created
August 23, 2022 19:09
-
-
Save dedsm/610a004d896cac3a93c59558a8326dd9 to your computer and use it in GitHub Desktop.
This gist is a helper using i3 ipc that makes i3 behave like xmonad in some workspace-related bindings Mod+{w,e,r} and sharing workspaces across all active displays
This file contains hidden or 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
| import argparse | |
| from i3ipc import Connection | |
| sway = Connection() | |
| outputs = [o for o in sway.get_outputs() if o.active] | |
| def focus_monitor(args): | |
| indices = {"left": 0, "center": 1, "right": 2} | |
| orientation = indices[args.orientation] | |
| if len(outputs) <= 1 or len(outputs) < orientation+1: | |
| print(len(outputs)) | |
| return | |
| sorted_outputs = sorted(outputs, key=lambda x: x.rect.x) | |
| output = sorted_outputs[orientation] | |
| sway.command(f"workspace {output.current_workspace}") | |
| def send_to_monitor(args): | |
| indices = {"left": 0, "center": 1, "right": 2} | |
| orientation = indices[args.orientation] | |
| if len(outputs) <= 1 or len(outputs) < orientation+1: | |
| print(len(outputs)) | |
| return | |
| sorted_outputs = sorted(outputs, key=lambda x: x.rect.x) | |
| output = sorted_outputs[orientation] | |
| sway.command(f"move container to workspace {output.current_workspace}") | |
| def switch_workspace(args): | |
| workspaces = sway.get_workspaces() | |
| workspaces_by_name = {w.name: w for w in workspaces} | |
| focused_workspace = next((w for w in workspaces if w.focused)) | |
| destination = args.workspace | |
| if focused_workspace.name == destination: | |
| return | |
| if destination not in workspaces_by_name: | |
| # workspace doesn't exist | |
| sway.command(f"workspace {destination}") | |
| return | |
| target_workspace = workspaces_by_name[destination] | |
| destination_output = focused_workspace.output | |
| source_output = target_workspace.output | |
| if destination_output == source_output: | |
| sway.command(f"workspace {destination}") | |
| return | |
| # workspace belongs to a different output | |
| if target_workspace.visible: | |
| # the workspace we want in the current output is | |
| # being displayed in another output, so we swap | |
| commands = [ | |
| "workspace ___temp___", | |
| f"move workspace to output {source_output}", | |
| f"workspace {destination}", | |
| f"move workspace to output {destination_output}", | |
| f"workspace {focused_workspace.name}", | |
| f"move workspace to output {source_output}", | |
| f"workspace {destination}", | |
| ] | |
| command = ";".join(commands) | |
| sway.command(command) | |
| else: | |
| # the workspace is in a different output but hidden | |
| # bring it to the destination output, no need for temp | |
| # since we know there's at least one more | |
| commands = [ | |
| f"workspace {destination}", | |
| f"move workspace to output {destination_output}" | |
| ] | |
| command = ";".join(commands) | |
| sway.command(command) | |
| parser = argparse.ArgumentParser(description="Process custom sway commands") | |
| subparsers = parser.add_subparsers(help="sub-command help") | |
| output_choose = subparsers.add_parser( | |
| "monitor", | |
| help="pick monitor in X orientation order" | |
| ) | |
| output_choose.add_argument( | |
| "orientation", | |
| type=str, | |
| choices=["left", "center", "right"] | |
| ) | |
| output_choose.set_defaults(func=focus_monitor) | |
| send_to_output = subparsers.add_parser( | |
| "send_to_output", | |
| help="pick monitor in X orientation order" | |
| ) | |
| send_to_output.add_argument( | |
| "orientation", | |
| type=str, | |
| choices=["left", "center", "right"] | |
| ) | |
| send_to_output.set_defaults(func=send_to_monitor) | |
| workspace_choose = subparsers.add_parser( | |
| "workspace", | |
| help="switch workspace" | |
| ) | |
| workspace_choose.add_argument( | |
| "workspace", | |
| type=str | |
| ) | |
| workspace_choose.set_defaults(func=switch_workspace) | |
| args = parser.parse_args() | |
| args.func(args) |
@Schievel1 I never used that with xmonad (sending to the right/left) but maybe it has.
I also used something similar in hyprland but there was already a plugin for this, and later on they added it in hyprland itself, this is my hyprland config for similar functionality:
"$mod, W, focusmonitor, l"
"$mod, E, focusmonitor, r"
"$mod SHIFT, W, movewindow, mon:l"
"$mod SHIFT, E, movewindow, mon:r"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey, I wrote the same thing for hyprland (https://github.com/hyprwm/contrib/blob/main/try_swap_workspace/try_swap_workspace). I have the same user story as you do, coming from Xmonad to wayland. I am having trouble with hyprlands dpms and therefore went to sway.
Although maybe I am mistaken but Xmonad has a way to send a window one output to the left/right. So when the window is on the left output, sending it one output to the right means it ends of on the center screen. Doing it again would send it to the right screen.
// edit: I hacked this together real quick:
This does the movement to the left/ right monitor to the currently focused monitor. I don't know python, so that is pretty rough and done in a C way I guess.
Usage is
(change path accordingly)