Repository: alacritty/alacritty (language: rust)

Issue:
Vi Mode Freezes
Vi Mode freezes. I have to close the terminal instance and open a new one.

Two things worth noting in my current setup:
- The mentioned issue occurs intermittently
- The mentioned issue occurs only when alacrity is launched using the shortcut, never when launched from the command line
- I use https://github.com/jeffreytse/zsh-vi-mode, perhaps this is causing contention?

### System

OS: Linux
Version: alacritty 0.13.0-dev (33306142)
X11, ubuntu:GNOME, GNOME Shell


Discussion / hints:
If this happens specifically when running something inside the shell, what makes you think it's an Alacritty issue?

Does selection still work? If so, it's  not Alacritty.
Selection doesn't work. 
I'd assume you select with the mouse and not by other means and you're talking about vi mode from alacritty on `ctrl + shift + space` (by default).
If mouse selection doesn't work while holding shift, then Alacritty might actually be frozen. In that case a gdb backtrace would be helpful.
I'm launching `alacritty` via an i3 shortcut:

```
# start a terminal
bindsym $mod+t exec alacritty
```

Then inside the terminal I launch a command, for example `toggl now`, which writes to `stdout`.

I hit `CTRL + SHIFT + SPACE`, `hjkl` keys don't work and hitting the shortcut does not exit the VI mode - `alacritty` is stuck. I must kill the process, otherwise I am not able to use the terminal.

Mouse selection does not work either - text gets selected, but I can't seem to be able to copy it.

It does not happen each time, but quite often :/
if you run alacritty with `--print-events` does it stuck? 
Besides, obtaining a backtrace from freeze with gdb could help, though, you should build yourself with `cargo run --release` and attach to that process once it freezes.
Yes, it also does freeze with `--print-events`.

