I introduced this issue with the recent rate limiting changes. If we
generated sufficient events to fill the pipe buffer and trigger an
EAGAIN on the write side of the pipe, we'd end up in a state where epoll
would continually wake us up to deal with it, but because we gated
reading from the pipe on having entries in the queue we could decide
that there was nothing to do and leave the pipe unread.
This commit adjusts things so that we always try to read some data from
it.
This is OK because we're using the pipe to knock the main thread out of
a sleep rather than as the definitive count of events.
I'm seeing occasional 100% cpu usage on my linux system and I'm
not sure if its just because I'm running a stale binary.
I added this (commented out in this commit, but live on my local
system) debug print to help understand it.
The `SpawnQueue::run_impl` would loop until it had exhausted
all queued items. This prevents returning to the main loop
and resulted in the UI hanging while eg: `yes` was running,
and could also block accepting keyboard input, which is
pretty bad.
In addition, the queue implementation could fill up a pipe
and block the write side while it held a lock, which in
turn would prevent the read side from making room for the
write to succeed!
This commit changes the behavior on linux to change the wakeup
behavior of the queue from having a 1:1 relationship between
enqueue:wakeup to n:m where n and m are both >= 1. This is
sufficient to wake a sleeping gui thread. The gui thread
can then pop and process a single item at a time, interleaved
with dispatching the gui events.
The result is a bit more responsive, however, there is no
backpressure from the gui to the read side, so if the read
side is eating 2MB/s of data and the GUI side is processing
less than this, then an interrupt signal may still take a
few seconds to take effect.
I have mixed feelings about adding backpressure, because
I'm not sure that it is worth actually rendering all of
the parsed output text when there is a lot of it.
I need to follow up and verify these changes on macOS
and Windows too.
Refs: https://github.com/wez/wezterm/issues/65
The compiler emitted `ud2` right around this code, effectively
breaking wezterm on startup.
In talking this through with @dtolnay, the definition of the
structs in the core_foundation crate makes it undefined behavior
to pass a null pointer to its fields, despite that being a valid
and documented way to use the struct.
This commit works around this by defining our own local versions
of the types and functions with the safe signature.
I'll follow up with the owners of the core_foundation crate
to submit an equivalent patch upstream.
we were running it immediately which is too soon: the empty
mux check would fire before some of the scheduled jobs would
have run and registered tabs/windows.
on mac the `Delete` key is really `Backspace` and should generate the
`BS` sequence.
`Fn-Delete` is equivalent to the `Delete` key on other keyboards and
should generate the `DEL` sequence.
BS maps to deleteBackward
DEL maps to deleteForward
heads up to @fanzeyi: this partially reverses 8c26b77057
The NSEvent::charactersIgnoringModifiers method ignores modifiers
except for shift, which is unfortunate because it produces eg: `!`
instead of `1`.
This commit adds a mapping from the underlying `keyCode` to the
corresponding letter position.
This diff adds some plumbing to track the `raw_key` in the KeyEvent;
this is the key prior to composing or eg: mapping dead keys.
With that field in place, we can teach the termwindow layer to attempt
looking up that key mapping from the user defined key bindings.
If we get a match then we can stop further key processing.
Rather than \n and bs these need to be \r and del respectively otherwise
we can end up triggering the wrong ctrl based key mappings in a remote
tmux session.
The front-end was treating both \r and \n as Enter and passing
that through to the terminal.
To verify behavior, pay attention to your termios configuration:
```
$ stty -icrnl
$ od -c
<CTRL-J><CTRL-D>
0000000 \n
0000001
$ od -c
<CTRL-M><CTRL-D><Enter>
0000000 \r \n
0000002
```
Closes https://github.com/wez/wezterm/issues/56
Similar to the windows IME support, the placement needs refinement, but
this is sufficient for pinyin input and insertion of emoji via the emoji
palette.
This isn't perfect, but is sufficient to allow using the IME to enter
eg: the heart emoji with cmd.exe.
We have some issues locating and rendering chinese characters that
make it difficult to prove/disprove that the IME is working 100%
because we just can't see the glyphs.
In addition, there appears to be something a bit wonky with conpty and
emoji. If we use eg: `wezterm ssh HOST` to log in to a remote system,
and use the IME to pick eg: the pig face emoji, this renders correctly.
In that scenario we don't use conpty at all.
The IME window is always placed in the top left corner of the window
at the moment, which isn't great, but is better than the system default
which is outside of the window. I need to introduce a way to set the
IME position in the window layer so that the front end gui can set it
to the current cursor position.
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
We handle this with a temporary buffer for the upload, which is
a little gross but avoids leaking that implementation aspect
out to the rest of the code.
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 uses the same plumbing as the software frontend, but tries
to enable opengl.
None of the opengl rendering is plumbed through here yet, so this
is currently functionally identical to the software renderer.
I'm not totally convinced that the refcounting is right
because I've not seen `dealloc` get triggered, but the
important thing is that closing the window does cause the
rust level objects to be dropped.