This helps to restore any individually dropped tabs and to detect
tabs that were created by other clients across a reconnection.
refs: https://github.com/wez/wezterm/issues/127
This is useful for setting up a reasonable initial environment.
For example, on Windows you might want to set the `prompt` environment
so that some basic shell integration is enabled; this will cause new
tabs to open with the same cwd as the current tab:
```
set_environment_variables = { "prompt"="$E]7;file://localhost/$P$E\\$P$G" }
```
This setting is intended to apply only to the local domain.
refs: https://github.com/wez/wezterm/issues/146
This allows this prompt setting to work:
```
prompt $E]7;file://localhost/$P$E\$P$G
```
although this one sets it for future prompts:
```
setx prompt $E]7;file://localhost/$P$E\$P$G
```
refs: https://github.com/wez/wezterm/issues/146
This is conceptually slightly cleaner and allows sessionhandler to
be agnostic of the details of the channel used to communicate with
the client; it just has a Sender<DecodedPdu> to work with.
I suspect some race condition because adding these made the connect
time hang stop reproducing for me on my local network.
Will try this to the corp vpn.
refs: https://github.com/wez/wezterm/issues/127
This commit adjusts the features in Cargo.toml to allow building
without openssl on unix systems.
It teaches the native_tls flavor of the code to perform bootstrapping
via ssh, but is still not usable because there still isn't a way
to get native_tls to use PEM files.
This makes the tls channel much easier to use; the config can now be as
simple as this on the server side:
```toml
[[tls_servers]]
bind_address = "192.168.1.8:8080"
```
and this on the client side:
```
[[tls_clients]]
name = "hostname"
bootstrap_via_ssh = "192.168.1.8"
remote_address = "hostname:8080"
```
and then `wezterm connect hostname` will use ssh to connect to the
host, start the mux server, request the CA and client certs and
then connect to it over TLS.
This is implemented only for openssl at the moment.
If we're actively outputting to the window and the user closes it,
we don't need to panic.
Make the window a little larger now that it shows more data.
Adds a default 60 second timeout for read and write for the tls
and unix domain sockets that we create. This applies to ssh
domains, but not `wezterm ssh` sessions that go direct to ssh ptys.
I noticed that the reconnection UI for TLS mux sessions was annoying
on macOS: it would flash up and steal the focus, make a connection
attempt that would immediately fail because the destination was not
routable and then close the window. It would do this each time
a connection attempt was made (every few seconds in the early
stages of backoff).
This commit pulls the UI up a level so that we open the window at
the start of the connection (or re-connection) attempt, and keep
the same one for its lifetime.
This also introduces a headless UI object that doesn't output or
respond to anything. You can set the log level to trace to see
what is happening inside. It is used by the CLI mode. It could
perhaps be made smart enough to conditionally show a UI when needed,
but since it is targeting local unix domain sockets, that doesn't
seem like it is needed right now.
I'm adding this primarily to avoid repeatedly showing "No more
fallbacks" errors when moving the mouse over a terminal that contains
cells with no matching glyphs.
It has the nice side effect of changing the typical opengl tab render
time from ~2.9ms to ~1.3ms.
The opengl based render first clears the window to the background
color and then renders the cells over the top.
on macOS I noticed a weird lighter strip to the bottom and right of
the window and ran it down to the initial clear: our colors are SRGB
rather than plain RGB and the discrepancy from rendering SRGB as RGB
results in the color being made a brighter shade. This was less
noticeable for black backgrounds.
We now display a list of tabs and allow selecting them with either
the up/down arrows or the k/j keys. Enter activates the selected
tab, Escape cancels the overlay.
An overlay is a little termwiz app that can be overlaid over the
content of a gui tab.
The intent is for these to provide the mechanism for meta operations;
listing all tabs in a long-form list and switching between them,
dropping into configuration or error log review and so on.
We now show a little status window when we're making a connection
for a remote mux domain.
This should make things feel slightly nicer if there is a connectivity
problem.
refs: https://github.com/wez/wezterm/issues/127
Rather than just a single attempt at each mechanism, let's allow up
to 3 loops, each time trying all supported mechanisms. This helps
for the case where the user makes a typo with their password, and
should also help for more complicated auth setups where succeeding
with one mechanism may not be sufficient.
While testing this out I noticed that were deferring closing the
OS level window until after the entire auth attempt, so I added
some logic to proactively close the prompt windows. In the longer
term I'd like all related prompts to render in the same window
for improved cognotive continuity.
This matches cmd.exe and other programs (notepad, office, etc) behavior:
First click selects "start", then Shift+click selects "end". They form
a range.
This is particularly useful to select a large range of text, since the
user can release the left button, then operate on the scroll bar without
worrying about messing up text selection.
It gets a bit more complicated with the POSIX "mouse grabbed" situation.
When the mouse is grabbed, it's usually a full-screen ncurses-like
application. Selection mostly likely only makes sense within a single
screen. So Shift + LeftClick just works as starting a selection in this
case (otherwise it'll be hard to clear a selection).
The IME position is related to on-screen Window, not the
off-screen buffer.
Buffer
+- 0
|
| Window
| +- 0
| | (Tab bar)
+- 20 physical_top +- 1
| | (Terminal view)
| |
| |
+- 30 cursor.y +- 11 Correct IME position
It's too fiddly to setup in practice, and literally no one has
expressed an interest in using it.
Removing it simplifies some upcoming work.
Closes: https://github.com/wez/wezterm/issues/35
While debugging on windows earlier today I saw that we were
blocked on this wait on the main thread. For whatever reason,
that only blocks in practice on Windows; I suspect that this is
due to a timing issue on windows where the server side takes
longer to respond than it does on posix.
The root cause and secondary effect were a little surprising: the mux
pub/sub notification pipe filled up and because the mux notify routine
uses `retain` with the success of the send as a predicate it meant that
the full pipe resulted in the muxer killing that end of the subscriber
and that in turn made the ClientSession loop fail when it was
dispatching a notify on the other end, which terminated the loop and
disconnected the client.
Now, with this fixed, we have a flow control problem and the terminal
will remain busy with ctrl-c not being effective in the mux session.
This was an accidental casualty of some recent refactoring;
we need to clear the selection range when lines that intersect
with it are changed, so that's what this does.
Fixes: https://github.com/wez/wezterm/issues/118
Matching against the current dir when it includes a host and a
path seems like a handy way to automate selecting appropriate
theme/color/profile settings, so I'd like to make sure that
we have the full URL content available for that.
Refs: https://github.com/wez/wezterm/issues/115
Refs: https://github.com/wez/wezterm/issues/117
I'll write up more comprehensive docs once CI has proven that
the color schemes are packaged correctly.
The gist of it is that you can now specify:
```
color_scheme = "Batman"
```
to specify the default color palette.
The name corresponds to one of the color schemes from the
`assets/colors` directory. That directory is packaged and installed by
the CI deployment script, but we're also able to load them from the
source dir if you're running from in the wezterm source tree.
You can see previews of the various schemes here:
<https://iterm2colorschemes.com/>
In addition to loading from those that path, wezterm will search:
* In the `config` dir that is a sibling to `wezterm.exe` on windows
(not yet tested!)
* The directories specified in your `color_scheme_dirs` config setting
(multiple paths can be specified)
* You may also define schemes directly inline in your config file
using syntax like this:
```
[color_schemes."My Name"]
foreground = "#4a4543"
background = "#f7f7f7"
```
These visual artifacts seemed to affect everything other than Wayland
and were a bit annoying. The manifestation was that the cursor outline
box might have an extra line of another color on one or more of the
borders; whether it did or not seemed dependent on a combination of the
position of the cursor and the pixel width/height of the overall window.
This commit sets the texture sampler to prefer not to interpolate/merge
the value if it is between pixels and instead take the nearest texel.
Resizes can transiently result in lines whose length doesn't
match the vertex buffer width. If that happens, we probably
still derive value from painting the remaining lines, so allow
that to continue rather than blowing up the render.
This fixes a problem where a closed tab would linger until a subsequent
input event. The issue was that the layer at which we detect the tab
closure didn't have a way to signal the gui layer to repaint.
This commit adds an invalidated flag to the mux window object that is
updated when structural changes occur to its tabs; added, deleted,
activated and so on.
We check that flag in our periodic function in the gui layer and then
trigger a gui level invalidation if we see that it is set.
Record a notion of the state of the invalidations that we've sent
to the client so that we can skip sending updates if nothing has
changed since the last push.
It was possible to exhaust the number of fds on the server by
opening a vertical vim split and aggressively sliding it left
and right.
This commit allows the produce side to clone an arbitrary number
of senders without using up file descriptors.
Still not perfect; there's a window invalidation missing from
the mux somewhere on higher latency connections that gets
resolved just by moving the mouse :-/
There was an issue where we'd get stuck with a placeholder empty
line in a couple of rows when running `ls -l /etc` and scrolling
backwards. The damage was actually done during execution of the
ls command and was because we'd get confused about the state of
some of the line entries.
This diff introduces a proper state enum for them and defines
state transitions more rigorously.
I noticed the mux was running hot when idle and observed that it was
repeatedly fetching the line with the cursor.
Extract the logic into a helper function that is called from both
of the places that fetch and put lines; noticed that we were not
consistently processing hyperlinks.
When running the mux server we don't have an active window::Connection
so we can't use its spawn_task function. This little helper runs
the futures on the appropriate Tasks instance.
We can't use a trait method for this because traits abhor generic
parameter types.
The client side will limit how many rows it decides to speculatively
prefetch and defer to the lines requested by the renderer once we
exceed a certain number of fetch requests per second.
On the server side, we weren't actually coalescing individual tab
output events together; this commit restructures the end of the
appropriate loop block to make that effective.
This avoids a hang on startup if you're using an ssh multiplexer
connection and haven't already registered your ssh key and need
to perform password authentication.
The last config reload time didn't seem to stick in the periodic timer
callback.
Need to investigate that further, and also see if the blink paint
time is similarly impacted.
The root cause of this was a bit of a hack to ensure that we didn't
prematurely shut down while waiting for ssh sessions.
Introduce an Activity token that will extend the lifetime of the
event loop even if there are no windows present.
This cleans things up both on macos the application would linger in
the application switcher until you had tabbed away and back again,
and also for the null frontend which had grown a less gross hack.
Rust maintains the borrow from the match expression for the lifetime of
the match blocks, even though there is no relationship between the
value in scope in the blocks :-/
Having separate statements makes things happier.
Selection got accidentally moved to be scoped by window during
the remodel. This commit moves it to the per tab state.
refs: https://github.com/wez/wezterm/issues/89
The IME stuff on macos tends to swallow repeats for some keys.
Ugh. So this commit adds an option to disable the use of the IME.
Switching away from it effectively inverts the meanging of backspace
and delete (because our method is no longer called by the IME), so
we need to check for that and remap it. Ugh.
Ugh.
double clicks weren't registering correctly with the new selection
logic. Tell windows that we're doing all our own click counting
and simplify the logic.
We would leave a copy of the alt screen lines at the top of the
scrollback.
This commit ensures that those lines are marked dirty and that
the dirty bits are propagated to the client to invalidate its cache.
We were ignoring the title returned by list tabs and would subsequently
only pick up the title after a later update.
This passes the title in at construction.
The issue is that when we start the proxy mode up, we haven't set
up a frontend, and the ssh client wants to kick off a non-essential
task via the executor.
This commit starts up a null frontend in proxy mode so that that
machinery is present.
Then, because we don't register any tabs with the mux, we need to
adjust the behavior of the null frontend to not terminate when
the mux has no tabs.
It's a little gross.
This mostly works, but has a cache invalidation issue wrt.
passing invalidated rows from the server to the client...
sometimes.
However, scrollback is cached on demand and selection works.
Use StableRowIndex to implement tracking the viewport in the gui layer.
This resolves an issue where a busy terminal would continue to scroll
through the scrollback when you were paging backwards and look weird.
There's still some cleanup though:
- This breaks the selection ui
- the cursor position is wrong when scrolling back
- shift-pageup/pagedown need to be processed in the gui layer
Refs: https://github.com/wez/wezterm/issues/106
It's not really moved, but rather duplicated there; we still have
fallback logic in terminalstate.rs that processes the equivalent
action, but adding the logic to the gui layer means that we can
process it in terms of the Tab and Renderable interfaces.
refs: https://github.com/wez/wezterm/issues/106
When the scrollbar is disabled we still create a quad for it, and that
quad stretches to the window height. It is left with undefined texture
and could be either partially or totally transparent and lead to weird
effects like it appearing as though the titlebar was too wide for the
window, or by dimming the RHS of the window when toggling the scroll
bar on and off a few times.
This commit ensures that we set a well defined size and color when
the scroll bar is disabled, and seems to improve things for me.
Refs: https://github.com/wez/wezterm/issues/103
This commit adds the ability to change the relative or absolute
position of a tab within its containing window through the
use of a key assignment.
We include a default assignment of CTRL+SHIFT+PageUp for moving
left and CTRL+SHIFT+PageDown for moving right.
Closes: https://github.com/wez/wezterm/issues/84
If the cells refer to the same object instance (rather than equivalent
instances), then we treat them as part of the same highlight.
Refs: https://github.com/wez/wezterm/issues/94
Now that we can track focus changes, we can eliminate an annoyance:
clicking in the window to focus it would cause a click event to
be passed to the terminal and clear the selection.
This commit will swallow button events that occur within 200ms
of the focus being gained by the window.
The cursor should only start blinking when its been sitting in once place;
a moving cursor should always be visible. Rather than making the cursor blink
relative to the creation time of the window, track its position, and use the
last time it moved as the blinking timebase.
Fixes https://github.com/wez/wezterm/issues/83
This is a bit of a speculative change to see if it helps with
refs: https://github.com/wez/wezterm/issues/82
I have sometimes seen my scrollbar have a color that I didn't
choose and ISTR having some issues in the past when updating
the quads if I didn't set all of the fields of the vertex
to a better defined value.
A while back I moved the clipboard related processing mostly out
of the term processing code, but since I mostly use the keyboard
for pasting, I'd overlooked the middle mouse button paste flow.
This is problematic because fetching the clipboard requires a
degree of inter process communication and needs the event loop
to be pumped. Since the terminal callbacks are dispatched from
an event loop callback, attempting to block on the clipboard
future causes a deadlock.
This commit resolves that issue by anticipating that we'll need
the clipboard contents for the majority of middle mouse button
clicks and scheduling a fetch and cache ahead of passing that
event down to the terminal layer.
Why don't we simply use the same technique as the Paste key
assignment? If the terminal is currently using SGR mouse
tracking mode then the application on the other end of the
pty will want the raw button press. Our layering doesn't
allow for passing up the concept of whether a middle button
does paste or sends the raw event.
tricksy!
Refs: https://github.com/wez/wezterm/issues/87
@jsgf mentioned this to me, and since I've started running "proper"
wayland gnome-shell/mutter on my pixelbook go, I'm seeing it too.
The issue is that the alpha values are potentially <1.0 when they
are committed to the frame buffer and the mutter compositor is
faithfully blending wezterm with the window behind it, leading to
weird looking effects such as varying brightness of text, or for
cases where the window behind wezterm is bright white, a halo
effect that makes the text less sharp.
This commit addresses this issue by asking glium to ask opengl to
set the destination alpha to 1.0 in the final draw stage.
I noticed this for small enough sizes of Fira Code the border width
for the cursor would round to zero, and then looking at eg: `man ls`,
the underlined portions had no underline.
Ensure that the underline size is at least 1 pixel.