aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/window_context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/window_context.rs')
-rw-r--r--alacritty/src/window_context.rs111
1 files changed, 50 insertions, 61 deletions
diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs
index 8935a9cc..0dd4b4bb 100644
--- a/alacritty/src/window_context.rs
+++ b/alacritty/src/window_context.rs
@@ -7,7 +7,6 @@ use std::mem;
#[cfg(not(windows))]
use std::os::unix::io::{AsRawFd, RawFd};
use std::rc::Rc;
-use std::sync::atomic::Ordering;
use std::sync::Arc;
use crossfont::Size;
@@ -17,12 +16,10 @@ use glutin::display::GetGlDisplay;
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
use glutin::platform::x11::X11GlConfigExt;
use log::{error, info};
-use raw_window_handle::HasRawDisplayHandle;
use serde_json as json;
-#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
-use wayland_client::EventQueue;
-use winit::event::{Event as WinitEvent, Modifiers, WindowEvent};
+use winit::event::{Event as WinitEvent, Modifiers};
use winit::event_loop::{EventLoopProxy, EventLoopWindowTarget};
+use winit::window::raw_window_handle::HasRawDisplayHandle;
use winit::window::WindowId;
use alacritty_config::SerdeReplace;
@@ -42,7 +39,7 @@ use crate::clipboard::Clipboard;
use crate::config::UiConfig;
use crate::display::window::Window;
use crate::display::Display;
-use crate::event::{ActionContext, Event, EventProxy, EventType, Mouse, SearchState, TouchPurpose};
+use crate::event::{ActionContext, Event, EventProxy, Mouse, SearchState, TouchPurpose};
use crate::logging::LOG_TARGET_IPC_CONFIG;
use crate::message_bar::MessageBuffer;
use crate::scheduler::Scheduler;
@@ -52,7 +49,8 @@ use crate::{input, renderer};
pub struct WindowContext {
pub message_buffer: MessageBuffer,
pub display: Display,
- event_queue: Vec<WinitEvent<'static, Event>>,
+ pub dirty: bool,
+ event_queue: Vec<WinitEvent<Event>>,
terminal: Arc<FairMutex<Term<EventProxy>>>,
cursor_blink_timed_out: bool,
modifiers: Modifiers,
@@ -61,7 +59,6 @@ pub struct WindowContext {
font_size: Size,
mouse: Mouse,
touch: TouchPurpose,
- dirty: bool,
occluded: bool,
preserve_title: bool,
#[cfg(not(windows))]
@@ -79,8 +76,6 @@ impl WindowContext {
proxy: EventLoopProxy<Event>,
config: Rc<UiConfig>,
options: WindowOptions,
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- wayland_event_queue: Option<&EventQueue>,
) -> Result<Self, Box<dyn Error>> {
let raw_display_handle = event_loop.raw_display_handle();
@@ -106,8 +101,6 @@ impl WindowContext {
event_loop,
&config,
&identity,
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- wayland_event_queue,
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
gl_config.x11_visual(),
)?;
@@ -126,8 +119,6 @@ impl WindowContext {
proxy: EventLoopProxy<Event>,
config: Rc<UiConfig>,
options: WindowOptions,
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- wayland_event_queue: Option<&EventQueue>,
) -> Result<Self, Box<dyn Error>> {
// Get any window and take its GL config and display to build a new context.
let (gl_display, gl_config) = {
@@ -142,8 +133,6 @@ impl WindowContext {
event_loop,
&config,
&identity,
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- wayland_event_queue,
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
gl_config.x11_visual(),
)?;
@@ -377,6 +366,35 @@ impl WindowContext {
self.update_config(config);
}
+ /// Draw the window.
+ pub fn draw(&mut self, scheduler: &mut Scheduler) {
+ self.display.window.requested_redraw = false;
+
+ if self.occluded {
+ return;
+ }
+
+ self.dirty = false;
+
+ // Force the display to process any pending display update.
+ self.display.process_renderer_update();
+
+ // Request immediate re-draw if visual bell animation is not finished yet.
+ if !self.display.visual_bell.completed() {
+ self.display.window.request_redraw();
+ }
+
+ // Redraw the window.
+ let terminal = self.terminal.lock();
+ self.display.draw(
+ terminal,
+ scheduler,
+ &self.message_buffer,
+ &self.config,
+ &self.search_state,
+ );
+ }
+
/// Process events for this terminal window.
pub fn handle_event(
&mut self,
@@ -384,30 +402,19 @@ impl WindowContext {
event_proxy: &EventLoopProxy<Event>,
clipboard: &mut Clipboard,
scheduler: &mut Scheduler,
- event: WinitEvent<'_, Event>,
+ event: WinitEvent<Event>,
) {
match event {
- // Skip further event handling with no staged updates.
- WinitEvent::RedrawEventsCleared if self.event_queue.is_empty() && !self.dirty => {
- return;
- },
- // Continue to process all pending events.
- WinitEvent::RedrawEventsCleared => (),
- // Remap scale_factor change event to remove the lifetime.
- WinitEvent::WindowEvent {
- event: WindowEvent::ScaleFactorChanged { scale_factor, new_inner_size },
- window_id,
- } => {
- let size = (new_inner_size.width, new_inner_size.height);
- let event =
- Event::new(EventType::ScaleFactorChanged(scale_factor, size), window_id);
- self.event_queue.push(event.into());
- return;
+ WinitEvent::AboutToWait | WinitEvent::RedrawRequested(_) => {
+ // Skip further event handling with no staged updates.
+ if self.event_queue.is_empty() {
+ return;
+ }
+
+ // Continue to process all pending events.
},
- // Transmute to extend lifetime, which exists only for `ScaleFactorChanged` event.
- // Since we remap that event to remove the lifetime, this is safe.
- event => unsafe {
- self.event_queue.push(mem::transmute(event));
+ event => {
+ self.event_queue.push(event);
return;
},
}
@@ -470,30 +477,12 @@ impl WindowContext {
self.mouse.hint_highlight_dirty = false;
}
- // Skip rendering until we get a new frame.
- if !self.display.window.has_frame.load(Ordering::Relaxed) {
- return;
- }
-
- if self.dirty && !self.occluded {
- // Force the display to process any pending display update.
- self.display.process_renderer_update();
-
- self.dirty = false;
-
- // Request immediate re-draw if visual bell animation is not finished yet.
- if !self.display.visual_bell.completed() {
- self.display.window.request_redraw();
- }
-
- // Redraw the window.
- self.display.draw(
- terminal,
- scheduler,
- &self.message_buffer,
- &self.config,
- &self.search_state,
- );
+ // Request a redraw.
+ //
+ // Even though redraw requests are squashed in winit, we try not to
+ // request more if we haven't received a new frame request yet.
+ if self.dirty && !self.occluded && !matches!(event, WinitEvent::RedrawRequested(_)) {
+ self.display.window.request_redraw();
}
}