It is only used by applications that repaint on a resize event,
and us rewrapping makes it harder to have an ideal view afterwards.
This change makes us more consistent with VTE's behavior in this case.
This helps with https://github.com/wez/wezterm/issues/574 but doesn't
completely resolve it.
I didn't realize that xterm inherited some additional mappings from
the X server, so this commit should make us more comformant with
xterms behavior.
Verified this by comparing `showkey -a` under both xterm and wezterm:
```
wezterm -n --config disable_default_key_bindings=true --config debug_key_events=true start -- showkey -a
```
refs: https://github.com/wez/wezterm/issues/236
refs: https://github.com/wez/wezterm/discussions/556
I've been meaning to do this for a while; this commit moves
the escape sequence parsing into the thread that reads the
pty output which achieves two goals:
* Large escape sequences (eg: image protocols) that span multiple
4k buffers can be processed without ping-ponging between the
reader thread and the main gui thread
* That parsing can happen in the reader thread, keeping the gui
thread more responsive.
These changes free up the CPU during intensive operations such
as timg video playback.
This is a slight layering violation, in that this processing
really belongs to local pane (or any pane that embeds Terminal),
rather than generically at the Mux layer, but it's not any
worse a violation than `advance_bytes` already was.
refs: https://github.com/wez/wezterm/issues/537
The default downscaling provided by the GPU can result in noisy
artifacts on highly detailed images.
This commit employs a cubic Catmull-Rom sampling filter for the
case where we have a single frame image that is being reduced
in size. This isn't the highest quality filter but strikes
a good balance with speed vs appearance and is strictly better
than the GPU texture sampling options that I could try.
when the size is set to auto, we'd essentially take the image as-is
and overflow the terminal.
This commit makes auto scale down the image to fit the terminal dimensions
if it is too big.
Using a boxed slice means that we hold exactly the memory required
for the file data, rather than the next-power-of-two, which can
be wasteful when a large number of images are being sent to
the terminal.
This is a API breaking change for termwiz, so bump its version.
refs: #534
```
echo -e "\033]777;notify;This is the notification title;This is the notification text\a"
```
Now pops up a notification in a similar manner to OSC 9, except
that this form allows setting both the title and the body separately.
refs: https://github.com/wez/wezterm/issues/489
Pasting a lot of text could cause a deadlock between writing
to the input side of the pty and consuming the output side.
Making the writer/input side non-blocking resolves this.
* Add ClearBuffer action
Clears all lines, both visible and those scrolled off the top of the viewport, making the prompt line the new first line and resetting the scrollbar thumb to the full height of the window.
This is the behavior that Hyper / xterm has for clearing the terminal.
* Combine ClearBuffer into ClearScrollback as enum with associated erase mode
Makes it easier to manage the different options of clearing the terminal.
This appears to have been broken since the introduction of mouse
assignments :-/
This commit adds Pane::is_alt_screen_active so that the gui layer
can tell whether the alt screen is active, and allow passing down
the event.
refs: #429
TL;DR: on unix, or if bracketed paste is on, then we paste with
unix newlines. If on windows && !bracketed paste then with CRLF.
See explanation in the code for more context.
refs: https://github.com/wez/wezterm/issues/411
These aren't currently rendered, but the parser and model now support
recognizing expanded underline sequences:
```
CSI 24 m -> No underline
CSI 4 m -> Single underline
CSI 21 m -> Double underline
CSI 60 m -> Curly underline
CSI 61 m -> Dotted underline
CSI 62 m -> Dashed underline
CSI 58 ; 2 ; R ; G ; B m -> set underline color to specified true color RGB
CSI 58 ; 5 ; I m -> set underline color to palette index I (0-255)
CSI 59 -> restore underline color to default
```
The Curly, Dotted and Dashed CSI codes are a wezterm assignment in the
SGR space. This is by no means official; I just picked some numbers
that were not used based on the xterm ctrl sequences.
The color assignment codes 58 and 59 are prior art from Kitty.
refs: https://github.com/wez/wezterm/issues/415
Following on from 8649056ac0,
this commit should make it harder to make a similar mistake
in the future, by introducing a new TerminalSize struct for
that purpose.
Tidies up the plumbing around pixel dimensions so that ImageData
can be rendered via the termwiztermtab bits.
I put this together to play with sticking the wezterm logo in
the close confirmation dialogs. I didn't end up using that though,
but have preserved the commented code for use in future hacking.
Sometimes, I'd notice that imgcat would have a weird aspect.
I stumbled across the root cause while debugging something else:
the order of the pixel width and height was flipped here.
when running eg: `wezterm imgcat assets/icon/terminal.png --width 3`
we were scaling the height up by the ratio between the physical
width and the specified width, instead of down.
Revise logging so that we use info level for things that we want
to always log, and adjust the logger config to always log info
level messages.
That means shifting some warning level logs down lower to debug level so
that they aren't noisy.
closes: https://github.com/wez/wezterm/issues/388
I'm gradually improving snapshot testing macro devx in k9 and preparing
to ship v1. Before i do this i'm changing the inline snapshot macro to be
just `snapshot!()` that takes `Debug` trait an an arg and figures out
serialization of it.
This commit adjusts the default color palette to use the same color
cube calculation as xterm; it isn't the ideal color cube calculation
and results in slightly brighter colors.
This commit also memoizes the default palette calculation so that
it isn't recomputed each time a palette is created.
refs: https://github.com/wez/wezterm/issues/348
This is one of those massive time sinks that I almost regret...
As part of recent changes to dust-off the allsorts shaper, I noticed
that the harfbuzz shaper wasn't shaping as well as the allsorts one.
This commit:
* Adds emoji-test.txt, a text file you can `cat` to see how well
the emoji are shaped and rendered.
* Fixes (or at least, improves) the column width calculation for
combining sequences such as "deaf man" which was previously calculated
at 3 cells in width when it should have just been 2 cells wide, which
resulted in a weird "prismatic" effect during rendering where the
glyph would be rendered with an extra RHS portion of the glyph across
3 cells.
* Improved/simplified the clustering logic used to compute fallbacks.
Previously we could end up with some wonky/disjoint sequence of
undefined glyphs which wouldn't be successfully resolved from a
fallback font. We now make a better effort to consolidate runs of
undefined glyphs for fallback.
* For sequences such as "woman with veil: dark skin tone" that occupy a
single cell, the shaper may return 3 clusters with 3 glyphs in the
case that the font doesn't fully support this grapheme. At render
time we'd just take the last glyph from that sequence and render it,
resulting in eg: a female symbol in this particular case. It is
generally a bit more useful to show the first glyph in the sequence
(eg: person with veil) rather than the gender or skin tone, so the
renderer now checks for this kind of overlapping sequence and renders
only the first glyph from the sequence.
Adds some supporting methods for computing the `SemanticZone`s
in the display and a key assignment that allows scrolling the
viewport to jump to the next/prev Prompt zone.
This commit allows the terminal to tag cells with their semantic
type, as defined by OSC 133 escape sequences.
The gist of it is that each cell is now semantically one of:
* Output (eg: from the activity performed by the user. This is the
default)
* Input (eg: something that the user typed as input)
* Prompt (eg: "uninteresting" chrome/UI from the shell)
The semantic type is applied almost exactly like an SGR attribute,
except that resetting SGR doesn't clear the semantic type.
Tagging the cells in this way allows for smarter UX in the future;
for example, selecting the entire input or output from the last
command without fiddling around to avoid the prompt line(s),
or "paging up" to a prior prompt rather than page.
This doc covers those escapes as used in domterm, iterm2 and other
terminals:
https://gitlab.freedesktop.org/Per_Bothner/specifications/blob/master/proposals/semantic-prompts.md
This is an example of how to configure the shell to emit these
sequences; I'll add a proper little blob of shell specifically
for wezterm in a later commit:
https://github.com/PerBothner/DomTerm/blob/master/tools/shell-integration.zsh
I've had a FIXME in here for a while to check the positioning,
but never got around to it.
The onefetch folks have an app that does care about this,
so it's time to resolve it!
This commit adjusts the cursor position for the iterm case
(not the sixel case), and results in both:
running in xterm:
```
onefetch --image ~/Downloads/squirrel.png
```
running in wezterm:
```
TERM_PROGRAM=iTerm.app onefetch --image ~/Downloads/squirrel.png --image-backend=iterm
```
```
onefetch --image ~/Downloads/squirrel.png --image-backend=sixel
```
showing consistent positioning.
refs: https://github.com/wez/wezterm/issues/317
refs: https://github.com/o2sh/onefetch/pull/305
This reverts to the original resize behavior of padding out
the display when resizing taller, but only for Windows systems.
More explanation in the comments in the code.
refs: #138
This seems to make our resize behavior a bit nicer and more
consistent with eg: xterm.
Previously we'd consider the previously existing scrollback
as immutable and prefer to add excess blank lines of padding
when making the window taller.
In practice that meant that content would scroll back when
making the window taller, which is annoying.
This commit removes that constraint and instead will prefer
to maintain the cursor position relative to the top of the
viewport when the size changes.
refs: #138
This avoids having a green (by default) border around the cursor.
The dynamic color escape sequences have been updated to also
change the border color when the cursor background color is changed.
This commit introduces a small, bounded, LRU cache for recently
decoded images.
This allows the same image ID to be used in the cache that the
same image bits are repeatedly sent to the terminal.
This is advantageous because it reduces the amount of texture
space required by the gui layer.
There was an integer conversion happening when taking the
per-cell image texture coordinates and applying them to the
texture atlas image coordinates.
This commit replaces that math with floating point and corrects
the visual artifacts within squirrel.png.
refs: #292
When returning the title string we prefer to return the OSC 1 Icon
title (which is interpreted as "tab title" by some emulators and
shell toolkits) on the basis that it will have been setup for
display in a more limited width than the overall window title
and will thus likely be a better choice to show to the user.
If OSC 1 hasn't been set then we'll fall back to the OSC 2 window
title as before.
refs: https://github.com/wez/wezterm/issues/247
OSC 1 is defined as setting the "Icon Title".
OSC 2 is defined as setting the "Window Title".
OSC 0 sets both of those.
Some terminal emulators will display the Icon title as the tab
title.
Wezterm doesn't make a distinction between any of those things; the
title is applied (during escape sequence parsing) to the terminal
instance in isolation from any other terminals; when the GUI layer
renders the titlebar it is composed from the title in the active tab.
refs: https://github.com/wez/wezterm/issues/247
I'm wondering if the non-deterministic portion of
refs: https://github.com/wez/wezterm/issues/241
might be due to splitting of data across multiple write calls.
This commit adopts the use of BufWriter around the writer so that
we can buffer up and explicitly flush the responses to the terminal.
This commit teaches the terminal model about the overline attribute
and the SGR codes to enable/disable overline.
The render layer in the GUI doesn't yet understand this attribute.
We were unconditionally adding the encoded form of the modifier
mask (eg: appending `;1~` to the sequence) and not all apps know
how to interpret that.
refs: https://github.com/wez/wezterm/issues/227
While testing this with esctest, it was apparent that xterm deviates
from the DEC docs by allowing a minimum region size smaller than 2,
so adjust our restriction accordingly.
Now that we're reporting a higher level from DA1, apps are asking
more exotic codes. eg: vttest now asks about the conformance level,
but doesn't have a timeout on that request and hangs if we don't
respond.
This commit adds a bit of plumbing to make it easier to consume
and parse DCS sequences that are known to be short/short-lived,
and teaches the term layer to respond to a couple of possible
DECRQSS queries.
This is an xterm sequence that adjusts how the terminal
encodes keyboard output.
This commit teaches termwiz to parse and encode the sequence,
but doesn't teach the terminal emulator to do anything with it
at this time.
I'm adding this because vim sends these sequences and I wanted
to understand what they were for.
This commit adds support for left/right margins and has been
tested against esctest, with a final status of:
```
309 tests passed, 239 known bugs
```
"known bugs" also includes unimplemented features; we have a
similar degree as iTerm2.
As of this commit, we now report as a vt520ish machine to DA1.
I confess to not having read enough of the relevant docs
to know whether this is totally righteous.
With this commit, we now survive a reinstall or upgrade of the nvidia
drivers on my Windows sytem without crashing.
This commit allows notifying the application of the context loss
so the application can either try to reinit opengl or open a new
window as a replacement and init opengl there.
I've not had success at reinitializing opengl after a driver upgrade;
it seems to be persistently stuck in a state where it fails to allocate
a vertex buffer.
SO, the state we have now is that we try to reinit opengl on a new
window, and if that fails, leave it set to the software renderer.
This isn't a perfect UX, but it is better than terminating!
refs: https://github.com/wez/wezterm/issues/156
This was originally intended to be swept in and dealt with as part of
adopting CSI-u (refs: https://github.com/wez/wezterm/issues/63) but the
default shift-space mapping is super irritating in vim (refs:
https://github.com/wez/wezterm/issues/126) so it got partially walked
back, but as a consequence we accidentally dropped the modifiers from
those keys (refs: https://github.com/wez/wezterm/issues/213 refs:
https://github.com/wez/wezterm/issues/214).
This commit restores the modifiers for that case.
In addition, since we now have a way to plumb configuration directly
into the term crate, this adds a config option to enable CSI-u for those
that want to use it.
If the image is smaller than the cell size we could end up
rounding that dimension to zero and ultimately not render
the texture to the cell.
This commit adjusts the math to round up, which yields
better results for the test in refs: https://github.com/wez/wezterm/issues/211
I noticed that we still weren't quite right.
I think the net change is really just that we must force
the use of the CSI representation when using CTRL/SHIFT
modifiers.
refs: https://github.com/wez/wezterm/issues/203
We were treating DECCKM as the sole thing to enable application
cursor reporting, but looking closely at the docs, that mode only
takes effect when both DECANM (Vt52 emulation mode) AND DECKPAM
(application keypad mode) are both active.
neovim enables DECCKM and DECKPAM but not DECANM.
refs: https://github.com/wez/wezterm/issues/203
Bound to CMD-K and CTRL+SHIFT-K by default. This also functions
while the output is filling up (eg: `find /` and hit the key binding
to keep pruning the scrollback).
closes: https://github.com/wez/wezterm/issues/194
The click/movement related events are now "table driven" with
defaults contained in the InputMap object.
This gives the the potential to be configured from the config
file, but there is not glue in the config layer to enable
this yet.
This also does not include mouse wheel events.
neovim will try to force the window to resize after suspend/resume.
No other terminal allows this today, so rather than log it as an
unhandled event, explicitly ignore it.
This was a bit of a pain to track down because this behavior
isn't specified anywhere or called out explicitly.
The issue is that if you use a true color escape sequence such as
```bash
printf "\x1b[38;2;255;100;0mTRUECOLOR\n"
```
the active color would remain active when switching between the
primary and the alt screen until something (eg: `ls --color`) changed
it again.
I hadn't run into this because in my prompt, many many years ago, I had
it set to perform an SGR reset (`\x1b[0m`) as the first thing to ensure
that the shell is in a saner state.
For users that don't do this they end up with a weird looking color
bleed effect.
refs: https://github.com/wez/wezterm/issues/169
The predictive echo feels pretty reasonable, but if the connection
is having problems and we're showing the tardiness indicator, the
echo can give the impression that your input is going to get processed.
That may not be (usually is not!) the case.
This commit makes it a bit more visually distinctive that something
isn't right by greying out the color palette in that case.
refs: https://github.com/wez/wezterm/issues/127
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
The rewrap logic makes dealing with the cursor position a bit
more complex and we had a problem where resizing the window shorter
and then taller would allow the shell to cursor up into the scrollback
when displaying its prompt, and allow it to overwrite something that
was logically in the scrollback.
Avoids accidentally moving the y position of the cursor; previously
we would keep it pinned to the physical viewport relative coordinate,
but we didn't account for the implicit scroll that happens when
making the window smaller, which meant that the shell would re-render
its prompt with some artifacts during a resize.
Adds logic to resize handling that will consider the original logical
line length when the width of the terminal is changed.
The intent is that this will cause the text to be re-flowed as if it had
been printed into the terminal at the new width. Lines that were
wrapped due to hittin the margin will be un-wrapped and made into a
single logical line, and then split into chunks of the new width.
This can cause new lines to be generated in the scrollback when
making the terminal narrower. To avoid losing the top of the buffer
in that case, the rewrapping logic will prune blank lines off the
bottom.
This is a pretty simplistic brute force algorithm: each of the lines
will be visited and split, and for large scrollback buffers this could
be relatively costly with a busy live resize. We don't have much choice
in the current implementation.
refs: https://github.com/wez/wezterm/issues/14
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 :-/
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.
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
Previously we would try to pass through the Backspace and Delete
code points without interference, but that behavior wasn't quite
right.
With this commit our behavior is now:
- At the window layer: Classify a `Backspace` key press as logically
`BS` and a `Delete` key press as logically `DEL` unless the
`swap_backspace_and_delete` is true (macOS is true by default), in
which case `Backspace` is mapped to `Delete` and vice versa.
- At the terminal input layer: A `Backspace` input from the Window sends
the `DEL` sequence to the pty as that matches the default `VERASE` stty
configuration. A `Delete` input from the Window emits `\033[3~`,
which matches up to the `TERMINFO` for `xterm-256color` which we
claim to be compatible with, and is our default `$TERM` value.
The net result of this is that `Backspace` will now start to emit `^?`
which should match folks stty verase. Heads up to @fanzeyi!
I've tested this only on a linux system so far and will follow up on
a macOS system a little later today.
Refs: https://github.com/wez/wezterm/issues/88
Refs: https://github.com/wez/wezterm/issues/63
@fanzeyi ran into part of this issue when using multiplexing;
tabs from a remote domain always used the default color scheme
rather than the local configuration file color scheme.
Another variation on this is that making changes to the `[colors]`
section of the config only impacts tabs created after the change
was loaded, rather than updating the running tabs.
The root of this was that each terminal was keeping its own
copy of the palette that was updated at creation time to reflect
the config file. Relatively recently I introduced a new trait
to allow the terminal state to reach out and obtain configuration
from another source.
This commit connects the terminal configuration layer to the
configuration file directly.
The color schemes are now pulled directly from the configuration
file, except in the case where a dynamic color scheme has been
applied: using escape sequences to change the colors causes
the palette to be forked away from the configuration file.
There's still a low pri TODO around this space: if we're connected
to a remote domain and someone uses dynamic color scheme escapes,
should we reflect those locally? If so then we'll need to build
some plumbing to transport the palette to/from the remote system.
Closes: https://github.com/wez/wezterm/pull/60
This commit:
* Removes the ability to drag the window by the tab bar. I added
that in anticipation of needing to do custom title bar dragging
with Wayland, but it turned out both to be not required and not
possible to drag windows around in that way.
* Replaces the drag logic with dragging the scrollbar thumb
* Clicking above the scrollbar thumb is equivalent to page up
* Clicking below the scrollbar thumb is equivalent to page down
This commit adds a scrollbar that shows the scroll position but
that does not currently allow dragging to scroll.
The scrollbar occupies the right hand side window padding.
The width of the scrollbar can be set by explicitly configuring
`window_padding.right`. If the right padding is set to 0 (which
is its default value), and the scroll bar is enabled then the cell
width will be used for the right padding value instead.
The scrollbar can be enabled/disabled via this config setting:
```
enable_scroll_bar = true
```
Its color by this:
```
[colors]
scrollbar_thumb = "#444444"
```
(Note that color palette config will be reloaded when the config
file is changed, but you'll need to spawn a new tab/window to
see the effects because we cannot assume that a config reload should
always replace a potentially dynamically adjusted color scheme in
a tab).
This commit adds some plumbing for describing the cursor shape
(block, line, blinking etc) and visibility, and feeds that through
the mux and render layers.
The renderer now knows to omit the cursor when it is not visible.