Tag CursorPosition with the seqno of the cursor move instead.
This should avoid over-invalidating lines and the selection
if it was just the cursor that moved.
Terminal now maintains a sequence number that increments
for each Action that is applied to it.
Changes to lines are tagged with the current sequence number.
This makes it a bit easier to reason about when an individual
line has changed relative to some point in "time"; the consumer
of the terminal can sample the current sequence number and then
can later determine which lines have changed since that point
in time.
refs: https://github.com/wez/wezterm/issues/867
We were previously only remembering the most recently pressed
button, but that's a lossy thing to do.
This commit remembers the button presses so that we can correctly
report all press/release events.
refs: #973
An implementation detail in wezterm is that it doesn't model
image placements as a separate entity; they are all bound to
the image cells in the terminal model.
The semantics of the kitty image protocol are that placements
are "permanent" wrt. overwriting a cell with text, except for
the explicit EraseInLine/EraseInDisplay sequences that are
used for clearing.
This commit takes a pass at implementing that semantic in
the wezterm data model.
refs: #986
We were actually moving it during placement, and then restoring
the original placement. That could potentially lead to the
screen being scrolled, so we want to avoid that.
refs: #986
As of this commit, `kitty +kitten icat ~/Downloads/fast-parallax.gif`
(wherein the icat kitten decodes the gif into frames and sends them
to the terminal to animate) behaves equivalently in wezterm and kitty.
(There appears to be an issue with the background color/deltas in
the icat kitten in kitty-0.21.1-1.fc33.x86_64 which I have installed,
so both wezterm and kitty have a funky black background for this
particular gif).
refs: #986
Since we can now mutate individual frames, we need to avoid
falsely caching across a change; switch from using (image_id, frame_idx)
to frame_hash.
refs: #986
Adds a use_image feature to termwiz that enables an optional
dep on the image crate. This in turn allows decoding of animation
formats (gif, apng) from file data, but more crucially, allows
modeling animation frames at the termwiz layer, which is a pre-req
for enabling kitty img protocol animation support.
refs: #986
This adds a simple garbage collection scheme; when adding an image,
check to see if we're over budget on the total amount of RAM used
by the image data.
If we are, remove unreferenced images (images that are not placed)
until we're below the budget.
refs: #986
I noticed when running the notcurses demo that we're spending a
decent amount of time decoding png data whenever we need to
re-do the texture atlas.
Let's avoid that by allowing for ImageData at the termwiz layer
to represent both the image file format and decoded rgba8 data.
This commit is a bit muddy and also includes some stuff to try
to delete placements from the model. It's not perfect by any
means--more expensive than I want, and there's something funky
that causes a large number of images to build up during some
phases of the demo.
refs: #986
This isn't complete; many of the placement options are not supported,
and the status reporting is missing in a number of cases, including
querying/probing, and shared memory objects are not supported yet.
However, this commit is sufficient to allow the kitty-png.py script
(that was copied from
https://sw.kovidgoyal.net/kitty/graphics-protocol/#a-minimal-example)
to render a PNG in the terminal.
This implementation routes the basic image display via the same
code that we use for iterm2 and sixel protocols, but it isn't
sufficient to support the rest of the placement options allowed
by the spec.
Notably, we'll need to add the concept of image placements to
the data model maintained by the terminal state and find a way
to efficiently manage placements both by id and by a viewport
range.
The renderer will need to manage separate quads for placements
and order them by z-index, and adjust the render phases so that
images can appear in the correct plane.
refs: #986
This teaches termwiz to recognize and encode the APC
sequences used by the kitty image protocol.
This doesn't include support for animations, just the
transmit, placement and delete requests.
refs: #986
This commit hooks up DECRQM so that we can report that we implement
synchronized updates, and then refines the code that manages sending
data to the terminal model; the first cut at synchronized updates
was a bit simplistic, and now we make a point of "flushing" pending
actions when we start a sync point, and again as soon as we release
the sync point.
This smooths out the jaggies around the orca that I mentioned in
dcbbda7702
and while testing this, I realized that recent parser changes had
mangled processing bundled dec private mode sequences where multiple
modes were specified in the same overall escape sequence. I've
added the missing unit test case for this and made that work again.
refs: https://github.com/wez/wezterm/issues/955
refs: https://github.com/wez/wezterm/issues/882
This implementation doesn't include a timeout, but should be
recoverable via a SoftReset.
There's no query response either: I think I'm missing DECRQM
entirely at the moment.
refs: https://github.com/wez/wezterm/issues/882
This commit introduces a 4th draw pass for rendering sixel and
iterm images that are attached to cells.
Previously, a cell could container either text or an image from
the perspective of the renderer. If it had an image then the glyph
bitmap would be ignored in favor of the image.
However, that causes sixel behavior to diverge from other terminals
(https://github.com/wez/wezterm/issues/942) so we need to be render
both of these.
The simplest way to achieve this is to add a distinct set of texture
coordinates for the attached image and then add a draw pass to alpha
blend it over the glyph content.
The sixel/iterm image processing stage is also adjusted to preserve
the prior cell information and "simply" attach the image info to
the cell. Previously, the cell would be replaced with a blank cell
with the image attached.
The result of this is that the notcurses-demo intro section can
now render the orca "enveloped in the soft glow of glyphs" rather
than caged in a black box.
Note that there are some cases where the render turns blocky but
I suspect that that is due to some other misunderstanding between
wezterm and notcurses and that we'll root cause it as a follow up.
This commit causes a window-config-reloaded event to trigger
when the appearance (dark/light mode) is changed on macos.
It also arranges to propagate the window level config to newly
spawned panes and tabs, created both via the gui and via the
CLI/mux interface.
refs: https://github.com/wez/wezterm/issues/894
refs: https://github.com/wez/wezterm/issues/806
This allows window-level config overrides to apply
to panes contained within the window.
For instance, this allows setting a window-level
color scheme.
Add the third device attributes (DA3) query+reply,
eliminating "unknown/unspecified CSI" error. Like
XTerm, simply reply with zeroes as opposed to site
codes or unique IDs.
https://vt100.net/docs/vt510-rm/DA3.html
This adjusts the cursor position after emitting a sixel.
@dankamongmen: I don't have much of a sixel test suite to speak
of (cat snake.six :-p); I'd appreciate it if you could run
notcurses against this and confirm that it is doing something
sane!
At the very least, we shouldn't be warning about the unhandled
mode any more!
refs: https://github.com/wez/wezterm/issues/863
refs: https://github.com/dankamongmen/notcurses/issues/1743
neovim doesn't like it when multiple drag events with the same
coordinates are received; it appears to treat that as though
the mouse button was double clicked.
This commit teaches the mouse report encoding to suppress multiple
drag events in succession that have the same payload.
refs: https://github.com/wez/wezterm/discussions/823
Use a similar hsv transformation to that used to dim inactive panes
instead of the treatment that made the black look grey, which felt
like a flash instead of a dim.
Two issues here:
* The hue angles need adjusting to work with the palette library
* The resultant RGB color had the wrong gamma level, resulting in
an overly bright image.
refs: https://github.com/wez/wezterm/issues/775
There were two bugs here:
* \u8D (the utf8 encoded representation of 0x8d, aka: RI) was not
recognized as a C1 code and was instead passed through as printable
text.
* The \u8D is a zero-width sequence which means that a subsequent
set_cell call on the new empty-by-default line wouldn't allocate
any cells in the line array, and the assigment to the line would
panic.
This commit avoids the panic for the second case, and then fixes up
the vtparser to correctly recognize the sequence as a C1 control.
refs: https://github.com/wez/wezterm/issues/768
When the title, icon, OSC 7 and SetUserVars sequences are processed,
notify the embedding application.
The gui layer uses this to trigger a titlebar update.
refs: #647
This has the effect of reducing the memory and scroll cost
for lines that are shorter than the physical width of the
terminal matrix.
refs: https://github.com/wez/wezterm/issues/740
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