diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | Cargo.lock | 299 | ||||
-rw-r--r-- | alacritty/Cargo.toml | 3 | ||||
-rw-r--r-- | alacritty/src/clipboard.rs | 19 | ||||
-rw-r--r-- | alacritty/src/display/mod.rs | 48 | ||||
-rw-r--r-- | alacritty/src/display/window.rs | 93 | ||||
-rw-r--r-- | alacritty/src/event.rs | 183 | ||||
-rw-r--r-- | alacritty/src/input.rs | 2 | ||||
-rw-r--r-- | alacritty/src/main.rs | 2 | ||||
-rw-r--r-- | alacritty/src/renderer/mod.rs | 1 | ||||
-rw-r--r-- | alacritty/src/renderer/platform.rs | 2 | ||||
-rw-r--r-- | alacritty/src/window_context.rs | 111 |
12 files changed, 414 insertions, 350 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d66beeb..ef262f2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Default Vi key bindings for `Last`/`First` actions not working on X11/Wayland - Cut off wide characters in preedit string - Scrolling on touchscreens +- Double clicking on CSD titlebar not always maximizing a window on Wayland ### Removed @@ -37,7 +37,7 @@ dependencies = [ "alacritty_config", "alacritty_config_derive", "alacritty_terminal", - "bitflags 2.3.1", + "bitflags 2.3.3", "clap", "clap_complete", "cocoa", @@ -55,7 +55,6 @@ dependencies = [ "once_cell", "parking_lot 0.12.1", "png", - "raw-window-handle", "serde", "serde_json", "serde_yaml", @@ -86,7 +85,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.18", + "syn", "toml 0.7.4", ] @@ -97,7 +96,7 @@ dependencies = [ "alacritty_config", "alacritty_config_derive", "base64", - "bitflags 2.3.1", + "bitflags 2.3.3", "home", "libc", "log", @@ -121,13 +120,15 @@ dependencies = [ [[package]] name = "android-activity" -version = "0.4.1" +version = "0.5.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c77a0045eda8b888c76ea473c2b0515ba6f471d318f8927c5c72240937035a6" +checksum = "934936a9ad4dc79563cd6644fcef68dc328f105d927679454de39ad03ca1cfe8" dependencies = [ "android-properties", - "bitflags 1.3.2", + "bitflags 2.3.3", "cc", + "cesu8", + "jni", "jni-sys", "libc", "log", @@ -135,6 +136,7 @@ dependencies = [ "ndk-context", "ndk-sys", "num_enum", + "thiserror", ] [[package]] @@ -205,6 +207,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] +name = "as-raw-xcb-connection" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5f312b0a56c5cdf967c0aeb67f6289603354951683bc97ddc595ab974ba9aa" + +[[package]] name = "atomic-waker" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -230,9 +238,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.1" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" dependencies = [ "serde", ] @@ -249,7 +257,16 @@ version = "0.1.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" dependencies = [ - "objc-sys", + "objc-sys 0.2.0-beta.2", +] + +[[package]] +name = "block-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dd7cf50912cddc06dc5ea7c08c5e81c1b2c842a70d19def1848d54c586fed92" +dependencies = [ + "objc-sys 0.3.1", ] [[package]] @@ -258,8 +275,18 @@ version = "0.2.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" dependencies = [ - "block-sys", - "objc2-encode", + "block-sys 0.1.0-beta.1", + "objc2-encode 2.0.0-pre.2", +] + +[[package]] +name = "block2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" +dependencies = [ + "block-sys 0.2.0", + "objc2 0.4.1", ] [[package]] @@ -275,6 +302,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" [[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] name = "calloop" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -298,6 +331,12 @@ dependencies = [ ] [[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -366,7 +405,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.18", + "syn", ] [[package]] @@ -432,6 +471,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] name = "copypasta" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -591,7 +640,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.0", + "libloading", ] [[package]] @@ -722,7 +771,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn", ] [[package]] @@ -795,6 +844,16 @@ dependencies = [ ] [[package]] +name = "gethostname" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb65d4ba3173c56a500b555b532f72c42e8d1fe64962b518897f8959fae2c177" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] name = "getrandom" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -818,9 +877,9 @@ dependencies = [ [[package]] name = "glutin" -version = "0.30.9" +version = "0.30.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b0385782048be65f0a9dd046c469d6a758a53fe1aa63a8111dea394d2ffa2f" +checksum = "8fc93b03242719b8ad39fb26ed2b01737144ce7bd4bfc7adadcef806596760fe" dependencies = [ "bitflags 1.3.2", "cfg_aliases", @@ -830,8 +889,8 @@ dependencies = [ "glutin_egl_sys", "glutin_glx_sys", "glutin_wgl_sys", - "libloading 0.7.4", - "objc2", + "libloading", + "objc2 0.3.0-beta.3.patch-leaks.3", "once_cell", "raw-window-handle", "wayland-sys 0.30.1", @@ -841,9 +900,9 @@ dependencies = [ [[package]] name = "glutin_egl_sys" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b3bcbddc51573b977fc6dca5d93867e4f29682cdbaf5d13e48f4fa4346d4d87" +checksum = "af784eb26c5a68ec85391268e074f0aa618c096eadb5d6330b0911cf34fe57c5" dependencies = [ "gl_generator", "windows-sys 0.45.0", @@ -882,9 +941,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "home" @@ -896,6 +955,17 @@ dependencies = [ ] [[package]] +name = "icrate" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" +dependencies = [ + "block2 0.3.0", + "dispatch", + "objc2 0.4.1", +] + +[[package]] name = "indexmap" version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -962,7 +1032,7 @@ checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi", "io-lifetimes", - "rustix", + "rustix 0.37.19", "windows-sys 0.48.0", ] @@ -973,6 +1043,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if 1.0.0", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] name = "jni-sys" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1052,9 +1138,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libloading" @@ -1067,16 +1153,6 @@ dependencies = [ ] [[package]] -name = "libloading" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" -dependencies = [ - "cfg-if 1.0.0", - "windows-sys 0.48.0", -] - -[[package]] name = "linked-hash-map" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1089,6 +1165,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + +[[package]] name = "lock_api" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1255,12 +1337,13 @@ dependencies = [ [[package]] name = "ndk" -version = "0.7.0" +version = "0.8.0-beta.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +checksum = "49f58741784b0f6ac12311c3f6fbdb3c766a992f8914d035c77a07b5fd2940dc" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.3.3", "jni-sys", + "log", "ndk-sys", "num_enum", "raw-window-handle", @@ -1275,9 +1358,9 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] name = "ndk-sys" -version = "0.4.1+23.1.7779620" +version = "0.5.0-beta.0+25.2.9519653" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +checksum = "ff38603775cba10d0f1141fab1b167df73662a0636a4b631c187fe11fb624042" dependencies = [ "jni-sys", ] @@ -1361,23 +1444,23 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.11" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.11" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1407,14 +1490,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" [[package]] +name = "objc-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e1d07c6eab1ce8b6382b8e3c7246fe117ff3f8b34be065f5ebace6749fe845" + +[[package]] name = "objc2" version = "0.3.0-beta.3.patch-leaks.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" dependencies = [ - "block2", - "objc-sys", - "objc2-encode", + "block2 0.2.0-alpha.6", + "objc-sys 0.2.0-beta.2", + "objc2-encode 2.0.0-pre.2", +] + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys 0.3.1", + "objc2-encode 3.0.0", ] [[package]] @@ -1423,10 +1522,16 @@ version = "2.0.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" dependencies = [ - "objc-sys", + "objc-sys 0.2.0-beta.2", ] [[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + +[[package]] name = "objc_id" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1637,7 +1742,20 @@ dependencies = [ "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys 0.4.3", "windows-sys 0.48.0", ] @@ -1670,9 +1788,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sctk-adwaita" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2704a44480b79e10d2185d1d246e86b02e177e33bdaaaab3b1f65fdf13771448" +checksum = "4b1ea0ce9e629064237c642f344cc2d9d8028e9b8367d894d2aa7f9243872176" dependencies = [ "crossfont", "log", @@ -1703,7 +1821,7 @@ checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn", ] [[package]] @@ -1905,17 +2023,6 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" @@ -1942,27 +2049,28 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn", ] [[package]] name = "tiny-skia" -version = "0.8.4" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" +checksum = "f4e37fdc219ee3d551882d24dc5e4df5f72fd9723cbca1ffaa57f7348bf7a47d" dependencies = [ "arrayref", "arrayvec", "bytemuck", "cfg-if 1.0.0", + "log", "tiny-skia-path", ] [[package]] name = "tiny-skia-path" -version = "0.8.4" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adbfb5d3f3dd57a0e11d12f4f13d4ebbbc1b5c15b7ab0a156d030b21da5f677c" +checksum = "93a323d1de20dad9bc8b32daf57702c585ce76e80792d8151de1fc9dfc8d1ca7" dependencies = [ "arrayref", "bytemuck", @@ -2127,7 +2235,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn", "wasm-bindgen-shared", ] @@ -2161,7 +2269,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2539,32 +2647,34 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winit" -version = "0.29.0-beta.0" +version = "0.29.1-beta" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f1afaf8490cc3f1309520ebb53a4cd3fc3642c7df8064a4b074bb9867998d44" +checksum = "ab977231134a3123c5382f0358b728118e70c216ec99017aa24e9eed35d5e3e1" dependencies = [ "android-activity", "atomic-waker", - "bitflags 2.3.1", + "bitflags 2.3.3", + "bytemuck", "calloop", "cfg_aliases", "core-foundation", "core-graphics", "cursor-icon", - "dispatch", "fnv", + "icrate", "js-sys", "libc", "log", "memmap2", "ndk", "ndk-sys", - "objc2", + "objc2 0.4.1", "once_cell", "orbclient", "percent-encoding", "raw-window-handle", "redox_syscall 0.3.5", + "rustix 0.38.4", "sctk-adwaita", "serde", "smithay-client-toolkit 0.17.0", @@ -2579,6 +2689,7 @@ dependencies = [ "web-time", "windows-sys 0.48.0", "x11-dl", + "x11rb 0.12.0", "xkbcommon-dl", ] @@ -2625,7 +2736,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "980b9aa9226c3b7de8e2adb11bf20124327c054e0e5812d2aac0b5b5a87e7464" dependencies = [ - "x11rb", + "x11rb 0.10.1", ] [[package]] @@ -2645,11 +2756,28 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" dependencies = [ - "gethostname", + "gethostname 0.2.3", "nix 0.24.3", "winapi 0.3.9", "winapi-wsapoll", - "x11rb-protocol", + "x11rb-protocol 0.10.0", +] + +[[package]] +name = "x11rb" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1641b26d4dec61337c35a1b1aaf9e3cba8f46f0b43636c609ab0291a648040a" +dependencies = [ + "as-raw-xcb-connection", + "gethostname 0.3.0", + "libc", + "libloading", + "nix 0.26.2", + "once_cell", + "winapi 0.3.9", + "winapi-wsapoll", + "x11rb-protocol 0.12.0", ] [[package]] @@ -2662,6 +2790,15 @@ dependencies = [ ] [[package]] +name = "x11rb-protocol" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d6c3f9a0fb6701fab8f6cea9b0c0bd5d6876f1f89f7fada07e558077c344bc" +dependencies = [ + "nix 0.26.2", +] + +[[package]] name = "xcursor" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2685,7 +2822,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "640e2c59cabea03b04fb0a34ca0fa7caaa1a50f7e588776fcda43a6a8ca28165" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.3", "dlib", "log", "once_cell", diff --git a/alacritty/Cargo.toml b/alacritty/Cargo.toml index 34ab89ed..d80bc3f8 100644 --- a/alacritty/Cargo.toml +++ b/alacritty/Cargo.toml @@ -35,13 +35,12 @@ log = { version = "0.4", features = ["std", "serde"] } notify = "5.1.0" once_cell = "1.12" parking_lot = "0.12.0" -raw-window-handle = "0.5.0" serde = { version = "1", features = ["derive"] } serde_json = "1" serde_yaml = "0.8" toml = "0.7.1" unicode-width = "0.1" -winit = { version = "0.29.0-beta.0", default-features = false, features = ["serde"] } +winit = { version = "0.29.1-beta", default-features = false, features = ["serde"] } [build-dependencies] gl_generator = "0.14.0" diff --git a/alacritty/src/clipboard.rs b/alacritty/src/clipboard.rs index dd0a8348..35982cf5 100644 --- a/alacritty/src/clipboard.rs +++ b/alacritty/src/clipboard.rs @@ -1,7 +1,5 @@ -#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] -use std::ffi::c_void; - use log::{debug, warn}; +use winit::window::raw_window_handle::RawDisplayHandle; use alacritty_terminal::term::ClipboardType; @@ -21,20 +19,15 @@ pub struct Clipboard { } impl Clipboard { - #[cfg(any(not(feature = "wayland"), target_os = "macos", windows))] - pub fn new() -> Self { - Self::default() - } - - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - pub unsafe fn new(display: Option<*mut c_void>) -> Self { + pub unsafe fn new(display: RawDisplayHandle) -> Self { match display { - Some(display) => { + #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] + RawDisplayHandle::Wayland(display) => { let (selection, clipboard) = - wayland_clipboard::create_clipboards_from_external(display); + wayland_clipboard::create_clipboards_from_external(display.display); Self { clipboard: Box::new(clipboard), selection: Some(Box::new(selection)) } }, - None => Self::default(), + _ => Self::default(), } } diff --git a/alacritty/src/display/mod.rs b/alacritty/src/display/mod.rs index c992e9cc..4037cd2e 100644 --- a/alacritty/src/display/mod.rs +++ b/alacritty/src/display/mod.rs @@ -6,7 +6,6 @@ use std::fmt::{self, Formatter}; use std::mem::{self, ManuallyDrop}; use std::num::NonZeroU32; use std::ops::{Deref, DerefMut}; -use std::sync::atomic::Ordering; use std::time::{Duration, Instant}; use glutin::context::{NotCurrentContext, PossiblyCurrentContext}; @@ -15,10 +14,10 @@ use glutin::surface::{Rect as DamageRect, Surface, SwapInterval, WindowSurface}; use log::{debug, info}; use parking_lot::MutexGuard; -use raw_window_handle::RawWindowHandle; use serde::{Deserialize, Serialize}; use winit::dpi::PhysicalSize; use winit::keyboard::ModifiersState; +use winit::window::raw_window_handle::RawWindowHandle; use winit::window::CursorIcon; use crossfont::{self, Rasterize, Rasterizer}; @@ -347,7 +346,7 @@ pub struct Display { /// Hint highlighted by the vi mode cursor. pub vi_highlighted_hint: Option<HintMatch>, - pub is_wayland: bool, + pub raw_window_handle: RawWindowHandle, /// UI cursor visibility for blinking. pub cursor_hidden: bool, @@ -394,7 +393,7 @@ impl Display { gl_context: NotCurrentContext, config: &UiConfig, ) -> Result<Display, Error> { - let is_wayland = matches!(window.raw_window_handle(), RawWindowHandle::Wayland(_)); + let raw_window_handle = window.raw_window_handle(); let scale_factor = window.scale_factor as f32; let rasterizer = Rasterizer::new(scale_factor)?; @@ -408,7 +407,7 @@ impl Display { // Resize the window to account for the user configured size. if let Some(dimensions) = config.window.dimensions() { let size = window_size(config, dimensions, cell_width, cell_height, scale_factor); - window.set_inner_size(size); + window.request_inner_size(size); } // Create the GL surface to draw into. @@ -459,9 +458,10 @@ impl Display { #[cfg(target_os = "macos")] window.set_has_shadow(config.window_opacity() >= 1.0); + let is_wayland = matches!(raw_window_handle, RawWindowHandle::Wayland(_)); + // On Wayland we can safely ignore this call, since the window isn't visible until you // actually draw something into it and commit those changes. - #[cfg(not(any(target_os = "macos", windows)))] if !is_wayland { surface.swap_buffers(&context).expect("failed to swap buffers."); renderer.finish(); @@ -479,7 +479,6 @@ impl Display { match config.window.startup_mode { #[cfg(target_os = "macos")] StartupMode::SimpleFullscreen => window.set_simple_fullscreen(true), - #[cfg(not(any(target_os = "macos", windows)))] StartupMode::Maximized if !is_wayland => window.set_maximized(true), _ => (), } @@ -511,7 +510,6 @@ impl Display { ime: Ime::new(), highlighted_hint: None, vi_highlighted_hint: None, - is_wayland, cursor_hidden: false, frame_timer: FrameTimer::new(), visual_bell: VisualBell::from(&config.bell), @@ -520,6 +518,7 @@ impl Display { pending_renderer_update: Default::default(), debug_damage, damage_rects, + raw_window_handle, next_frame_damage_rects, hint_mouse_point: None, }) @@ -552,7 +551,8 @@ impl Display { let res = match (self.surface.deref(), &self.context.get()) { #[cfg(not(any(target_os = "macos", windows)))] (Surface::Egl(surface), PossiblyCurrentContext::Egl(context)) - if self.is_wayland && !self.debug_damage => + if matches!(self.raw_window_handle, RawWindowHandle::Wayland(_)) + && !self.debug_damage => { surface.swap_buffers_with_damage(context, &self.damage_rects) }, @@ -972,17 +972,13 @@ impl Display { self.draw_hyperlink_preview(config, cursor_point, display_offset); } - // Frame event should be requested before swapping buffers on Wayland, since it requires - // surface `commit`, which is done by swap buffers under the hood. - if self.is_wayland { - self.request_frame(scheduler); - } + // Notify winit that we're about to present. + self.window.pre_present_notify(); // Clearing debug highlights from the previous frame requires full redraw. self.swap_buffers(); - #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] - if !self.is_wayland { + if matches!(self.raw_window_handle, RawWindowHandle::Xcb(_) | RawWindowHandle::Xlib(_)) { // On X11 `swap_buffers` does not block for vsync. However the next OpenGl command // will block to synchronize (this is `glClear` in Alacritty), which causes a // permanent one frame delay. @@ -991,7 +987,10 @@ impl Display { // XXX: Request the new frame after swapping buffers, so the // time to finish OpenGL operations is accounted for in the timeout. - if !self.is_wayland { + if matches!( + self.raw_window_handle, + RawWindowHandle::AppKit(_) | RawWindowHandle::Xlib(_) | RawWindowHandle::Xcb(_) + ) { self.request_frame(scheduler); } @@ -1364,7 +1363,7 @@ impl Display { /// Returns `true` if damage information should be collected, `false` otherwise. #[inline] fn collect_damage(&self) -> bool { - self.is_wayland || self.debug_damage + matches!(self.raw_window_handle, RawWindowHandle::Wayland(_)) || self.debug_damage } /// Highlight damaged rects. @@ -1385,18 +1384,7 @@ impl Display { /// Requst a new frame for a window on Wayland. fn request_frame(&mut self, scheduler: &mut Scheduler) { // Mark that we've used a frame. - self.window.has_frame.store(false, Ordering::Relaxed); - - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - if let Some(surface) = self.window.wayland_surface() { - let has_frame = self.window.has_frame.clone(); - // Request a new frame. - surface.frame().quick_assign(move |_, _, _| { - has_frame.store(true, Ordering::Relaxed); - }); - - return; - } + self.window.has_frame = false; // Get the display vblank interval. let monitor_vblank_interval = 1_000_000. diff --git a/alacritty/src/display/window.rs b/alacritty/src/display/window.rs index 0cf95f7f..942b28ee 100644 --- a/alacritty/src/display/window.rs +++ b/alacritty/src/display/window.rs @@ -1,11 +1,3 @@ -#[rustfmt::skip] -#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] -use { - wayland_client::protocol::wl_surface::WlSurface, - wayland_client::{Attached, EventQueue, Proxy}, - winit::platform::wayland::{EventLoopWindowTargetExtWayland, WindowExtWayland}, -}; - #[cfg(all(not(feature = "x11"), not(any(target_os = "macos", windows))))] use winit::platform::wayland::WindowBuilderExtWayland; @@ -13,8 +5,8 @@ use winit::platform::wayland::WindowBuilderExtWayland; #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] use { std::io::Cursor, - - winit::platform::x11::{WindowExtX11, WindowBuilderExtX11}, + winit::platform::x11::{WindowBuilderExtX11, EventLoopWindowTargetExtX11}, + winit::window::raw_window_handle::{HasRawDisplayHandle, RawDisplayHandle}, glutin::platform::x11::X11VisualInfo, x11_dl::xlib::{Display as XDisplay, PropModeReplace, XErrorEvent, Xlib}, winit::window::Icon, @@ -22,8 +14,6 @@ use { }; use std::fmt::{self, Display, Formatter}; -use std::sync::atomic::AtomicBool; -use std::sync::Arc; #[cfg(target_os = "macos")] use { @@ -33,13 +23,12 @@ use { winit::platform::macos::{OptionAsAlt, WindowBuilderExtMacOS, WindowExtMacOS}, }; -use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; - use winit::dpi::{PhysicalPosition, PhysicalSize}; use winit::event_loop::EventLoopWindowTarget; use winit::monitor::MonitorHandle; #[cfg(windows)] use winit::platform::windows::IconExtWindows; +use winit::window::raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; use winit::window::{ CursorIcon, Fullscreen, ImePurpose, UserAttentionType, Window as WinitWindow, WindowBuilder, WindowId, @@ -107,15 +96,14 @@ impl From<crossfont::Error> for Error { /// Wraps the underlying windowing library to provide a stable API in Alacritty. pub struct Window { /// Flag tracking that we have a frame we can draw. - pub has_frame: Arc<AtomicBool>, - - /// Attached Wayland surface to request new frame events. - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - pub wayland_surface: Option<Attached<WlSurface>>, + pub has_frame: bool, /// Cached scale factor for quickly scaling pixel sizes. pub scale_factor: f64, + /// Flag indicating whether redraw was requested. + pub requested_redraw: bool, + window: WinitWindow, /// Current window title. @@ -133,8 +121,6 @@ impl Window { event_loop: &EventLoopWindowTarget<E>, config: &UiConfig, identity: &Identity, - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - wayland_event_queue: Option<&EventQueue>, #[rustfmt::skip] #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] x11_visual: Option<X11VisualInfo>, @@ -161,12 +147,6 @@ impl Window { .with_fullscreen(config.window.fullscreen()) .build(event_loop)?; - // Check if we're running Wayland to disable vsync. - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - let is_wayland = event_loop.is_wayland(); - #[cfg(all(not(feature = "wayland"), not(any(target_os = "macos", windows))))] - let is_wayland = false; - // Text cursor. let current_mouse_cursor = CursorIcon::Text; window.set_cursor_icon(current_mouse_cursor); @@ -181,35 +161,23 @@ impl Window { #[cfg(target_os = "macos")] use_srgb_color_space(&window); + // On X11, embed the window inside another if the parent ID has been set. #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] - if !is_wayland { - // On X11, embed the window inside another if the parent ID has been set. - if let Some(parent_window_id) = config.window.embed { - x_embed_window(&window, parent_window_id); - } + if let Some(parent_window_id) = event_loop.is_x11().then_some(config.window.embed).flatten() + { + x_embed_window(&window, parent_window_id); } - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - let wayland_surface = if is_wayland { - // Attach surface to Alacritty's internal wayland queue to handle frame callbacks. - let surface = window.wayland_surface().unwrap(); - let proxy: Proxy<WlSurface> = unsafe { Proxy::from_c_ptr(surface as _) }; - Some(proxy.attach(wayland_event_queue.as_ref().unwrap().token())) - } else { - None - }; - let scale_factor = window.scale_factor(); log::info!("Window scale factor: {}", scale_factor); Ok(Self { current_mouse_cursor, mouse_visible: true, + requested_redraw: false, window, title: identity.title, - has_frame: Arc::new(AtomicBool::new(true)), - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - wayland_surface, + has_frame: true, scale_factor, }) } @@ -220,8 +188,8 @@ impl Window { } #[inline] - pub fn set_inner_size(&self, size: PhysicalSize<u32>) { - self.window.set_inner_size(size); + pub fn request_inner_size(&self, size: PhysicalSize<u32>) { + let _ = self.window.request_inner_size(size); } #[inline] @@ -248,8 +216,11 @@ impl Window { } #[inline] - pub fn request_redraw(&self) { - self.window.request_redraw(); + pub fn request_redraw(&mut self) { + if !self.requested_redraw { + self.requested_redraw = true; + self.window.request_redraw(); + } } #[inline] @@ -296,7 +267,7 @@ impl Window { #[cfg(feature = "x11")] let builder = match x11_visual { - Some(visual) => builder.with_x11_visual(visual.into_raw()), + Some(visual) => builder.with_x11_visual(visual.visual_id() as u32), None => builder, }; @@ -367,6 +338,13 @@ impl Window { self.set_maximized(!self.window.is_maximized()); } + /// Inform windowing system about presenting to the window. + /// + /// Should be called right before presenting to the window with e.g. `eglSwapBuffers`. + pub fn pre_present_notify(&self) { + self.window.pre_present_notify(); + } + #[cfg(target_os = "macos")] pub fn toggle_simple_fullscreen(&self) { self.set_simple_fullscreen(!self.window.simple_fullscreen()); @@ -394,11 +372,6 @@ impl Window { self.window.set_simple_fullscreen(simple_fullscreen); } - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - pub fn wayland_surface(&self) -> Option<&Attached<WlSurface>> { - self.wayland_surface.as_ref() - } - pub fn set_ime_allowed(&self, allowed: bool) { self.window.set_ime_allowed(allowed); } @@ -437,8 +410,12 @@ impl Window { #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] fn x_embed_window(window: &WinitWindow, parent_id: std::os::raw::c_ulong) { - let (xlib_display, xlib_window) = match (window.xlib_display(), window.xlib_window()) { - (Some(display), Some(window)) => (display, window), + let xlib_display = window.raw_display_handle(); + let xlib_window = window.raw_window_handle(); + let (xlib_display, xlib_window) = match (xlib_display, xlib_window) { + (RawDisplayHandle::Xlib(display), RawWindowHandle::Xlib(window)) => { + (display.display, window.window) + }, _ => return, }; @@ -448,7 +425,7 @@ fn x_embed_window(window: &WinitWindow, parent_id: std::os::raw::c_ulong) { let atom = (xlib.XInternAtom)(xlib_display as *mut _, "_XEMBED".as_ptr() as *const _, 0); (xlib.XChangeProperty)( xlib_display as _, - xlib_window as _, + xlib_window, atom, atom, 32, diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index add30722..6717e0ab 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -10,15 +10,12 @@ use std::fmt::Debug; use std::os::unix::io::RawFd; use std::path::PathBuf; use std::rc::Rc; -use std::sync::atomic::Ordering; use std::time::{Duration, Instant}; use std::{env, f32, mem}; use ahash::RandomState; +use crossfont::{self, Size}; use log::{debug, error, info, warn}; -#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] -use wayland_client::{Display as WaylandDisplay, EventQueue}; -use winit::dpi::PhysicalSize; use winit::event::{ ElementState, Event as WinitEvent, Ime, Modifiers, MouseButton, StartCause, Touch as TouchEvent, WindowEvent, @@ -26,13 +23,9 @@ use winit::event::{ use winit::event_loop::{ ControlFlow, DeviceEvents, EventLoop, EventLoopProxy, EventLoopWindowTarget, }; -use winit::platform::run_return::EventLoopExtRunReturn; -#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] -use winit::platform::wayland::EventLoopWindowTargetExtWayland; +use winit::window::raw_window_handle::HasRawDisplayHandle; use winit::window::WindowId; -use crossfont::{self, Size}; - use alacritty_terminal::config::LOG_TARGET_CONFIG; use alacritty_terminal::event::{Event as TerminalEvent, EventListener, Notify}; use alacritty_terminal::event_loop::Notifier; @@ -87,7 +80,7 @@ impl Event { } } -impl From<Event> for WinitEvent<'_, Event> { +impl From<Event> for WinitEvent<Event> { fn from(event: Event) -> Self { WinitEvent::UserEvent(event) } @@ -96,7 +89,6 @@ impl From<Event> for WinitEvent<'_, Event> { /// Alacritty events. #[derive(Debug, Clone)] pub enum EventType { - ScaleFactorChanged(f64, (u32, u32)), Terminal(TerminalEvent), ConfigReload(PathBuf), Message(Message), @@ -1178,30 +1170,9 @@ pub struct AccumulatedScroll { impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> { /// Handle events from winit. - pub fn handle_event(&mut self, event: WinitEvent<'_, Event>) { + pub fn handle_event(&mut self, event: WinitEvent<Event>) { match event { WinitEvent::UserEvent(Event { payload, .. }) => match payload { - EventType::ScaleFactorChanged(scale_factor, (width, height)) => { - self.ctx.window().scale_factor = scale_factor; - - let display_update_pending = &mut self.ctx.display.pending_update; - - // Push current font to update its scale factor. - let font = self.ctx.config.font.clone(); - display_update_pending.set_font(font.with_size(*self.ctx.font_size)); - - // Ignore resize events to zero in any dimension, to avoid issues with Winit - // and the ConPTY. A 0x0 resize will also occur when the window is minimized - // on Windows. - if width != 0 && height != 0 { - // Resize to event's dimensions, since no resize event is emitted on - // Wayland. - display_update_pending.set_dimensions(PhysicalSize::new(width, height)); - } - }, - EventType::Frame => { - self.ctx.display.window.has_frame.store(true, Ordering::Relaxed); - }, EventType::SearchNext => self.ctx.goto_match(None), EventType::Scroll(scroll) => self.ctx.scroll(scroll), EventType::BlinkCursor => { @@ -1233,7 +1204,6 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> { self.ctx.display.window.set_title(window_config.identity.title.clone()); } }, - TerminalEvent::Wakeup => *self.ctx.dirty = true, TerminalEvent::Bell => { // Set window urgency hint when window is not focused. let focused = self.ctx.terminal.is_focused; @@ -1271,18 +1241,28 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> { }, TerminalEvent::PtyWrite(text) => self.ctx.write_to_pty(text.into_bytes()), TerminalEvent::MouseCursorDirty => self.reset_mouse_cursor(), - TerminalEvent::Exit => (), TerminalEvent::CursorBlinkingChange => self.ctx.update_cursor_blinking(), + TerminalEvent::Exit | TerminalEvent::Wakeup => (), }, #[cfg(unix)] EventType::IpcConfig(_) => (), - EventType::ConfigReload(_) | EventType::CreateWindow(_) | EventType::Message(_) => { - }, + EventType::Message(_) + | EventType::ConfigReload(_) + | EventType::CreateWindow(_) + | EventType::Frame => (), }, - WinitEvent::RedrawRequested(_) => *self.ctx.dirty = true, WinitEvent::WindowEvent { event, .. } => { match event { WindowEvent::CloseRequested => self.ctx.terminal.exit(), + WindowEvent::ScaleFactorChanged { scale_factor, .. } => { + self.ctx.window().scale_factor = scale_factor; + + let display_update_pending = &mut self.ctx.display.pending_update; + + // Push current font to update its scale factor. + let font = self.ctx.config.font.clone(); + display_update_pending.set_font(font.with_size(*self.ctx.font_size)); + }, WindowEvent::Resized(size) => { // Ignore resize events to zero in any dimension, to avoid issues with Winit // and the ConPTY. A 0x0 resize will also occur when the window is minimized @@ -1370,11 +1350,11 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> { }, }, WindowEvent::KeyboardInput { is_synthetic: true, .. } + | WindowEvent::ActivationTokenDone { .. } | WindowEvent::TouchpadPressure { .. } | WindowEvent::TouchpadMagnify { .. } | WindowEvent::TouchpadRotate { .. } | WindowEvent::SmartMagnify { .. } - | WindowEvent::ScaleFactorChanged { .. } | WindowEvent::CursorEntered { .. } | WindowEvent::AxisMotion { .. } | WindowEvent::HoveredFileCancelled @@ -1387,10 +1367,10 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> { WinitEvent::Suspended { .. } | WinitEvent::NewEvents { .. } | WinitEvent::DeviceEvent { .. } - | WinitEvent::MainEventsCleared - | WinitEvent::RedrawEventsCleared + | WinitEvent::LoopExiting | WinitEvent::Resumed - | WinitEvent::LoopDestroyed => (), + | WinitEvent::AboutToWait + | WinitEvent::RedrawRequested(_) => (), } } } @@ -1400,8 +1380,6 @@ impl input::Processor<EventProxy, ActionContext<'_, Notifier, EventProxy>> { /// Stores some state from received events and dispatches actions when they are /// triggered. pub struct Processor { - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - wayland_event_queue: Option<EventQueue>, windows: HashMap<WindowId, WindowContext, RandomState>, #[cfg(unix)] global_ipc_options: Vec<String>, @@ -1418,21 +1396,12 @@ impl Processor { cli_options: CliOptions, _event_loop: &EventLoop<Event>, ) -> Processor { - // Initialize Wayland event queue, to handle Wayland callbacks. - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - let wayland_event_queue = _event_loop.wayland_display().map(|display| { - let display = unsafe { WaylandDisplay::from_external_display(display as _) }; - display.create_event_queue() - }); - Processor { - config: Rc::new(config), cli_options, - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - wayland_event_queue, + config: Rc::new(config), + windows: Default::default(), #[cfg(unix)] global_ipc_options: Default::default(), - windows: Default::default(), } } @@ -1446,14 +1415,8 @@ impl Processor { proxy: EventLoopProxy<Event>, options: WindowOptions, ) -> Result<(), Box<dyn Error>> { - let window_context = WindowContext::initial( - event_loop, - proxy, - self.config.clone(), - options, - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - self.wayland_event_queue.as_ref(), - )?; + let window_context = + WindowContext::initial(event_loop, proxy, self.config.clone(), options)?; self.windows.insert(window_context.id(), window_context); @@ -1470,14 +1433,8 @@ impl Processor { let window = self.windows.iter().next().as_ref().unwrap().1; #[allow(unused_mut)] - let mut window_context = window.additional( - event_loop, - proxy, - self.config.clone(), - options, - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - self.wayland_event_queue.as_ref(), - )?; + let mut window_context = + window.additional(event_loop, proxy, self.config.clone(), options)?; // Apply global IPC options. #[cfg(unix)] @@ -1496,7 +1453,7 @@ impl Processor { /// The result is exit code generate from the loop. pub fn run( &mut self, - mut event_loop: EventLoop<Event>, + event_loop: EventLoop<Event>, initial_window_options: WindowOptions, ) -> Result<(), Box<dyn Error>> { let proxy = event_loop.create_proxy(); @@ -1504,15 +1461,12 @@ impl Processor { let mut initial_window_options = Some(initial_window_options); // NOTE: Since this takes a pointer to the winit event loop, it MUST be dropped first. - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - let mut clipboard = unsafe { Clipboard::new(event_loop.wayland_display()) }; - #[cfg(any(not(feature = "wayland"), target_os = "macos", windows))] - let mut clipboard = Clipboard::new(); + let mut clipboard = unsafe { Clipboard::new(event_loop.raw_display_handle()) }; // Disable all device events, since we don't care about them. event_loop.listen_device_events(DeviceEvents::Never); - let exit_code = event_loop.run_return(move |event, event_loop, control_flow| { + let result = event_loop.run(move |event, event_loop, control_flow| { if self.config.debug.print_events { info!("winit event: {:?}", event); } @@ -1526,8 +1480,8 @@ impl Processor { // 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. Othwerwise the first window - // won't handle tabs. + // properly initialize state, like tab management. Othwerwise 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, @@ -1546,6 +1500,30 @@ impl Processor { info!("Initialisation complete"); }, + // 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), @@ -1570,16 +1548,24 @@ impl Processor { *control_flow = ControlFlow::Exit; } }, - // Process all pending events. - WinitEvent::RedrawEventsCleared => { - // Check for pending frame callbacks on Wayland. - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - if let Some(wayland_event_queue) = self.wayland_event_queue.as_mut() { - wayland_event_queue - .dispatch_pending(&mut (), |_, _, _| {}) - .expect("failed to dispatch wayland event queue"); - } + WinitEvent::RedrawRequested(window_id) => { + let window_context = match self.windows.get_mut(&window_id) { + Some(window_context) => window_context, + None => return, + }; + + window_context.handle_event( + event_loop, + &proxy, + &mut clipboard, + &mut scheduler, + WinitEvent::RedrawRequested(window_id), + ); + 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( @@ -1587,7 +1573,7 @@ impl Processor { &proxy, &mut clipboard, &mut scheduler, - WinitEvent::RedrawEventsCleared, + WinitEvent::AboutToWait, ); } @@ -1644,8 +1630,9 @@ impl Processor { 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 + // 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(); @@ -1669,8 +1656,7 @@ impl Processor { }, // Process window-specific events. WinitEvent::WindowEvent { window_id, .. } - | WinitEvent::UserEvent(Event { window_id: Some(window_id), .. }) - | WinitEvent::RedrawRequested(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( event_loop, @@ -1685,15 +1671,11 @@ impl Processor { } }); - if exit_code == 0 { - Ok(()) - } else { - Err(format!("Event loop terminated with code: {}", exit_code).into()) - } + result.map_err(Into::into) } /// Check if an event is irrelevant and can be skipped. - fn skip_event(event: &WinitEvent<'_, Event>) -> bool { + fn skip_event(event: &WinitEvent<Event>) -> bool { match event { WinitEvent::NewEvents(StartCause::Init) => false, WinitEvent::WindowEvent { event, .. } => matches!( @@ -1709,8 +1691,7 @@ impl Processor { ), WinitEvent::Suspended { .. } | WinitEvent::NewEvents { .. } - | WinitEvent::MainEventsCleared - | WinitEvent::LoopDestroyed => true, + | WinitEvent::LoopExiting => true, _ => false, } } diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs index 5075729b..54580fa6 100644 --- a/alacritty/src/input.rs +++ b/alacritty/src/input.rs @@ -1325,7 +1325,7 @@ mod tests { let mut processor = Processor::new(context); - let event: WinitEvent::<'_, TerminalEvent> = $input; + let event: WinitEvent::<TerminalEvent> = $input; if let WinitEvent::WindowEvent { event: WindowEvent::MouseInput { state, diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs index 55f81502..ea4cd281 100644 --- a/alacritty/src/main.rs +++ b/alacritty/src/main.rs @@ -126,7 +126,7 @@ impl Drop for TemporaryFiles { /// config change monitor, and runs the main display loop. fn alacritty(options: Options) -> Result<(), Box<dyn Error>> { // Setup winit event loop. - let window_event_loop = WinitEventLoopBuilder::<Event>::with_user_event().build(); + let window_event_loop = WinitEventLoopBuilder::<Event>::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()) diff --git a/alacritty/src/renderer/mod.rs b/alacritty/src/renderer/mod.rs index 98e29542..87ccf2f6 100644 --- a/alacritty/src/renderer/mod.rs +++ b/alacritty/src/renderer/mod.rs @@ -254,7 +254,6 @@ impl Renderer { } } - #[cfg(not(any(target_os = "macos", windows)))] pub fn finish(&self) { unsafe { gl::Finish(); diff --git a/alacritty/src/renderer/platform.rs b/alacritty/src/renderer/platform.rs index 10c17cb7..495e837e 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 8935a9cc..0dd4b4bb 100644 --- a/alacritty/src/window_context.rs +++ b/alacritty/src/window_context.rs @@ -7,7 +7,6 @@ use std::mem; #[cfg(not(windows))] use std::os::unix::io::{AsRawFd, RawFd}; use std::rc::Rc; -use std::sync::atomic::Ordering; use std::sync::Arc; use crossfont::Size; @@ -17,12 +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; -#[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] -use wayland_client::EventQueue; -use winit::event::{Event as WinitEvent, Modifiers, WindowEvent}; +use winit::event::{Event as WinitEvent, Modifiers}; use winit::event_loop::{EventLoopProxy, EventLoopWindowTarget}; +use winit::window::raw_window_handle::HasRawDisplayHandle; use winit::window::WindowId; use alacritty_config::SerdeReplace; @@ -42,7 +39,7 @@ use crate::clipboard::Clipboard; use crate::config::UiConfig; use crate::display::window::Window; use crate::display::Display; -use crate::event::{ActionContext, Event, EventProxy, EventType, Mouse, SearchState, TouchPurpose}; +use crate::event::{ActionContext, Event, EventProxy, Mouse, SearchState, TouchPurpose}; use crate::logging::LOG_TARGET_IPC_CONFIG; use crate::message_bar::MessageBuffer; use crate::scheduler::Scheduler; @@ -52,7 +49,8 @@ use crate::{input, renderer}; pub struct WindowContext { pub message_buffer: MessageBuffer, pub display: Display, - event_queue: Vec<WinitEvent<'static, Event>>, + pub dirty: bool, + event_queue: Vec<WinitEvent<Event>>, terminal: Arc<FairMutex<Term<EventProxy>>>, cursor_blink_timed_out: bool, modifiers: Modifiers, @@ -61,7 +59,6 @@ pub struct WindowContext { font_size: Size, mouse: Mouse, touch: TouchPurpose, - dirty: bool, occluded: bool, preserve_title: bool, #[cfg(not(windows))] @@ -79,8 +76,6 @@ impl WindowContext { proxy: EventLoopProxy<Event>, config: Rc<UiConfig>, options: WindowOptions, - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - wayland_event_queue: Option<&EventQueue>, ) -> Result<Self, Box<dyn Error>> { let raw_display_handle = event_loop.raw_display_handle(); @@ -106,8 +101,6 @@ impl WindowContext { event_loop, &config, &identity, - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - wayland_event_queue, #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] gl_config.x11_visual(), )?; @@ -126,8 +119,6 @@ impl WindowContext { proxy: EventLoopProxy<Event>, config: Rc<UiConfig>, options: WindowOptions, - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - wayland_event_queue: Option<&EventQueue>, ) -> Result<Self, Box<dyn Error>> { // Get any window and take its GL config and display to build a new context. let (gl_display, gl_config) = { @@ -142,8 +133,6 @@ impl WindowContext { event_loop, &config, &identity, - #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] - wayland_event_queue, #[cfg(all(feature = "x11", not(any(target_os = "macos", windows))))] gl_config.x11_visual(), )?; @@ -377,6 +366,35 @@ impl WindowContext { self.update_config(config); } + /// Draw the window. + pub fn draw(&mut self, scheduler: &mut Scheduler) { + self.display.window.requested_redraw = false; + + if self.occluded { + return; + } + + self.dirty = false; + + // Force the display to process any pending display update. + self.display.process_renderer_update(); + + // Request immediate re-draw if visual bell animation is not finished yet. + if !self.display.visual_bell.completed() { + self.display.window.request_redraw(); + } + + // Redraw the window. + let terminal = self.terminal.lock(); + self.display.draw( + terminal, + scheduler, + &self.message_buffer, + &self.config, + &self.search_state, + ); + } + /// Process events for this terminal window. pub fn handle_event( &mut self, @@ -384,30 +402,19 @@ impl WindowContext { event_proxy: &EventLoopProxy<Event>, clipboard: &mut Clipboard, scheduler: &mut Scheduler, - event: WinitEvent<'_, Event>, + event: WinitEvent<Event>, ) { match event { - // Skip further event handling with no staged updates. - WinitEvent::RedrawEventsCleared if self.event_queue.is_empty() && !self.dirty => { - return; - }, - // Continue to process all pending events. - WinitEvent::RedrawEventsCleared => (), - // Remap scale_factor change event to remove the lifetime. - WinitEvent::WindowEvent { - event: WindowEvent::ScaleFactorChanged { scale_factor, new_inner_size }, - window_id, - } => { - let size = (new_inner_size.width, new_inner_size.height); - let event = - Event::new(EventType::ScaleFactorChanged(scale_factor, size), window_id); - self.event_queue.push(event.into()); - return; + WinitEvent::AboutToWait | WinitEvent::RedrawRequested(_) => { + // Skip further event handling with no staged updates. + if self.event_queue.is_empty() { + return; + } + + // Continue to process all pending events. }, - // Transmute to extend lifetime, which exists only for `ScaleFactorChanged` event. - // Since we remap that event to remove the lifetime, this is safe. - event => unsafe { - self.event_queue.push(mem::transmute(event)); + event => { + self.event_queue.push(event); return; }, } @@ -470,30 +477,12 @@ impl WindowContext { self.mouse.hint_highlight_dirty = false; } - // Skip rendering until we get a new frame. - if !self.display.window.has_frame.load(Ordering::Relaxed) { - return; - } - - if self.dirty && !self.occluded { - // Force the display to process any pending display update. - self.display.process_renderer_update(); - - self.dirty = false; - - // Request immediate re-draw if visual bell animation is not finished yet. - if !self.display.visual_bell.completed() { - self.display.window.request_redraw(); - } - - // Redraw the window. - self.display.draw( - terminal, - scheduler, - &self.message_buffer, - &self.config, - &self.search_state, - ); + // 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(_)) { + self.display.window.request_redraw(); } } |