This was honestly a PITA because of its complexity. The `clipboard`
crate (now dropped as a dep) didn't support wayland, so I looked at
the `smithay-clipboard` crate, which caused all of my input to become
laggy just by enabling it--even without actually copying or pasting!
Both of those crates try to hide a number of details of working with
the clipboard from the embedding application, but that works against
our window crate implementation, so I decided to integrate it into
the window crate using Futures so that the underlying IPC timing and
potential for the peer to flake out are not completely hidden.
This first commit removes the SystemClipboard type from wezterm
and instead bridges the window crate clipboard to the term crate
Clipboard concept.
The clipboard must be associated with a window in order to function
at all on Wayland, to we place the get/set operations in WindowOps.
This commit effectively breaks the keyboard on the other window
environments; will fix those up in follow on commits.
This isn't complete but begins the process of extracting
the embedding application configuration into a trait provided
by the application rather than passing the values in at
construction.
This allows the application to change configuration at
runtime.
The first option to handle this is the scrollback size.
I keep holding shift while pressing space and seeing stuff get
undone in vim. Super annoying. I didn't see a good way to
teach applications about this via terminfo, so this is off
by default for now.
refs: https://github.com/wez/wezterm/issues/63
Alt-Backspace is the GNUReadline-style shortcut for kill-previous-word.
In wezterm, this currently doesn't work, since this gets trapped by the generic `Backspace` match case.
This diff adds a more specific case for when Backspace is combined with Alt to produce the correct sequence.
This is definitely a hack and there should probably be a more general solution for GNUReadline combinations, but this solves the immediate problem.
I noticed while scrolling `emoji-test.txt` that some of the combined
emoji sequences rendered very poorly. This was due to the unicode
width being reported as up to 4 in some cases.
Digging into it, I discovered that the unicode width crate uses a
standard calculation that doesn't take emoji combination sequences
into account (see https://github.com/unicode-rs/unicode-width/issues/4).
This commit takes a dep on the xi-unicode crate as a lightweight way
to gain access to emoji tables and test whether a given grapheme is
part of a combining sequence of emoji.
This was an unintended casualty of the recent gui layer refactoring.
If you press `option-h` macos generates DOT ABOVE which we pass through
to the terminal key processing layer. It sees that ALT is set and emits
an escape byte (to indicate that ALT is set) followed by the UTF-8
sequence for DOT ABOVE. `zsh` gets confused and treats this as
`<ffffffff>` in its line editor.
This diff restricts the emission of the ESC leader to ascii alphanumeric
characters only.
There needs to be a followup diff to allow configuring how we process
these ALT modified characters on macOS because our current behavior
breaks eg: `ALT-1` which is a hotkey that I use in tmux. Granted that
I don't need tmux with end to end wezterm, but it does prevent me from
using that if I wanted to.
I thought that I'd broken something with the DEL processing in vim with
the new frontend but it turned out that the other frontend was emitting
BS always and that I'd actuall unbroken passing DEL through and that
other layers were translating DEL into an application cursor mode output
for DEL that emits a totally different sequence.
This diff preserves DEL and disables that other sequence.
Will follow up with some explicit configuration to control this
behavior, but in the short term, the default behavior should be much
closer to what people actually want and expect!
refs: https://github.com/wez/wezterm/issues/52
This is still a bit rough because the terminal parser doesn't
understand the pixel sizes, so it relies on the hard coded
cell dimensions being accurate.
This enables using large OSC buffers in a form that we can publish
to crates.io without blocking on an external crate. Large OSC
buffers are important both for some tunnelling use cases and for
eg: iTerm2 image protocol handling.
Repeated moves or wheel events are collapsed so that we don't clog up
the queue. The queue size doesn't matter as much as the latency of
processing a large queue. For fast or repeated moves the queue can grow
rather quickly, and with what is currently ~25-50 ms round trip per
entry for a remote session, that is a poor UX.
These codes are used to change the color palette, but if the `?`
string is used in place of a color spec, then we must respond with
the current color value string for that palette entry, so lets
implement that!
This one has been bugging me for a while; we now know when we've
wrapped a line and can join it without a line break when double-clicking
to select a word.
This commit introduces a wrapped attribute to help record this
information, which could potentially help with when it comes
to looking at nicer resize behavior in refs: https://github.com/wez/wezterm/issues/14
Application cursor keys are a separate set of encodings that applications can
ask the terminal to produce for cursor keys.
Unfortunately, PuTTY generates these for shift-modified cursor keys. If an
application is to distinguish between normal and shift-modified cursor keys
on PuTTY then it will need to be able to distinguish between normal and
application cursor keys.
Add new `KeyCode` variants for application cursor keys.
A big paste could saturate the input/output of the pty and
lead to an effective deadlock; the application wants to send
output to us but we are busy trying to write the paste to it.
Break up large pastes into chunks and send them piece by piece.
This does mean that a large bracketed paste is not an atomic
unit any longer, but it seems to work out ok when pasting into
vim.
We were incorrectly treating it as \r\n, but it should only have
been moving vertically.
This fixes the positioning of the cursor when using eg:
`dialog --yesno hello 0 0`
Without this change, the cursor would be way over to the left.
With this change, the cursor is correctly positioned inside
the "YES" box.
In the case where the screen was enlarged, we don't eagerly resize
the line vectors.
If a subsequent erase display occurred, we'd only erase to the old
size of the lines, rather than the new size, which could result
in a black square in the upper right corner of the display.
Repro scenario is:
* resize window larger than initial height
* `dialog --yesno hello 0 0`
The dialog background should fill the display.
This was responsible for eg: dialog rendering a black (or whatever
the default background color was) strip behind the text in an
invocation like:
`dialog --yesno hello 0 0`
Rather than render a default cell, render a blank cell using the
current pen.
This was an off-by-one issue when using scroll margins just shorter
than the screen and when scrollback is enabled.
Added a unit test to verify the behavior.
I've had mixed results with esctest; the IRM and cursor save/restore
tests fail for me in terminal.app, iterm2 and xterm, and fail in the
same way on wezterm, so I'm not sure if I'm not running those tests
correctly. However, they did encourage the discovery of some other
real issues in the wezterm emulation.
These were showing up as unrecognized sequences on my mac, and I
wondered what they were. We now parse them and do nothing with
them, other than print out the parsed form :)
I wanted to see how much work remains to enable iterm2 image
display; one of the blockers was a limit in the size of the
buffer in the vte crate, which has been removed in my fork
of vte.
As part of testing our ability to absorb that data, I found
a couple of issues with applying the image cells to the display,
so this commit also takes care of that.
We still don't have code to connect the cell image data to the
opengl render layer.
My original idea was that I would centralize of the key binding
logic in the terminalstate, but this places a bit of a burden on
the TerminalHost portion of the interface.
In particular: when running a multiplexer server we may be headless
or have multiple heads. In that scenario we want the terminal
to be backed by a virtualized screen, and that means removing
the direct callback to access eg: the host clipboard. This
diff is the first of a couple that have the goal of removing
those sorts of dependencies.
This is an unfortunately large diff that:
* Separates Tab ownership from TerminalWindow
* Introduces a Mux container for all of the tabs in the application,
across all windows
* Moves ownership of processing pty responses to the mux; it sets
up and has logic to process data for the ptys and apply to the
tabs
I've moved the logic for processing new tab and new window hotkeys
to the TerminalWindow's themselves as we need some context to
associate the tab with the right window and to create a new window.
I think that will simplify and allow unifying more code.
previously this just used unicode word segmentation rules, but that
is insufficient for most technical users.
Change this to look for sequences that are non-whitespace and not
enclosed by bracket/quote delimiters. This allows selecting file names
with a double click, which was my main issue.
There isn't really any reliable consistency in the virtual_keycodes
being set for simple keys or shifted keys, so we need to go all in
and add our own scancode processing as a fall back.
This makes it even harder to process unicode input, particularly
because we have no idea whether a ReceivedCharacter event will
follow.
We don't yet have any code to render them, and the vte parser seems
to truncate incoming image sequences ~1kb in size, so more work is
needed to make this useful.
We were deleting the current row and below rather than the rows below.
This was the cause of lines going blank during `apt upgrade` runs;
the line just above the bottom would get erased instead of scrolling
up.
I found this by running the termwiz widget demo; the top line was being
erased by mistake.
The issue here was that we were not updating the tab stops when making
the window larger. This had the side effect of causing the cursor to
move in unexpected ways when tabbing to the right.
Fixes: https://github.com/wez/wezterm/issues/13
When using the default monospace font on ubuntu (typicaly
DejaVuSansMono), the texture atlas would end up the bottom left pixel
being a shade of gray.
Since we were using (0,0) coords for whitespace cells, all whitespace
cells would appear shaded gray.
We now reserve a black pixel in the bottom left of the underline texture
and switch to that for whitespace instead.
I added Debug support to the ColorPalette while tracking this down,
and figured that I might as well keep it.
If the user enlarges the terminal we can have regions of the vertex
buffer that have colors that default to alpha channel 0. This is
normally fine but breaks rendering of the cursor and the selection;
those attributes are out of band from the normal cell attributes,
especially for whitespace cells, so we need to handle those in
the degenerate case at the end of a line render.
Refactor the code that computes the cursor and selection colors
so that we can call it and use it in both places.
We were marking the entire scrollback history as dirty on each line
scroll. This was from the early days and isn't needed any more.
This brings the runtime of:
```
$ find /usr > /tmp/usr-files.txt
$ time cat /tmp/usr-files.txt
```
down from ~2.5s to ~1.2s.
Also avoid a redundant line_mut() call in set_cell().
Adds some plumbing to track the current mouse position and
extract the hyperlink from the cell that is being hovered over.
We render those cells with underline, possibly in a different color.
We don't yet do anything on click.
This felt a bit repeatey and it pre-dated the TerminalHost trait.
I'd like to remove it completely but there are some frustrating and
fiddly lifetime concerns with mutable TerminalHost reference so I'm
hiding it from the public interface and bridging it the answerback
stream into the host at the bottom of the advance_bytes method for
now.