Use some heuristics to verify the data that is about to be parsed;
this can help to detect eg: data being output to stdout prior
to us sending any encoded data to the remote mux.
In addition, add a timeout to help avoid waiting forever in
the case that we didn't detect a problem.
refs: https://github.com/wez/wezterm/issues/1860
The heart of the issue here was due to the window-reuse logic that
tries to reuse a GUI window that is no longer associated with a mux
window.
Each GUI window subscribes to the mux for mux events, but it filters
according to is understanding of the mux_window_id that it is associated
with.
The GUI frontend maintains an mapping of GUI and mux window so that it
knows when to reuse a GUI window and when to close it.
When connecting to a remote mux, wezterm spawns a temporary connection
progress window. Once connected, workspace reconiliation is triggered
and decides that this window can be used for something else.
As part of workspace reconciliation, this mapping can be adjusted and
the frontend will notify a GUI window that its mux window has changed.
However, that updated mux window was not visible to the mux notification
subscription so the effect was that a variety of notifications were
effectively ignored, including updates from a remote mux when the output
was changed.
To make matters worse, the workspace reconciliation could "double-tap"
window creation and create excess windows only to later realize they
weren't needed and close them out again.
This commit addresses both of these concerns.
refs: #1841
refs: #1814
After killing the remote pane, we no longer trigger the renderable
poll stuff that would detect that the pane was dead.
Let's speculatively set it to dead so that we don't get stuck with
stray tabs/panes.
https://github.com/wez/wezterm/issues/1752
There were a a couple of issues:
* `ImageData::hash` would re-hash the image on every call, and this was
called for every cell that comprised an image on the mux server side
* `SerializedLine` needed to understand how to remove the `Arc<ImageData>`
image attachments so that we didn't serialize a complete copy of the
image per cell that comprised the image.
A new RPC was introduced to attempt to fetch `ImageData` given its
content hash and pane, row and cell index as a hint to locate it.
A client side LRU of content hash to `ImageData` is used to avoid
issuing repeat calls to that new RPC.
refs: #1237
Pretty much the same test plan as b4c4c85683
but start wezterm:
./target/debug/wezterm -n --config 'ssh_domains={{name="s",remote_address="localhost"}}' connect s
This reliably propagates focus=true events, but if the client switches
focus away from a mux pane to a local pane, then the focus=false event
may not be propagated to the remote mux.
refs: #1608
wezterm cli spawn, and wezterm cli split-pane can use this information
to pick a default for the pane id when invoked from outside of wezterm.
refs: https://github.com/wez/wezterm/issues/1531
This was used by the mux client when the session is tardy.
I've heard feedback that the greying out is distracting and not
especially useful, so I don't think this is any great loss.
This commit does two related things, from opposite ends of the spectrum:
* Sets the sticky bit on pid files and unix sockets to avoid tmpwatch
deleting them in cleanup scenarios
* Falls back to looking at the changed time if the filesystem doesn't
support reporting creation time when wezterm does its own liveness
and cleanup checks for unix domain sockets in the runtime dir
* Allow any wezterm instance to perform that cleanup
refs: #1601
Introduce a new config knob called 'local_echo_threshold_ms' to let
users configure when the local echo prediction should kick in. The
default value is 100ms to retain the current behavior.
This action causes the active workspace for the gui to change.
If the name is omitted a random name will be generated.
If the workspace doesn't exist, it will be be created.
The optional spawn parameter can be used to launch a specific
program into the new workspace; if omitted, the default prog
will be used.
The gui only supports a single active workspace. Switching workspaces
will repurpose existing gui windows and re-assign them to windows
in the new workspace, adjusting their size to fit those windows,
spawning new windows or closing unused windows as required.
The gui now exits when there are no panes in the active workspace,
rather than no panes at all.
refs: #1531
Tidies up some code duplication within the mux protocol handler.
Move some of the logic into Mux, remove legacy Spawn Pdu to reduce
more duplication.
I want to dedup some of the similar logic that exists in the gui
spawn implementation as well in a follow up.
This is not exposed through any UX; the mux api allows setting
the workspace and propagating information about windows whose
workspace has changed.
Windows start with a blank workspace name.
This is just plumbing; nothing uses it yet.
refs: #1531
Define a way to compute a client ID and pass that through to the
mux server when verifying version compatibility.
Once associated, the session handler will keep some metadata
updated in the mux.
A new cli subcommand exposes the info:
```
; ./target/debug/wezterm cli list-clients
USER HOST PID CONNECTED IDLE WORKSPACE
wez mba.localdomain 52979 30.009225s 1.009225s
```
refs: #1531
This is a similar race condition to one we had before with the
multiplexer, where the connection UI made us think that we didn't
need to start a new process.
Additionally, the attach method would unconditionally create a
new client without checking whether we already had one.
In the case that the published symlink is stale, our default
client connection logic was to retry connecting with backoff
to give a newly spawned server a chance to startup.
In the context of a newly launched gui process checking to see
if an existing gui process can serve the same request, we don't
need to give it any grace: it will either answer immediately
or be deemed not useful.
This commit limits us to a single connection attempt in the case
where we're not automatically starting the server, which in turn
constrains the overhead to something in the order of microseconds
rather than nearly 0.5 seconds.
While we're in here, I noticed that if we thought we had a socket
to try and that failed, we'd always try to publish a new symlink.
However, if we failed due to mismatched version info, we shouldn't
publish over the top of the already running instance.
refs: #1529
user vars were stubbed out. This commit adds storage for them
in the mux client and adds a new notification that publishes each
var as it is changed. That differential stream is applied to the
storage in the mux client when it is received.
```lua
local wezterm = require 'wezterm'
wezterm.on("update-right-status", function(window, pane)
local woot = pane:get_user_vars().woot
window:set_right_status(tostring(woot))
end);
return {
unix_domains = {
{name="unix"},
},
}
```
then running:
* `wezterm connect unix`
* in that session: `printf "\033]1337;SetUserVar=%s=%s\007" woot `echo -n nice | base64``
causes `nice` to show in the status area.
refs: #1528
If an ssh domain is set to use_multiplexer=false, it is now
possible to `wezterm connect` to it.
Previously, it was only possible to connect to domains that
used the mux client.
refs: https://github.com/wez/wezterm/issues/1456
The client machinery would try to spawn an async attempt at
detaching the unixdomain from the mux on shutdown, but since
we're in the middle of tearing down the scoped executor,
we could sometimes panic.
The client we have in this situation isn't actually associated
with a domain, so we don't need to detach in that situation.
Formalize that by making it an Option, and address the
fanout.
When spawned with no WEZTERM_UNIX_SOCKET environment set,
we now prefer to resolve the gui instance, falling back to
the mux if it doesn't look like the gui is running.
`wezterm cli --prefer-mux` will use the original behavior of
trying to resolve the path from the unix domain in the config.
Nothing generates them right now, and the mux client has no
way to represent them on the wire.
I'm considering constraining them to just win32 for now.
refs: https://github.com/wez/wezterm/issues/1509
Previously, we would implicitly set it to the special SEQ_ZERO
value, but since that value always flags the row as changed,
it causes some over-invalidation issues downstream in wezterm.
This commit makes that parameter required, so that the code that
is creating a new Line always passes down the seqno from that event.
refs: #1472
Finally getting around to fixing this usability wart: this commit
changes the behavior of Window closing so that you can close a window
containing multiplexer panes without prompting and without killing
off those panes.
This is achieved through some plumbing:
* The mux can now advise Domains about an impending window closure,
giving them the opportunity to "do things" in readiness.
* The mux client domain informs the container ClientPane instances
to ignore the next Pane::kill call, which would otherwise inform
the mux server to kill the remote pane
* Pane:can_close_without_prompting now requires a CloseReason.
* ClientPane's can_close_without_prompting impl allows Window closing
without prompting on the assumption that the ignore-next-kill hack
above is working
refs: #848
refs: #917
refs: #1224
The mux client just returns a dummy reader, and some overlays
have panicking stubs: just allow for them to return None
instead of potentially spawning a useless thread.
In some cases, the `wezterm cli proxy` subcommand had terminated
with error, but the client was still happily waiting for more data
to read.
This commit spawns a thread to detect the process termination and
then drop the child struct when it completes; that in turn causes
the stdio descriptors to close and then things tick over.
refs: #1358