Repository: alacritty/alacritty
File: alacritty/src/event.rs (Rust)

Code before:

            for event in event_queue.drain(..) {
                Processor::handle_event(event, &mut processor);
            }

            // Process DisplayUpdate events
            if !display_update_pending.is_empty() {
                self.display.handle_update(
                    &mut terminal,
                    &mut self.notifier,
                    &self.message_buffer,
                    &self.config,
                    display_update_pending,
                );
            }

            #[cfg(not(any(target_os = "macos", windows)))]
            {
                if event_loop.is_wayland()
                    && !self.display.window.should_draw.load(Ordering::Relaxed)
                {
                    return;
                }
            }

            if terminal.dirty {
                terminal.dirty = false;

                // Request immediate re-draw if visual bell animation is not finished yet
                if !terminal.visual_bell.completed() {
                    event_queue.push(GlutinEvent::UserEvent(Event::Wakeup));
                }

                // Redraw screen
                self.display.draw(
                    terminal,
                    &self.message_buffer,
                    &self.config,
                    &self.mouse,
                    self.modifiers,
                );
            }
        });

        // Write ref tests to disk
        self.write_ref_test_results(&terminal.lock());
    }

    /// Handle events from glutin
    ///
    /// Doesn't take self mutably due to borrow checking.

Review comment (performance):
What you seem to do in this PR is basically just ignore redraw opportunities until Wayland says it's ready, but I'm a bit concerned if that's the ideal approach.

At least in theory, that should open us for potential latency issues. If we miss the vsync just by a hair and go into the next event loop, every event we receive leaves us open to miss the vsync window. Which would mean that we'd probably miss the vsync and then latency is increased by one frame whenever this happens.

It's possible that this still improves things in general, but this seems like a bit of a design flaw? Have you considered this and potential solutions for it?

Code after:
            let mut processor = input::Processor::new(context, &self.display.highlighted_url);

            for event in self.event_queue.drain(..) {
                Processor::handle_event(event, &mut processor);
            }

            // Process DisplayUpdate events.
            if !display_update_pending.is_empty() {
                self.display.handle_update(
                    &mut terminal,
                    &mut self.notifier,
                    &self.message_buffer,
                    &self.config,
                    display_update_pending,
                );
            }

            #[cfg(not(any(target_os = "macos", windows)))]
            {
                // Skip rendering on Wayland until we get frame event from compositor.
                if event_loop.is_wayland()
                    && !self.display.window.should_draw.load(Ordering::Relaxed)
                {
                    return;
                }
            }

            if terminal.dirty {
                terminal.dirty = false;

                // Request immediate re-draw if visual bell animation is not finished yet.
                if !terminal.visual_bell.completed() {
                    self.event_queue.push(GlutinEvent::UserEvent(Event::Wakeup));
                }

                // Redraw screen.
                self.display.draw(
                    terminal,
                    &self.message_buffer,
                    &self.config,
                    &self.mouse,
                    self.modifiers,
                );
            }
        });

        // Write ref tests to disk
        self.write_ref_test_results(&terminal.lock());
    }

    /// Handle events from glutin