diff --git a/Cargo.lock b/Cargo.lock index 498cadf..df1cdd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,47 +20,58 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] name = "accesskit" -version = "0.21.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf203f9d3bd8f29f98833d1fbef628df18f759248a547e7e01cfbf63cda36a99" +checksum = "5351dcebb14b579ccab05f288596b2ae097005be7ee50a7c3d4ca9d0d5a66f6a" dependencies = [ "enumn", "serde", + "uuid", ] [[package]] name = "accesskit_atspi_common" -version = "0.14.2" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "890d241cf51fc784f0ac5ac34dfc847421f8d39da6c7c91a0fcc987db62a8267" +checksum = "1e8c61bee90b42a772d39d06a740207dc71a4e780004ace1db8d99fb1baaa954" dependencies = [ "accesskit", - "accesskit_consumer", + "accesskit_consumer 0.36.0", "atspi-common", + "phf", "serde", - "thiserror 1.0.69", "zvariant", ] [[package]] name = "accesskit_consumer" -version = "0.31.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db81010a6895d8707f9072e6ce98070579b43b717193d2614014abd5cb17dd43" +checksum = "53cf47daed85312e763fbf85ceca136e0d7abc68e0a7e12abe11f48172bc3b10" dependencies = [ "accesskit", - "hashbrown 0.15.5", + "hashbrown 0.16.1", +] + +[[package]] +name = "accesskit_consumer" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25e0d7e25d06f4dc21d1774d67146e9e80d6789216cbd4d1e88185b0095dba60" +dependencies = [ + "accesskit", + "hashbrown 0.16.1", ] [[package]] name = "accesskit_macos" -version = "0.22.2" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0089e5c0ac0ca281e13ea374773898d9354cc28d15af9f0f7394d44a495b575" +checksum = "4c5c87e8d94f2ec10cce590aadff24c76f576dab5502d45d0aed9fc3065d4451" dependencies = [ "accesskit", - "accesskit_consumer", - "hashbrown 0.15.5", + "accesskit_consumer 0.36.0", + "hashbrown 0.16.1", "objc2 0.5.2", "objc2-app-kit 0.2.2", "objc2-foundation 0.2.2", @@ -68,9 +79,9 @@ dependencies = [ [[package]] name = "accesskit_unix" -version = "0.17.2" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301e55b39cfc15d9c48943ce5f572204a551646700d0e8efa424585f94fec528" +checksum = "b016ca8db0ea0ea2ceff29a9d6240391492d960716aa471967c00e8cc8cb197c" dependencies = [ "accesskit", "accesskit_atspi_common", @@ -86,23 +97,23 @@ dependencies = [ [[package]] name = "accesskit_windows" -version = "0.29.2" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2d63dd5041e49c363d83f5419a896ecb074d309c414036f616dc0b04faca971" +checksum = "eff7009f1a532e917d66970a1e80c965140c6cfbbabbdde3d64e5431e6c78e21" dependencies = [ "accesskit", - "accesskit_consumer", - "hashbrown 0.15.5", + "accesskit_consumer 0.35.0", + "hashbrown 0.16.1", "static_assertions", - "windows 0.61.3", - "windows-core 0.61.2", + "windows", + "windows-core", ] [[package]] name = "accesskit_winit" -version = "0.29.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cfabe59d0eaca7412bfb1f70198dd31e3b0496fee7e15b066f9c36a1a140a0" +checksum = "1fe9a94394896352cc4660ca2288bd4ef883d83238853c038b44070c8f134313" dependencies = [ "accesskit", "accesskit_macos", @@ -166,6 +177,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android-activity" version = "0.6.0" @@ -267,7 +284,7 @@ dependencies = [ "clipboard-win", "image", "log", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit 0.3.2", "objc2-core-foundation", "objc2-core-graphics", @@ -444,20 +461,19 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atspi" -version = "0.25.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c83247582e7508838caf5f316c00791eee0e15c0bf743e6880585b867e16815c" +checksum = "c77886257be21c9cd89a4ae7e64860c6f0eefca799bb79127913052bd0eefb3d" dependencies = [ "atspi-common", - "atspi-connection", "atspi-proxies", ] [[package]] name = "atspi-common" -version = "0.9.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33dfc05e7cdf90988a197803bf24f5788f94f7c94a69efa95683e8ffe76cfdfb" +checksum = "20c5617155740c98003016429ad13fe43ce7a77b007479350a9f8bf95a29f63d" dependencies = [ "enumflags2", "serde", @@ -469,23 +485,11 @@ dependencies = [ "zvariant", ] -[[package]] -name = "atspi-connection" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4193d51303d8332304056ae0004714256b46b6635a5c556109b319c0d3784938" -dependencies = [ - "atspi-common", - "atspi-proxies", - "futures-lite", - "zbus", -] - [[package]] name = "atspi-proxies" -version = "0.9.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2eebcb9e7e76f26d0bcfd6f0295e1cd1e6f33bedbc5698a971db8dc43d7751c" +checksum = "2230e48787ed3eb4088996eab66a32ca20c0b67bbd4fd6cdfe79f04f1f04c9fc" dependencies = [ "atspi-common", "serde", @@ -506,18 +510,18 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bit-set" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +checksum = "34ddef2995421ab6a5c779542c81ee77c115206f4ad9d5a8e05f4ff49716a3dd" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51" [[package]] name = "bitflags" @@ -534,12 +538,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - [[package]] name = "block2" version = "0.5.1" @@ -549,6 +547,15 @@ dependencies = [ "objc2 0.5.2", ] +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2 0.6.4", +] + [[package]] name = "blocking" version = "1.6.2" @@ -701,15 +708,24 @@ dependencies = [ [[package]] name = "codespan-reporting" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" dependencies = [ "serde", "termcolor", "unicode-width", ] +[[package]] +name = "color" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18ef4657441fb193b65f34dc39b3781f0dfec23d3bd94d0eeb4e88cde421edb" +dependencies = [ + "bytemuck", +] + [[package]] name = "colorchoice" version = "1.0.4" @@ -769,7 +785,7 @@ checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", - "core-graphics-types 0.1.3", + "core-graphics-types", "foreign-types", "libc", ] @@ -785,17 +801,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-graphics-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" -dependencies = [ - "bitflags 2.10.0", - "core-foundation 0.10.1", - "libc", -] - [[package]] name = "crc32fast" version = "1.5.0" @@ -848,7 +853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", + "objc2 0.6.4", ] [[package]] @@ -905,9 +910,9 @@ dependencies = [ [[package]] name = "ecolor" -version = "0.33.3" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ddb8ac7643d1dba1bb02110e804406dd459a838efcb14011ced10556711a8e" +checksum = "a05fbfa222ffb51989d5ccf33e5f7aebfcf96c5023413856b0c3618a7f79896e" dependencies = [ "bytemuck", "emath", @@ -916,9 +921,9 @@ dependencies = [ [[package]] name = "eframe" -version = "0.33.3" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "457481173e6db5ca9fa2be93a58df8f4c7be639587aeb4853b526c6cf87db4e6" +checksum = "f98fe83b2589105b69dd25ca1e0fa2135a6e864d502fd8e08978f937e128cfef" dependencies = [ "ahash", "bytemuck", @@ -933,9 +938,9 @@ dependencies = [ "image", "js-sys", "log", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", "parking_lot", "percent-encoding", "pollster", @@ -955,9 +960,9 @@ dependencies = [ [[package]] name = "egui" -version = "0.33.3" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9b567d356674e9a5121ed3fedfb0a7c31e059fe71f6972b691bcd0bfc284e3" +checksum = "42112be0ae157289312b92b3dfaf20e911b5a3c4c65d4aab0e7c47fbc0ce16e3" dependencies = [ "accesskit", "ahash", @@ -975,9 +980,9 @@ dependencies = [ [[package]] name = "egui-wgpu" -version = "0.33.3" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4d209971c84b2352a06174abdba701af1e552ce56b144d96f2bd50a3c91236" +checksum = "9f0c0559ac5598a1b887a6206dccbab7e3e6246c57cb00ae287262bd44776c9c" dependencies = [ "ahash", "bytemuck", @@ -986,7 +991,7 @@ dependencies = [ "epaint", "log", "profiling", - "thiserror 2.0.17", + "thiserror 2.0.18", "type-map", "web-time", "wgpu", @@ -995,18 +1000,18 @@ dependencies = [ [[package]] name = "egui-winit" -version = "0.33.3" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec6687e5bb551702f4ad10ac428bab12acf9d53047ebb1082d4a0ed8c6251a29" +checksum = "967c5b323625d46d46a59b5daba3fef742248d27693cc18972458619858c4239" dependencies = [ "accesskit_winit", "arboard", "bytemuck", "egui", "log", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-ui-kit", + "objc2 0.6.4", + "objc2-foundation 0.3.2", + "objc2-ui-kit 0.3.2", "profiling", "raw-window-handle", "serde", @@ -1018,20 +1023,21 @@ dependencies = [ [[package]] name = "egui_dock" -version = "0.18.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0f689738efbd4afb811433b873379c6a8f3af48f2d296d9849fe70ee021d6" +checksum = "db51b9023b9d65cb4d561fd981946f987c54f25413c75b2c8e634c774c3d70ad" dependencies = [ "duplicate", "egui", "paste", + "thiserror 2.0.18", ] [[package]] name = "egui_glow" -version = "0.33.3" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6420863ea1d90e750f75075231a260030ad8a9f30a7cef82cdc966492dc4c4eb" +checksum = "62b652957fa7e1ab01e8fecbfbf4e35f6e43a53fa98af8a562b50d5403cd44b9" dependencies = [ "bytemuck", "egui", @@ -1051,14 +1057,16 @@ dependencies = [ "alacritty_terminal", "anyhow", "egui", + "libc", "open", + "windows-sys 0.59.0", ] [[package]] name = "emath" -version = "0.33.3" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "491bdf728bf25ddd9ad60d4cf1c48588fa82c013a2440b91aa7fc43e34a07c32" +checksum = "b53f0d33a479321da6b0caa71366c9f67e8a2c149762d90bdc0d16e601ee8ecb" dependencies = [ "bytemuck", "serde", @@ -1127,28 +1135,32 @@ dependencies = [ [[package]] name = "epaint" -version = "0.33.3" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "009d0dd3c2163823a0abdb899451ecbc78798dec545ee91b43aff1fa790bab62" +checksum = "6675898a291ec212fc3df04f537d177fce8496120244590e6359dcaa4c25da79" dependencies = [ - "ab_glyph", "ahash", "bytemuck", "ecolor", "emath", "epaint_default_fonts", + "font-types", "log", "nohash-hasher", "parking_lot", "profiling", + "self_cell", "serde", + "skrifa", + "smallvec", + "vello_cpu", ] [[package]] name = "epaint_default_fonts" -version = "0.33.3" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4fbe202b6578d3d56428fa185cdf114a05e49da05f477b3c7f0fbb221f1862" +checksum = "f8970033a4282a7bcf899b38b5ed3a58b732fe093d03785d58648515d8d309da" [[package]] name = "equivalent" @@ -1172,6 +1184,15 @@ version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" +[[package]] +name = "euclid" +version = "0.22.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" +dependencies = [ + "num-traits", +] + [[package]] name = "event-listener" version = "5.4.1" @@ -1228,6 +1249,15 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "fearless_simd" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb2907d1f08b2b316b9223ced5b0e89d87028ba8deae9764741dba8ff7f3903" +dependencies = [ + "bytemuck", +] + [[package]] name = "find-msvc-tools" version = "0.1.5" @@ -1256,6 +1286,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +[[package]] +name = "font-types" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7" +dependencies = [ + "bytemuck", + "serde", +] + [[package]] name = "fonts" version = "0.1.0" @@ -1379,7 +1419,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ "rustix 1.1.2", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -1407,9 +1447,9 @@ dependencies = [ [[package]] name = "glow" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" +checksum = "29038e1c483364cc6bb3cf78feee1816002e127c331a1eec55a4d202b9e1adb5" dependencies = [ "js-sys", "slotmap", @@ -1431,7 +1471,7 @@ dependencies = [ "glutin_glx_sys", "glutin_wgl_sys", "libloading", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit 0.3.2", "objc2-core-foundation", "objc2-foundation 0.3.2", @@ -1483,35 +1523,18 @@ dependencies = [ "gl_generator", ] -[[package]] -name = "gpu-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" -dependencies = [ - "bitflags 2.10.0", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" -dependencies = [ - "bitflags 2.10.0", -] - [[package]] name = "gpu-allocator" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795" dependencies = [ + "ash", + "hashbrown 0.16.1", "log", "presser", - "thiserror 1.0.69", - "windows 0.58.0", + "thiserror 2.0.18", + "windows", ] [[package]] @@ -1557,10 +1580,12 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ + "allocator-api2", + "equivalent", "foldhash 0.2.0", ] @@ -1720,7 +1745,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown 0.16.1", ] [[package]] @@ -1806,10 +1831,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.82" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -1831,6 +1858,18 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "kurbo" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b60dfc32f652b926df6192e55525b16d186c69d47876c3ead4da5cc9f8450e2" +dependencies = [ + "arrayvec", + "euclid", + "polycool", + "smallvec", +] + [[package]] name = "libc" version = "0.2.177" @@ -1844,7 +1883,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -1864,6 +1903,12 @@ dependencies = [ "redox_syscall 0.5.18", ] +[[package]] +name = "linebender_resource_handle" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a5ff6bcca6c4867b1c4fd4ef63e4db7436ef363e0ad7531d1558856bae64f4" + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -1903,15 +1948,6 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - [[package]] name = "memchr" version = "2.7.6" @@ -1936,21 +1972,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "metal" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" -dependencies = [ - "bitflags 2.10.0", - "block", - "core-graphics-types 0.2.0", - "foreign-types", - "log", - "objc", - "paste", -] - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -1982,9 +2003,9 @@ dependencies = [ [[package]] name = "naga" -version = "27.0.3" +version = "29.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8" +checksum = "0dd91265cc2454558f659b3b4b9640f0ddb8cc6521277f166b8a8c181c898079" dependencies = [ "arrayvec", "bit-set", @@ -1993,7 +2014,7 @@ dependencies = [ "cfg_aliases", "codespan-reporting", "half", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "hexf-parse", "indexmap", "libm", @@ -2002,7 +2023,7 @@ dependencies = [ "once_cell", "rustc-hash 1.1.0", "spirv", - "thiserror 2.0.17", + "thiserror 2.0.18", "unicode-ident", ] @@ -2087,15 +2108,6 @@ dependencies = [ "syn", ] -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - [[package]] name = "objc-sys" version = "0.3.5" @@ -2114,9 +2126,9 @@ dependencies = [ [[package]] name = "objc2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" dependencies = [ "objc2-encode", ] @@ -2128,13 +2140,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ "bitflags 2.10.0", - "block2", + "block2 0.5.1", "libc", "objc2 0.5.2", "objc2-core-data", "objc2-core-image", "objc2-foundation 0.2.2", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", ] [[package]] @@ -2144,7 +2156,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-core-foundation", "objc2-core-graphics", "objc2-foundation 0.3.2", @@ -2157,7 +2169,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ "bitflags 2.10.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", @@ -2169,7 +2181,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -2181,7 +2193,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.10.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -2194,7 +2206,7 @@ checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags 2.10.0", "dispatch2", - "objc2 0.6.3", + "objc2 0.6.4", ] [[package]] @@ -2205,7 +2217,7 @@ checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ "bitflags 2.10.0", "dispatch2", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-core-foundation", "objc2-io-surface", ] @@ -2216,10 +2228,10 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", - "objc2-metal", + "objc2-metal 0.2.2", ] [[package]] @@ -2228,7 +2240,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-contacts", "objc2-foundation 0.2.2", @@ -2247,7 +2259,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.10.0", - "block2", + "block2 0.5.1", "dispatch", "libc", "objc2 0.5.2", @@ -2260,7 +2272,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", + "block2 0.6.2", + "objc2 0.6.4", "objc2-core-foundation", ] @@ -2271,7 +2284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-core-foundation", ] @@ -2281,7 +2294,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-app-kit 0.2.2", "objc2-foundation 0.2.2", @@ -2294,11 +2307,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.10.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-metal" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" +dependencies = [ + "bitflags 2.10.0", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-quartz-core" version = "0.2.2" @@ -2306,10 +2331,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.10.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", - "objc2-metal", + "objc2-metal 0.2.2", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", ] [[package]] @@ -2329,7 +2367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ "bitflags 2.10.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-cloud-kit", "objc2-core-data", @@ -2337,19 +2375,31 @@ dependencies = [ "objc2-core-location", "objc2-foundation 0.2.2", "objc2-link-presentation", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", "objc2-symbols", "objc2-uniform-type-identifiers", "objc2-user-notifications", ] +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.10.0", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-uniform-type-identifiers" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -2361,7 +2411,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ "bitflags 2.10.0", - "block2", + "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", @@ -2453,7 +2503,7 @@ dependencies = [ "libc", "redox_syscall 0.5.18", "smallvec", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -2468,12 +2518,68 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +[[package]] +name = "peniko" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2b6aadb221872732e87d465213e9be5af2849b0e8cc5300a8ba98fffa2e00a" +dependencies = [ + "bytemuck", + "color", + "kurbo", + "linebender_resource_handle", + "smallvec", +] + [[package]] name = "percent-encoding" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros", + "phf_shared", + "serde", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "1.1.10" @@ -2556,6 +2662,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" +[[package]] +name = "polycool" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50596ddc09eb5ad5f75cacd40209568e66df71baf86e1499a0e99c4cff12a5a6" +dependencies = [ + "arrayvec", +] + [[package]] name = "portable-atomic" version = "1.11.1" @@ -2683,6 +2798,28 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "raw-window-metal" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" +dependencies = [ + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", +] + +[[package]] +name = "read-fonts" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b634fabf032fab15307ffd272149b622260f55974d9fad689292a5d33df02e5" +dependencies = [ + "bytemuck", + "font-types", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -2738,14 +2875,15 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "ron" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" +checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" dependencies = [ - "base64", "bitflags 2.10.0", + "once_cell", "serde", "serde_derive", + "typeid", "unicode-ident", ] @@ -2838,6 +2976,12 @@ dependencies = [ "tiny-skia", ] +[[package]] +name = "self_cell" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89" + [[package]] name = "serde" version = "1.0.228" @@ -2910,6 +3054,22 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "skrifa" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fbdfe3d2475fbd7ddd1f3e5cf8288a30eb3e5f95832829570cd88115a7434ac" +dependencies = [ + "bytemuck", + "read-fonts", +] + [[package]] name = "slab" version = "0.4.11" @@ -2930,6 +3090,9 @@ name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] [[package]] name = "smithay-client-toolkit" @@ -2970,7 +3133,7 @@ dependencies = [ "log", "memmap2", "rustix 1.1.2", - "thiserror 2.0.17", + "thiserror 2.0.18", "wayland-backend", "wayland-client", "wayland-csd-frame", @@ -3005,9 +3168,9 @@ dependencies = [ [[package]] name = "spirv" -version = "0.3.0+sdk-1.3.268.0" +version = "0.4.0+sdk-1.4.341.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +checksum = "d9571ea910ebd84c86af4b3ed27f9dbdc6ad06f17c5f96146b2b671e2976744f" dependencies = [ "bitflags 2.10.0", ] @@ -3123,11 +3286,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -3143,9 +3306,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -3278,6 +3441,12 @@ dependencies = [ "rustc-hash 2.1.1", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "uds_windows" version = "1.1.0" @@ -3342,6 +3511,32 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "vello_common" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd1a4c633ce09e7d713df1a6e036644a125e15e0c169cfb5180ddf5836ca04b" +dependencies = [ + "bytemuck", + "fearless_simd", + "hashbrown 0.16.1", + "log", + "peniko", + "skrifa", + "smallvec", +] + +[[package]] +name = "vello_cpu" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162bfe48aabf6a9fdcd401b628c7d9f260c2cbabb343c70a65feba6f7849edc" +dependencies = [ + "bytemuck", + "hashbrown 0.16.1", + "vello_common", +] + [[package]] name = "version_check" version = "0.9.5" @@ -3383,9 +3578,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.105" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -3396,22 +3591,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.55" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ - "cfg-if", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.105" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3419,9 +3611,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.105" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -3432,9 +3624,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.105" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] @@ -3576,9 +3768,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.82" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", @@ -3604,7 +3796,7 @@ dependencies = [ "jni", "log", "ndk-context", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-foundation 0.3.2", "url", "web-sys", @@ -3618,16 +3810,17 @@ checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] name = "wgpu" -version = "27.0.1" +version = "29.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77" +checksum = "bb3feacc458f7bee8bc1737149b42b6c731aa461039a4264a67bb6681646b250" dependencies = [ "arrayvec", "bitflags 2.10.0", + "bytemuck", "cfg-if", "cfg_aliases", "document-features", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "js-sys", "log", "naga", @@ -3647,9 +3840,9 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "27.0.3" +version = "29.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27a75de515543b1897b26119f93731b385a19aea165a1ec5f0e3acecc229cae7" +checksum = "02da3ad1b568337f25513b317870960ef87073ea0945502e44b864b67a8c77b7" dependencies = [ "arrayvec", "bit-set", @@ -3658,7 +3851,7 @@ dependencies = [ "bytemuck", "cfg_aliases", "document-features", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "indexmap", "log", "naga", @@ -3669,72 +3862,84 @@ dependencies = [ "raw-window-handle", "rustc-hash 1.1.0", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.18", "wgpu-core-deps-apple", "wgpu-core-deps-emscripten", + "wgpu-core-deps-wasm", "wgpu-core-deps-windows-linux-android", "wgpu-hal", + "wgpu-naga-bridge", "wgpu-types", ] [[package]] name = "wgpu-core-deps-apple" -version = "27.0.0" +version = "29.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0772ae958e9be0c729561d5e3fd9a19679bcdfb945b8b1a1969d9bfe8056d233" +checksum = "62e51b5447e144b3dbba4feb01f80f4fa21696fa0cd99afb2c3df1affd6fdb28" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "27.0.0" +version = "29.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3487cd6293a963bc5c0c0396f6a2192043c50003c07f4efdccbad3d90ec9d819" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-wasm" +version = "29.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06ac3444a95b0813ecfd81ddb2774b66220b264b3e2031152a4a29fda4da6b5" +checksum = "0c2f2fb042f36920771deb0b966543c5751b18f3d327760ffc90f74e20b2dcd4" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "27.0.0" +version = "29.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71197027d61a71748e4120f05a9242b2ad142e3c01f8c1b47707945a879a03c3" +checksum = "1bfb01076d0aa08b0ba9bd741e178b5cc440f5abe99d9581323a4c8b5d1a1916" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-hal" -version = "27.0.4" +version = "29.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b21cb61c57ee198bc4aff71aeadff4cbb80b927beb912506af9c780d64313ce" +checksum = "31f8e1a9e7a8512f276f7c62e018c7fa8d60954303fed2e5750114332049193f" dependencies = [ "android_system_properties", "arrayvec", "ash", "bit-set", "bitflags 2.10.0", - "block", + "block2 0.6.2", "bytemuck", "cfg-if", "cfg_aliases", - "core-graphics-types 0.2.0", "glow", "glutin_wgl_sys", - "gpu-alloc", "gpu-allocator", "gpu-descriptor", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "js-sys", "khronos-egl", "libc", "libloading", "log", - "metal", "naga", "ndk-sys", - "objc", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.2", + "objc2-metal 0.3.2", + "objc2-quartz-core 0.3.2", "once_cell", "ordered-float", "parking_lot", @@ -3743,27 +3948,41 @@ dependencies = [ "profiling", "range-alloc", "raw-window-handle", + "raw-window-metal", "renderdoc-sys", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.18", "wasm-bindgen", + "wayland-sys", "web-sys", + "wgpu-naga-bridge", + "wgpu-types", + "windows", + "windows-core", + "windows-result", +] + +[[package]] +name = "wgpu-naga-bridge" +version = "29.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c654c483f058800972c3645e95388a7eca31bf9fe1933bc20e036588a0be02" +dependencies = [ + "naga", "wgpu-types", - "windows 0.58.0", - "windows-core 0.58.0", ] [[package]] name = "wgpu-types" -version = "27.0.1" +version = "29.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb" +checksum = "a9bcc31518a0e9735aefebedb5f7a9ef3ed1c42549c9f4c882fa9060ceaac639" dependencies = [ "bitflags 2.10.0", "bytemuck", "js-sys", "log", - "thiserror 2.0.17", + "raw-window-handle", "web-sys", ] @@ -3800,84 +4019,49 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.58.0" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows" -version = "0.61.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" dependencies = [ "windows-collections", - "windows-core 0.61.2", + "windows-core", "windows-future", - "windows-link 0.1.3", "windows-numerics", ] [[package]] name = "windows-collections" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" -dependencies = [ - "windows-core 0.61.2", -] - -[[package]] -name = "windows-core" -version = "0.58.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ - "windows-implement 0.58.0", - "windows-interface 0.58.0", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", + "windows-core", ] [[package]] name = "windows-core" -version = "0.61.2" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] name = "windows-future" -version = "0.2.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", + "windows-core", + "windows-link", "windows-threading", ] -[[package]] -name = "windows-implement" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-implement" version = "0.60.2" @@ -3889,17 +4073,6 @@ dependencies = [ "syn", ] -[[package]] -name = "windows-interface" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-interface" version = "0.59.3" @@ -3911,12 +4084,6 @@ dependencies = [ "syn", ] -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" @@ -3925,49 +4092,30 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-numerics" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", -] - -[[package]] -name = "windows-result" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ - "windows-targets 0.52.6", + "windows-core", + "windows-link", ] [[package]] name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", + "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] @@ -4012,7 +4160,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -4052,7 +4200,7 @@ version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.2.1", + "windows-link", "windows_aarch64_gnullvm 0.53.1", "windows_aarch64_msvc 0.53.1", "windows_i686_gnu 0.53.1", @@ -4065,11 +4213,11 @@ dependencies = [ [[package]] name = "windows-threading" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] @@ -4212,15 +4360,15 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" +checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d" dependencies = [ "ahash", "android-activity", "atomic-waker", "bitflags 2.10.0", - "block2", + "block2 0.5.1", "bytemuck", "calloop 0.13.0", "cfg_aliases", @@ -4236,7 +4384,7 @@ dependencies = [ "objc2 0.5.2", "objc2-app-kit 0.2.2", "objc2-foundation 0.2.2", - "objc2-ui-kit", + "objc2-ui-kit 0.2.2", "orbclient", "percent-encoding", "pin-project", diff --git a/Cargo.toml b/Cargo.toml index 4964299..a104d6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,8 @@ members = ["examples/*"] # dependencies that are shared throughout the workspace (mostly for examples) [workspace.dependencies] -egui = "0.33" -eframe = { version = "0.33", default-features = false, features = [ +egui = "0.34" +eframe = { version = "0.34", default-features = false, features = [ "accesskit", # Make egui compatible with screen readers. NOTE: adds a lot of dependencies. "default_fonts", # Embed the default egui fonts. "wgpu", # Use the glow rendering backend. Alternative: "wgpu". @@ -12,7 +12,7 @@ eframe = { version = "0.33", default-features = false, features = [ ] } env_logger = "0.11.6" log = "0.4" -wgpu = "27" # enables the wgpu default features so we get the default backends +wgpu = "29" # enables the wgpu default features so we get the default backends [package] name = "egui_term" @@ -29,3 +29,7 @@ egui = { workspace = true } alacritty_terminal = "0.25.1" anyhow = "1.0.100" open = "5.3.2" +libc = "0.2" + +[target.'cfg(windows)'.dependencies] +windows-sys = { version = "0.59", features = ["Win32_Foundation", "Win32_System_Threading"] } diff --git a/README.md b/README.md index 138e744..02add33 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,24 @@ - -
+# egui_term fork gives you: -# egui_term +## Bug Fixes -[![GitHub License][license-badge]][license-link] -[![crates.io][crates.io-badge]][crates.io-link] -[![docs.rs][docs.rs-badge]][docs.rs-link] -[![Rust CI][ci-badge]][ci-link] +- **Copying multi-line text** — added newline characters when copying terminal text +- **Bracketed paste** — fixed proper bracketed paste support +- **Ctrl+X** — fixed handling (was intercepted by egui) +- **Kill child process** — proper termination when TerminalBackend is dropped +- **Alternate screen scroll** — fixed scroll handling in MOUSE_MODE -Terminal emulator widget powered by EGUI framework and alacritty terminal backend. +## New Features - - - - - - +- **Ctrl+Shift+PageUp/Down** — bindings for terminal scrolling +- **ScrollPageUp/ScrollPageDown** — page scrolling support +- **Autoscrolling** — automatic scrolling while input +- **UP/DOWN** — navigation key improvements +- **clear_history()** — method to clear terminal history +- **scroll_to_bottom()** — method to scroll to bottom +- **Shell arguments** — support for shell arguments (--login for bash) +- **ENV support** — TERM and COLORTERM in BackendSettings -
+--- -## Features - -The widget is currently under development and does not provide full terminal features make sure that widget is covered everything you want. - -- PTY content rendering -- Multiple instance support -- Basic keyboard input -- Adding custom keyboard or mouse bindings -- Resizing -- Scrolling -- Focusing -- Selecting -- Changing Font/Color scheme -- Hyperlinks processing (hover/open) - -This widget was tested on MacOS, Linux, and Windows. - -## Examples - -You can also look at [examples](./examples) directory for more information about widget using. - -- [full_screen](./examples/full_screen/) - The basic example of terminal emulator. -- [tabs](./examples/tabs/) - The example with tab widget that show how multiple instance feature work. -- [custom_bindings](./examples/custom_bindings/) - The example that show how you can add custom keyboard or mouse bindings to your terminal emulator app. -- [themes](./examples/themes/) - The example that show how you can change terminal color scheme. -- [fonts](./examples/fonts/) - The examples that show how you can change font type or font size in your terminal emulator app. - -## Dependencies - -[![dependency status][deps.rs-badge]][deps.rs-link] - -- [alacritty_terminal](https://github.com/alacritty/alacritty) (Apache-2.0) -- [anyhow](https://github.com/dtolnay/anyhow) (MIT OR Apache-2.0) -- [egui](https://github.com/emilk/egui) (MIT OR Apache-2.0) -- [open](https://github.com/Byron/open-rs) (MIT) - -[license-badge]: https://img.shields.io/github/license/Harzu/egui_term -[license-link]: https://github.com/Harzu/egui_term/blob/main/LICENSE -[crates.io-badge]: https://img.shields.io/crates/v/egui_term -[crates.io-link]: https://crates.io/crates/egui_term -[docs.rs-badge]: https://img.shields.io/docsrs/egui_term -[docs.rs-link]: https://docs.rs/egui_term -[ci-badge]: https://github.com/Harzu/egui_term/actions/workflows/rust.yml/badge.svg -[ci-link]: https://github.com/Harzu/egui_term/actions/workflows/rust.yml -[deps.rs-badge]: https://img.shields.io/deps-rs/egui_term/latest?style=for-the-badge&label=dependency%20status -[deps.rs-link]: https://deps.rs/crate/egui_term +Forked from [Harzu/egui_term](https://github.com/Harzu/egui_term) diff --git a/examples/custom_bindings/src/app.rs b/examples/custom_bindings/src/app.rs index 11f2489..33d660d 100644 --- a/examples/custom_bindings/src/app.rs +++ b/examples/custom_bindings/src/app.rs @@ -80,7 +80,8 @@ impl App { } impl eframe::App for App { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { + let ctx = ui.ctx(); if let Ok((_, PtyEvent::Exit)) = self.pty_proxy_receiver.try_recv() { ctx.send_viewport_cmd(egui::ViewportCommand::Close); return; diff --git a/examples/fonts/src/app.rs b/examples/fonts/src/app.rs index f361683..bdc1c06 100644 --- a/examples/fonts/src/app.rs +++ b/examples/fonts/src/app.rs @@ -82,7 +82,8 @@ impl App { } impl eframe::App for App { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { + let ctx = ui.ctx(); if let Ok((_, PtyEvent::Exit)) = self.pty_proxy_receiver.try_recv() { ctx.send_viewport_cmd(egui::ViewportCommand::Close); return; diff --git a/examples/full_screen/src/app.rs b/examples/full_screen/src/app.rs index 0278ac6..168df9f 100644 --- a/examples/full_screen/src/app.rs +++ b/examples/full_screen/src/app.rs @@ -35,7 +35,8 @@ impl App { } impl eframe::App for App { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { + let ctx = ui.ctx(); if let Ok((_, PtyEvent::Exit)) = self.pty_proxy_receiver.try_recv() { ctx.send_viewport_cmd(egui::ViewportCommand::Close); return; diff --git a/examples/split_view/Cargo.toml b/examples/split_view/Cargo.toml index 7cc2077..2464c62 100644 --- a/examples/split_view/Cargo.toml +++ b/examples/split_view/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] egui = { workspace = true } -egui_dock = "0.18.0" +egui_dock = "0.19.1" eframe = { workspace = true } log = { workspace = true } egui_term = { path = "../../" } diff --git a/examples/split_view/src/app.rs b/examples/split_view/src/app.rs index 9179d7c..b6b8967 100644 --- a/examples/split_view/src/app.rs +++ b/examples/split_view/src/app.rs @@ -124,7 +124,8 @@ impl App { } impl eframe::App for App { - fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) { + fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { + let ctx = ui.ctx(); DockArea::new(&mut self.dock_state) .show_add_buttons(false) .style(Style::from_egui(ctx.style().as_ref())) diff --git a/examples/tabs/input_link b/examples/tabs/input_link new file mode 120000 index 0000000..16193db --- /dev/null +++ b/examples/tabs/input_link @@ -0,0 +1 @@ +/home/oleg/alacritty/alacritty/src/input/ \ No newline at end of file diff --git a/examples/tabs/src/app.rs b/examples/tabs/src/app.rs index 6966540..b097d67 100644 --- a/examples/tabs/src/app.rs +++ b/examples/tabs/src/app.rs @@ -22,7 +22,8 @@ impl App { } impl eframe::App for App { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { + let ctx = ui.ctx(); if ctx.input(|i| i.viewport().close_requested()) { self.tab_manager.clear(); } @@ -161,16 +162,23 @@ impl Tab { ) -> Self { #[cfg(unix)] let system_shell = - std::env::var("SHELL").expect("SHELL variable is not defined"); + std::env::var("SHELL").unwrap_or_else(|_| "bash".to_string()); #[cfg(windows)] let system_shell = "cmd.exe".to_string(); + let shell_args = if system_shell.contains("bash") { + vec!["--login".to_string()] + } else { + vec![] + }; + let backend = TerminalBackend::new( id, ctx, command_sender, egui_term::BackendSettings { shell: system_shell, + args: shell_args, ..Default::default() }, ) diff --git a/examples/themes/src/app.rs b/examples/themes/src/app.rs index dcd4b69..c0bd79e 100644 --- a/examples/themes/src/app.rs +++ b/examples/themes/src/app.rs @@ -39,7 +39,8 @@ impl App { } impl eframe::App for App { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) { + let ctx = ui.ctx(); if let Ok((_, PtyEvent::Exit)) = self.pty_proxy_receiver.try_recv() { ctx.send_viewport_cmd(egui::ViewportCommand::Close); return; diff --git a/notes/ALTERNATE_SCROLL.md b/notes/ALTERNATE_SCROLL.md new file mode 100644 index 0000000..70ca57b --- /dev/null +++ b/notes/ALTERNATE_SCROLL.md @@ -0,0 +1,81 @@ +# ALTERNATE_SCROLL Fix + +## Problem + +Mouse wheel scrolling was not working correctly in applications using ncurses with alternate screen mode (e.g., opencode, tmux, less, vim). Instead of scrolling the content within the application, the terminal was sending arrow key sequences (ESC O A / ESC O B). + +## Root Cause + +The issue was in the scroll handling logic in `src/view.rs` and `src/backend/mod.rs`: + +1. **Incorrect priority check**: The condition `terminal.mode().contains(TermMode::ALTERNATE_SCROLL | TermMode::ALT_SCREEN)` would return `true` even when `MOUSE_MODE` was active, because `contains()` checks if ANY of the flags are present. + +2. **Missing terminal mode priority**: When `MOUSE_MODE` (specifically `SGR_MOUSE`) is active in ncurses applications, the application expects mouse wheel events via SGR protocol, not arrow key sequences. + +3. **Focus/pointer check issue**: All input events were blocked if either focus was lost OR pointer was outside widget, which prevented scroll from working even when the mouse was over the widget. + +## Solution + +### 1. Corrected terminal mode priority + +Updated scroll handling in `src/view.rs` to follow alacrity's priority order: + +```rust +// Priority 1: MOUSE_MODE (SGR_MOUSE active) → Send mouse wheel report +if terminal_mode.intersects(TermMode::MOUSE_MODE) { + // Send SGR mouse wheel report +} +// Priority 2: ALT_SCREEN | ALTERNATE_SCROLL → Send arrow keys +else if terminal_mode.contains(TermMode::ALT_SCREEN | TermMode::ALTERNATE_SCROLL) { + // Send ESC O A / ESC O B +} +// Priority 3: Default → Scroll viewport +else { + // Scroll terminal viewport +} +``` + +Key changes: +- Use `intersects()` for `MOUSE_MODE` check (it's a combination of multiple flags) +- Ensure MOUSE_MODE is checked BEFORE ALTERNATE_SCROLL +- Use `contains()` for ALT_SCREEN | ALTERNATE_SCROLL combination + +### 2. Separated keyboard and mouse event handling + +Modified `process_input()` in `src/view.rs` to have different focus requirements: + +- **Keyboard events** (Text, Key, Copy, Paste): Require `layout.has_focus()` +- **Mouse events** (MouseWheel, PointerButton, PointerMoved): Require `layout.contains_pointer()` + +This allows mouse wheel to work even when keyboard focus is on different widgets. + +### 3. Inverted scroll direction + +Adjusted scroll direction to match standard behavior: + +- **Mouse wheel up** → Scroll content up (send ScrollUp / ESC O A) +- **Mouse wheel down** → Scroll content down (send ScrollDown / ESC O B) + +## Files Changed + +- `src/view.rs`: + - Modified `process_input()` to separate keyboard/mouse event handling + - Rewrote `process_mouse_wheel()` with correct terminal mode priority + - Removed rigid focus check at the start + +- `src/backend/mod.rs`: + - Simplified `scroll()` function to only handle viewport scrolling + +## Testing + +Tested with opencode (ncurses-based application) in alternate screen mode: +- ✅ Mouse wheel now correctly scrolls application content +- ✅ Mouse wheel events are sent via SGR protocol when MOUSE_MODE is active +- ✅ Scroll direction matches standard behavior +- ✅ Works without requiring explicit focus + +## References + +- Alacrity scroll handling: `alacritty/src/input/mod.rs` - `scroll_terminal()` function +- Terminal mode definitions: `alacritty_terminal/src/term/mod.rs` - `TermMode` enum +- DEC Private Mode 1007 (ALTERNATE_SCROLL): Controls arrow key substitution for scroll events diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 4b3e43c..e4e3d68 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -4,7 +4,7 @@ use crate::types::Size; use alacritty_terminal::event::{ Event, EventListener, Notify, OnResize, WindowSize, }; -use alacritty_terminal::event_loop::{EventLoop, Msg, Notifier}; +use alacritty_terminal::event_loop::{EventLoop, Notifier}; use alacritty_terminal::grid::{Dimensions, Scroll}; use alacritty_terminal::index::{Column, Direction, Line, Point, Side}; use alacritty_terminal::selection::{ @@ -33,6 +33,8 @@ pub type SelectionType = AlacrittySelectionType; pub enum BackendCommand { Write(Vec), Scroll(i32), + ScrollPageUp, + ScrollPageDown, Resize(Size, Size), SelectStart(SelectionType, f32, f32), SelectUpdate(f32, f32), @@ -79,6 +81,106 @@ pub enum LinkAction { Open, } +#[derive(Clone, Debug, Default)] +pub struct SearchState { + pub query: String, + pub regex: Option, + pub matches: Vec, + pub current_match_index: usize, + pub active: bool, + pub no_match: bool, +} + +impl SearchState { + pub fn new() -> Self { + Self::default() + } + + pub fn set_query(&mut self, query: &str) { + self.query = query.to_string(); + if query.is_empty() { + self.regex = None; + self.matches.clear(); + self.no_match = false; + return; + } + + match RegexSearch::new(query) { + Ok(regex) => { + self.regex = Some(regex); + }, + Err(_) => { + self.regex = None; + self.matches.clear(); + self.no_match = true; + }, + } + } + + pub fn update_matches(&mut self, term: &Term) { + if let Some(ref mut regex) = self.regex { + let viewport_start = Line(-(term.grid().display_offset() as i32)); + let viewport_end = viewport_start + term.bottommost_line(); + let mut start = + term.line_search_left(Point::new(viewport_start, Column(0))); + let mut end = + term.line_search_right(Point::new(viewport_end, Column(0))); + start.line = start.line.max(viewport_start - 100); + end.line = end.line.min(viewport_end + 100); + + self.matches = + RegexIter::new(start, end, Direction::Right, term, regex) + .skip_while(|rm| rm.end().line < viewport_start) + .take_while(|rm| rm.start().line <= viewport_end) + .collect(); + + self.no_match = self.matches.is_empty(); + if self.current_match_index >= self.matches.len() { + self.current_match_index = 0; + } + } else { + self.matches.clear(); + self.no_match = !self.query.is_empty(); + } + } + + pub fn next_match(&mut self) -> Option<&Match> { + if self.matches.is_empty() { + return None; + } + let m = self.matches.get(self.current_match_index)?; + self.current_match_index = + (self.current_match_index + 1) % self.matches.len(); + Some(m) + } + + pub fn prev_match(&mut self) -> Option<&Match> { + if self.matches.is_empty() { + return None; + } + if self.current_match_index == 0 { + self.current_match_index = self.matches.len() - 1; + } else { + self.current_match_index -= 1; + } + self.matches.get(self.current_match_index) + } + + pub fn current_match(&self) -> Option<&Match> { + self.matches.get(self.current_match_index) + } + + pub fn point_in_match(&self, point: Point) -> Option { + self.matches.iter().position(|m| m.contains(&point)) + } + + pub fn is_focused_match(&self, point: Point) -> bool { + self.current_match() + .map(|m| m.contains(&point)) + .unwrap_or(false) + } +} + #[derive(Clone, Copy, Debug)] pub struct TerminalSize { pub cell_width: u16, @@ -141,6 +243,16 @@ pub struct TerminalBackend { size: TerminalSize, notifier: Notifier, last_content: RenderableContent, + _event_loop_thread: Option>, + _event_loop_thread_pty: Option< + std::thread::JoinHandle<( + alacritty_terminal::event_loop::EventLoop< + alacritty_terminal::tty::Pty, + EventProxy, + >, + alacritty_terminal::event_loop::State, + )>, + >, } impl TerminalBackend { @@ -153,6 +265,7 @@ impl TerminalBackend { let pty_config = tty::Options { shell: Some(tty::Shell::new(settings.shell, settings.args)), working_directory: settings.working_directory, + env: settings.env, ..tty::Options::default() }; let config = term::Config::default(); @@ -179,6 +292,7 @@ impl TerminalBackend { terminal_size, cursor: term.grid_mut().cursor_cell().clone(), hovered_hyperlink: None, + search_state: SearchState::default(), }; let term = Arc::new(FairMutex::new(term)); let pty_event_loop = @@ -186,23 +300,30 @@ impl TerminalBackend { let notifier = Notifier(pty_event_loop.channel()); let pty_notifier = Notifier(pty_event_loop.channel()); let url_regex = RegexSearch::new(r#"(ipfs:|ipns:|magnet:|mailto:|gemini://|gopher://|https://|http://|news:|file://|git://|ssh:|ftp://)[^\u{0000}-\u{001F}\u{007F}-\u{009F}<>"\s{-}\^⟨⟩`]+"#).unwrap(); - let _pty_event_loop_thread = pty_event_loop.spawn(); - let _pty_event_subscription = std::thread::Builder::new() + let event_loop_thread = pty_event_loop.spawn(); + let event_subscription_thread = std::thread::Builder::new() .name(format!("pty_event_subscription_{}", id)) - .spawn(move || loop { - if let Ok(event) = event_receiver.recv() { - pty_event_proxy_sender - .send((id, event.clone())) - .unwrap_or_else(|_| { - panic!("pty_event_subscription_{}: sending PtyEvent is failed", id) - }); - app_context.clone().request_repaint(); - match event { - Event::Exit => break, - Event::PtyWrite(pty) => pty_notifier.notify(pty.into_bytes()), - _ => {} + .spawn(move || { + eprintln!("pty_event_subscription_{}: started, pty_id={}", id, pty_id); + loop { + if let Ok(event) = event_receiver.recv() { + pty_event_proxy_sender + .send((id, event.clone())) + .unwrap_or_else(|_| { + panic!("pty_event_subscription_{}: sending PtyEvent is failed", id) + }); + app_context.clone().request_repaint(); + match event { + Event::Exit => { + eprintln!("pty_event_subscription_{}: received Exit event", id); + break; + } + Event::PtyWrite(pty) => pty_notifier.notify(pty.into_bytes()), + _ => {} + } } } + eprintln!("pty_event_subscription_{}: thread exiting", id); })?; Ok(Self { @@ -213,6 +334,8 @@ impl TerminalBackend { size: terminal_size, notifier, last_content: initial_content, + _event_loop_thread: Some(event_subscription_thread), + _event_loop_thread_pty: Some(event_loop_thread), }) } @@ -222,11 +345,19 @@ impl TerminalBackend { match cmd { BackendCommand::Write(input) => { self.write(input); - term.scroll_display(Scroll::Bottom); + if term.grid().total_lines() > term.grid().screen_lines() { + term.scroll_display(Scroll::Bottom); + } }, BackendCommand::Scroll(delta) => { self.scroll(&mut term, delta); }, + BackendCommand::ScrollPageUp => { + term.scroll_display(Scroll::PageUp); + }, + BackendCommand::ScrollPageDown => { + term.scroll_display(Scroll::PageDown); + }, BackendCommand::Resize(layout_size, font_size) => { self.resize(&mut term, layout_size, font_size); }, @@ -264,8 +395,15 @@ impl TerminalBackend { let content = self.last_content(); let mut result = String::new(); if let Some(range) = content.selectable_range { + let mut prev_line: Option = None; for indexed in content.grid.display_iter() { if range.contains(indexed.point) { + if let Some(prev) = prev_line { + if indexed.point.line.0 != prev { + result.push('\n'); + } + } + prev_line = Some(indexed.point.line.0); result.push(indexed.c); } } @@ -275,7 +413,14 @@ impl TerminalBackend { pub fn sync(&mut self) -> &RenderableContent { let term = self.term.clone(); - let mut terminal = term.lock(); + let mut terminal = match term.try_lock_unfair() { + Some(guard) => guard, + // The PTY reader thread currently holds the terminal lock while + // processing a batch of output. Block the UI only briefly: paint + // the previous frame's content instead of waiting for the lock. + None => return &self.last_content, + }; + let selectable_range = match &terminal.selection { Some(s) => s.to_range(&terminal), None => None, @@ -287,6 +432,11 @@ impl TerminalBackend { self.last_content.cursor = cursor.clone(); self.last_content.terminal_mode = *terminal.mode(); self.last_content.terminal_size = self.size; + + if self.last_content.search_state.active { + self.last_content.search_state.update_matches(&terminal); + } + self.last_content() } @@ -302,6 +452,85 @@ impl TerminalBackend { self.pty_id } + pub fn scroll_to_bottom(&mut self) { + let term = self.term.clone(); + let mut term = term.lock(); + term.scroll_display(Scroll::Bottom); + } + + pub fn scroll_to_top(&mut self) { + let term = self.term.clone(); + let mut term = term.lock(); + term.scroll_display(Scroll::Top); + } + + pub fn clear_history(&mut self) { + let term = self.term.clone(); + let mut term = term.lock(); + term.grid_mut().clear_history(); + } + + pub fn search_set_query(&mut self, query: &str) { + self.last_content.search_state.set_query(query); + let term = self.term.clone(); + let term = term.lock(); + self.last_content.search_state.update_matches(&term); + } + + pub fn search_next(&mut self) -> Option { + let term = self.term.clone(); + let term = term.lock(); + self.last_content.search_state.update_matches(&term); + + if let Some(m) = self.last_content.search_state.next_match() { + let start = *m.start(); + return Some(start); + } + None + } + + pub fn search_prev(&mut self) -> Option { + let term = self.term.clone(); + let term = term.lock(); + self.last_content.search_state.update_matches(&term); + + if let Some(m) = self.last_content.search_state.prev_match() { + let start = *m.start(); + return Some(start); + } + None + } + + pub fn scroll_to_point(&mut self, point: Point) { + let term = self.term.clone(); + let mut term = term.lock(); + let display_offset = term.grid().display_offset(); + let viewport_top = -(display_offset as i32); + let viewport_bottom = viewport_top + (self.size.num_lines as i32 - 1); + + if point.line.0 < viewport_top { + let delta = viewport_top - point.line.0; + term.grid_mut().scroll_display(Scroll::Delta(delta as i32)); + } else if point.line.0 > viewport_bottom { + let delta = point.line.0 - viewport_bottom; + term.grid_mut() + .scroll_display(Scroll::Delta(-(delta as i32))); + } + } + + pub fn search_active(&self) -> bool { + self.last_content.search_state.active + } + + pub fn search_set_active(&mut self, active: bool) { + self.last_content.search_state.active = active; + if !active { + self.last_content.search_state.matches.clear(); + self.last_content.search_state.query.clear(); + self.last_content.search_state.no_match = false; + } + } + fn process_link_action( &mut self, terminal: &Term, @@ -510,23 +739,7 @@ impl TerminalBackend { fn scroll(&mut self, terminal: &mut Term, delta_value: i32) { if delta_value != 0 { let scroll = Scroll::Delta(delta_value); - if terminal - .mode() - .contains(TermMode::ALTERNATE_SCROLL | TermMode::ALT_SCREEN) - { - let line_cmd = if delta_value > 0 { b'A' } else { b'B' }; - let mut content = vec![]; - - for _ in 0..delta_value.abs() { - content.push(0x1b); - content.push(b'O'); - content.push(line_cmd); - } - - self.notifier.notify(content); - } else { - terminal.grid_mut().scroll_display(scroll); - } + terminal.grid_mut().scroll_display(scroll); } } @@ -570,6 +783,7 @@ pub struct RenderableContent { pub cursor: Cell, pub terminal_mode: TermMode, pub terminal_size: TerminalSize, + pub search_state: SearchState, } impl Default for RenderableContent { @@ -581,13 +795,30 @@ impl Default for RenderableContent { cursor: Cell::default(), terminal_mode: TermMode::empty(), terminal_size: TerminalSize::default(), + search_state: SearchState::default(), } } } impl Drop for TerminalBackend { fn drop(&mut self) { - let _ = self.notifier.0.send(Msg::Shutdown); + eprintln!("TerminalBackend::drop(): killing pid={}", self.pty_id); + #[cfg(unix)] + unsafe { + let pid = self.pty_id as i32; + let _ = libc::kill(-pid, libc::SIGHUP); + let _ = libc::kill(-pid, libc::SIGKILL); + } + #[cfg(windows)] + unsafe { + use windows_sys::Win32::Foundation::CloseHandle; + use windows_sys::Win32::System::Threading::{OpenProcess, TerminateProcess, PROCESS_TERMINATE}; + let handle = OpenProcess(PROCESS_TERMINATE, 0, self.pty_id); + if !handle.is_null() { + let _ = TerminateProcess(handle, 1); + let _ = CloseHandle(handle); + } + } } } diff --git a/src/backend/settings.rs b/src/backend/settings.rs index 3c58f8e..b980ed2 100644 --- a/src/backend/settings.rs +++ b/src/backend/settings.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap; use std::path::PathBuf; const DEFAULT_SHELL: &str = "/bin/bash"; @@ -7,14 +8,20 @@ pub struct BackendSettings { pub shell: String, pub args: Vec, pub working_directory: Option, + pub env: HashMap, } impl Default for BackendSettings { fn default() -> Self { + let mut env = HashMap::new(); + env.insert("TERM".to_string(), "xterm-256color".to_string()); + env.insert("COLORTERM".to_string(), "truecolor".to_string()); + Self { shell: DEFAULT_SHELL.to_string(), args: vec![], working_directory: None, + env, } } } diff --git a/src/bindings.rs b/src/bindings.rs index b33d803..a44617e 100644 --- a/src/bindings.rs +++ b/src/bindings.rs @@ -303,8 +303,10 @@ fn default_keyboard_bindings() -> Vec<(Binding, BindingAction)> { // CTRL + ALT End, Modifiers::CTRL | Modifiers::ALT; BindingAction::Esc("\x1b[1;7F".into()); Home, Modifiers::CTRL | Modifiers::ALT; BindingAction::Esc("\x1b[1;7H".into()); - PageUp, Modifiers::CTRL | Modifiers::ALT; BindingAction::Esc("\x1b[5;7~".into()); - PageDown, Modifiers::CTRL | Modifiers::ALT; BindingAction::Esc("\x1b[6;7~".into()); + PageUp, Modifiers::CTRL | Modifiers::ALT; BindingAction::Esc("\x1b[5;7~".into()); + PageDown, Modifiers::CTRL | Modifiers::ALT; BindingAction::Esc("\x1b[6;7~".into()); + PageUp, Modifiers::SHIFT | Modifiers::CTRL; BindingAction::Esc("\x1b[5;6~".into()); + PageDown, Modifiers::SHIFT | Modifiers::CTRL; BindingAction::Esc("\x1b[6;6~".into()); ArrowUp, Modifiers::CTRL | Modifiers::ALT; BindingAction::Esc("\x1b[1;7A".into()); ArrowDown, Modifiers::CTRL | Modifiers::ALT; BindingAction::Esc("\x1b[1;7B".into()); ArrowLeft, Modifiers::CTRL | Modifiers::ALT; BindingAction::Esc("\x1b[1;7D".into()); diff --git a/src/lib.rs b/src/lib.rs index 20cbcd3..4e32029 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,9 @@ mod types; mod view; pub use backend::settings::BackendSettings; -pub use backend::{BackendCommand, PtyEvent, TerminalBackend, TerminalMode}; +pub use backend::{ + BackendCommand, PtyEvent, SearchState, TerminalBackend, TerminalMode, +}; pub use bindings::{Binding, BindingAction, InputKind, KeyboardBinding}; pub use font::{FontSettings, TerminalFont}; pub use theme::{ColorPalette, TerminalTheme}; diff --git a/src/theme.rs b/src/theme.rs index 63bef9e..5ecba2b 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -206,13 +206,20 @@ impl TerminalTheme { } fn hex_to_color(hex: &str) -> anyhow::Result { - if hex.len() != 7 { + let is_solid = hex.len() == 7; + let is_transparent = hex.len() == 9; + if !is_solid && !is_transparent || !hex.starts_with('#') { return Err(anyhow::format_err!("input string is in non valid format")); } let r = u8::from_str_radix(&hex[1..3], 16)?; let g = u8::from_str_radix(&hex[3..5], 16)?; let b = u8::from_str_radix(&hex[5..7], 16)?; + let a = if is_transparent { + u8::from_str_radix(&hex[7..9], 16)? + } else { + 255 + }; - Ok(Color32::from_rgb(r, g, b)) + Ok(Color32::from_rgba_unmultiplied(r, g, b, a)) } diff --git a/src/view.rs b/src/view.rs index cdbccdc..3499fc6 100644 --- a/src/view.rs +++ b/src/view.rs @@ -8,7 +8,7 @@ use egui::MouseWheelUnit; use egui::Shape; use egui::Widget; use egui::{Align2, Painter, Pos2, Rect, Response, Stroke, Vec2}; -use egui::{CornerRadius, Key}; +use egui::{Color32, CornerRadius, Key}; use egui::{Id, PointerButton}; use crate::backend::BackendCommand; @@ -21,6 +21,8 @@ use crate::theme::TerminalTheme; use crate::types::Size; const EGUI_TERM_WIDGET_ID_PREFIX: &str = "egui_term::instance::"; +const SEARCH_HIGHLIGHT_COLOR: Color32 = Color32::from_rgb(255, 165, 0); +const SEARCH_FOCUSED_HIGHLIGHT_COLOR: Color32 = Color32::from_rgb(255, 140, 0); #[derive(Debug, Clone)] enum InputAction { @@ -144,10 +146,6 @@ impl<'a> TerminalView<'a> { layout: &Response, state: &mut TerminalViewState, ) -> Self { - if !layout.has_focus() || !layout.contains_pointer() { - return self; - } - let modifiers = layout.ctx.input(|i| i.modifiers); let events = layout.ctx.input(|i| i.events.clone()); for event in events { @@ -157,45 +155,58 @@ impl<'a> TerminalView<'a> { egui::Event::Text(_) | egui::Event::Key { .. } | egui::Event::Copy + | egui::Event::Cut | egui::Event::Paste(_) => { - input_actions.push(process_keyboard_event( - event, - self.backend, - &self.bindings_layout, - modifiers, - )) + if layout.has_focus() { + input_actions.push(process_keyboard_event( + event, + self.backend, + &self.bindings_layout, + modifiers, + )) + } + }, + egui::Event::MouseWheel { unit, delta, .. } => { + if layout.contains_pointer() { + input_actions.push(process_mouse_wheel( + state, + self.font.font_type().size, + unit, + delta, + self.backend, + )) + } }, - egui::Event::MouseWheel { unit, delta, .. } => input_actions - .push(process_mouse_wheel( - state, - self.font.font_type().size, - unit, - delta, - )), egui::Event::PointerButton { button, pressed, modifiers, pos, .. - } => input_actions.push(process_button_click( - state, - layout, - self.backend, - &self.bindings_layout, - button, - pos, - &modifiers, - pressed, - )), + } => { + if layout.contains_pointer() { + input_actions.push(process_button_click( + state, + layout, + self.backend, + &self.bindings_layout, + button, + pos, + &modifiers, + pressed, + )) + } + }, egui::Event::PointerMoved(pos) => { - input_actions = process_mouse_move( - state, - layout, - self.backend, - pos, - &modifiers, - ) + if layout.contains_pointer() { + input_actions = process_mouse_move( + state, + layout, + self.backend, + pos, + &modifiers, + ) + } }, _ => {}, }; @@ -230,11 +241,16 @@ impl<'a> TerminalView<'a> { let global_bg = self.theme.get_color(Color::Named(NamedColor::Background)); - let mut shapes = vec![Shape::Rect(RectShape::filled( - Rect::from_min_max(layout_min, layout_max), - CornerRadius::ZERO, - global_bg, - ))]; + let mut shapes = Vec::new(); + + // Only draw the global background when it is not fully transparent. + if global_bg.a() > 0 { + shapes.push(Shape::Rect(RectShape::filled( + Rect::from_min_max(layout_min, layout_max), + CornerRadius::ZERO, + global_bg, + ))); + } for indexed in content.grid.display_iter() { let flags = indexed.cell.flags; @@ -258,6 +274,10 @@ impl<'a> TerminalView<'a> { r.contains(&indexed.point) && r.contains(&state.current_mouse_position_on_grid) }); + let is_search_match = content.search_state.active + && content.search_state.point_in_match(indexed.point).is_some(); + let is_focused_search_match = content.search_state.active + && content.search_state.is_focused_match(indexed.point); let x = layout_min.x + (cell_width * indexed.point.column.0 as f32); let line_num = @@ -292,6 +312,22 @@ impl<'a> TerminalView<'a> { ))); } + if is_search_match { + let highlight_color = if is_focused_search_match { + SEARCH_FOCUSED_HIGHLIGHT_COLOR + } else { + SEARCH_HIGHLIGHT_COLOR + }; + shapes.push(Shape::Rect(RectShape::filled( + Rect::from_min_size( + Pos2::new(x, y), + Vec2::new(cell_width + 1., cell_height + 1.), + ), + CornerRadius::ZERO, + highlight_color, + ))); + } + // Handle hovered hyperlink underline if is_hovered_hyperling { let underline_height = y + cell_height; @@ -355,27 +391,52 @@ fn process_keyboard_event( egui::Event::Text(text) => { process_text_event(&text, modifiers, backend, bindings_layout) }, - egui::Event::Paste(text) => InputAction::BackendCall( + egui::Event::Paste(text) => { + let terminal_mode = backend.last_content().terminal_mode; + InputAction::BackendCall( + if terminal_mode.contains(TermMode::BRACKETED_PASTE) { + // Bracketed paste mode: wrap text with markers and filter escape sequences + let mut payload = Vec::new(); + payload.extend_from_slice(b"\x1b[200~"); + // Filter out escape sequences that could terminate the paste early + for byte in text.bytes() { + if byte != 0x1b && byte != 0x03 { + payload.push(byte); + } + } + payload.extend_from_slice(b"\x1b[201~"); + BackendCommand::Write(payload) + } else { + // Normal mode: replace newlines with carriage returns + let processed = + text.replace("\r\n", "\r").replace('\n', "\r"); + BackendCommand::Write(processed.into_bytes()) + }, + ) + }, + egui::Event::Copy => { #[cfg(not(any(target_os = "ios", target_os = "macos")))] if modifiers.contains(Modifiers::COMMAND | Modifiers::SHIFT) { - BackendCommand::Write(text.as_bytes().to_vec()) + let content = backend.selectable_content(); + InputAction::WriteToClipboard(content) } else { - // Hotfix - Send ^V when there's not selection on view. - BackendCommand::Write([0x16].to_vec()) - }, + // Hotfix - Send ^C when there's not selection on view. + InputAction::BackendCall(BackendCommand::Write([0x3].to_vec())) + } #[cfg(any(target_os = "ios", target_os = "macos"))] { - BackendCommand::Write(text.as_bytes().to_vec()) - }, - ), - egui::Event::Copy => { + let content = backend.selectable_content(); + InputAction::WriteToClipboard(content) + } + }, + egui::Event::Cut => { #[cfg(not(any(target_os = "ios", target_os = "macos")))] if modifiers.contains(Modifiers::COMMAND | Modifiers::SHIFT) { let content = backend.selectable_content(); InputAction::WriteToClipboard(content) } else { - // Hotfix - Send ^C when there's not selection on view. - InputAction::BackendCall(BackendCommand::Write([0x3].to_vec())) + // Hotfix - Send ^X when there's not selection on view. + InputAction::BackendCall(BackendCommand::Write([0x18].to_vec())) } #[cfg(any(target_os = "ios", target_os = "macos"))] { @@ -463,23 +524,53 @@ fn process_mouse_wheel( font_size: f32, unit: MouseWheelUnit, delta: Vec2, + backend: &TerminalBackend, ) -> InputAction { - match unit { + let lines = match unit { MouseWheelUnit::Line => { - let lines = delta.y.signum() * delta.y.abs().ceil(); - InputAction::BackendCall(BackendCommand::Scroll(lines as i32)) + (delta.y.signum() * delta.y.abs().ceil()) as i32 }, MouseWheelUnit::Point => { state.scroll_pixels -= delta.y; - let lines = (state.scroll_pixels / font_size).trunc(); + let lines = (state.scroll_pixels / font_size).trunc() as i32; state.scroll_pixels %= font_size; - if lines != 0.0 { - InputAction::BackendCall(BackendCommand::Scroll(-lines as i32)) - } else { - InputAction::Ignore - } + lines }, - MouseWheelUnit::Page => InputAction::Ignore, + MouseWheelUnit::Page => 0, + }; + + if lines == 0 { + return InputAction::Ignore; + } + + let terminal_mode = backend.last_content().terminal_mode; + + if terminal_mode.intersects(crate::backend::TerminalMode::MOUSE_MODE) { + let mouse_btn = if lines > 0 { + crate::backend::MouseButton::ScrollDown + } else { + crate::backend::MouseButton::ScrollUp + }; + InputAction::BackendCall(BackendCommand::MouseReport( + mouse_btn, + egui::Modifiers::NONE, + state.current_mouse_position_on_grid, + true, + )) + } else if terminal_mode.contains( + crate::backend::TerminalMode::ALT_SCREEN + | crate::backend::TerminalMode::ALTERNATE_SCROLL, + ) { + let line_cmd = if lines > 0 { b'B' } else { b'A' }; + let mut content = vec![]; + for _ in 0..lines.abs() { + content.push(0x1b); + content.push(b'O'); + content.push(line_cmd); + } + InputAction::BackendCall(BackendCommand::Write(content)) + } else { + InputAction::BackendCall(BackendCommand::Scroll(lines)) } }