aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2023-10-21 22:56:20 +0400
committerGitHub <noreply@github.com>2023-10-21 22:56:20 +0400
commit80d4daccc307622f8e604af4f36ac89ecccf5db7 (patch)
treed63c17a09337bb044543c2ec83302d85ffeb5cbf /alacritty/src
parent6071a7bf35cfd99be8ba70f479f188b7370cda6f (diff)
downloadr-alacritty-80d4daccc307622f8e604af4f36ac89ecccf5db7.tar.gz
r-alacritty-80d4daccc307622f8e604af4f36ac89ecccf5db7.tar.bz2
r-alacritty-80d4daccc307622f8e604af4f36ac89ecccf5db7.zip
Update winit to 0.29.2 and copypasta to 0.10.0
Fixes #7236. Fixes #7201. Fixes #7146. Fixes #6848. Fixes #3601. Fixes #3108. Fixes #2453.
Diffstat (limited to 'alacritty/src')
-rw-r--r--alacritty/src/cli.rs5
-rw-r--r--alacritty/src/clipboard.rs2
-rw-r--r--alacritty/src/config/bindings.rs31
-rw-r--r--alacritty/src/config/window.rs3
-rw-r--r--alacritty/src/display/mod.rs7
-rw-r--r--alacritty/src/display/window.rs70
-rw-r--r--alacritty/src/event.rs55
-rw-r--r--alacritty/src/renderer/platform.rs2
-rw-r--r--alacritty/src/window_context.rs18
9 files changed, 87 insertions, 106 deletions
diff --git a/alacritty/src/cli.rs b/alacritty/src/cli.rs
index d2982bde..c9890b9b 100644
--- a/alacritty/src/cli.rs
+++ b/alacritty/src/cli.rs
@@ -1,5 +1,4 @@
use std::cmp::max;
-use std::os::raw::c_ulong;
use std::path::PathBuf;
use clap::{ArgAction, Args, Parser, Subcommand, ValueHint};
@@ -149,10 +148,10 @@ fn parse_class(input: &str) -> Result<Class, String> {
}
/// Convert to hex if possible, else decimal
-fn parse_hex_or_decimal(input: &str) -> Option<c_ulong> {
+fn parse_hex_or_decimal(input: &str) -> Option<u32> {
input
.strip_prefix("0x")
- .and_then(|value| c_ulong::from_str_radix(value, 16).ok())
+ .and_then(|value| u32::from_str_radix(value, 16).ok())
.or_else(|| input.parse().ok())
}
diff --git a/alacritty/src/clipboard.rs b/alacritty/src/clipboard.rs
index 35982cf5..b3818c75 100644
--- a/alacritty/src/clipboard.rs
+++ b/alacritty/src/clipboard.rs
@@ -1,5 +1,5 @@
use log::{debug, warn};
-use winit::window::raw_window_handle::RawDisplayHandle;
+use raw_window_handle::RawDisplayHandle;
use alacritty_terminal::term::ClipboardType;
diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs
index 71278fd7..914d25ff 100644
--- a/alacritty/src/config/bindings.rs
+++ b/alacritty/src/config/bindings.rs
@@ -8,8 +8,9 @@ use serde::{Deserialize, Deserializer};
use toml::Value as SerdeValue;
use winit::event::MouseButton;
use winit::keyboard::Key::*;
-use winit::keyboard::{Key, KeyCode, KeyLocation, ModifiersState};
-use winit::platform::scancode::KeyCodeExtScancode;
+use winit::keyboard::NamedKey::*;
+use winit::keyboard::{Key, KeyCode, KeyLocation, ModifiersState, NamedKey, PhysicalKey};
+use winit::platform::scancode::PhysicalKeyExtScancode;
use alacritty_config_derive::{ConfigDeserialize, SerdeReplace};
@@ -418,7 +419,7 @@ macro_rules! trigger {
BindingKey::Keycode { key: Character($key.into()), location: KeyLocation::Standard }
}};
(KeyBinding, $key:expr,) => {{
- BindingKey::Keycode { key: $key, location: KeyLocation::Standard }
+ BindingKey::Keycode { key: Named($key), location: KeyLocation::Standard }
}};
($ty:ident, $key:expr,) => {{
$key
@@ -716,7 +717,7 @@ pub fn platform_key_bindings() -> Vec<KeyBinding> {
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum BindingKey {
- Scancode(KeyCode),
+ Scancode(PhysicalKey),
Keycode { key: Key, location: KeyLocation },
}
@@ -727,7 +728,7 @@ impl<'a> Deserialize<'a> for BindingKey {
{
let value = SerdeValue::deserialize(deserializer)?;
match u32::deserialize(value.clone()) {
- Ok(scancode) => Ok(BindingKey::Scancode(KeyCode::from_scancode(scancode))),
+ Ok(scancode) => Ok(BindingKey::Scancode(PhysicalKey::from_scancode(scancode))),
Err(_) => {
let keycode = String::deserialize(value.clone()).map_err(D::Error::custom)?;
let (key, location) = if keycode.chars().count() == 1 {
@@ -735,15 +736,15 @@ impl<'a> Deserialize<'a> for BindingKey {
} else {
// Translate legacy winit codes into their modern counterparts.
match keycode.as_str() {
- "Up" => (Key::ArrowUp, KeyLocation::Standard),
- "Back" => (Key::Backspace, KeyLocation::Standard),
- "Down" => (Key::ArrowDown, KeyLocation::Standard),
- "Left" => (Key::ArrowLeft, KeyLocation::Standard),
- "Right" => (Key::ArrowRight, KeyLocation::Standard),
+ "Up" => (Key::Named(ArrowUp), KeyLocation::Standard),
+ "Back" => (Key::Named(Backspace), KeyLocation::Standard),
+ "Down" => (Key::Named(ArrowDown), KeyLocation::Standard),
+ "Left" => (Key::Named(ArrowLeft), KeyLocation::Standard),
+ "Right" => (Key::Named(ArrowRight), KeyLocation::Standard),
"At" => (Key::Character("@".into()), KeyLocation::Standard),
"Colon" => (Key::Character(":".into()), KeyLocation::Standard),
"Period" => (Key::Character(".".into()), KeyLocation::Standard),
- "Return" => (Key::Enter, KeyLocation::Standard),
+ "Return" => (Key::Named(Enter), KeyLocation::Standard),
"LBracket" => (Key::Character("[".into()), KeyLocation::Standard),
"RBracket" => (Key::Character("]".into()), KeyLocation::Standard),
"Semicolon" => (Key::Character(";".into()), KeyLocation::Standard),
@@ -766,7 +767,7 @@ impl<'a> Deserialize<'a> for BindingKey {
"Key0" => (Key::Character("0".into()), KeyLocation::Standard),
// Special case numpad.
- "NumpadEnter" => (Key::Enter, KeyLocation::Numpad),
+ "NumpadEnter" => (Key::Named(Enter), KeyLocation::Numpad),
"NumpadAdd" => (Key::Character("+".into()), KeyLocation::Numpad),
"NumpadComma" => (Key::Character(",".into()), KeyLocation::Numpad),
"NumpadDivide" => (Key::Character("/".into()), KeyLocation::Numpad),
@@ -783,10 +784,14 @@ impl<'a> Deserialize<'a> for BindingKey {
"Numpad8" => (Key::Character("8".into()), KeyLocation::Numpad),
"Numpad9" => (Key::Character("9".into()), KeyLocation::Numpad),
"Numpad0" => (Key::Character("0".into()), KeyLocation::Numpad),
- _ => (
+ _ if keycode.starts_with("Dead") => (
Key::deserialize(value).map_err(D::Error::custom)?,
KeyLocation::Standard,
),
+ _ => (
+ Key::Named(NamedKey::deserialize(value).map_err(D::Error::custom)?),
+ KeyLocation::Standard,
+ ),
}
};
diff --git a/alacritty/src/config/window.rs b/alacritty/src/config/window.rs
index 4b63c3e9..9d40b5ad 100644
--- a/alacritty/src/config/window.rs
+++ b/alacritty/src/config/window.rs
@@ -1,5 +1,4 @@
use std::fmt::{self, Formatter};
-use std::os::raw::c_ulong;
use log::{error, warn};
use serde::de::{self, MapAccess, Visitor};
@@ -31,7 +30,7 @@ pub struct WindowConfig {
/// XEmbed parent.
#[config(skip)]
- pub embed: Option<c_ulong>,
+ pub embed: Option<u32>,
/// System decorations theme variant.
pub decorations_theme_variant: Option<Theme>,
diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs
index 255b587a..2b5cc348 100644
--- a/alacritty/src/display/mod.rs
+++ b/alacritty/src/display/mod.rs
@@ -14,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};
@@ -987,10 +987,7 @@ impl Display {
// XXX: Request the new frame after swapping buffers, so the
// time to finish OpenGL operations is accounted for in the timeout.
- if matches!(
- self.raw_window_handle,
- RawWindowHandle::AppKit(_) | RawWindowHandle::Xlib(_) | RawWindowHandle::Xcb(_)
- ) {
+ if !matches!(self.raw_window_handle, RawWindowHandle::Wayland(_)) {
self.request_frame(scheduler);
}
diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs
index afa5a181..5606ca4f 100644
--- a/alacritty/src/display/window.rs
+++ b/alacritty/src/display/window.rs
@@ -11,9 +11,7 @@ use winit::platform::wayland::WindowBuilderExtWayland;
use {
std::io::Cursor,
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,
png::Decoder,
};
@@ -28,12 +26,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, Theme, UserAttentionType, Window as WinitWindow,
WindowBuilder, WindowId,
@@ -154,9 +152,14 @@ impl Window {
window_builder = window_builder.with_activation_token(token);
// Remove the token from the env.
- unsafe {
- startup_notify::reset_activation_token_env();
- }
+ startup_notify::reset_activation_token_env();
+ }
+
+ // 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 let Some(parent_window_id) = event_loop.is_x11().then_some(config.window.embed).flatten()
+ {
+ window_builder = window_builder.with_embed_parent_window(parent_window_id);
}
let window = window_builder
@@ -182,13 +185,6 @@ 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 let Some(parent_window_id) = event_loop.is_x11().then_some(config.window.embed).flatten()
- {
- x_embed_window(&window, parent_window_id);
- }
-
let scale_factor = window.scale_factor();
log::info!("Window scale factor: {}", scale_factor);
@@ -238,7 +234,9 @@ impl Window {
#[inline]
pub fn request_redraw(&mut self) {
- if !self.requested_redraw {
+ // 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 {
self.requested_redraw = true;
self.window.request_redraw();
}
@@ -470,44 +468,6 @@ 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 = 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,
- };
-
- let xlib = Xlib::open().expect("get xlib");
-
- unsafe {
- let atom = (xlib.XInternAtom)(xlib_display as *mut _, "_XEMBED".as_ptr() as *const _, 0);
- (xlib.XChangeProperty)(
- xlib_display as _,
- xlib_window,
- atom,
- atom,
- 32,
- PropModeReplace,
- [0, 1].as_ptr(),
- 2,
- );
-
- // Register new error handler.
- let old_handler = (xlib.XSetErrorHandler)(Some(xembed_error_handler));
-
- // Check for the existence of the target before attempting reparenting.
- (xlib.XReparentWindow)(xlib_display as _, xlib_window as _, parent_id, 0, 0);
-
- // Drain errors and restore original error handler.
- (xlib.XSync)(xlib_display as _, 0);
- (xlib.XSetErrorHandler)(old_handler);
- }
-}
-
#[cfg(target_os = "macos")]
fn use_srgb_color_space(window: &WinitWindow) {
let raw_window = match window.raw_window_handle() {
@@ -519,9 +479,3 @@ fn use_srgb_color_space(window: &WinitWindow) {
let _: () = msg_send![raw_window, setColorSpace: NSColorSpace::sRGBColorSpace(nil)];
}
}
-
-#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
-unsafe extern "C" fn xembed_error_handler(_: *mut XDisplay, _: *mut XErrorEvent) -> i32 {
- log::error!("Could not embed into specified window.");
- std::process::exit(1);
-}
diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs
index 7bb3a83e..b7a87855 100644
--- a/alacritty/src/event.rs
+++ b/alacritty/src/event.rs
@@ -15,7 +15,9 @@ use std::{env, f32, mem};
use ahash::RandomState;
use crossfont::{self, Size};
+use glutin::display::{Display as GlutinDisplay, GetGlDisplay};
use log::{debug, error, info, warn};
+use raw_window_handle::HasRawDisplayHandle;
use winit::event::{
ElementState, Event as WinitEvent, Ime, Modifiers, MouseButton, StartCause,
Touch as TouchEvent, WindowEvent,
@@ -23,7 +25,6 @@ use winit::event::{
use winit::event_loop::{
ControlFlow, DeviceEvents, EventLoop, EventLoopProxy, EventLoopWindowTarget,
};
-use winit::window::raw_window_handle::HasRawDisplayHandle;
use winit::window::WindowId;
use alacritty_terminal::config::LOG_TARGET_CONFIG;
@@ -1447,6 +1448,7 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
| WindowEvent::Destroyed
| WindowEvent::ThemeChanged(_)
| WindowEvent::HoveredFile(_)
+ | WindowEvent::RedrawRequested
| WindowEvent::Moved(_) => (),
}
},
@@ -1455,8 +1457,8 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
| WinitEvent::DeviceEvent { .. }
| WinitEvent::LoopExiting
| WinitEvent::Resumed
- | WinitEvent::AboutToWait
- | WinitEvent::RedrawRequested(_) => (),
+ | WinitEvent::MemoryWarning
+ | WinitEvent::AboutToWait => (),
}
}
}
@@ -1467,6 +1469,7 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> {
/// triggered.
pub struct Processor {
windows: HashMap<WindowId, WindowContext, RandomState>,
+ gl_display: Option<GlutinDisplay>,
#[cfg(unix)]
global_ipc_options: Vec<String>,
cli_options: CliOptions,
@@ -1484,6 +1487,7 @@ impl Processor {
) -> Processor {
Processor {
cli_options,
+ gl_display: None,
config: Rc::new(config),
windows: Default::default(),
#[cfg(unix)]
@@ -1504,6 +1508,7 @@ impl Processor {
let window_context =
WindowContext::initial(event_loop, proxy, self.config.clone(), options)?;
+ self.gl_display = Some(window_context.display.gl_context().display());
self.windows.insert(window_context.id(), window_context);
Ok(())
@@ -1552,7 +1557,8 @@ impl Processor {
// Disable all device events, since we don't care about them.
event_loop.listen_device_events(DeviceEvents::Never);
- let result = event_loop.run(move |event, event_loop, control_flow| {
+ let mut initial_window_error = Ok(());
+ let result = event_loop.run(|event, event_loop| {
if self.config.debug.print_events {
info!("winit event: {:?}", event);
}
@@ -1578,14 +1584,30 @@ impl Processor {
proxy.clone(),
initial_window_options,
) {
- // Log the error right away since we can't return it.
- eprintln!("Error: {}", err);
- *control_flow = ControlFlow::ExitWithCode(1);
+ initial_window_error = Err(err);
+ event_loop.exit();
return;
}
info!("Initialisation complete");
},
+ WinitEvent::LoopExiting => {
+ match self.gl_display.take() {
+ #[cfg(not(target_os = "macos"))]
+ Some(glutin::display::Display::Egl(display)) => {
+ // Ensure that all the windows are dropped, so the destructors for
+ // Renderer and contexts ran.
+ self.windows.clear();
+
+ // SAFETY: the display is being destroyed after destroying all the
+ // windows, thus no attempt to access the EGL state will be made.
+ unsafe {
+ display.terminate();
+ }
+ },
+ _ => (),
+ }
+ },
// NOTE: This event bypasses batching to minimize input latency.
WinitEvent::UserEvent(Event {
window_id: Some(window_id),
@@ -1631,10 +1653,10 @@ impl Processor {
window_context.write_ref_test_results();
}
- *control_flow = ControlFlow::Exit;
+ event_loop.exit();
}
},
- WinitEvent::RedrawRequested(window_id) => {
+ WinitEvent::WindowEvent { window_id, event: WindowEvent::RedrawRequested } => {
let window_context = match self.windows.get_mut(&window_id) {
Some(window_context) => window_context,
None => return,
@@ -1645,7 +1667,7 @@ impl Processor {
&proxy,
&mut clipboard,
&mut scheduler,
- WinitEvent::RedrawRequested(window_id),
+ event,
);
window_context.draw(&mut scheduler);
@@ -1665,10 +1687,11 @@ impl Processor {
// Update the scheduler after event processing to ensure
// the event loop deadline is as accurate as possible.
- *control_flow = match scheduler.update() {
+ let control_flow = match scheduler.update() {
Some(instant) => ControlFlow::WaitUntil(instant),
None => ControlFlow::Wait,
};
+ event_loop.set_control_flow(control_flow);
},
// Process config update.
WinitEvent::UserEvent(Event { payload: EventType::ConfigReload(path), .. }) => {
@@ -1757,7 +1780,11 @@ impl Processor {
}
});
- result.map_err(Into::into)
+ if initial_window_error.is_err() {
+ initial_window_error
+ } else {
+ result.map_err(Into::into)
+ }
}
/// Check if an event is irrelevant and can be skipped.
@@ -1775,9 +1802,7 @@ impl Processor {
| WindowEvent::HoveredFile(_)
| WindowEvent::Moved(_)
),
- WinitEvent::Suspended { .. }
- | WinitEvent::NewEvents { .. }
- | WinitEvent::LoopExiting => true,
+ WinitEvent::Suspended { .. } | WinitEvent::NewEvents { .. } => true,
_ => false,
}
}
diff --git a/alacritty/src/renderer/platform.rs b/alacritty/src/renderer/platform.rs
index b31e6974..3568bd20 100644
--- a/alacritty/src/renderer/platform.rs
+++ b/alacritty/src/renderer/platform.rs
@@ -12,10 +12,10 @@ use glutin::prelude::*;
use glutin::surface::{Surface, SurfaceAttributesBuilder, WindowSurface};
use log::{debug, LevelFilter};
+use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
use winit::dpi::PhysicalSize;
#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))]
use winit::platform::x11;
-use winit::window::raw_window_handle::{RawDisplayHandle, RawWindowHandle};
/// Create the GL display.
pub fn create_gl_display(
diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs
index 301d30ad..f76faf7a 100644
--- a/alacritty/src/window_context.rs
+++ b/alacritty/src/window_context.rs
@@ -16,10 +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;
-use winit::event::{Event as WinitEvent, Modifiers};
+use winit::event::{Event as WinitEvent, Modifiers, WindowEvent};
use winit::event_loop::{EventLoopProxy, EventLoopWindowTarget};
-use winit::window::raw_window_handle::HasRawDisplayHandle;
use winit::window::WindowId;
use alacritty_config::SerdeReplace;
@@ -419,7 +419,8 @@ impl WindowContext {
event: WinitEvent<Event>,
) {
match event {
- WinitEvent::AboutToWait | WinitEvent::RedrawRequested(_) => {
+ WinitEvent::AboutToWait
+ | WinitEvent::WindowEvent { event: WindowEvent::RedrawRequested, .. } => {
// Skip further event handling with no staged updates.
if self.event_queue.is_empty() {
return;
@@ -492,11 +493,12 @@ impl WindowContext {
self.mouse.hint_highlight_dirty = false;
}
- // 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(_)) {
+ // 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.occluded
+ && !matches!(event, WinitEvent::WindowEvent { event: WindowEvent::RedrawRequested, .. })
+ {
self.display.window.request_redraw();
}
}