Repository: alacritty/alacritty (language: rust)

Issue:
Visual bell animation on Mac is really long
On macOS, the visual bell animation lasts for around 1 second regardless of what non-zero duration is in the config file. This seems to be the case since commit 80d4daccc307622f8e604af4f36ac89ecccf5db7.

Before that commit, visual bell animation worked fine.


Discussion / hints:
What if you have something like `yes` running?
Sorry, I don't understand the question.

Here are 2 videos of the visual bell in action. The first video is commit 6071a7bf35cfd99be8ba70f479f188b7370cda6f which shows the bell working properly. The down arrow was pressed 3 times triggering 3 brief red flashes:

https://github.com/alacritty/alacritty/assets/118104/4e87f92f-c9d2-46c9-8fc9-2be7693037f7

The second video is the next commit, 80d4daccc307622f8e604af4f36ac89ecccf5db7, which shows the bug. The down arrow was again pressed 3 times triggering 3 long flashes:

https://github.com/alacritty/alacritty/assets/118104/2f092c0d-6391-4a63-974e-69582b840320

The visual bell is configured as:
```
[bell]
color = "#ff1c1c"
duration = 100
```

Now run yes while/immediately after flashing the bell.
I ran yes immediately after pressing the down arrow to trigger the bell. The yes command ran immediately, interrupting the prolonged red flash animation.
Don't just type it manually. Does the animation play properly then?
Again, I don't follow. How do I run yes if I don't first type it manually? What I had done was type "yes" at the prompt, then hit down-arrow to trigger the prolonged flash, then immediately hit return to execute yes. The yes command interrupted the prolonged flash.
I tested this yesterday on macOS 14.0 and also noticed an issue, though it wasn't just hanging around for a second. The visual bell seemed to freeze on screen until another event caused a `RedrawRequested`.

Also noticed that the animation may be a bit choppier than it could be.

Fix patch:
diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs
index f5128e752ea..7dc6375eade 100644
--- a/alacritty/src/display/window.rs
+++ b/alacritty/src/display/window.rs
@@ -235,9 +235,7 @@ impl Window {
 
     #[inline]
     pub fn request_redraw(&mut self) {
-        // No need to request a frame when we don't have one. The next `Frame` event will check the
-        // `dirty` flag on the display and submit a redraw request.
-        if self.has_frame && !self.requested_redraw {
+        if !self.requested_redraw {
             self.requested_redraw = true;
             self.window.request_redraw();
         }
diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs
index 329e7ef804c..c5b00085e83 100644
--- a/alacritty/src/window_context.rs
+++ b/alacritty/src/window_context.rs
@@ -380,7 +380,13 @@ impl WindowContext {
 
         // Request immediate re-draw if visual bell animation is not finished yet.
         if !self.display.visual_bell.completed() {
-            self.display.window.request_redraw();
+            // We can get an OS redraw which bypasses alacritty's frame throttling, thus
+            // marking the window as dirty when we don't have frame yet.
+            if self.display.window.has_frame {
+                self.display.window.request_redraw();
+            } else {
+                self.dirty = true;
+            }
         }
 
         // Redraw the window.
@@ -481,6 +487,7 @@ impl WindowContext {
         // Don't call `request_redraw` when event is `RedrawRequested` since the `dirty` flag
         // represents the current frame, but redraw is for the next frame.
         if self.dirty
+            && self.display.window.has_frame
             && !self.occluded
             && !matches!(event, WinitEvent::WindowEvent { event: WindowEvent::RedrawRequested, .. })
         {


Test patch: