Glutin sends both a received character and the key pressed event when a
key is pressed. Because delete and backspace are mapped in reverse by
terminal standards, we ignore the received character 0x07 and 0x7f
values. However, this breaks Control-H since this normally sends 0x07 as
well. The fix here adds handling for Control-H through the input
tracking system.
Cells with no content that had the cell::INVERSE flag were not being
rendered. This was noticeable in `man` where the bar at the bottom would
have gaps in it.
Previous version of serde no longer worked; cargo packages were updated
as a result. `Zero` and `One` traits were deprecated. Use of those was
removed. The `Step` trait gained a lot more methods, and the index::$ty
implementations were updated.
A few instances of println! are replaced with debug_println! as to be
excluded in release builds. Unimplemented methods are now tagged with
[unimlemented] in the format string.
The default characters sent for this were incorrect. Delete now sends
xterm-compatible escapes (dch1, kdch1), and Backspace sends the delete
code 0x7f.
debug_println! statements are compiled out in release builds. This
allows us to see what the terminal is sending in debug builds while
having good perf in release builds.
The extra render thread just resulted in extra complexity. There were
also some startup bugs not resolved with that architecture. Finally,
there was no noticeable performance boost from having the additional
thread.
The grid and term modules already rely on the index types, and ansi is
about to be updated with strongly typed APIs. Since Cursor, Line, and
Column are fundamental to the code in several modules, namespacing them
under one of them seems less correct than a module that stands by
itself.
The original idea with ansi::Handler and the ansi::Parser was that the
Parser being generic over Handler could result in code equivalent to a
hand written parser + handler from a method dispatch perspective. Proper
inlining is required to achieve that, so this marks the ansi::Handler
methods appropriately.
The Grid no longer knows about a `Cell` and is instead generic. The
`Cell` type is coupled to the `term` module already, and it's been moved
there to reflect the strong relationship.
Grid APIs previously accepted `usize` for many arguments. If the caller
intended rows to be columns, but the function accepted them in reverse,
there would be no compiler error. Now there is, and this should prevent
such bugs from entering the code.
The Grid internals grew significantly to accomodate the strongly typed
APIs. There is now a `grid::index` module which defines Cursor, Line,
and Column. The Grid APIs are all based on these types now. Indexing for
Ranges proved to be somewhat awkward. A new range had to be constructed
in the implementation. If the optimizer can't figure out what's going on
in that case, the ranges may not be a zero-cost abstraction.
It's a generic impl of `input::Notify` for `Write` types; as such, it
seems completely reasonable to include in the input module. Moving it
also serves to declutter main.
Fixes last known issue with htop. I think this implementation might not
be correct, but I don't yet understand the difference between erasing
and deleting (I imagine it's the difference between graphics state vs
grid state). Will probably need to circle back here.
Adds all range indexing operations to rows. Some were needed for the
erase_chars impl, and the rest are there for fully generality.
The pty read thread now runs the parser and directly updates the
terminal in the same thread. This obviates the need for a channel which
sends every char read from the pty; this is a huge performance boon.
Synchronization between the updater and the renderer is now achieved
with a PriorityMutex. Previously, an atomic bool was (poorly) used to
request the lock on terminal. The PriorityMutex is dead simple to use,
and it _Just Works_.
The upcoming Utf8Chars iterator was vendored from a libstd PR. The
iterator works on BufRead types which is critical for improving
performance. A small modification was made where the number of unused
bytes is included with Utf8CharsError::IncompleteUtf8.
The pty reader thread was updated to use this new type. Next steps will
be moving the parsing there and either sending parse results in batches
or updating the terminal directly from that thread.
Configuration may now be specified in either `$HOME/.alacritty.yml` or
`$HOME/.config/alacritty.yml`. See `alacritty.yml` in the repository
root for an example.
When a configuration file cannot be located, a default configuration is
used.
The resize callback is the only way to perform live resizing on macOS. A
callback is provided, and a static variable is used to provide a Sender
to that function so that resize events may be processed in the usual
way.
The resize event is received from glutin on the update thread, but the
renderer needs to be informed as well for updating the viewport and
projection matrix. This is achieved with an mpsc::channel.
To support resizing, the grid now offers methods for growing and
shrinking, and there are several implementations available for
clear_region based on different Range* types.
Core resize logic is all in Term::resize. It attempts to keep as much
context as possible when shinking the window. When growing, it's
basically just adding rows.
This moves more logic out of main() and prepares the Term type to handle
resizing. By providing all size data to Term, it is now possible to
implement a resize function there which handles all resizing logic save
for the rendering subsystem.
The input/pty processing loop previously consumed input on a channel and
hit the rendering when the queue became empty. This had a couple of
problems
1. It was possible to be overwhelmed with input and not give the
renderer an opportunity to update the screen. This gave the
appearance of locking up.
2. Multiple frames could be rendered for a single vblank (redundant
work)
3. Open loop rendering would inevitably have buffer swapping out of sync
with vblanks and visual tearing would occur.
This commit enables vsync on the glutin window. The rendering was all
moved onto a separate thread from input/pty processing to support vsync.
However, the rendering thread must be 100% synchronized with the updater
thread. There's now a Mutex on the Term, and an atomic bool to ask the
input/pty processing to yield to the renderer.
One aspect of this feature that hasn't been worked out is how to limit
the frame rate. Currently, it just free runs at the screen refresh rate.
The initial attempt here included the input/pty processor holding a lock
while waiting for input. This *almost* worked, but there was a (not
uncommon) edge case where the terminal state was "dirty" but the
renderer was not ready to draw.
Instead of blocking on the refresh issue, it's being punted to after an
MVP is released. The overhead of drawing at 60Hz was profiled to be ~5%
CPU usage, and this is deemed acceptable for an MVP.
This adds a bunch of APIs to CGContext (and supporting types) that
aren't actually necessary to turn on subpixel rendering. The key for
subpixel rendering were the options passed to bitmap_context_create().
Specifically, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host
are necessary to enable it.
There's a number of keys/combinations that should emit escape sequences
to the PTY when triggered. This commit adds a framework to support that.
The input::Processor is a type which tracks state of modifier keys. When
special keys (like arrow, function) are detected, the processor pulls up
a list of candidate escapes to send, and picks the first one based on
terminal mode and active modifier keys. The input::Processor is generic
over the thing receiving the escape sequences, the input::Notify type.
Included is a wrapper for `&mut io::Write` which implements
input::Notify and is currently used to connect the processor to the PTY
stream.
This added handling of the APP_CURSOR mode which changes affects input
processing.
The sense of set_mode and unset_mode was inverted. The
TextCursor/ShowCursor mode depended on the incorrect behavior, and that
was fixed as well. TextCursor was renamed to ShowCursor to be perfectly
clear on the intent.
Alacritty now runs on macOS using CoreText for font rendering.
The font rendering subsystems were moved into a separate crate called
`font`. The font crate provides a unified (albeit limited) API which
wraps CoreText on macOS and FreeType/FontConfig on other platforms. The
unified API differed slightly from what the original Rasterizer for
freetype implemented, and it was updated accordingly.
The cell separation properties (sep_x and sep_y) are now premultiplied
into the cell width and height. They were previously passed through as
uniforms to the shaders; removing them prevents a lot of redundant work.
`libc` has some differences between Linux and macOS. `__errno_location`
is not available on macOS, and the `errno` crate was brought in to
provide a cross-platform API for dealing with errno.
Differences in `openpty` were handled by implementing a macOS specific
version. It would be worth investigating a way to unify the
implementations at some point.
A type mismatch with TIOCSCTTY was resolved with a cast.
Differences in libc::passwd struct fields were resolved by using
std::mem::uninitialized instead of zeroing the struct ourselves. This
has the benefit of being much cleaner.
The thread setup had to be changed to support both macOS and Linux.
macOS requires that events from the window be handled on the main
thread. Failure to do so will prevent the glutin window from even
showing up! For this reason, the renderer and parser were moved to their
own thread, and the input is received on the main thread. This is
essentially reverse the setup prior to this commit. Renderer
initialization (and thus font cache initialization) had to be moved to
the rendering thread as well since there's no way to make_context(null)
with glx on Linux. Trying to just call make_context a second time on the
rendering thread had resulted in a panic!.
Of note are the `ansi` and `grid` modules becoming public. There are
several bits of unused code in each of these. In the case of `grid`, the
unused parts are generally useful, like some indexing implementations.
In ansi, there are pieces that will be used once the parser is more
complete. In any case, these modules are fairly generic and mostly
usable outside of Alacritty.
Unused cargo packages were also removed.