wezterm
wezterm copied to clipboard
Switching workspaces opens windows when it shouldn't
What Operating System(s) are you seeing this problem on?
Linux X11
Which Wayland compositor or X11 Window manager(s) are you using?
xfce
WezTerm version
wezterm 20230119-074737-730c41b7
Did you try the latest nightly build to see if the issue is better (or worse!) than your current version?
Yes, and I updated the version box above to show the version of the nightly that I tried
Describe the bug
When switching to a new workspace, sometimes wezterm uses the existing window, and sometimes it doesn't and opens a new window (leaving the old one present). It should always re-use the existing window. When closing one of the workspace windows, sometimes it closes, and sometimes it immediately re-opens another window.
To Reproduce
Ensure no wezterm (or mux server) is already running, then start with the provided config:
$ wezterm-nightly --config-file wezterm.lua
You'll get one window, on a workspace named after the current host. I think it's on the local domain.
- Press backtick-shift-p (to switch to a workspace named "Project X" on a domain named after the current host). The workspace will be created, re-using the existing window.
- Press backtick-shift-s (to switch to a workspace named "Somethingelse", also the domain named after the current host). The workspace will be created, re-using the existing window.
- Press backtick-s (to bring up the workspace selector, showing the three workspaces), and select the "Project X" workspace. Note that it correctly switches in the existing window.
- Press backtick-s (to bring up the workspace selector again, showing the three workspaces), and select the original workspace (named after the current host).
At this point a brand new window appears - it should have re-used the existing window. Both windows are on the just selected workspace.
Configuration
local wezterm = require("wezterm");
local hostname = wezterm.hostname();
-- Dynamically build the unix domains configuration element.
-- This lets us use an ssh proxy for hosts except for the current host.
--
-- Note: We are using an ssh proxy to permit port forwarding (since wezterm
-- native ssh domains do not permit this.)
local unix_hosts = {"localhost", "ruru", "noir", "tron" }
local unix_domains = {}
while #unix_hosts > 0 do
local host = table.remove(unix_hosts, 1)
if host == "localhost" or host == hostname then
table.insert(unix_domains, {name = host })
else
table.insert(unix_domains, {name = host, proxy_command = {"ssh", "-T", host, "wezterm-nightly", "cli", "proxy"}})
end
end
return {
default_workspace = hostname,
unix_domains = unix_domains,
disable_default_key_bindings = true,
exit_behavior = "Close",
enable_tab_bar = true, -- false when using tmux, true for wezterm multiplexing
leader = { key = "`", timeout_milliseconds = 2000},
keys = {
-- Send "`" key to the terminal when pressed after LEADER
{ key = "`", mods = "LEADER", action = wezterm.action{SendString = "`"}},
{ key = "\t",mods = "LEADER", action = "ActivateLastTab"},
{ key = " ", mods = "LEADER", action = "ShowLauncher"},
{ key = " ", mods = "LEADER|CTRL", action = wezterm.action{ShowLauncherArgs = {flags = "FUZZY|DOMAINS|WORKSPACES|TABS|LAUNCH_MENU_ITEMS|KEY_ASSIGNMENTS"}}},
{ key = "s", mods = "LEADER", action = wezterm.action{ShowLauncherArgs = {title = "Workspaces", flags = "FUZZY|WORKSPACES"}}},
-- Experimental, associate workspace with domain, see https://github.com/wez/wezterm/issues/1874
-- Should switch to the "default" workspace, (named after this host).
{ key = "l", mods = "LEADER|CTRL", action = wezterm.action{SwitchToWorkspace = {
name = hostname,
spawn = {
domain = {
DomainName = hostname
}
}
}}},
-- A project workspace, on the current host
{ key = "s", mods = "LEADER|SHIFT", action = wezterm.action{SwitchToWorkspace = {
name = "SomethingElse",
spawn = {
domain = {
DomainName = hostname
}
}
}}},
-- A project workspace, possibly on a remote host but here we just use the local host
{ key = "p", mods = "LEADER|SHIFT", action = wezterm.action{SwitchToWorkspace = {
name = "Project X",
spawn = {
domain = {
DomainName = hostname
}
}
}}},
},
}
Expected Behavior
It should have re-used the existing window.
Logs
No response
Anything else?
No response
Hey, I just found this issue and I can confirm that it is still a problem.
The code in SwitchToWorkspace seems to fail when the spawn is in a remote domain. So the final line in this snippet:
let switcher = crate::frontend::WorkspaceSwitcher::new(&name);
mux.set_active_workspace(&name);
if mux.iter_windows_in_workspace(&name).is_empty() {
Fails to find any windows in the workspace, because the test is run before the actual connection to the remote server has completed. And a new window is mistakenly created.
This also means that there is no way to attach to an already running remote mux server, without also spawning a new process at the same time. It would be nice to attach to the remote server and not have to kill a spurious shell.
Disclaimer: I have no experience with Rust, so this might be wrong. Just hoping it might be a useful clue for someone who knows what they're doing.
Solved my local problem and posting it here for whatever value, if any, it might offer others...
function switch_to_domain(dom, window, pane)
local ws={name=dom, spawn={domain={DomainName=dom}}}
local action=wezterm.action{SwitchToWorkspace=ws}
window:perform_action(action, pane)
end
function toggle_domain(dom, window, pane)
if window:active_workspace() == dom
then
switch_to_domain("default", window, pane)
else
wezterm.mux.get_domain(dom):attach()
switch_to_domain(dom, window, pane)
end
end
function toggle_domain_action(dom)
return wezterm.action_callback(
function(win, pane)
toggle_domain(dom, win, pane)
end
)
end
and then:
{key="k", mods="CTRL|SHIFT", action=toggle_domain_action("kia")},
{key="o", mods="CTRL|SHIFT", action=toggle_domain_action("ox")},
Creating two keys: "k" which toggles the "kia" ssh domain, and "o" which toggles the "ox" ssh domain. A workspace, the same name as the domain is created if it doesn't already exist. If the workspace already exists and is the current workspace, those keystrokes instead toggle to the default workspace.
Probably the only potential clue is the line :
wezterm.mux.get_domain(dom):attach()
Which attaches the domain first, before attempting to switch to it. This removes the spurious window that I was seeing here. But I fear it might be a slightly different problem than others were reporting above.