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 is a pretty gross and coarse "smash them together" commit.
There is some redundancy between the two connection and window
impls that I'd like to unify later, but this lets us build with
support for both systems for now.
The future won't ever complete if you don't connect the waker
from the context!
Prove this out by making the windowops functions async and
verifying them in the async example
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.