Add support for urgency hints CSI

Teach Alacritty to stop setting the window as urgent upon a bell by
emulating xterm's 'bellIsUrgent' resource and relevant CSI. When this
resource is enabled (with 'CSI ? 1042 h'), a bell event causes the
window to be marked as urgent. When the resource is disabled (with 'CSI
? 1042 l'), the window is not marked urgent in the event of a bell.

There are two wrinkles worth noting here:

  - The 'TermMode::URGENCY_HINTS' does _not_ affect the terminal's
    configured bell command, since we only want to control whether or
    not the window is marked as urgent, not anything else.

  - In xterm, the 'bellIsUrgent' resource is _disabled_ by default.
    Since bouncing the dock icon has been the default in Alacritty on
    macOS thus far, do not make an effort to change that in this patch.

This allows users to emit "\e[?1042l" and disable bouncing the dock
icon.

Fixes #2950.
This commit is contained in:
Taylor Blau 2020-10-10 17:24:40 -04:00 committed by GitHub
parent 860adde457
commit 56e0f5bb05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 16 additions and 3 deletions

View File

@ -25,6 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Escape sequences to report text area size in pixels (`CSI 14 t`) and in characters (`CSI 18 t`)
- Support for single line terminals dimensions
- Right clicking on Wayland's client side decorations will show application menu
- Escape sequences to enable and disable window urgency hints (`CSI ? 1042 h`, `CSI ? 1042 l`)
### Changed

View File

@ -943,7 +943,9 @@ impl<N: Notify + OnResize> Processor<N> {
TerminalEvent::Bell => {
let bell_command = processor.ctx.config.bell().command.as_ref();
let _ = bell_command.map(|cmd| start_daemon(cmd.program(), cmd.args()));
processor.ctx.window.set_urgent(!processor.ctx.terminal.is_focused);
if processor.ctx.terminal.mode().contains(TermMode::URGENCY_HINTS) {
processor.ctx.window.set_urgent(!processor.ctx.terminal.is_focused);
}
},
TerminalEvent::ClipboardStore(clipboard_type, content) => {
processor.ctx.clipboard.store(clipboard_type, content);

View File

@ -402,6 +402,8 @@ pub enum Mode {
SgrMouse = 1006,
/// ?1007
AlternateScroll = 1007,
/// ?1042
UrgencyHints = 1042,
/// ?1049
SwapScreenAndSetRestoreCursor = 1049,
/// ?2004
@ -434,6 +436,7 @@ impl Mode {
1005 => Mode::Utf8Mouse,
1006 => Mode::SgrMouse,
1007 => Mode::AlternateScroll,
1042 => Mode::UrgencyHints,
1049 => Mode::SwapScreenAndSetRestoreCursor,
2004 => Mode::BracketedPaste,
_ => {

View File

@ -480,13 +480,17 @@ pub mod mode {
const UTF8_MOUSE = 0b0000_0100_0000_0000_0000;
const ALTERNATE_SCROLL = 0b0000_1000_0000_0000_0000;
const VI = 0b0001_0000_0000_0000_0000;
const URGENCY_HINTS = 0b0010_0000_0000_0000_0000;
const ANY = std::u32::MAX;
}
}
impl Default for TermMode {
fn default() -> TermMode {
TermMode::SHOW_CURSOR | TermMode::LINE_WRAP | TermMode::ALTERNATE_SCROLL
TermMode::SHOW_CURSOR
| TermMode::LINE_WRAP
| TermMode::ALTERNATE_SCROLL
| TermMode::URGENCY_HINTS
}
}
}
@ -2132,6 +2136,7 @@ impl<T: EventListener> Handler for Term<T> {
fn set_mode(&mut self, mode: ansi::Mode) {
trace!("Setting mode: {:?}", mode);
match mode {
ansi::Mode::UrgencyHints => self.mode.insert(TermMode::URGENCY_HINTS),
ansi::Mode::SwapScreenAndSetRestoreCursor => {
if !self.mode.contains(TermMode::ALT_SCREEN) {
self.swap_alt();
@ -2182,6 +2187,7 @@ impl<T: EventListener> Handler for Term<T> {
fn unset_mode(&mut self, mode: ansi::Mode) {
trace!("Unsetting mode: {:?}", mode);
match mode {
ansi::Mode::UrgencyHints => self.mode.remove(TermMode::URGENCY_HINTS),
ansi::Mode::SwapScreenAndSetRestoreCursor => {
if self.mode.contains(TermMode::ALT_SCREEN) {
self.swap_alt();

View File

@ -56,7 +56,8 @@ brevity.
| `CSI h` | PARTIAL | Only modes `4` and `20` are supported |
| `CSI ? h` | PARTIAL | Supported modes: |
| | | `1`, `3`, `6`, `7`, `12`, `25`, `1000`, `1002` |
| | | `1004`, `1005`, `1006`, `1007`, `1049`, `2004` |
| | | `1004`, `1005`, `1006`, `1007`, `1042`, `1049` |
| | | `2004` |
| `CSI I` | IMPLEMENTED | |
| `CSI J` | IMPLEMENTED | |
| `CSI K` | IMPLEMENTED | |