The KeyModifiers Display implementation incorrectly formatted modifier keys, causing the output to be concatenated without + separators. This is now corrected.
This adds a feature flag to allow opting out of the `derive_more`
dependency and derivations added in e063091. `derive_more` brings in
heavy proc macro dependencies and isn't crucial for the core functioning
of crossterm, so it should be possible for a crossterm dependent to opt
out of bringing in the transitive dependency.
* Add is_ and as_ methods to the event enums
Often application code only cares about a small subset of possible
events. These methods make it simpler to write code which checks whether
an event is a particular event type or converts events into the specific
type (returning an Option).
This can help simplify some nested match blocks. E.g.:
```rust
match event {
Event::Key(key) if key.kind == KeyEventKind::Press => { ... }
}
```
becomes:
```rust
if let Some(key) = event.as_key_press() { ... }
```
Similar flexible methods are aded across all the event enums:
- `Event::is_focus_gained()`
- `Event::is_focus_lost()`
- `Event::is_key()`
- `Event::is_mouse()`
- `Event::is_paste()`
- `Event::is_resize()`
- `Event::is_key_press()`
- `Event::as_key_press() -> Option<&KeyEvent>`
- `MouseEventKind::is_*()`
- `MouseButton::is_*()`
- `KeyEventKind::is_*()`
- `KeyEvent::is_press()`
- `KeyEvent::is_release()`
- `KeyEvent::is_repeat()`
- `KeyCode::is_*()`
- `KeyCode::is_function_key(n)`
- `KeyCode::is_char(c)`
- `KeyCode::as_char() -> Option<char>`
- `KeyCode::is_media_key(media)`
- `KeyCode::is_modifier(modifier)`
- add is_key_release() and is_key_repeat() checks
- add as_key_event()
- rename as_key_press() to as_key_press_event()
- add as_key_repeat_event()
- add as_key_release_event()
- add as_mouse_event()
- add as_paste_event()
- more tests
- update event-match and key-display examples
This is mostly a refactor of `supports_keyboard_enhancement` and its
helper functions. We previously discarded the response to the `CSI ? u`
query but this returns the currently active flags. This response value
can be useful for a client to know which flags to emit to disable the
keyboard enhancement protocol or to know which flags a terminal supports
(after the client has pushed flags).
* Autoformat Cargo.toml
Uses VSCode Even Better TOML plugin for opinionated formatting
* Document feature flags
Use the document-features crate to automatically add documentation about the features to the crate documentation at the crate level.
* Move InternalEventFilter into tests mod
This is only used in test code, so should be defined there
* Remove winapi feature flag checks
These checks were impossible to trigger as there is no separate feature
flag for winapi and crossterm_winapi. The windows feature flag
automatically enables these dependencies.
* Fix clippy lints for byte char slices
https://rust-lang.github.io/rust-clippy/master/index.html\#byte_char_slices
Fixes#882 by improving `style::available_color_count()`:
- Checks ANSI support on Windows.
- Uses the COLORTERM environment variable and falls back to the TERM environment variable.
- Supports "xterm-24bit" and "truecolor" values which return `u16::MAX`.
* use rustix instead of libc
* make rustix the default feature
* bump msrv to 1.63.0
* fix remaining libc issues
- use rustix version of sigwinch signal
- add a lifetime to FileDesc and replace FileDesc::Static to
FileDesc::Borrowed. This made it necessary to either add a lifetime to
the libc version of FileDesc or replace all the callers with multiple
paths (libc, rustix). Changing FileDesc was more straightforward.
There are no usages of FileDesc found in any repo on github, so this
change should be reasonably safe.
* add changelog entry for rustix / filedesc change
The `size` argument to `FileDesc::read()` is not checked against the
length of the buffer, so `libc::read()` could end up writing past the
buffer if we passed a size that's too large. However, we always pass
exactly the size of the buffer, so that doesn't happen. Let's just
remove the argument since it's not currently needed, thereby removing
the risk of bugs if the function is used incorrectly by future
callers.
This came up in review of `unsafe` Rust code at my company.
The SetColors command was executing SetForegroundColor and then
SetBackgroundColor, which writes 2 extra characters per cell compared to
writing both colors in one command. This resulted in about 15-25% more
FPS (19->24 fps) on a fullscreen (171x51) app that writes every cell
with a different foreground and background color, compared to separately
using the SetForegroundColor and SetBackgroundColor commands (iTerm2, M2
Macbook Pro).
The app is the colors_rgb example in Ratatui, which writes every cell
with a different foreground and background color in a loop. The
CrosstermBackend was changed to use SetColors instead of
SetForegroundColor and SetBackgroundColor.
Previously, the only ways to construct new `Attributes` values were
`Attributes::default()` or `Attributes::from(_)`, neither of can be
made `const fn` due to limitations of these standard library traits.
When double clicking on Windows, the crossterm_winapi emits the first
click with `EventFlags::PressOrRelease` and the second click with
`EventFlags::DoubleClick`. Previously this code explicitly ignored mouse
events with `EventFlags::DoubleClick` because "double click not
supported by unix terminals." This change captures the double click and
surfaces them as normal click events.
This change does two things:
- add the serial_test crate to run selected tests serial rather
than in parallel. This is done because they use global state
so running them in parallel leads to race conditions and flaky
results (sometimes they pass, sometimes they fail). Running
them serialy avoids this flakiness.
- create a screen buffer within the test. This avoids changing
the terminal (screen buffer) which is running the test. for
example, a test that changes the terminal size to 20 x 20 can
leave the developer running the test with a resized terminal.
Creating a separate screen buffer for the test avoids this.
It is possible to render images in terminals with protocols such as Sixel,
iTerm2's, or Kitty's. For a basic sixel or iTerm2 image printing, it is
sufficient to print some escape sequence with the data, e.g. cat image just
works, the image is displayed and enough lines are scrolled.
But for more sophisticated usage of images, such as TUIs, it is necessary to
know exactly what area that image would cover, in terms of columns/rows of
characters. Then it would be possible to e.g. resize the image to a size that
fits a col/row area precisely, not overdraw the image area, accommodate layouts,
etc.
Thus, provide the window size in pixel width/height, in addition to cols/rows.
The windows implementation always returns a "not implemented" error. The
windows API exposes a font-size, but in logical units, not pixels.
This could be further extended to expose either "logical window size",
or "pixel font size" and "logical font size".