This is a suggestion for two alternate ways of switching between workspaces (virtual desktops) in Sway.
So far, as much as I want to like Sway, I greatly dislike how the workspaces are handled. Right now, they closely follow the implementation of vanilla i3, where workspaces are shared, but separated between monitors (or screens).
For example, I have two monitors, and both workspace 1 and workspace 2 are automatically created on each monitor when I start Sway.
When the user presses Mod+1 it will focus on the workspace on the "first monitor" and if you press Mod+2, it will focus on the "second monitor".
If anything else but Mod+1 and Mod+2 are pressed, a new workspace is created on the currently "focused monitor", and empty workspaces are removed if there are no windows in the workspace, which makes sense.
However, you can imagine how lost someone would be if 4 workspaces were automatically created among 4 monitors, and since there are only 10 digits in most English/cardinal languages, having 10 workspaces only accessible with a minimum of two key-presses can be very limiting, especially when divided among 4 monitors.
Also, new users have to keep remembering which workspaces are created on which screens, which are removed, which exist, and which windows are open in each workspace, on each screen! It's frustrating to say the least!
With all that in mind, here's some alternatives to, in my opinion, this very counter-intuitive, default method.
Each monitor can be treated as a separate group. For example, they could be called Workspace Groups. Let's say that workspace 1-1 is workspace 1 on the first monitor, and workspace 2-1 is workspace 1 on the second monitor. You can see where this is going....
Applications/Windows can easily be separated between screens, yet still, because you can display whichever workspaces you want for each monitor, it is very flexible for the user to show and hide whichever workspaces you want, and it offers an option for 10 easily accessible workspaces per-monitor (or to be more precise, per-group)!
In order to switch between workspace groups, you could use some unused keybinds, that involve arrow keys or numbering, or perhaps you could just have your mouse cursor on whichever monitor you wanted, in order to specify the group.
Either way, it just makes a lot of sense. Even if it may be difficult to implement.
Instead of separating workspaces between screens, why not use each workspace for all screens? This is actually somewhat similar to how most DEs and WMs work, such as Openbox and XFCE, and it should be easier to implement!
Like the default implementation, the same amount of keystrokes are required to switch between groups. But you would have a maximum of 10 groups before needing additional keypresses to access more workspaces.
Both the default and this implementation do not scale well the more screens you have, but it should be a lot easier to implement in the meantime.
I honestly think all 3 methods should be implemented, to give the power-user more options, but the way it works right now is great for veteran i3 users. I am a new user of Sway/i3, so I have a fresh perspective of how these things should work.
I was just really disappointed of how it handles right now. Sure, it's great for single-monitor use, but Sway still extremely fails in terms of dual-monitor, or higher, and I keep going back to other WMs because of it.
I hope the developers consider these options, and I hope non-developers and other uses can support decisions like these, at the very least.
Thank you for reading!
This has a low chance of being implemented in sway without being implemented in i3 first, I think. Maybe you'd like to just change your keybinds?
Have you considered making use of 'workspace next_on_output', 'focus output ___', or 'workspace
I had a similar idea recently, I have something non-generic here: https://github.com/synaptiko/.files/blob/master/sway/switch-output.sh
It's adjusted to my setup where I have two monitors, the one on the top, the other on the bottom and I have bindings to switch between them. And because Sway allows to re-bind keys dynamically, you can write a script similar to the above one. It should be possible to automate it with IPC.
If anything else but Mod+1 and Mod+2 are pressed, a new workspace is created on the currently "focused monitor", and empty workspaces are removed if there are no windows in the workspace, which makes sense.
You can assign workspace to output, then when you press Mod+3 then workspace 3 will be created at proper monitor:
# Define outputs
set $output-primary DP-1
set $output-secondary eDP-1
# workspace to displays
workspace 1 output $output-primary
workspace 2 output $output-primary
workspace 3 output $output-primary
workspace 4 output $output-primary
workspace 5 output $output-primary
workspace 6 output $output-primary
workspace 7 output $output-secondary
workspace 8 output $output-secondary
workspace 9 output $output-secondary
workspace 10 output $output-secondary
If DP-1 is not connected then workspace will be created at monitor which has focus. When you connect DP1, they will move to proper monitors
I'm using i3, but I guess that in sway it works same way.
I'm using i3, but I guess that in sway it works same way.
Yes it does, and I do use it just like you.
# Workspaces:
# Special workspaces shortcuts
# Personal firefox
set $wsp 
# Music (Deezer)
set $wsd ♪
# Messaging (Franz)
set $wsm 
# Telegram
set $wst 
# Switch to workspace
bindsym F1 workspace 1
bindsym F2 workspace 2
bindsym F3 workspace 3
bindsym F4 workspace 4
bindsym F5 workspace 5
bindsym F6 workspace 6
bindsym F7 workspace 7
bindsym F8 workspace 8
bindsym F9 workspace 9
bindsym F10 workspace 10
bindsym F11 workspace $wsm
bindsym F12 workspace $wst
bindsym $mod+m workspace $wsd
bindsym $mod+p workspace $wsp
# Move focused container to workspace
bindsym $mods+F1 move container to workspace 1
bindsym $mods+F2 move container to workspace 2
bindsym $mods+F3 move container to workspace 3
bindsym $mods+F4 move container to workspace 4
bindsym $mods+F5 move container to workspace 5
bindsym $mods+F6 move container to workspace 6
bindsym $mods+F7 move container to workspace 7
bindsym $mods+F8 move container to workspace 8
bindsym $mods+F9 move container to workspace 9
bindsym $mods+F10 move container to workspace 10
bindsym $mods+F11 move container to workspace $wsm
bindsym $mods+F12 move container to workspace $wst
bindsym $mods+m move container to workspace $wsd
bindsym $mods+p move container to workspace $wsp
# Attaching workspaces to outputs
workspace 1 output DP-2 DP-1 eDP-1
workspace 2 output DP-2 DP-1 eDP-1
workspace 3 output DP-2 DP-1 eDP-1
workspace 4 output DP-2 DP-1 eDP-1
workspace $wsp output eDP-1 DP-2 DP-1
workspace $wsd output eDP-1 DP-2 DP-1
workspace $wsm output eDP-1 DP-2 DP-1
workspace $wst output eDP-1 DP-2 DP-1
I'd also add that you are not limited to 10 workspaces, as you can see in my config I have some other workspaces using other letters that are more meaningful, and I attach some applications to these workspaces.
I also don't particularly like this i3 style of workspace management (coming from the Awesome WM). I have two monitors, so I bound \# Set first monitor workspaces to first monitor
workspace $ws_1 output $first_monitor
workspace $ws_2 output $first_monitor
workspace $ws_3 output $first_monitor
workspace $ws_4 output $first_monitor
workspace $ws_5 output $first_monitor
workspace $ws_6 output $first_monitor
workspace $ws_7 output $first_monitor
workspace $ws_8 output $first_monitor
workspace $ws_9 output $first_monitor
workspace $ws_10 output $first_monitor
# Set second monitor workspaces to second monitor
workspace $ws_11 output $second_monitor
workspace $ws_12 output $second_monitor
workspace $ws_13 output $second_monitor
workspace $ws_14 output $second_monitor
workspace $ws_15 output $second_monitor
workspace $ws_16 output $second_monitor
workspace $ws_17 output $second_monitor
workspace $ws_18 output $second_monitor
workspace $ws_19 output $second_monitor
workspace $ws_20 output $second_monitor
# Switch to workspace
bindsym --to-code $mod+1 workspace $ws_1
bindsym --to-code $mod+2 workspace $ws_2
bindsym --to-code $mod+3 workspace $ws_3
bindsym --to-code $mod+4 workspace $ws_4
bindsym --to-code $mod+5 workspace $ws_5
bindsym --to-code $mod+6 workspace $ws_6
bindsym --to-code $mod+7 workspace $ws_7
bindsym --to-code $mod+8 workspace $ws_8
bindsym --to-code $mod+9 workspace $ws_9
bindsym --to-code $mod+0 workspace $ws_10
# Move focused container to workspace
bindsym --to-code $mod+Shift+1 move container to workspace $ws_1
bindsym --to-code $mod+Shift+2 move container to workspace $ws_2
bindsym --to-code $mod+Shift+3 move container to workspace $ws_3
bindsym --to-code $mod+Shift+4 move container to workspace $ws_4
bindsym --to-code $mod+Shift+5 move container to workspace $ws_5
bindsym --to-code $mod+Shift+6 move container to workspace $ws_6
bindsym --to-code $mod+Shift+7 move container to workspace $ws_7
bindsym --to-code $mod+Shift+8 move container to workspace $ws_8
bindsym --to-code $mod+Shift+9 move container to workspace $ws_9
bindsym --to-code $mod+Shift+0 move container to workspace $ws_10
# Second monitor workspaces with F-keys
bindsym --to-code $mod+F1 workspace $ws_11
bindsym --to-code $mod+F2 workspace $ws_12
bindsym --to-code $mod+F3 workspace $ws_13
bindsym --to-code $mod+F4 workspace $ws_14
bindsym --to-code $mod+F5 workspace $ws_15
bindsym --to-code $mod+F6 workspace $ws_16
bindsym --to-code $mod+F7 workspace $ws_17
bindsym --to-code $mod+F8 workspace $ws_18
bindsym --to-code $mod+F9 workspace $ws_19
bindsym --to-code $mod+F10 workspace $ws_20
bindsym --to-code $mod+Shift+F1 move container to workspace $ws_11
bindsym --to-code $mod+Shift+F2 move container to workspace $ws_12
bindsym --to-code $mod+Shift+F3 move container to workspace $ws_13
bindsym --to-code $mod+Shift+F4 move container to workspace $ws_14
bindsym --to-code $mod+Shift+F5 move container to workspace $ws_15
bindsym --to-code $mod+Shift+F6 move container to workspace $ws_16
bindsym --to-code $mod+Shift+F7 move container to workspace $ws_17
bindsym --to-code $mod+Shift+F8 move container to workspace $ws_18
bindsym --to-code $mod+Shift+F9 move container to workspace $ws_19
bindsym --to-code $mod+Shift+F10 move container to workspace $ws_20
I'd like to add that the aforementioned workarounds are workable for fixed dual-screen setups, but does not help in variable-screen setups. Imagine a laptop that is often docked, possibly in multiple places. At any given point, I have anywhere between 1 and 3 screens, and I am sure others' would take it further.
Such a setup pretty much renders i3-style workspaces border-line unusable. Default-positioned workspaces are chaotic: Their initial position is not logical, and empty workspaces spawn on the focused output leaving disorganized workspace->output assignments. On the other hand, trying to fix the issue with a config generalized for N outputs is pretty much impossible. An IPC client could be made to organize workspaces as a sequence over outputs, but that still does not make it easy to say "Go to the second workspace on the monitor I'm looking at!"
Per-output workspaces (like is the case for awesomewm's tags) handles this in a general fashion much more elegantly. I think optional support for such a mode would be a very small feature, and could possibly be implemented without needing i3 support first.
Hey, I am also okay with using multiple workspaces with Alt now.
Here's a snippet of what I'm using:
# Set mod key
set $mod Mod4
# Secondary monitor
set $secondary = DisplayPort-0
# Workspace labels
set $ws1 "1"
set $ws2 "2"
set $ws3 "3"
set $ws4 "4"
set $ws5 "5"
set $ws6 "6"
set $ws7 "7"
set $ws8 "8"
set $ws9 "9"
set $ws0 "0"
set $wsa1 "A-1"
set $wsa2 "A-2"
set $wsa3 "A-3"
set $wsa4 "A-4"
set $wsa5 "A-5"
set $wsa6 "A-6"
set $wsa7 "A-7"
set $wsa8 "A-8"
set $wsa9 "A-9"
set $wsa0 "A-0"
# Switch to workspace
bindsym --to-code $mod+1 workspace $ws1
bindsym --to-code $mod+2 workspace $ws2
bindsym --to-code $mod+3 workspace $ws3
bindsym --to-code $mod+4 workspace $ws4
bindsym --to-code $mod+5 workspace $ws5
bindsym --to-code $mod+6 workspace $ws6
bindsym --to-code $mod+7 workspace $ws7
bindsym --to-code $mod+8 workspace $ws8
bindsym --to-code $mod+9 workspace $ws9
bindsym --to-code $mod+0 workspace $ws0
bindsym --to-code $mod+Mod1+1 workspace $wsa1
bindsym --to-code $mod+Mod1+2 workspace $wsa2
bindsym --to-code $mod+Mod1+3 workspace $wsa3
bindsym --to-code $mod+Mod1+4 workspace $wsa4
bindsym --to-code $mod+Mod1+5 workspace $wsa5
bindsym --to-code $mod+Mod1+6 workspace $wsa6
bindsym --to-code $mod+Mod1+7 workspace $wsa7
bindsym --to-code $mod+Mod1+8 workspace $wsa8
bindsym --to-code $mod+Mod1+9 workspace $wsa9
bindsym --to-code $mod+Mod1+0 workspace $wsa0
# Move focused container to workspace
bindsym --to-code $mod+Shift+1 move container to $ws1
bindsym --to-code $mod+Shift+2 move container to $ws2
bindsym --to-code $mod+Shift+3 move container to $ws3
bindsym --to-code $mod+Shift+4 move container to $ws4
bindsym --to-code $mod+Shift+5 move container to $ws5
bindsym --to-code $mod+Shift+6 move container to $ws6
bindsym --to-code $mod+Shift+7 move container to $ws7
bindsym --to-code $mod+Shift+8 move container to $ws8
bindsym --to-code $mod+Shift+9 move container to $ws9
bindsym --to-code $mod+Shift+0 move container to $ws0
bindsym --to-code $mod+Mod1+Shift+1 move container to workspace $wsa1
bindsym --to-code $mod+Mod1+Shift+2 move container to workspace $wsa2
bindsym --to-code $mod+Mod1+Shift+3 move container to workspace $wsa3
bindsym --to-code $mod+Mod1+Shift+4 move container to workspace $wsa4
bindsym --to-code $mod+Mod1+Shift+5 move container to workspace $wsa5
bindsym --to-code $mod+Mod1+Shift+6 move container to workspace $wsa6
bindsym --to-code $mod+Mod1+Shift+7 move container to workspace $wsa7
bindsym --to-code $mod+Mod1+Shift+8 move container to workspace $wsa8
bindsym --to-code $mod+Mod1+Shift+9 move container to workspace $wsa9
bindsym --to-code $mod+Mod1+Shift+0 move container to workspace $wsa0
# Workspace output settings
workspace $ws1 output primary
workspace $ws2 output primary
workspace $ws3 output primary
workspace $ws4 output primary
workspace $ws5 output primary
workspace $ws6 output primary
workspace $ws7 output primary
workspace $ws8 output primary
workspace $ws9 output primary
workspace $ws0 output primary
workspace $wsa1 output $secondary
workspace $wsa2 output $secondary
workspace $wsa3 output $secondary
workspace $wsa4 output $secondary
workspace $wsa5 output $secondary
workspace $wsa6 output $secondary
workspace $wsa7 output $secondary
workspace $wsa8 output $secondary
workspace $wsa9 output $secondary
workspace $wsa0 output $secondary
While this works okay, my problem is that whichever window is focused, or when the mouse is focused on another output, or something like that, creates the workspace in that output. If that makes sense.
What I want to do is force a newly created workspace to a specific output no matter what, and never create a workspace in a different output that I specify. How do I do that? I couldn't find any kind of setting in the docs so far.
# Secondary monitor set $secondary = DisplayPort-0 # Workspace output settings workspace $ws1 output primary ... workspace $ws0 output primary workspace $wsa1 output $secondary ... workspace $wsa0 output $secondary
Three things.
$primary variable$secondary variable (there should be no "equal" there)$primary variable do not forget to use it with $primary.That may help you @mrjpaxton :)
I honestly think all 3 methods should be implemented, to give the power-user more options, but the way it works right now is great for veteran i3 users. I am a new user of Sway/i3, so I have a fresh perspective of how these things should work.
Have you tried scripting? What about these?
# Grouped workspaces per-monitor
bindsym $mod+1 exec /path/to/wpo 1
bindsym $mod+2 exec /path/to/wpo 2
...
# Moving between outputs.
bindsym $mod+Left focus output left
...
# Workspaces are shared among all screens
# (Not sure if understood correctly...)
bindsym $mod+1 exec /path/to/biw "1: A"
bindsym $mod+2 exec /path/to/biw "1: B"
...
/path/to/wpo:
#!/bin/sh
OUTPUT_INDEX="$(swaymsg -t get_outputs | jq 'map(.focused)|to_entries|.[]|select(.value)|.key+1')"
NUMBER=$1
# Prefix every workspace with output index:
# - If it doesn't exist yet, it will be created on the current, focused output.
# - If it exists it must be on the current output and it will be focused.
swaymsg workspace "$OUTPUT_INDEX-$NUMBER"
/path/to/biw:
#!/bin/sh
OUTPUT="$(swaymsg -t get_outputs | jq -r '.[]|select(.focused)|.name')"
WORKSPACE="$1"
# Switch to workspace and move it to the focused output. Focus it again, because move just moves.
swaymsg workspace "$WORKSPACE" \; move workspace to output "$OUTPUT" \; workspace "$WORKSPACE"
(Untested, but hope it's helpful somewhat.)
See https://github.com/swaywm/sway/pull/4846 for a draft implementation of output-local workspaces ala how awesomewm behaves.
We're not interested in diverging this far from i3.
Sorry, I should have asked this before, but @kennylevinsen can you open a new issue on the i3 bug tracker to see if they would be interested in this feature?
Probably is late for this, but I founded this discuss right now, maybe you want take a look to this multi screen possibly config.
https://github.com/NessunoZero/Sway-multimonitors-config-and-scripts
Most helpful comment
Have you tried scripting? What about these?
/path/to/wpo:/path/to/biw:(Untested, but hope it's helpful somewhat.)