diff options
author | Kirill Chibisov <contact@kchibisov.com> | 2023-10-21 22:56:20 +0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-21 22:56:20 +0400 |
commit | 80d4daccc307622f8e604af4f36ac89ecccf5db7 (patch) | |
tree | d63c17a09337bb044543c2ec83302d85ffeb5cbf /alacritty/src | |
parent | 6071a7bf35cfd99be8ba70f479f188b7370cda6f (diff) | |
download | r-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.rs | 5 | ||||
-rw-r--r-- | alacritty/src/clipboard.rs | 2 | ||||
-rw-r--r-- | alacritty/src/config/bindings.rs | 31 | ||||
-rw-r--r-- | alacritty/src/config/window.rs | 3 | ||||
-rw-r--r-- | alacritty/src/display/mod.rs | 7 | ||||
-rw-r--r-- | alacritty/src/display/window.rs | 70 | ||||
-rw-r--r-- | alacritty/src/event.rs | 55 | ||||
-rw-r--r-- | alacritty/src/renderer/platform.rs | 2 | ||||
-rw-r--r-- | alacritty/src/window_context.rs | 18 |
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(); } } |