[print_events.zip](https://github.com/alacritty/alacritty/files/13601833/print_events.zip)

> Besides, obtaining a backtrace from freeze with gdb could help, though, you should build yourself with cargo run --release and attach to that process once it freezes.

What do you mean by:
> attach to that process

please?
Process with the INSTALL.md and build alacritty yourself. Then you run it with `cargo run --release` and try to repro your issue (cargo is rust's package manager, should come with rust package on your system).

Then once it freezes, you should run `gdb -p <PID>`(requires root), it'll attach to the process and you should obtain backtrace with `bt full`, there could be multiple threads, so you should do that for each thread and look around to figure out the place it blocks.

From your log it blocks inside the winit though, would be nice to know where.
Here is the `bt full` output:

[bt_full.zip](https://github.com/alacritty/alacritty/files/13601979/bt_full.zip)

Thanks for your cooperation.

NOTE: `alacritty` was built from `d83d5af2b571e5dc2c5c622277096a91c04ca7eb`
I would also like to add that this issue began to appear without me updating `alacritty` (meaning that the referenced hash was working fine before). It started appearing after I've updated my Ubuntu packages.
It just gets no events from X server it seems. Which video driver are you using? 
I am using `amdgpu`:
```
amdgpu-dkms-firmware/now 1:5.11.32.40501-1337797 all [installed,local]
amdgpu-dkms/now 1:5.11.32.40501-1337797 all [installed,local]
amdgpu-install/now 21.40.1.40501-1337797 all [installed,local]
libdrm-amdgpu1/jammy-updates,now 2.4.113-2~ubuntu0.22.04.1 amd64 [installed,automatic]
libdrm-amdgpu1/jammy-updates,now 2.4.113-2~ubuntu0.22.04.1 i386 [installed,automatic]
xserver-xorg-video-amdgpu/jammy-updates,now 22.0.0-1ubuntu0.2 amd64 [installed]
```
Just in case, when you have a freeze with `--print-events` typing, etc won't making new events appear in the log? It looks like x.org just ignores us or something, maybe related to driver doing weird things. If you run with `-o debug.prefer_egl=true` does it change anything?
`debug.prefer_egl` flag does not help with the issue, however, events keep appearing in the log even though `alacritty` is stuck:

```
[8.841345430s] [INFO ] [alacritty] winit event: NewEvents(WaitCancelled { start: Instant { tv_sec: 152222, tv_nsec: 116116207 }, requested_resume: None })
[8.855378879s] [INFO ] [alacritty] winit event: AboutToWait
[8.899044901s] [INFO ] [alacritty] winit event: NewEvents(WaitCancelled { start: Instant { tv_sec: 152226, tv_nsec: 216604926 }, requested_resume: None })
[8.899164722s] [INFO ] [alacritty] winit event: AboutToWait
[9.152222310s] [INFO ] [alacritty] winit event: NewEvents(WaitCancelled { start: Instant { tv_sec: 152226, tv_nsec: 260369667 }, requested_resume: None })
[9.152350292s] [INFO ] [alacritty] winit event: AboutToWait
[9.210126070s] [INFO ] [alacritty] winit event: NewEvents(WaitCancelled { start: Instant { tv_sec: 152226, tv_nsec: 513563268 }, requested_resume: None })
[9.210224359s] [INFO ] [alacritty] winit event: AboutToWait
[9.431258604s] [INFO ] [alacritty] winit event: NewEvents(WaitCancelled { start: Instant { tv_sec: 152226, tv_nsec: 571416583 }, requested_resume: None })
[9.431373045s] [INFO ] [alacritty] winit event: AboutToWait
[9.505198837s] [INFO ] [alacritty] winit event: NewEvents(WaitCancelled { start: Instant { tv_sec: 152226, tv_nsec: 792569060 }, requested_resume: None })
[9.505273664s] [INFO ] [alacritty] winit event: AboutToWait
[9.709262954s] [INFO ] [alacritty] winit event: NewEvents(WaitCancelled { start: Instant { tv_sec: 152226, tv_nsec: 866464998 }, requested_resume: None })
[9.709381435s] [INFO ] [alacritty] winit event: AboutToWait
[9.783386253s] [INFO ] [alacritty] winit event: NewEvents(WaitCancelled { start: Instant { tv_sec: 152227, tv_nsec: 70582850 }, requested_resume: None })
[9.783503514s] [INFO ] [alacritty] winit event: AboutToWait

```

Logs above were logged after visual mode was entered, terminal freezed, and I hit hjkl keys.

EDIT: updated attached log with hjkl presses
Oh, so it froze on `swap_buffers` and you trace was a bit wrong. Sounds like a driver bug? When it freezes after `RedrawRequested` could you provide a trace from all threads? 
I'll have a look at that (btw I've updated my trace to include only hjkl presses. Before it contained other events).
It looks like you just stop getting keyboard events? Is resize freezing? Like if you run something like `htop` inside of it and try to resize, does it update?
Yeah, I can confirm that running `htop` and resizing the window using `i3` works correctly, as `htop` redraws its TUI.

When I run `htop,` then enter visual mode and `alacritty` freezes, `htop` beneath still updates to reflect the current usage.
so it's not freezing, you just don't get key events. Could you change the hotkey to enter Vi mode to `Ctrl + Esc`? I think maybe you trigger some global hotkey and it breaks something, you don't actually have a freeze it seems.
Still occurs when the following shortcut is used:

```toml
[[keyboard.bindings]]
action = "ToggleViMode"
key = "Escape"
mods = "Shift"
```

I have also been able to reproduce it with
```toml
[[keyboard.bindings]]
action = "ToggleViMode"
key = "M"
mods = "Shift"
```

even though it does not occur that often.

🤔 

EDIT: updated the comment to note that it happens even when simple shortcuts such ass Shift+M are used.

Had the same problem too.

`CTRL+SHIFT+Space` (Vi Mode) occasionally prevents new events from entering.
To reproduce: Just enter and exit Vi Mode repeatedly. :smile: 

I don't know much about Alacritty internally, but taking a look, it seems that the origin of this "freeze" is when pass `false` to `set_ime_allowed` inside of `toggle_vi_mode` of `/alacritty/src/event.rs`.


But, when passing `true` (or not making this `set_ime_allowed` call)...
[/alacritty/src/event.rs](https://github.com/alacritty/alacritty/blob/c0c267d60e1b877d5c2c76893751d13547a233c4/alacritty/src/event.rs#L870)
```rs
// self.window().set_ime_allowed(was_in_vi_mode);
self.window().set_ime_allowed(true);
```
... everything works perfectly.
But, I really don't know the impacts of making this call with `true` hardcoded.

Interesting: Not calling `set_ime_allowed` also solves the problem.

Running on X11.

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8e37ade43cd..1d7f1a20b5a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,7 @@ The sections should follow the order `Packaging`, `Added`, `Changed`, `Fixed` an
 
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
-## 0.13.0-rc1
+## 0.13.0-rc2
 
 ### Packaging
 
diff --git a/Cargo.lock b/Cargo.lock
index f3b2d42e207..5129dffd9d1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -32,7 +32,7 @@ dependencies = [
 
 [[package]]
 name = "alacritty"
-version = "0.13.0-rc1"
+version = "0.13.0-rc2"
 dependencies = [
  "ahash",
  "alacritty_config",
@@ -69,7 +69,7 @@ dependencies = [
 
 [[package]]
 name = "alacritty_config"
-version = "0.1.2-rc1"
+version = "0.1.2-rc2"
 dependencies = [
  "log",
  "serde",
@@ -78,7 +78,7 @@ dependencies = [
 
 [[package]]
 name = "alacritty_config_derive"
-version = "0.2.2-rc1"
+version = "0.2.2-rc2"
 dependencies = [
  "alacritty_config",
  "log",
@@ -91,7 +91,7 @@ dependencies = [
 
 [[package]]
 name = "alacritty_terminal"
-version = "0.20.0-rc1"
+version = "0.20.0-rc2"
 dependencies = [
  "base64",
  "bitflags 2.4.1",
@@ -563,9 +563,9 @@ dependencies = [
 
 [[package]]
 name = "crossfont"
-version = "0.5.2"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3eb5a3822b594afc99b503cc1859b94686d3c3efdd60507a28587dab80ee1071"
+checksum = "80c5cf9f7d8f5478dbebc0e7a9ddcd350401e4cd9275d003481d8ec9613b7de1"
 dependencies = [
  "cocoa",
  "core-foundation",
@@ -649,7 +649,7 @@ version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
 dependencies = [
- "libloading 0.8.1",
+ "libloading",
 ]
 
 [[package]]
@@ -822,6 +822,16 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "gethostname"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
+dependencies = [
+ "libc",
+ "windows-targets 0.48.5",
+]
+
 [[package]]
 name = "getrandom"
 version = "0.2.11"
@@ -859,7 +869,7 @@ dependencies = [
  "glutin_glx_sys",
  "glutin_wgl_sys",
  "icrate",
- "libloading 0.8.1",
+ "libloading",
  "objc2",
  "once_cell",
  "raw-window-handle 0.5.2",
@@ -1049,16 +1059,6 @@ version = "0.2.150"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
 
-[[package]]
-name = "libloading"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
-dependencies = [
- "cfg-if",
- "winapi",
-]
-
 [[package]]
 name = "libloading"
 version = "0.8.1"
@@ -1587,11 +1587,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
 [[package]]
 name = "sctk-adwaita"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1729a30a469de249c6effc17ec8d039b0aa29b3af79b819b7f51cb6ab8046a90"
+checksum = "c6d3124356ea1b31eb808b07d45c31c2a8341c75789846781e4e965977e92b7b"
 dependencies = [
- "crossfont 0.5.2",
+ "crossfont 0.6.0",
  "log",
  "smithay-client-toolkit",
  "tiny-skia",
@@ -2356,9 +2356,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
 
 [[package]]
 name = "winit"
-version = "0.29.4"
+version = "0.29.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d25d662bb83b511acd839534bb2d88521b0bbc81440969cb077d23c4db9e62c7"
+checksum = "2cc935117ef48caed8822a893efef723e07ad868f668dfc4d244aea8873b07f9"
 dependencies = [
  "ahash",
  "android-activity",
@@ -2399,7 +2399,7 @@ dependencies = [
  "web-time",
  "windows-sys 0.48.0",
  "x11-dl",
- "x11rb",
+ "x11rb 0.13.0",
  "xkbcommon-dl",
 ]
 
@@ -2437,7 +2437,7 @@ version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b41aca1115b1f195f21c541c5efb423470848d48143127d0f07f8b90c27440df"
 dependencies = [
- "x11rb",
+ "x11rb 0.12.0",
 ]
 
 [[package]]
@@ -2457,15 +2457,26 @@ version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b1641b26d4dec61337c35a1b1aaf9e3cba8f46f0b43636c609ab0291a648040a"
 dependencies = [
- "as-raw-xcb-connection",
- "gethostname",
- "libc",
- "libloading 0.7.4",
+ "gethostname 0.3.0",
  "nix",
- "once_cell",
  "winapi",
  "winapi-wsapoll",
- "x11rb-protocol",
+ "x11rb-protocol 0.12.0",
+]
+
+[[package]]
+name = "x11rb"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a"
+dependencies = [
+ "as-raw-xcb-connection",
+ "gethostname 0.4.3",
+ "libc",
+ "libloading",
+ "once_cell",
+ "rustix",
+ "x11rb-protocol 0.13.0",
 ]
 
 [[package]]
@@ -2477,6 +2488,12 @@ dependencies = [
  "nix",
 ]
 
+[[package]]
+name = "x11rb-protocol"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34"
+
 [[package]]
 name = "xcursor"
 version = "0.3.4"
diff --git a/README.md b/README.md
index 88001d972a4..776f9900b5b 100644
--- a/README.md
+++ b/README.md
@@ -60,10 +60,10 @@ and all their settings were documented in the `alacritty.yml`. The example
 `alacritty.yml` file for each release can be found on [GitHub releases page](https://github.com/alacritty/alacritty/releases).**
 
 You can find the documentation for Alacritty's configuration in `man 5
-alacritty`, or by looking at [the scdoc file] if you do not have the manpages
+alacritty`, or by looking at [the website] if you do not have the manpages
 installed.
 
-[the scdoc file]: ./extra/man/alacritty.5.scd
+[the website]: https://alacritty.org/config-alacritty.html
 
 Alacritty doesn't create the config file for you, but it looks for one in the
 following locations:
diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml
index 045d7ae976b..b9675d9e4e0 100644
--- a/alacritty/Cargo.toml
+++ b/alacritty/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "alacritty"
-version = "0.13.0-rc1"
+version = "0.13.0-rc2"
 authors = ["Christian Duerr <contact@christianduerr.com>", "Joe Wilm <joe@jwilm.com>"]
 license = "Apache-2.0"
 description = "A fast, cross-platform, OpenGL terminal emulator"
@@ -11,15 +11,15 @@ rust-version = "1.70.0"
 
 [dependencies.alacritty_terminal]
 path = "../alacritty_terminal"
-version = "0.20.0-rc1"
+version = "0.20.0-rc2"
 
 [dependencies.alacritty_config_derive]
 path = "../alacritty_config_derive"
-version = "0.2.2-rc1"
+version = "0.2.2-rc2"
 
 [dependencies.alacritty_config]
 path = "../alacritty_config"
-version = "0.1.2-rc1"
+version = "0.1.2-rc2"
 
 [dependencies]
 ahash = { version = "0.8.6", features = ["no-rng"] }
@@ -40,7 +40,7 @@ serde_json = "1"
 serde_yaml = "0.9.25"
 toml = "0.8.2"
 unicode-width = "0.1"
-winit = { version = "0.29.4", default-features = false, features = ["rwh_05", "serde"] }
+winit = { version = "0.29.5", default-features = false, features = ["rwh_05", "serde"] }
 
 [build-dependencies]
 gl_generator = "0.14.0"
diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs
index 36f5f521eb9..b75676a33bf 100644
--- a/alacritty/src/config/bindings.rs
+++ b/alacritty/src/config/bindings.rs
@@ -545,12 +545,12 @@ pub fn default_key_bindings() -> Vec<KeyBinding> {
 fn common_keybindings() -> Vec<KeyBinding> {
     bindings!(
         KeyBinding;
-        "c",    ModifiersState::CONTROL | ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection;
         "v",    ModifiersState::CONTROL | ModifiersState::SHIFT, ~BindingMode::VI;                       Action::Paste;
         "f",    ModifiersState::CONTROL | ModifiersState::SHIFT, ~BindingMode::SEARCH;                   Action::SearchForward;
         "b",    ModifiersState::CONTROL | ModifiersState::SHIFT, ~BindingMode::SEARCH;                   Action::SearchBackward;
         Insert, ModifiersState::SHIFT,                           ~BindingMode::VI;                       Action::PasteSelection;
         "c",    ModifiersState::CONTROL | ModifiersState::SHIFT;                                         Action::Copy;
+        "c",    ModifiersState::CONTROL | ModifiersState::SHIFT, +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection;
         "0",    ModifiersState::CONTROL;                                                                 Action::ResetFontSize;
         "=",    ModifiersState::CONTROL;                                                                 Action::IncreaseFontSize;
         "+",    ModifiersState::CONTROL;                                                                 Action::IncreaseFontSize;
@@ -579,7 +579,6 @@ pub fn platform_key_bindings() -> Vec<KeyBinding> {
 pub fn platform_key_bindings() -> Vec<KeyBinding> {
     bindings!(
         KeyBinding;
-        "c",    ModifiersState::SUPER, +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection;
         Insert, ModifiersState::SHIFT, ~BindingMode::VI, ~BindingMode::SEARCH; Action::Esc("\x1b[2;2~".into());
         // Tabbing api.
         "t",    ModifiersState::SUPER;                                         Action::CreateNewTab;
@@ -606,6 +605,7 @@ pub fn platform_key_bindings() -> Vec<KeyBinding> {
         "n",    ModifiersState::SUPER;                                         Action::CreateNewWindow;
         "f",    ModifiersState::CONTROL | ModifiersState::SUPER;               Action::ToggleFullscreen;
         "c",    ModifiersState::SUPER;                                         Action::Copy;
+        "c",    ModifiersState::SUPER, +BindingMode::VI, ~BindingMode::SEARCH; Action::ClearSelection;
         "h",    ModifiersState::SUPER;                                         Action::Hide;
         "h",    ModifiersState::SUPER   | ModifiersState::ALT;                 Action::HideOtherApplications;
         "m",    ModifiersState::SUPER;                                         Action::Minimize;
diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs
index 14df091daae..f36d05e972d 100644
--- a/alacritty/src/display/window.rs
+++ b/alacritty/src/display/window.rs
@@ -410,7 +410,10 @@ impl Window {
     }
 
     pub fn set_ime_allowed(&self, allowed: bool) {
-        self.window.set_ime_allowed(allowed);
+        // Skip runtime IME manipulation on X11 since it breaks some IMEs.
+        if !self.is_x11 {
+            self.window.set_ime_allowed(allowed);
+        }
     }
 
     /// Adjust the IME editor position according to the new location of the cursor.
diff --git a/alacritty/src/input/keyboard.rs b/alacritty/src/input/keyboard.rs
index 9db67f4255c..160600a1b9d 100644
--- a/alacritty/src/input/keyboard.rs
+++ b/alacritty/src/input/keyboard.rs
@@ -78,13 +78,16 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
             return;
         }
 
+        // Mask `Alt` modifier from input when we won't send esc.
+        let mods = if self.alt_send_esc(&key, text) { mods } else { mods & !ModifiersState::ALT };
+
         let build_key_sequence = Self::should_build_sequence(&key, text, mode, mods);
 
         let bytes = if build_key_sequence {
             build_sequence(key, mods, mode)
         } else {
             let mut bytes = Vec::with_capacity(text.len() + 1);
-            if self.alt_send_esc() && text.len() == 1 {
+            if mods.alt_key() {
                 bytes.push(b'\x1b');
             }
 
@@ -99,6 +102,34 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
         }
     }
 
+    fn alt_send_esc(&mut self, key: &KeyEvent, text: &str) -> bool {
+        #[cfg(not(target_os = "macos"))]
+        let alt_send_esc = self.ctx.modifiers().state().alt_key();
+
+        #[cfg(target_os = "macos")]
+        let alt_send_esc = {
+            let option_as_alt = self.ctx.config().window.option_as_alt();
+            self.ctx.modifiers().state().alt_key()
+                && (option_as_alt == OptionAsAlt::Both
+                    || (option_as_alt == OptionAsAlt::OnlyLeft
+                        && self.ctx.modifiers().lalt_state() == ModifiersKeyState::Pressed)
+                    || (option_as_alt == OptionAsAlt::OnlyRight
+                        && self.ctx.modifiers().ralt_state() == ModifiersKeyState::Pressed))
+        };
+
+        match key.logical_key {
+            Key::Named(named) => {
+                if named.to_text().is_some() {
+                    alt_send_esc
+                } else {
+                    // Treat `Alt` as modifier for named keys without text, like ArrowUp.
+                    self.ctx.modifiers().state().alt_key()
+                }
+            },
+            _ => text.len() == 1 && alt_send_esc,
+        }
+    }
+
     /// Check whether we should try to build escape sequence for the [`KeyEvent`].
     fn should_build_sequence(
         key: &KeyEvent,
@@ -123,23 +154,6 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
         }
     }
 
-    /// Whether we should send `ESC` due to `Alt` being pressed.
-    #[cfg(not(target_os = "macos"))]
-    fn alt_send_esc(&mut self) -> bool {
-        self.ctx.modifiers().state().alt_key()
-    }
-
-    #[cfg(target_os = "macos")]
-    fn alt_send_esc(&mut self) -> bool {
-        let option_as_alt = self.ctx.config().window.option_as_alt();
-        self.ctx.modifiers().state().alt_key()
-            && (option_as_alt == OptionAsAlt::Both
-                || (option_as_alt == OptionAsAlt::OnlyLeft
-                    && self.ctx.modifiers().lalt_state() == ModifiersKeyState::Pressed)
-                || (option_as_alt == OptionAsAlt::OnlyRight
-                    && self.ctx.modifiers().ralt_state() == ModifiersKeyState::Pressed))
-    }
-
     /// Attempt to find a binding and execute its action.
     ///
     /// The provided mode, mods, and key must match what is allowed by a binding
@@ -190,6 +204,10 @@ impl<T: EventListener, A: ActionContext<T>> Processor<T, A> {
             return;
         }
 
+        // Mask `Alt` modifier from input when we won't send esc.
+        let text = key.text_with_all_modifiers().unwrap_or_default();
+        let mods = if self.alt_send_esc(&key, text) { mods } else { mods & !ModifiersState::ALT };
+
         let bytes: Cow<'static, [u8]> = match key.logical_key.as_ref() {
             // NOTE: Echo the key back on release to follow kitty/foot behavior. When
             // KEYBOARD_REPORT_ALL_KEYS_AS_ESC is used, we build proper escapes for
diff --git a/alacritty/windows/wix/alacritty.wxs b/alacritty/windows/wix/alacritty.wxs
index ed5f9489705..3979352c01c 100644
--- a/alacritty/windows/wix/alacritty.wxs
+++ b/alacritty/windows/wix/alacritty.wxs
@@ -1,5 +1,5 @@
 <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:ui="http://wixtoolset.org/schemas/v4/wxs/ui">
-   <Package Name="Alacritty" UpgradeCode="87c21c74-dbd5-4584-89d5-46d9cd0c40a7" Language="1033" Codepage="1252" Version="0.13.0-rc1" Manufacturer="Alacritty" InstallerVersion="200">
+   <Package Name="Alacritty" UpgradeCode="87c21c74-dbd5-4584-89d5-46d9cd0c40a7" Language="1033" Codepage="1252" Version="0.13.0-rc2" Manufacturer="Alacritty" InstallerVersion="200">
       <MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
       <Icon Id="AlacrittyIco" SourceFile=".\alacritty\windows\alacritty.ico" />
       <WixVariable Id="WixUILicenseRtf" Value=".\alacritty\windows\wix\license.rtf" />
diff --git a/alacritty_config/Cargo.toml b/alacritty_config/Cargo.toml
index f41e9206459..6fed7fa1bf9 100644
--- a/alacritty_config/Cargo.toml
+++ b/alacritty_config/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "alacritty_config"
-version = "0.1.2-rc1"
+version = "0.1.2-rc2"
 authors = ["Christian Duerr <contact@christianduerr.com>"]
 license = "MIT OR Apache-2.0"
 description = "Alacritty configuration abstractions"
diff --git a/alacritty_config_derive/Cargo.toml b/alacritty_config_derive/Cargo.toml
index 4359e36b59f..938fbc752e5 100644
--- a/alacritty_config_derive/Cargo.toml
+++ b/alacritty_config_derive/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "alacritty_config_derive"
-version = "0.2.2-rc1"
+version = "0.2.2-rc2"
 authors = ["Christian Duerr <contact@christianduerr.com>"]
 license = "MIT OR Apache-2.0"
 description = "Failure resistant deserialization derive"
@@ -18,7 +18,7 @@ syn = { version = "2.0.16", features = ["derive", "parsing", "proc-macro", "prin
 
 [dev-dependencies.alacritty_config]
 path = "../alacritty_config"
-version = "0.1.2-rc1"
+version = "0.1.2-rc2"
 
 [dev-dependencies]
 log = "0.4.11"
diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml
index e7c2704a2c3..f0911cd5faf 100644
--- a/alacritty_terminal/Cargo.toml
+++ b/alacritty_terminal/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "alacritty_terminal"
-version = "0.20.0-rc1"
+version = "0.20.0-rc2"
 authors = ["Christian Duerr <contact@christianduerr.com>", "Joe Wilm <joe@jwilm.com>"]
 license = "Apache-2.0"
 description = "Library for writing terminal emulators"
diff --git a/extra/osx/Alacritty.app/Contents/Info.plist b/extra/osx/Alacritty.app/Contents/Info.plist
index ab9cbcf83a2..52c5f137c2c 100644
--- a/extra/osx/Alacritty.app/Contents/Info.plist
+++ b/extra/osx/Alacritty.app/Contents/Info.plist
@@ -15,7 +15,7 @@
   <key>CFBundlePackageType</key>
   <string>APPL</string>
   <key>CFBundleShortVersionString</key>
-  <string>0.13.0-rc1</string>
+  <string>0.13.0-rc2</string>
   <key>CFBundleSupportedPlatforms</key>
   <array>
     <string>MacOSX</string>


Test patch: