1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-25 14:05:41 -05:00

Make use of glutin wayland/x11 features

This should allow users that are not using Wayland/X11
to reduce the resulted binary size and compilation times.
This commit is contained in:
Kirill Chibisov 2020-10-12 12:22:36 +03:00 committed by GitHub
parent 56e0f5bb05
commit 721f789b5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 98 additions and 68 deletions

View file

@ -12,10 +12,16 @@ sources:
tasks:
- rustup: |
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain stable --profile minimal
- 1-43-1: |
$HOME/.cargo/bin/rustup toolchain install --profile minimal 1.43.1
- 1-43-1: |
cd alacritty
$HOME/.cargo/bin/cargo +1.43.1 test
- 1-43-1-wayland: |
cd alacritty/alacritty
$HOME/.cargo/bin/cargo +1.43.1 test --no-default-features --features=wayland
- 1-43-1-x11: |
cd alacritty/alacritty
$HOME/.cargo/bin/cargo +1.43.1 test --no-default-features --features=x11
- stable: |
cd alacritty
$HOME/.cargo/bin/cargo +stable test

4
Cargo.lock generated
View file

@ -847,9 +847,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "glutin"
version = "0.25.0"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94c05751b6948879d2b15d49930e16ecc0144e51fcb8cd873686d6c4b5ebed"
checksum = "d8bae26a39a728b003e9fad473ea89527de0de050143b4df866f18bb154bc86e"
dependencies = [
"android_glue",
"cgl",

View file

@ -21,7 +21,7 @@ fnv = "1"
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.8"
serde_json = "1"
glutin = { version = "0.25.0", features = ["serde"] }
glutin = { version = "0.25.1", default-features = false, features = ["serde"] }
notify = "4"
parking_lot = "0.11.0"
crossfont = { version = "0.1.0", features = ["force_system_fontconfig"] }
@ -47,8 +47,8 @@ objc = "0.2.2"
dirs = "2.0.2"
[target.'cfg(not(any(target_os="windows", target_os="macos")))'.dependencies]
x11-dl = "2"
wayland-client = { version = "0.28.0", features = ["dlopen"] }
x11-dl = { version = "2", optional = true }
wayland-client = { version = "0.28.0", features = ["dlopen"], optional = true }
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.7", features = ["impl-default", "wincon"]}
@ -58,8 +58,8 @@ embed-resource = "1.3"
[features]
default = ["wayland", "x11", "winpty"]
x11 = ["copypasta/x11"]
wayland = ["copypasta/wayland"]
x11 = ["copypasta/x11", "glutin/x11", "x11-dl"]
wayland = ["copypasta/wayland", "glutin/wayland", "wayland-client"]
winpty = ["alacritty_terminal/winpty"]
# Enabling this feature makes shaders automatically reload when changed
live-shader-reload = []

View file

@ -4,7 +4,7 @@
use std::cmp::min;
use std::f64;
use std::fmt::{self, Formatter};
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
use std::sync::atomic::Ordering;
use std::time::Instant;
@ -17,7 +17,7 @@ use glutin::window::CursorIcon;
use log::{debug, info};
use parking_lot::MutexGuard;
use unicode_width::UnicodeWidthChar;
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
use wayland_client::{Display as WaylandDisplay, EventQueue};
#[cfg(target_os = "macos")]
@ -154,14 +154,15 @@ pub struct Display {
/// Currently highlighted URL.
pub highlighted_url: Option<Url>,
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
pub wayland_event_queue: Option<EventQueue>,
#[cfg(not(any(target_os = "macos", windows)))]
pub is_x11: bool,
renderer: QuadRenderer,
glyph_cache: GlyphCache,
meter: Meter,
#[cfg(not(any(target_os = "macos", windows)))]
is_x11: bool,
}
impl Display {
@ -184,11 +185,11 @@ impl Display {
debug!("Estimated window size: {:?}", estimated_size);
debug!("Estimated cell size: {} x {}", cell_width, cell_height);
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
let mut wayland_event_queue = None;
// Initialize Wayland event queue, to handle Wayland callbacks.
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
if let Some(display) = event_loop.wayland_display() {
let display = unsafe { WaylandDisplay::from_external_display(display as _) };
wayland_event_queue = Some(display.create_event_queue());
@ -199,7 +200,7 @@ impl Display {
event_loop,
&config,
estimated_size,
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
wayland_event_queue.as_ref(),
)?;
@ -253,8 +254,10 @@ impl Display {
#[cfg(target_os = "macos")]
set_font_smoothing(config.ui_config.font.use_thin_strokes());
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
let is_x11 = event_loop.is_x11();
#[cfg(not(any(feature = "x11", target_os = "macos", windows)))]
let is_x11 = false;
// 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.
@ -296,7 +299,7 @@ impl Display {
highlighted_url: None,
#[cfg(not(any(target_os = "macos", windows)))]
is_x11,
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
wayland_event_queue,
})
}
@ -582,12 +585,12 @@ impl Display {
// Frame event should be requested before swaping buffers, since it requires surface
// `commit`, which is done by swap buffers under the hood.
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
self.request_frame(&self.window);
self.window.swap_buffers();
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
if self.is_x11 {
// 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
@ -662,7 +665,7 @@ impl Display {
/// Requst a new frame for a window on Wayland.
#[inline]
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
fn request_frame(&self, window: &Window) {
let surface = match window.wayland_surface() {
Some(surface) => surface,

View file

@ -19,7 +19,7 @@ use glutin::dpi::PhysicalSize;
use glutin::event::{ElementState, Event as GlutinEvent, ModifiersState, MouseButton, WindowEvent};
use glutin::event_loop::{ControlFlow, EventLoop, EventLoopProxy, EventLoopWindowTarget};
use glutin::platform::desktop::EventLoopExtDesktop;
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
use glutin::platform::unix::EventLoopWindowTargetExtUnix;
use log::info;
use serde_json as json;
@ -749,7 +749,7 @@ impl<N: Notify + OnResize> Processor<N> {
/// Return `true` if `event_queue` is empty, `false` otherwise.
#[inline]
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
fn event_queue_empty(&mut self) -> bool {
let wayland_event_queue = match self.display.wayland_event_queue.as_mut() {
Some(wayland_event_queue) => wayland_event_queue,
@ -767,7 +767,7 @@ impl<N: Notify + OnResize> Processor<N> {
/// Return `true` if `event_queue` is empty, `false` otherwise.
#[inline]
#[cfg(any(target_os = "macos", windows))]
#[cfg(any(target_os = "macos", windows, not(feature = "wayland")))]
fn event_queue_empty(&mut self) -> bool {
self.event_queue.is_empty()
}
@ -863,7 +863,7 @@ impl<N: Notify + OnResize> Processor<N> {
// Skip rendering on Wayland until we get frame event from compositor.
#[cfg(not(any(target_os = "macos", windows)))]
if event_loop.is_wayland() && !self.display.window.should_draw.load(Ordering::Relaxed) {
if !self.display.is_x11 && !self.display.window.should_draw.load(Ordering::Relaxed) {
return;
}
@ -1114,7 +1114,7 @@ impl<N: Notify + OnResize> Processor<N> {
processor.ctx.window.set_title(&config.ui_config.window.title);
}
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
if processor.ctx.event_loop.is_wayland() {
processor.ctx.window.set_wayland_theme(&config.colors);
}

View file

@ -48,7 +48,7 @@ mod scheduler;
mod url;
mod window;
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
mod wayland_theme;
mod gl {
@ -160,10 +160,7 @@ fn run(
// The PTY forks a process to run the shell on the slave side of the
// pseudoterminal. A file descriptor for the master side is retained for
// reading/writing to the shell.
#[cfg(not(any(target_os = "macos", windows)))]
let pty = tty::new(&config, &display.size_info, display.window.x11_window_id());
#[cfg(any(target_os = "macos", windows))]
let pty = tty::new(&config, &display.size_info, None);
// Create the pseudoterminal I/O loop.
//

View file

@ -1,23 +1,27 @@
#[rustfmt::skip]
#[cfg(not(any(target_os = "macos", windows)))]
use {
std::ffi::c_void,
std::os::raw::c_ulong,
std::sync::atomic::AtomicBool,
std::sync::Arc,
glutin::platform::unix::{EventLoopWindowTargetExtUnix, WindowBuilderExtUnix, WindowExtUnix},
image::ImageFormat,
log::error,
};
#[rustfmt::skip]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
use {
wayland_client::protocol::wl_surface::WlSurface,
wayland_client::{Attached, EventQueue, Proxy},
x11_dl::xlib::{Display as XDisplay, PropModeReplace, XErrorEvent, Xlib},
alacritty_terminal::config::Colors,
crate::wayland_theme::AlacrittyWaylandTheme,
};
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
use x11_dl::xlib::{Display as XDisplay, PropModeReplace, XErrorEvent, Xlib};
use std::fmt::{self, Display, Formatter};
use glutin::dpi::{PhysicalPosition, PhysicalSize};
@ -134,7 +138,7 @@ pub struct Window {
pub should_draw: Arc<AtomicBool>,
/// Attached Wayland surface to request new frame events.
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
pub wayland_surface: Option<Attached<WlSurface>>,
/// Cached DPR for quickly scaling pixel sizes.
@ -153,20 +157,23 @@ impl Window {
event_loop: &EventLoop<E>,
config: &Config,
size: Option<PhysicalSize<u32>>,
#[cfg(not(any(target_os = "macos", windows)))] wayland_event_queue: Option<&EventQueue>,
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
wayland_event_queue: Option<&EventQueue>,
) -> Result<Window> {
let window_config = &config.ui_config.window;
let window_builder = Window::get_platform_window(&window_config.title, &window_config);
// Disable vsync on Wayland.
#[cfg(not(any(target_os = "macos", windows)))]
let vsync = !event_loop.is_wayland();
#[cfg(any(target_os = "macos", windows))]
let vsync = true;
// 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(any(target_os = "macos", windows, not(feature = "wayland")))]
let is_wayland = false;
let windowed_context =
create_gl_window(window_builder.clone(), &event_loop, false, vsync, size)
.or_else(|_| create_gl_window(window_builder, &event_loop, true, vsync, size))?;
create_gl_window(window_builder.clone(), &event_loop, false, !is_wayland, size)
.or_else(|_| {
create_gl_window(window_builder, &event_loop, true, !is_wayland, size)
})?;
// Text cursor.
let current_mouse_cursor = CursorIcon::Text;
@ -175,16 +182,19 @@ impl Window {
// Set OpenGL symbol loader. This call MUST be after window.make_current on windows.
gl::load_with(|symbol| windowed_context.get_proc_address(symbol) as *const _);
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
let mut wayland_surface = None;
#[cfg(not(any(target_os = "macos", windows)))]
if event_loop.is_x11() {
#[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) = window_config.embed {
x_embed_window(windowed_context.window(), parent_window_id);
}
} else {
}
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
if is_wayland {
// Apply client side decorations theme.
let theme = AlacrittyWaylandTheme::new(&config.colors);
windowed_context.window().set_wayland_theme(theme);
@ -203,7 +213,7 @@ impl Window {
windowed_context,
#[cfg(not(any(target_os = "macos", windows)))]
should_draw: Arc::new(AtomicBool::new(true)),
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
wayland_surface,
dpr,
})
@ -254,22 +264,26 @@ impl Window {
let class = &window_config.class;
let mut builder = WindowBuilder::new()
let builder = WindowBuilder::new()
.with_title(title)
.with_visible(false)
.with_transparent(true)
.with_decorations(window_config.decorations != Decorations::None)
.with_maximized(window_config.maximized())
.with_fullscreen(window_config.fullscreen())
.with_window_icon(icon.ok())
// X11.
.with_class(class.instance.clone(), class.general.clone())
// Wayland.
.with_app_id(class.instance.clone());
.with_window_icon(icon.ok());
if let Some(ref val) = window_config.gtk_theme_variant {
builder = builder.with_gtk_theme_variant(val.clone())
}
#[cfg(feature = "wayland")]
let builder = builder.with_app_id(class.instance.clone());
#[cfg(feature = "x11")]
let builder = builder.with_class(class.instance.clone(), class.general.clone());
#[cfg(feature = "x11")]
let builder = match &window_config.gtk_theme_variant {
Some(val) => builder.with_gtk_theme_variant(val.clone()),
None => builder,
};
builder
}
@ -312,7 +326,7 @@ impl Window {
}
}
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
pub fn set_urgent(&self, is_urgent: bool) {
self.window().set_urgent(is_urgent);
}
@ -326,18 +340,23 @@ impl Window {
self.window().request_user_attention(RequestUserAttentionType::Critical);
}
#[cfg(windows)]
#[cfg(any(windows, not(feature = "x11")))]
pub fn set_urgent(&self, _is_urgent: bool) {}
pub fn set_outer_position(&self, pos: PhysicalPosition<i32>) {
self.window().set_outer_position(pos);
}
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
pub fn x11_window_id(&self) -> Option<usize> {
self.window().xlib_window().map(|xlib_window| xlib_window as usize)
}
#[cfg(any(target_os = "macos", windows, not(feature = "x11")))]
pub fn x11_window_id(&self) -> Option<usize> {
None
}
pub fn window_id(&self) -> WindowId {
self.window().id()
}
@ -374,17 +393,22 @@ impl Window {
self.window().set_simple_fullscreen(simple_fullscreen);
}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
pub fn wayland_display(&self) -> Option<*mut c_void> {
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
pub fn wayland_display(&self) -> Option<*mut std::ffi::c_void> {
self.window().wayland_display()
}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
#[cfg(any(not(feature = "wayland"), any(target_os = "macos", windows)))]
pub fn wayland_display(&self) -> Option<*mut std::ffi::c_void> {
None
}
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
pub fn wayland_surface(&self) -> Option<&Attached<WlSurface>> {
self.wayland_surface.as_ref()
}
#[cfg(not(any(target_os = "macos", target_os = "windows")))]
#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))]
pub fn set_wayland_theme(&mut self, colors: &Colors) {
self.window().set_wayland_theme(AlacrittyWaylandTheme::new(colors));
}
@ -415,8 +439,8 @@ impl Window {
}
}
#[cfg(not(any(target_os = "macos", windows)))]
fn x_embed_window(window: &GlutinWindow, parent_id: c_ulong) {
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
fn x_embed_window(window: &GlutinWindow, 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),
_ => return,
@ -449,8 +473,8 @@ fn x_embed_window(window: &GlutinWindow, parent_id: c_ulong) {
}
}
#[cfg(not(any(target_os = "macos", windows)))]
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
unsafe extern "C" fn xembed_error_handler(_: *mut XDisplay, _: *mut XErrorEvent) -> i32 {
error!("Could not embed into specified window.");
log::error!("Could not embed into specified window.");
std::process::exit(1);
}