diff --git a/CHANGELOG.md b/CHANGELOG.md index 959ae73e..5ae7ffb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Notable changes to the `alacritty_terminal` crate are documented in its ### Changed - Pressing `Alt` with unicode input will now add `ESC` like for ASCII input +- Decorations use opaque style and system window background on macOS ### Fixed diff --git a/Cargo.lock b/Cargo.lock index c4197c3c..f73c36a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,7 +61,7 @@ dependencies = [ "serde_yaml", "toml", "unicode-width", - "windows-sys 0.48.0", + "windows-sys 0.52.0", "winit", "xdg", ] @@ -109,14 +109,14 @@ dependencies = [ "signal-hook", "unicode-width", "vte", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "android-activity" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", "bitflags 2.4.2", @@ -260,7 +260,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" dependencies = [ "block-sys", - "objc2", + "objc2 0.4.1", +] + +[[package]] +name = "block2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43ff7d91d3c1d568065b06c899777d1e48dcf76103a672a0adbc238a7f247f1e" +dependencies = [ + "objc2 0.5.1", ] [[package]] @@ -335,6 +344,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cfg_aliases" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e53693616d3075149f4ead59bdeecd204ac6b8192d8969757601b74bddf00f" + [[package]] name = "cgl" version = "0.3.2" @@ -403,15 +418,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "cmake" -version = "0.1.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" -dependencies = [ - "cc", -] - [[package]] name = "cocoa" version = "0.25.0" @@ -559,9 +565,9 @@ checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crossfont" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89c65306ecd118368d875f48d69394b5c3ff6bb7c57ae6deb638782735a093c" +checksum = "c44e28d120f3c9254800ea53349b09cbb45ac1f15f09215011a16241ae0289bc" dependencies = [ "cocoa", "core-foundation", @@ -576,8 +582,18 @@ dependencies = [ "objc", "once_cell", "pkg-config", - "servo-fontconfig", "winapi", + "yeslogic-fontconfig-sys", +] + +[[package]] +name = "cstr" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68523903c8ae5aacfa32a0d9ae60cadeb764e1da14ee0d26b1f3089f13a54636" +dependencies = [ + "proc-macro2", + "quote", ] [[package]] @@ -631,6 +647,15 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" +dependencies = [ + "serde", +] + [[package]] name = "dwrote" version = "0.11.0" @@ -675,16 +700,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "expat-sys" -version = "2.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" -dependencies = [ - "cmake", - "pkg-config", -] - [[package]] name = "fastrand" version = "2.0.1" @@ -751,22 +766,22 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "freetype-rs" -version = "0.26.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb" +checksum = "5442dee36ca09604133580dc0553780e867936bb3cbef3275859e889026d2b17" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "freetype-sys", "libc", ] [[package]] name = "freetype-sys" -version = "0.13.1" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" +checksum = "0e7edc5b9669349acfda99533e9e0bcf26a51862ab43b08ee7745c55d28eb134" dependencies = [ - "cmake", + "cc", "libc", "pkg-config", ] @@ -825,7 +840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18fcd4ae4e86d991ad1300b8f57166e5be0c95ef1f63f3f5b827f8a164548746" dependencies = [ "bitflags 2.4.2", - "cfg_aliases", + "cfg_aliases 0.1.1", "cgl", "core-foundation", "dispatch", @@ -834,7 +849,7 @@ dependencies = [ "glutin_wgl_sys", "icrate", "libloading", - "objc2", + "objc2 0.4.1", "once_cell", "raw-window-handle", "wayland-sys", @@ -898,9 +913,9 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" dependencies = [ - "block2", + "block2 0.3.0", "dispatch", - "objc2", + "objc2 0.4.1", ] [[package]] @@ -1137,9 +1152,9 @@ dependencies = [ [[package]] name = "ndk" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ "bitflags 2.4.2", "jni-sys", @@ -1158,9 +1173,9 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] name = "ndk-sys" -version = "0.5.0+25.2.9519653" +version = "0.6.0+11769913" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" dependencies = [ "jni-sys", ] @@ -1227,9 +1242,9 @@ dependencies = [ [[package]] name = "objc-sys" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459" +checksum = "da284c198fb9b7b0603f8635185e85fbd5b64ee154b1ed406d489077de2d6d60" [[package]] name = "objc2" @@ -1238,7 +1253,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" dependencies = [ "objc-sys", - "objc2-encode", + "objc2-encode 3.0.0", +] + +[[package]] +name = "objc2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b25e1034d0e636cd84707ccdaa9f81243d399196b8a773946dcffec0401659" +dependencies = [ + "objc-sys", + "objc2-encode 4.0.1", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb79768a710a9a1798848179edb186d1af7e8a8679f369e4b8d201dd2a034047" +dependencies = [ + "block2 0.5.0", + "objc2 0.5.1", + "objc2-core-data", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e092bc42eaf30a08844e6a076938c60751225ec81431ab89f5d1ccd9f958d6c" +dependencies = [ + "block2 0.5.0", + "objc2 0.5.1", + "objc2-foundation", ] [[package]] @@ -1247,6 +1295,23 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" +[[package]] +name = "objc2-encode" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88658da63e4cc2c8adb1262902cd6af51094df0488b760d6fd27194269c0950a" + +[[package]] +name = "objc2-foundation" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfaefe14254871ea16c7d88968c0ff14ba554712a20d76421eec52f0a7fb8904" +dependencies = [ + "block2 0.5.0", + "dispatch", + "objc2 0.5.1", +] + [[package]] name = "objc_id" version = "0.1.1" @@ -1306,6 +1371,26 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1507,9 +1592,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sctk-adwaita" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550" +checksum = "7de61fa7334ee8ee1f5c3c58dcc414fb9361e7e8f5bff9d45f4d69eeb89a7169" dependencies = [ "crossfont", "log", @@ -1576,27 +1661,6 @@ dependencies = [ "unsafe-libyaml", ] -[[package]] -name = "servo-fontconfig" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c" -dependencies = [ - "libc", - "servo-fontconfig-sys", -] - -[[package]] -name = "servo-fontconfig-sys" -version = "5.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388" -dependencies = [ - "expat-sys", - "freetype-sys", - "pkg-config", -] - [[package]] name = "signal-hook" version = "0.3.17" @@ -2094,9 +2158,9 @@ dependencies = [ [[package]] name = "web-time" -version = "0.2.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -2151,6 +2215,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -2181,6 +2254,22 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -2193,6 +2282,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -2205,6 +2300,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -2217,6 +2318,18 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -2229,6 +2342,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -2241,6 +2360,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -2253,6 +2378,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -2266,10 +2397,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] -name = "winit" -version = "0.29.15" +name = "windows_x86_64_msvc" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winit" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea9e6d5d66cbf702e0dd820302144f51b69a95acdc495dd98ca280ff206562b1" dependencies = [ "ahash", "android-activity", @@ -2277,28 +2414,30 @@ dependencies = [ "bitflags 2.4.2", "bytemuck", "calloop", - "cfg_aliases", + "cfg_aliases 0.2.0", + "concurrent-queue", "core-foundation", "core-graphics", "cursor-icon", - "icrate", + "dpi", "js-sys", "libc", - "log", "memmap2", "ndk", - "ndk-sys", - "objc2", - "once_cell", + "objc2 0.5.1", + "objc2-app-kit", + "objc2-foundation", "orbclient", "percent-encoding", + "pin-project", "raw-window-handle", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "rustix", "sctk-adwaita", "serde", "smithay-client-toolkit", "smol_str", + "tracing", "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", @@ -2308,7 +2447,7 @@ dependencies = [ "wayland-protocols-plasma", "web-sys", "web-time", - "windows-sys 0.48.0", + "windows-sys 0.52.0", "x11-dl", "x11rb", "xkbcommon-dl", @@ -2430,6 +2569,18 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" +[[package]] +name = "yeslogic-fontconfig-sys" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb6b23999a8b1a997bf47c7bb4d19ad4029c3327bb3386ebe0a5ff584b33c7a" +dependencies = [ + "cstr", + "dlib", + "once_cell", + "pkg-config", +] + [[package]] name = "zerocopy" version = "0.7.32" diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index 7fcbb13a..10ee1aee 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -27,7 +27,7 @@ ahash = { version = "0.8.6", features = ["no-rng"] } bitflags = "2.2.1" clap = { version = "4.2.7", features = ["derive", "env"] } copypasta = { version = "0.10.1", default-features = false } -crossfont = { version = "0.7.0", features = ["force_system_fontconfig"] } +crossfont = "0.8.0" glutin = { version = "0.31.1", default-features = false, features = ["egl", "wgl"] } home = "0.5.5" libc = "0.2" @@ -40,7 +40,7 @@ serde_json = "1" serde_yaml = "0.9.25" toml = "0.8.2" unicode-width = "0.1" -winit = { version = "0.29.15", default-features = false, features = ["rwh_05", "serde"] } +winit = { version = "0.30.0", default-features = false, features = ["rwh_05", "serde"] } [build-dependencies] gl_generator = "0.14.0" @@ -60,7 +60,7 @@ objc = "0.2.2" [target.'cfg(windows)'.dependencies] dirs = "5.0.1" -windows-sys = { version = "0.48", features = [ +windows-sys = { version = "0.52", features = [ "Win32_UI_WindowsAndMessaging", "Win32_System_Threading", "Win32_System_Console", diff --git a/alacritty/src/clipboard.rs b/alacritty/src/clipboard.rs index b3818c75..bb90a13d 100644 --- a/alacritty/src/clipboard.rs +++ b/alacritty/src/clipboard.rs @@ -3,7 +3,6 @@ use raw_window_handle::RawDisplayHandle; use alacritty_terminal::term::ClipboardType; -#[cfg(any(test, not(any(feature = "x11", target_os = "macos", windows))))] use copypasta::nop_clipboard::NopClipboardContext; #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] use copypasta::wayland_clipboard; @@ -31,9 +30,8 @@ impl Clipboard { } } - /// Used for tests and to handle missing clipboard provider when built without the `x11` - /// feature. - #[cfg(any(test, not(any(feature = "x11", target_os = "macos", windows))))] + /// Used for tests, to handle missing clipboard provider when built without the `x11` + /// feature, and as default clipboard value. pub fn new_nop() -> Self { Self { clipboard: Box::new(NopClipboardContext::new().unwrap()), selection: None } } diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs index e4bfa2cb..09793fa0 100644 --- a/alacritty/src/display/window.rs +++ b/alacritty/src/display/window.rs @@ -1,16 +1,16 @@ #[cfg(not(any(target_os = "macos", windows)))] use winit::platform::startup_notify::{ - self, EventLoopExtStartupNotify, WindowBuilderExtStartupNotify, + self, EventLoopExtStartupNotify, WindowAttributesExtStartupNotify, }; #[cfg(all(not(feature = "x11"), not(any(target_os = "macos", windows))))] -use winit::platform::wayland::WindowBuilderExtWayland; +use winit::platform::wayland::WindowAttributesExtWayland; #[rustfmt::skip] #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] use { std::io::Cursor, - winit::platform::x11::{WindowBuilderExtX11, EventLoopWindowTargetExtX11}, + winit::platform::x11::{WindowAttributesExtX11, ActiveEventLoopExtX11}, glutin::platform::x11::X11VisualInfo, winit::window::Icon, png::Decoder, @@ -23,18 +23,18 @@ use { cocoa::appkit::NSColorSpace, cocoa::base::{id, nil, NO, YES}, objc::{msg_send, sel, sel_impl}, - winit::platform::macos::{OptionAsAlt, WindowBuilderExtMacOS, WindowExtMacOS}, + winit::platform::macos::{OptionAsAlt, WindowAttributesExtMacOS, WindowExtMacOS}, }; use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; use winit::dpi::{PhysicalPosition, PhysicalSize}; -use winit::event_loop::EventLoopWindowTarget; +use winit::event_loop::ActiveEventLoop; use winit::monitor::MonitorHandle; #[cfg(windows)] use winit::platform::windows::IconExtWindows; use winit::window::{ CursorIcon, Fullscreen, ImePurpose, Theme, UserAttentionType, Window as WinitWindow, - WindowBuilder, WindowId, + WindowAttributes, WindowId, }; use alacritty_terminal::index::Point; @@ -121,8 +121,8 @@ impl Window { /// Create a new window. /// /// This creates a window and fully initializes a window. - pub fn new( - event_loop: &EventLoopWindowTarget, + pub fn new( + event_loop: &ActiveEventLoop, config: &UiConfig, identity: &Identity, #[rustfmt::skip] @@ -133,7 +133,7 @@ impl Window { x11_visual: Option, ) -> Result { let identity = identity.clone(); - let mut window_builder = Window::get_platform_window( + let mut window_attributes = Window::get_platform_window( &identity, &config.window, #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] @@ -143,14 +143,14 @@ impl Window { ); if let Some(position) = config.window.position { - window_builder = window_builder + window_attributes = window_attributes .with_position(PhysicalPosition::::from((position.x, position.y))); } #[cfg(not(any(target_os = "macos", windows)))] if let Some(token) = event_loop.read_token_from_env() { log::debug!("Activating window with token: {token:?}"); - window_builder = window_builder.with_activation_token(token); + window_attributes = window_attributes.with_activation_token(token); // Remove the token from the env. startup_notify::reset_activation_token_env(); @@ -160,22 +160,23 @@ impl Window { #[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); + window_attributes = window_attributes.with_embed_parent_window(parent_window_id); } - let window = window_builder + window_attributes = window_attributes .with_title(&identity.title) .with_theme(config.window.theme()) .with_visible(false) .with_transparent(true) .with_blur(config.window.blur) .with_maximized(config.window.maximized()) - .with_fullscreen(config.window.fullscreen()) - .build(event_loop)?; + .with_fullscreen(config.window.fullscreen()); + + let window = event_loop.create_window(window_attributes)?; // Text cursor. let current_mouse_cursor = CursorIcon::Text; - window.set_cursor_icon(current_mouse_cursor); + window.set_cursor(current_mouse_cursor); // Enable IME. window.set_ime_allowed(true); @@ -248,7 +249,7 @@ impl Window { pub fn set_mouse_cursor(&mut self, cursor: CursorIcon) { if cursor != self.current_mouse_cursor { self.current_mouse_cursor = cursor; - self.window.set_cursor_icon(cursor); + self.window.set_cursor(cursor); } } @@ -267,7 +268,7 @@ impl Window { #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] x11_visual: Option< X11VisualInfo, >, - ) -> WindowBuilder { + ) -> WindowAttributes { #[cfg(feature = "x11")] let icon = { let mut decoder = Decoder::new(Cursor::new(WINDOW_ICON)); @@ -279,7 +280,7 @@ impl Window { .expect("invalid embedded icon format") }; - let builder = WindowBuilder::new() + let builder = WinitWindow::default_attributes() .with_name(&identity.class.general, &identity.class.instance) .with_decorations(window_config.decorations != Decorations::None); @@ -296,10 +297,10 @@ impl Window { } #[cfg(windows)] - pub fn get_platform_window(_: &Identity, window_config: &WindowConfig) -> WindowBuilder { + pub fn get_platform_window(_: &Identity, window_config: &WindowConfig) -> WindowAttributes { let icon = winit::window::Icon::from_resource(IDI_ICON, None); - WindowBuilder::new() + WinitWindow::default_attributes() .with_decorations(window_config.decorations != Decorations::None) .with_window_icon(icon.ok()) } @@ -309,8 +310,9 @@ impl Window { _: &Identity, window_config: &WindowConfig, tabbing_id: &Option, - ) -> WindowBuilder { - let mut window = WindowBuilder::new().with_option_as_alt(window_config.option_as_alt()); + ) -> WindowAttributes { + let mut window = + WinitWindow::default_attributes().with_option_as_alt(window_config.option_as_alt()); if let Some(tabbing_id) = tabbing_id { window = window.with_tabbing_identifier(tabbing_id); diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index 5276776a..ac8474be 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -18,13 +18,12 @@ use crossfont::Size as FontSize; use glutin::display::{Display as GlutinDisplay, GetGlDisplay}; use log::{debug, error, info, warn}; use raw_window_handle::HasRawDisplayHandle; +use winit::application::ApplicationHandler; use winit::event::{ ElementState, Event as WinitEvent, Ime, Modifiers, MouseButton, StartCause, Touch as TouchEvent, WindowEvent, }; -use winit::event_loop::{ - ControlFlow, DeviceEvents, EventLoop, EventLoopProxy, EventLoopWindowTarget, -}; +use winit::event_loop::{ActiveEventLoop, ControlFlow, DeviceEvents, EventLoop, EventLoopProxy}; use winit::window::WindowId; use alacritty_terminal::event::{Event as TerminalEvent, EventListener, Notify}; @@ -49,7 +48,7 @@ use crate::display::hint::HintMatch; use crate::display::window::Window; use crate::display::{Display, Preedit, SizeInfo}; use crate::input::{self, ActionContext as _, FONT_SIZE_STEP}; -use crate::logging::LOG_TARGET_CONFIG; +use crate::logging::{LOG_TARGET_CONFIG, LOG_TARGET_WINIT}; use crate::message_bar::{Message, MessageBuffer}; use crate::scheduler::{Scheduler, TimerId, Topic}; use crate::window_context::WindowContext; @@ -66,6 +65,372 @@ const MAX_SEARCH_HISTORY_SIZE: usize = 255; /// Touch zoom speed. const TOUCH_ZOOM_FACTOR: f32 = 0.01; +/// The event processor. +/// +/// Stores some state from received events and dispatches actions when they are +/// triggered. +pub struct Processor { + clipboard: Clipboard, + scheduler: Scheduler, + initial_window_options: Option, + initial_window_error: Option>, + windows: HashMap, + proxy: EventLoopProxy, + gl_display: Option, + #[cfg(unix)] + global_ipc_options: ParsedOptions, + cli_options: CliOptions, + config: Rc, +} + +impl Processor { + /// Create a new event processor. + pub fn new( + config: UiConfig, + cli_options: CliOptions, + event_loop: &EventLoop, + ) -> Processor { + let proxy = event_loop.create_proxy(); + let scheduler = Scheduler::new(proxy.clone()); + let initial_window_options = Some(cli_options.window_options.clone()); + + // Disable all device events, since we don't care about them. + event_loop.listen_device_events(DeviceEvents::Never); + + // SAFETY: Since this takes a pointer to the winit event loop, it MUST be dropped first, + // which is done in `loop_exiting`. + let clipboard = unsafe { Clipboard::new(event_loop.raw_display_handle()) }; + + Processor { + initial_window_options, + initial_window_error: None, + cli_options, + proxy, + scheduler, + gl_display: None, + config: Rc::new(config), + clipboard, + windows: Default::default(), + #[cfg(unix)] + global_ipc_options: Default::default(), + } + } + + /// Create initial window and load GL platform. + /// + /// This will initialize the OpenGL Api and pick a config that + /// will be used for the rest of the windows. + pub fn create_initial_window( + &mut self, + event_loop: &ActiveEventLoop, + options: WindowOptions, + ) -> Result<(), Box> { + let window_context = + WindowContext::initial(event_loop, self.proxy.clone(), self.config.clone(), options)?; + + self.gl_display = Some(window_context.display.gl_context().display()); + self.windows.insert(window_context.id(), window_context); + + Ok(()) + } + + /// Create a new terminal window. + pub fn create_window( + &mut self, + event_loop: &ActiveEventLoop, + options: WindowOptions, + ) -> Result<(), Box> { + let window = self.windows.iter().next().as_ref().unwrap().1; + + // Overide config with CLI/IPC options. + let mut config_overrides = options.config_overrides(); + #[cfg(unix)] + config_overrides.extend_from_slice(&self.global_ipc_options); + let mut config = self.config.clone(); + config = config_overrides.override_config_rc(config); + + #[allow(unused_mut)] + let mut window_context = + window.additional(event_loop, self.proxy.clone(), config, options, config_overrides)?; + + self.windows.insert(window_context.id(), window_context); + Ok(()) + } + + /// Run the event loop. + /// + /// The result is exit code generate from the loop. + pub fn run(mut self, event_loop: EventLoop) -> Result<(), Box> { + let result = event_loop.run_app(&mut self); + if let Some(initial_window_error) = self.initial_window_error.take() { + Err(initial_window_error) + } else { + result.map_err(Into::into) + } + } + + /// Check if an event is irrelevant and can be skipped. + fn skip_window_event(event: &WindowEvent) -> bool { + matches!( + event, + WindowEvent::KeyboardInput { is_synthetic: true, .. } + | WindowEvent::ActivationTokenDone { .. } + | WindowEvent::DoubleTapGesture { .. } + | WindowEvent::TouchpadPressure { .. } + | WindowEvent::RotationGesture { .. } + | WindowEvent::CursorEntered { .. } + | WindowEvent::PinchGesture { .. } + | WindowEvent::AxisMotion { .. } + | WindowEvent::PanGesture { .. } + | WindowEvent::HoveredFileCancelled + | WindowEvent::Destroyed + | WindowEvent::ThemeChanged(_) + | WindowEvent::HoveredFile(_) + | WindowEvent::Moved(_) + ) + } +} + +impl ApplicationHandler for Processor { + fn resumed(&mut self, _event_loop: &ActiveEventLoop) {} + + fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) { + if cause != StartCause::Init { + return; + } + + let initial_window_options = match self.initial_window_options.take() { + Some(initial_window_options) => initial_window_options, + None => return, + }; + + if let Err(err) = self.create_initial_window(event_loop, initial_window_options) { + self.initial_window_error = Some(err); + event_loop.exit(); + return; + } + + info!("Initialisation complete"); + } + + fn window_event( + &mut self, + _event_loop: &ActiveEventLoop, + window_id: WindowId, + event: WindowEvent, + ) { + if self.config.debug.print_events { + info!(target: LOG_TARGET_WINIT, "{event:?}"); + } + + // Ignore all events we do not care about. + if Self::skip_window_event(&event) { + return; + } + + let window_context = match self.windows.get_mut(&window_id) { + Some(window_context) => window_context, + None => return, + }; + + let is_redraw = matches!(event, WindowEvent::RedrawRequested); + + window_context.handle_event( + #[cfg(target_os = "macos")] + _event_loop, + &self.proxy, + &mut self.clipboard, + &mut self.scheduler, + WinitEvent::WindowEvent { window_id, event }, + ); + + if is_redraw { + window_context.draw(&mut self.scheduler); + } + } + + fn user_event(&mut self, event_loop: &ActiveEventLoop, event: Event) { + if self.config.debug.print_events { + info!(target: LOG_TARGET_WINIT, "{event:?}"); + } + + // Handle events which don't mandate the WindowId. + match &event.payload { + // Process IPC config update. + #[cfg(unix)] + EventType::IpcConfig(ipc_config) => { + // Try and parse options as toml. + let mut options = ParsedOptions::from_options(&ipc_config.options); + + // Override IPC config for each window with matching ID. + for (_, window_context) in self + .windows + .iter_mut() + .filter(|(id, _)| event.window_id.is_none() || event.window_id == Some(**id)) + { + if ipc_config.reset { + window_context.reset_window_config(self.config.clone()); + } else { + window_context.add_window_config(self.config.clone(), &options); + } + } + + // Persist global options for future windows. + if event.window_id.is_none() { + if ipc_config.reset { + self.global_ipc_options.clear(); + } else { + self.global_ipc_options.append(&mut options); + } + } + }, + EventType::ConfigReload(path) => { + // Clear config logs from message bar for all terminals. + for window_context in self.windows.values_mut() { + if !window_context.message_buffer.is_empty() { + window_context.message_buffer.remove_target(LOG_TARGET_CONFIG); + window_context.display.pending_update.dirty = true; + } + } + + // Load config and update each terminal. + if let Ok(config) = config::reload(path, &mut self.cli_options) { + self.config = Rc::new(config); + + for window_context in self.windows.values_mut() { + window_context.update_config(self.config.clone()); + } + } + }, + // Create a new terminal window. + EventType::CreateWindow(options) => { + // XXX Ensure that no context is current when creating a new window, + // otherwise it may lock the backing buffer of the + // surface of current context when asking + // e.g. EGL on Wayland to create a new context. + for window_context in self.windows.values_mut() { + window_context.display.make_not_current(); + } + + if let Err(err) = self.create_window(event_loop, options.clone()) { + error!("Could not open window: {:?}", err); + } + }, + _ => (), + }; + + let window_id = match event.window_id { + Some(window_id) => window_id, + None => return, + }; + + // Handle the rest of events which require WindowId. + match event.payload { + EventType::Terminal(TerminalEvent::Wakeup) => { + if let Some(window_context) = self.windows.get_mut(&window_id) { + window_context.dirty = true; + if window_context.display.window.has_frame { + window_context.display.window.request_redraw(); + } + } + }, + EventType::Terminal(TerminalEvent::Exit) => { + // Remove the closed terminal. + let window_context = match self.windows.remove(&window_id) { + Some(window_context) => window_context, + None => return, + }; + + // Unschedule pending events. + self.scheduler.unschedule_window(window_context.id()); + + // Shutdown if no more terminals are open. + if self.windows.is_empty() { + // Write ref tests of last window to disk. + if self.config.debug.ref_test { + window_context.write_ref_test_results(); + } + + event_loop.exit(); + } + }, + // NOTE: This event bypasses batching to minimize input latency. + EventType::Frame => { + if let Some(window_context) = self.windows.get_mut(&window_id) { + window_context.display.window.has_frame = true; + if window_context.dirty { + window_context.display.window.request_redraw(); + } + } + }, + _ => { + if let Some(window_context) = self.windows.get_mut(&window_id) { + window_context.handle_event( + #[cfg(target_os = "macos")] + event_loop, + &self.proxy, + &mut self.clipboard, + &mut self.scheduler, + WinitEvent::UserEvent(event), + ); + } + }, + } + } + + fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) { + if self.config.debug.print_events { + info!(target: LOG_TARGET_WINIT, "About to wait"); + } + + // Dispatch event to all windows. + for window_context in self.windows.values_mut() { + window_context.handle_event( + #[cfg(target_os = "macos")] + event_loop, + &self.proxy, + &mut self.clipboard, + &mut self.scheduler, + WinitEvent::AboutToWait, + ); + } + + // Update the scheduler after event processing to ensure + // the event loop deadline is as accurate as possible. + let control_flow = match self.scheduler.update() { + Some(instant) => ControlFlow::WaitUntil(instant), + None => ControlFlow::Wait, + }; + event_loop.set_control_flow(control_flow); + } + + fn exiting(&mut self, _event_loop: &ActiveEventLoop) { + if self.config.debug.print_events { + info!("Exiting the event loop"); + } + + 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(); + } + }, + _ => (), + } + + // SAFETY: The clipboard must be dropped before the event loop, so use the nop clipboard + // as a safe placeholder. + mem::swap(&mut self.clipboard, &mut Clipboard::new_nop()); + } +} + /// Alacritty events. #[derive(Debug, Clone)] pub struct Event { @@ -218,7 +583,7 @@ pub struct ActionContext<'a, N, T> { pub config: &'a UiConfig, pub cursor_blink_timed_out: &'a mut bool, #[cfg(target_os = "macos")] - pub event_loop: &'a EventLoopWindowTarget, + pub event_loop: &'a ActiveEventLoop, pub event_proxy: &'a EventLoopProxy, pub scheduler: &'a mut Scheduler, pub search_state: &'a mut SearchState, @@ -919,7 +1284,7 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon } #[cfg(target_os = "macos")] - fn event_loop(&self) -> &EventLoopWindowTarget { + fn event_loop(&self) -> &ActiveEventLoop { self.event_loop } @@ -1468,12 +1833,13 @@ impl input::Processor> { }, WindowEvent::KeyboardInput { is_synthetic: true, .. } | WindowEvent::ActivationTokenDone { .. } + | WindowEvent::DoubleTapGesture { .. } | WindowEvent::TouchpadPressure { .. } - | WindowEvent::TouchpadMagnify { .. } - | WindowEvent::TouchpadRotate { .. } - | WindowEvent::SmartMagnify { .. } + | WindowEvent::RotationGesture { .. } | WindowEvent::CursorEntered { .. } + | WindowEvent::PinchGesture { .. } | WindowEvent::AxisMotion { .. } + | WindowEvent::PanGesture { .. } | WindowEvent::HoveredFileCancelled | WindowEvent::Destroyed | WindowEvent::ThemeChanged(_) @@ -1493,363 +1859,6 @@ impl input::Processor> { } } -/// The event processor. -/// -/// Stores some state from received events and dispatches actions when they are -/// triggered. -pub struct Processor { - windows: HashMap, - gl_display: Option, - #[cfg(unix)] - global_ipc_options: ParsedOptions, - cli_options: CliOptions, - config: Rc, -} - -impl Processor { - /// Create a new event processor. - /// - /// Takes a writer which is expected to be hooked up to the write end of a PTY. - pub fn new( - config: UiConfig, - cli_options: CliOptions, - _event_loop: &EventLoop, - ) -> Processor { - Processor { - cli_options, - gl_display: None, - config: Rc::new(config), - windows: Default::default(), - #[cfg(unix)] - global_ipc_options: Default::default(), - } - } - - /// Create initial window and load GL platform. - /// - /// This will initialize the OpenGL Api and pick a config that - /// will be used for the rest of the windows. - pub fn create_initial_window( - &mut self, - event_loop: &EventLoopWindowTarget, - proxy: EventLoopProxy, - options: WindowOptions, - ) -> Result<(), Box> { - 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(()) - } - - /// Create a new terminal window. - pub fn create_window( - &mut self, - event_loop: &EventLoopWindowTarget, - proxy: EventLoopProxy, - options: WindowOptions, - ) -> Result<(), Box> { - let window = self.windows.iter().next().as_ref().unwrap().1; - - // Overide config with CLI/IPC options. - let mut config_overrides = options.config_overrides(); - #[cfg(unix)] - config_overrides.extend_from_slice(&self.global_ipc_options); - let mut config = self.config.clone(); - config = config_overrides.override_config_rc(config); - - #[allow(unused_mut)] - let mut window_context = - window.additional(event_loop, proxy, config, options, config_overrides)?; - - self.windows.insert(window_context.id(), window_context); - Ok(()) - } - - /// Run the event loop. - /// - /// The result is exit code generate from the loop. - pub fn run( - &mut self, - event_loop: EventLoop, - initial_window_options: WindowOptions, - ) -> Result<(), Box> { - let proxy = event_loop.create_proxy(); - let mut scheduler = Scheduler::new(proxy.clone()); - let mut initial_window_options = Some(initial_window_options); - - // Disable all device events, since we don't care about them. - event_loop.listen_device_events(DeviceEvents::Never); - - let mut initial_window_error = Ok(()); - let initial_window_error_loop = &mut initial_window_error; - // SAFETY: Since this takes a pointer to the winit event loop, it MUST be dropped first, - // which is done by `move` into event loop. - let mut clipboard = unsafe { Clipboard::new(event_loop.raw_display_handle()) }; - let result = event_loop.run(move |event, event_loop| { - if self.config.debug.print_events { - info!("winit event: {:?}", event); - } - - // Ignore all events we do not care about. - if Self::skip_event(&event) { - return; - } - - match event { - // The event loop just got initialized. Create a window. - WinitEvent::Resumed => { - // Creating window inside event loop is required for platforms like macOS to - // properly initialize state, like tab management. Otherwise the first - // window won't handle tabs. - let initial_window_options = match initial_window_options.take() { - Some(initial_window_options) => initial_window_options, - None => return, - }; - - if let Err(err) = self.create_initial_window( - event_loop, - proxy.clone(), - initial_window_options, - ) { - *initial_window_error_loop = 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), - payload: EventType::Terminal(TerminalEvent::Wakeup), - }) => { - if let Some(window_context) = self.windows.get_mut(&window_id) { - window_context.dirty = true; - if window_context.display.window.has_frame { - window_context.display.window.request_redraw(); - } - } - }, - // NOTE: This event bypasses batching to minimize input latency. - WinitEvent::UserEvent(Event { - window_id: Some(window_id), - payload: EventType::Frame, - }) => { - if let Some(window_context) = self.windows.get_mut(&window_id) { - window_context.display.window.has_frame = true; - if window_context.dirty { - window_context.display.window.request_redraw(); - } - } - }, - // Check for shutdown. - WinitEvent::UserEvent(Event { - window_id: Some(window_id), - payload: EventType::Terminal(TerminalEvent::Exit), - }) => { - // Remove the closed terminal. - let window_context = match self.windows.remove(&window_id) { - Some(window_context) => window_context, - None => return, - }; - - // Unschedule pending events. - scheduler.unschedule_window(window_context.id()); - - // Shutdown if no more terminals are open. - if self.windows.is_empty() { - // Write ref tests of last window to disk. - if self.config.debug.ref_test { - window_context.write_ref_test_results(); - } - - event_loop.exit(); - } - }, - WinitEvent::WindowEvent { window_id, event: WindowEvent::RedrawRequested } => { - let window_context = match self.windows.get_mut(&window_id) { - Some(window_context) => window_context, - None => return, - }; - - window_context.handle_event( - #[cfg(target_os = "macos")] - event_loop, - &proxy, - &mut clipboard, - &mut scheduler, - event, - ); - - window_context.draw(&mut scheduler); - }, - // Process all pending events. - WinitEvent::AboutToWait => { - // Dispatch event to all windows. - for window_context in self.windows.values_mut() { - window_context.handle_event( - #[cfg(target_os = "macos")] - event_loop, - &proxy, - &mut clipboard, - &mut scheduler, - WinitEvent::AboutToWait, - ); - } - - // Update the scheduler after event processing to ensure - // the event loop deadline is as accurate as possible. - 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), .. }) => { - // Clear config logs from message bar for all terminals. - for window_context in self.windows.values_mut() { - if !window_context.message_buffer.is_empty() { - window_context.message_buffer.remove_target(LOG_TARGET_CONFIG); - window_context.display.pending_update.dirty = true; - } - } - - // Load config and update each terminal. - if let Ok(config) = config::reload(&path, &mut self.cli_options) { - self.config = Rc::new(config); - - for window_context in self.windows.values_mut() { - window_context.update_config(self.config.clone()); - } - } - }, - // Process IPC config update. - #[cfg(unix)] - WinitEvent::UserEvent(Event { - payload: EventType::IpcConfig(ipc_config), - window_id, - }) => { - // Try and parse options as toml. - let mut options = ParsedOptions::from_options(&ipc_config.options); - - // Override IPC config for each window with matching ID. - for (_, window_context) in self - .windows - .iter_mut() - .filter(|(id, _)| window_id.is_none() || window_id == Some(**id)) - { - if ipc_config.reset { - window_context.reset_window_config(self.config.clone()); - } else { - window_context.add_window_config(self.config.clone(), &options); - } - } - - // Persist global options for future windows. - if window_id.is_none() { - if ipc_config.reset { - self.global_ipc_options.clear(); - } else { - self.global_ipc_options.append(&mut options); - } - } - }, - // Create a new terminal window. - WinitEvent::UserEvent(Event { - payload: EventType::CreateWindow(options), .. - }) => { - // XXX Ensure that no context is current when creating a new window, - // otherwise it may lock the backing buffer of the - // surface of current context when asking - // e.g. EGL on Wayland to create a new context. - for window_context in self.windows.values_mut() { - window_context.display.make_not_current(); - } - - if let Err(err) = self.create_window(event_loop, proxy.clone(), options) { - error!("Could not open window: {:?}", err); - } - }, - // Process events affecting all windows. - WinitEvent::UserEvent(event @ Event { window_id: None, .. }) => { - for window_context in self.windows.values_mut() { - window_context.handle_event( - #[cfg(target_os = "macos")] - event_loop, - &proxy, - &mut clipboard, - &mut scheduler, - event.clone().into(), - ); - } - }, - // Process window-specific events. - WinitEvent::WindowEvent { window_id, .. } - | WinitEvent::UserEvent(Event { window_id: Some(window_id), .. }) => { - if let Some(window_context) = self.windows.get_mut(&window_id) { - window_context.handle_event( - #[cfg(target_os = "macos")] - event_loop, - &proxy, - &mut clipboard, - &mut scheduler, - event, - ); - } - }, - _ => (), - } - }); - - 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. - fn skip_event(event: &WinitEvent) -> bool { - match event { - WinitEvent::NewEvents(StartCause::Init) => false, - WinitEvent::WindowEvent { event, .. } => matches!( - event, - WindowEvent::KeyboardInput { is_synthetic: true, .. } - | WindowEvent::TouchpadPressure { .. } - | WindowEvent::CursorEntered { .. } - | WindowEvent::AxisMotion { .. } - | WindowEvent::HoveredFileCancelled - | WindowEvent::Destroyed - | WindowEvent::HoveredFile(_) - | WindowEvent::Moved(_) - ), - WinitEvent::Suspended { .. } | WinitEvent::NewEvents { .. } => true, - _ => false, - } - } -} - #[derive(Debug, Clone)] pub struct EventProxy { proxy: EventLoopProxy, diff --git a/alacritty/src/input/mod.rs b/alacritty/src/input/mod.rs index 365717c3..095e8737 100644 --- a/alacritty/src/input/mod.rs +++ b/alacritty/src/input/mod.rs @@ -20,10 +20,10 @@ use winit::event::{ ElementState, Modifiers, MouseButton, MouseScrollDelta, Touch as TouchEvent, TouchPhase, }; #[cfg(target_os = "macos")] -use winit::event_loop::EventLoopWindowTarget; +use winit::event_loop::ActiveEventLoop; use winit::keyboard::ModifiersState; #[cfg(target_os = "macos")] -use winit::platform::macos::EventLoopWindowTargetExtMacOS; +use winit::platform::macos::ActiveEventLoopExtMacOS; use winit::window::CursorIcon; use alacritty_terminal::event::EventListener; @@ -107,7 +107,7 @@ pub trait ActionContext { fn message(&self) -> Option<&Message>; fn config(&self) -> &UiConfig; #[cfg(target_os = "macos")] - fn event_loop(&self) -> &EventLoopWindowTarget; + fn event_loop(&self) -> &ActiveEventLoop; fn mouse_mode(&self) -> bool; fn clipboard_mut(&mut self) -> &mut Clipboard; fn scheduler_mut(&mut self) -> &mut Scheduler; @@ -1224,7 +1224,7 @@ mod tests { } #[cfg(target_os = "macos")] - fn event_loop(&self) -> &EventLoopWindowTarget { + fn event_loop(&self) -> &ActiveEventLoop { unimplemented!(); } diff --git a/alacritty/src/logging.rs b/alacritty/src/logging.rs index a3833a5b..59303649 100644 --- a/alacritty/src/logging.rs +++ b/alacritty/src/logging.rs @@ -28,6 +28,9 @@ const ALACRITTY_LOG_ENV: &str = "ALACRITTY_LOG"; /// Logging target for config error messages. pub const LOG_TARGET_CONFIG: &str = "alacritty_config_derive"; +/// Logging target for winit events. +pub const LOG_TARGET_WINIT: &str = "alacritty_winit_event"; + /// Name for the environment variable containing extra logging targets. /// /// The targets are semicolon separated. @@ -47,6 +50,7 @@ fn extra_log_targets() -> &'static [String] { const ALLOWED_TARGETS: &[&str] = &[ LOG_TARGET_IPC_CONFIG, LOG_TARGET_CONFIG, + LOG_TARGET_WINIT, "alacritty_config_derive", "alacritty_terminal", "alacritty", diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs index f9301767..2951c224 100644 --- a/alacritty/src/main.rs +++ b/alacritty/src/main.rs @@ -19,11 +19,11 @@ use std::path::PathBuf; use std::{env, fs}; use log::info; +#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] +use raw_window_handle::{HasRawDisplayHandle, RawDisplayHandle}; #[cfg(windows)] use windows_sys::Win32::System::Console::{AttachConsole, FreeConsole, ATTACH_PARENT_PROCESS}; -use winit::event_loop::EventLoopBuilder as WinitEventLoopBuilder; -#[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] -use winit::platform::x11::EventLoopWindowTargetExtX11; +use winit::event_loop::EventLoop; use alacritty_terminal::tty; @@ -125,7 +125,7 @@ impl Drop for TemporaryFiles { /// config change monitor, and runs the main display loop. fn alacritty(mut options: Options) -> Result<(), Box> { // Setup winit event loop. - let window_event_loop = WinitEventLoopBuilder::::with_user_event().build()?; + let window_event_loop = EventLoop::::with_user_event().build()?; // Initialize the logger as soon as possible as to capture output from other subsystems. let log_file = logging::initialize(&options, window_event_loop.create_proxy()) @@ -135,7 +135,14 @@ fn alacritty(mut options: Options) -> Result<(), Box> { info!("Version {}", env!("VERSION")); #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] - info!("Running on {}", if window_event_loop.is_x11() { "X11" } else { "Wayland" }); + info!( + "Running on {}", + if matches!(window_event_loop.raw_display_handle(), RawDisplayHandle::Wayland(_)) { + "Wayland" + } else { + "X11" + } + ); #[cfg(not(any(feature = "x11", target_os = "macos", windows)))] info!("Running on Wayland"); @@ -189,13 +196,14 @@ fn alacritty(mut options: Options) -> Result<(), Box> { }; // Event processor. - let window_options = options.window_options.clone(); - let mut processor = Processor::new(config, options, &window_event_loop); + let processor = Processor::new(config, options, &window_event_loop); // Start event loop and block until shutdown. - let result = processor.run(window_event_loop, window_options); + let result = processor.run(window_event_loop); - // This explicit drop is needed for Windows, ConPTY backend. Otherwise a deadlock can occur. + // `Processor` must be dropped before calling `FreeConsole`. + // + // This is needed for ConPTY backend. Otherwise a deadlock can occur. // The cause: // - Drop for ConPTY will deadlock if the conout pipe has already been dropped // - ConPTY is dropped when the last of processor and window context are dropped, because both @@ -206,7 +214,6 @@ fn alacritty(mut options: Options) -> Result<(), Box> { // order. // // FIXME: Change PTY API to enforce the correct drop order with the typesystem. - drop(processor); // Terminate the config monitor. if let Some(config_monitor) = config_monitor.take() { @@ -234,5 +241,5 @@ fn log_config_path(config: &UiConfig) { let _ = write!(msg, "\n {:?}", path.display()); } - info!("{}", msg); + info!("{msg}"); } diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs index f0f24fe8..f5fb5cc5 100644 --- a/alacritty/src/window_context.rs +++ b/alacritty/src/window_context.rs @@ -17,7 +17,7 @@ use log::info; use raw_window_handle::HasRawDisplayHandle; use serde_json as json; use winit::event::{Event as WinitEvent, Modifiers, WindowEvent}; -use winit::event_loop::{EventLoopProxy, EventLoopWindowTarget}; +use winit::event_loop::{ActiveEventLoop, EventLoopProxy}; use winit::window::WindowId; use alacritty_terminal::event::Event as TerminalEvent; @@ -70,7 +70,7 @@ pub struct WindowContext { impl WindowContext { /// Create initial window context that does bootstrapping the graphics API we're going to use. pub fn initial( - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, proxy: EventLoopProxy, config: Rc, options: WindowOptions, @@ -120,7 +120,7 @@ impl WindowContext { /// Create additional context with the graphics platform other windows are using. pub fn additional( &self, - event_loop: &EventLoopWindowTarget, + event_loop: &ActiveEventLoop, proxy: EventLoopProxy, config: Rc, options: WindowOptions, @@ -399,7 +399,7 @@ impl WindowContext { /// Process events for this terminal window. pub fn handle_event( &mut self, - #[cfg(target_os = "macos")] event_loop: &EventLoopWindowTarget, + #[cfg(target_os = "macos")] event_loop: &ActiveEventLoop, event_proxy: &EventLoopProxy, clipboard: &mut Clipboard, scheduler: &mut Scheduler, diff --git a/alacritty_terminal/Cargo.toml b/alacritty_terminal/Cargo.toml index ed36cc36..79e7c05b 100644 --- a/alacritty_terminal/Cargo.toml +++ b/alacritty_terminal/Cargo.toml @@ -34,7 +34,7 @@ signal-hook = "0.3.10" [target.'cfg(windows)'.dependencies] piper = "0.2.1" miow = "0.6.0" -windows-sys = { version = "0.48.0", features = [ +windows-sys = { version = "0.52.0", features = [ "Win32_System_Console", "Win32_Foundation", "Win32_Security",