aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/display
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/display')
-rw-r--r--alacritty/src/display/mod.rs48
-rw-r--r--alacritty/src/display/window.rs93
2 files changed, 53 insertions, 88 deletions
diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs
index c992e9cc..4037cd2e 100644
--- a/alacritty/src/display/mod.rs
+++ b/alacritty/src/display/mod.rs
@@ -6,7 +6,6 @@ use std::fmt::{self, Formatter};
use std::mem::{self, ManuallyDrop};
use std::num::NonZeroU32;
use std::ops::{Deref, DerefMut};
-use std::sync::atomic::Ordering;
use std::time::{Duration, Instant};
use glutin::context::{NotCurrentContext, PossiblyCurrentContext};
@@ -15,10 +14,10 @@ use glutin::surface::{Rect as DamageRect, Surface, SwapInterval, WindowSurface};
use log::{debug, info};
use parking_lot::MutexGuard;
-use raw_window_handle::RawWindowHandle;
use serde::{Deserialize, Serialize};
use winit::dpi::PhysicalSize;
use winit::keyboard::ModifiersState;
+use winit::window::raw_window_handle::RawWindowHandle;
use winit::window::CursorIcon;
use crossfont::{self, Rasterize, Rasterizer};
@@ -347,7 +346,7 @@ pub struct Display {
/// Hint highlighted by the vi mode cursor.
pub vi_highlighted_hint: Option<HintMatch>,
- pub is_wayland: bool,
+ pub raw_window_handle: RawWindowHandle,
/// UI cursor visibility for blinking.
pub cursor_hidden: bool,
@@ -394,7 +393,7 @@ impl Display {
gl_context: NotCurrentContext,
config: &UiConfig,
) -> Result<Display, Error> {
- let is_wayland = matches!(window.raw_window_handle(), RawWindowHandle::Wayland(_));
+ let raw_window_handle = window.raw_window_handle();
let scale_factor = window.scale_factor as f32;
let rasterizer = Rasterizer::new(scale_factor)?;
@@ -408,7 +407,7 @@ impl Display {
// Resize the window to account for the user configured size.
if let Some(dimensions) = config.window.dimensions() {
let size = window_size(config, dimensions, cell_width, cell_height, scale_factor);
- window.set_inner_size(size);
+ window.request_inner_size(size);
}
// Create the GL surface to draw into.
@@ -459,9 +458,10 @@ impl Display {
#[cfg(target_os = "macos")]
window.set_has_shadow(config.window_opacity() >= 1.0);
+ let is_wayland = matches!(raw_window_handle, RawWindowHandle::Wayland(_));
+
// On Wayland we can safely ignore this call, since the window isn't visible until you
// actually draw something into it and commit those changes.
- #[cfg(not(any(target_os = "macos", windows)))]
if !is_wayland {
surface.swap_buffers(&context).expect("failed to swap buffers.");
renderer.finish();
@@ -479,7 +479,6 @@ impl Display {
match config.window.startup_mode {
#[cfg(target_os = "macos")]
StartupMode::SimpleFullscreen => window.set_simple_fullscreen(true),
- #[cfg(not(any(target_os = "macos", windows)))]
StartupMode::Maximized if !is_wayland => window.set_maximized(true),
_ => (),
}
@@ -511,7 +510,6 @@ impl Display {
ime: Ime::new(),
highlighted_hint: None,
vi_highlighted_hint: None,
- is_wayland,
cursor_hidden: false,
frame_timer: FrameTimer::new(),
visual_bell: VisualBell::from(&config.bell),
@@ -520,6 +518,7 @@ impl Display {
pending_renderer_update: Default::default(),
debug_damage,
damage_rects,
+ raw_window_handle,
next_frame_damage_rects,
hint_mouse_point: None,
})
@@ -552,7 +551,8 @@ impl Display {
let res = match (self.surface.deref(), &self.context.get()) {
#[cfg(not(any(target_os = "macos", windows)))]
(Surface::Egl(surface), PossiblyCurrentContext::Egl(context))
- if self.is_wayland && !self.debug_damage =>
+ if matches!(self.raw_window_handle, RawWindowHandle::Wayland(_))
+ && !self.debug_damage =>
{
surface.swap_buffers_with_damage(context, &self.damage_rects)
},
@@ -972,17 +972,13 @@ impl Display {
self.draw_hyperlink_preview(config, cursor_point, display_offset);
}
- // Frame event should be requested before swapping buffers on Wayland, since it requires
- // surface `commit`, which is done by swap buffers under the hood.
- if self.is_wayland {
- self.request_frame(scheduler);
- }
+ // Notify winit that we're about to present.
+ self.window.pre_present_notify();
// Clearing debug highlights from the previous frame requires full redraw.
self.swap_buffers();
- #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
- if !self.is_wayland {
+ if matches!(self.raw_window_handle, RawWindowHandle::Xcb(_) | RawWindowHandle::Xlib(_)) {
// On X11 `swap_buffers` does not block for vsync. However the next OpenGl command
// will block to synchronize (this is `glClear` in Alacritty), which causes a
// permanent one frame delay.
@@ -991,7 +987,10 @@ impl Display {
// XXX: Request the new frame after swapping buffers, so the
// time to finish OpenGL operations is accounted for in the timeout.
- if !self.is_wayland {
+ if matches!(
+ self.raw_window_handle,
+ RawWindowHandle::AppKit(_) | RawWindowHandle::Xlib(_) | RawWindowHandle::Xcb(_)
+ ) {
self.request_frame(scheduler);
}
@@ -1364,7 +1363,7 @@ impl Display {
/// Returns `true` if damage information should be collected, `false` otherwise.
#[inline]
fn collect_damage(&self) -> bool {
- self.is_wayland || self.debug_damage
+ matches!(self.raw_window_handle, RawWindowHandle::Wayland(_)) || self.debug_damage
}
/// Highlight damaged rects.
@@ -1385,18 +1384,7 @@ impl Display {
/// Requst a new frame for a window on Wayland.
fn request_frame(&mut self, scheduler: &mut Scheduler) {
// Mark that we've used a frame.
- self.window.has_frame.store(false, Ordering::Relaxed);
-
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- if let Some(surface) = self.window.wayland_surface() {
- let has_frame = self.window.has_frame.clone();
- // Request a new frame.
- surface.frame().quick_assign(move |_, _, _| {
- has_frame.store(true, Ordering::Relaxed);
- });
-
- return;
- }
+ self.window.has_frame = false;
// Get the display vblank interval.
let monitor_vblank_interval = 1_000_000.
diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs
index 0cf95f7f..942b28ee 100644
--- a/alacritty/src/display/window.rs
+++ b/alacritty/src/display/window.rs
@@ -1,11 +1,3 @@
-#[rustfmt::skip]
-#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
-use {
- wayland_client::protocol::wl_surface::WlSurface,
- wayland_client::{Attached, EventQueue, Proxy},
- winit::platform::wayland::{EventLoopWindowTargetExtWayland, WindowExtWayland},
-};
-
#[cfg(all(not(feature = "x11"), not(any(target_os = "macos", windows))))]
use winit::platform::wayland::WindowBuilderExtWayland;
@@ -13,8 +5,8 @@ use winit::platform::wayland::WindowBuilderExtWayland;
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
use {
std::io::Cursor,
-
- winit::platform::x11::{WindowExtX11, WindowBuilderExtX11},
+ winit::platform::x11::{WindowBuilderExtX11, EventLoopWindowTargetExtX11},
+ winit::window::raw_window_handle::{HasRawDisplayHandle, RawDisplayHandle},
glutin::platform::x11::X11VisualInfo,
x11_dl::xlib::{Display as XDisplay, PropModeReplace, XErrorEvent, Xlib},
winit::window::Icon,
@@ -22,8 +14,6 @@ use {
};
use std::fmt::{self, Display, Formatter};
-use std::sync::atomic::AtomicBool;
-use std::sync::Arc;
#[cfg(target_os = "macos")]
use {
@@ -33,13 +23,12 @@ use {
winit::platform::macos::{OptionAsAlt, WindowBuilderExtMacOS, WindowExtMacOS},
};
-use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
-
use winit::dpi::{PhysicalPosition, PhysicalSize};
use winit::event_loop::EventLoopWindowTarget;
use winit::monitor::MonitorHandle;
#[cfg(windows)]
use winit::platform::windows::IconExtWindows;
+use winit::window::raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
use winit::window::{
CursorIcon, Fullscreen, ImePurpose, UserAttentionType, Window as WinitWindow, WindowBuilder,
WindowId,
@@ -107,15 +96,14 @@ impl From<crossfont::Error> for Error {
/// Wraps the underlying windowing library to provide a stable API in Alacritty.
pub struct Window {
/// Flag tracking that we have a frame we can draw.
- pub has_frame: Arc<AtomicBool>,
-
- /// Attached Wayland surface to request new frame events.
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- pub wayland_surface: Option<Attached<WlSurface>>,
+ pub has_frame: bool,
/// Cached scale factor for quickly scaling pixel sizes.
pub scale_factor: f64,
+ /// Flag indicating whether redraw was requested.
+ pub requested_redraw: bool,
+
window: WinitWindow,
/// Current window title.
@@ -133,8 +121,6 @@ impl Window {
event_loop: &EventLoopWindowTarget<E>,
config: &UiConfig,
identity: &Identity,
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- wayland_event_queue: Option<&EventQueue>,
#[rustfmt::skip]
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
x11_visual: Option<X11VisualInfo>,
@@ -161,12 +147,6 @@ impl Window {
.with_fullscreen(config.window.fullscreen())
.build(event_loop)?;
- // Check if we're running Wayland to disable vsync.
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- let is_wayland = event_loop.is_wayland();
- #[cfg(all(not(feature = "wayland"), not(any(target_os = "macos", windows))))]
- let is_wayland = false;
-
// Text cursor.
let current_mouse_cursor = CursorIcon::Text;
window.set_cursor_icon(current_mouse_cursor);
@@ -181,35 +161,23 @@ impl Window {
#[cfg(target_os = "macos")]
use_srgb_color_space(&window);
+ // On X11, embed the window inside another if the parent ID has been set.
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
- if !is_wayland {
- // On X11, embed the window inside another if the parent ID has been set.
- if let Some(parent_window_id) = config.window.embed {
- x_embed_window(&window, parent_window_id);
- }
+ if let Some(parent_window_id) = event_loop.is_x11().then_some(config.window.embed).flatten()
+ {
+ x_embed_window(&window, parent_window_id);
}
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- let wayland_surface = if is_wayland {
- // Attach surface to Alacritty's internal wayland queue to handle frame callbacks.
- let surface = window.wayland_surface().unwrap();
- let proxy: Proxy<WlSurface> = unsafe { Proxy::from_c_ptr(surface as _) };
- Some(proxy.attach(wayland_event_queue.as_ref().unwrap().token()))
- } else {
- None
- };
-
let scale_factor = window.scale_factor();
log::info!("Window scale factor: {}", scale_factor);
Ok(Self {
current_mouse_cursor,
mouse_visible: true,
+ requested_redraw: false,
window,
title: identity.title,
- has_frame: Arc::new(AtomicBool::new(true)),
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- wayland_surface,
+ has_frame: true,
scale_factor,
})
}
@@ -220,8 +188,8 @@ impl Window {
}
#[inline]
- pub fn set_inner_size(&self, size: PhysicalSize<u32>) {
- self.window.set_inner_size(size);
+ pub fn request_inner_size(&self, size: PhysicalSize<u32>) {
+ let _ = self.window.request_inner_size(size);
}
#[inline]
@@ -248,8 +216,11 @@ impl Window {
}
#[inline]
- pub fn request_redraw(&self) {
- self.window.request_redraw();
+ pub fn request_redraw(&mut self) {
+ if !self.requested_redraw {
+ self.requested_redraw = true;
+ self.window.request_redraw();
+ }
}
#[inline]
@@ -296,7 +267,7 @@ impl Window {
#[cfg(feature = "x11")]
let builder = match x11_visual {
- Some(visual) => builder.with_x11_visual(visual.into_raw()),
+ Some(visual) => builder.with_x11_visual(visual.visual_id() as u32),
None => builder,
};
@@ -367,6 +338,13 @@ impl Window {
self.set_maximized(!self.window.is_maximized());
}
+ /// Inform windowing system about presenting to the window.
+ ///
+ /// Should be called right before presenting to the window with e.g. `eglSwapBuffers`.
+ pub fn pre_present_notify(&self) {
+ self.window.pre_present_notify();
+ }
+
#[cfg(target_os = "macos")]
pub fn toggle_simple_fullscreen(&self) {
self.set_simple_fullscreen(!self.window.simple_fullscreen());
@@ -394,11 +372,6 @@ impl Window {
self.window.set_simple_fullscreen(simple_fullscreen);
}
- #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
- pub fn wayland_surface(&self) -> Option<&Attached<WlSurface>> {
- self.wayland_surface.as_ref()
- }
-
pub fn set_ime_allowed(&self, allowed: bool) {
self.window.set_ime_allowed(allowed);
}
@@ -437,8 +410,12 @@ impl Window {
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
fn x_embed_window(window: &WinitWindow, parent_id: std::os::raw::c_ulong) {
- let (xlib_display, xlib_window) = match (window.xlib_display(), window.xlib_window()) {
- (Some(display), Some(window)) => (display, window),
+ let xlib_display = window.raw_display_handle();
+ let xlib_window = window.raw_window_handle();
+ let (xlib_display, xlib_window) = match (xlib_display, xlib_window) {
+ (RawDisplayHandle::Xlib(display), RawWindowHandle::Xlib(window)) => {
+ (display.display, window.window)
+ },
_ => return,
};
@@ -448,7 +425,7 @@ fn x_embed_window(window: &WinitWindow, parent_id: std::os::raw::c_ulong) {
let atom = (xlib.XInternAtom)(xlib_display as *mut _, "_XEMBED".as_ptr() as *const _, 0);
(xlib.XChangeProperty)(
xlib_display as _,
- xlib_window as _,
+ xlib_window,
atom,
atom,
32,