aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2022-03-23 09:08:35 +0100
committerGitHub <noreply@github.com>2022-03-23 09:08:35 +0100
commit7141779153743cb98771c6582a1feff32ec2e494 (patch)
treebf30b37263858d5e166caa226ffadbb1e53c8c0f
parentchore(docs): update changelog with rounded corners (diff)
downloadsl0ppij-7141779153743cb98771c6582a1feff32ec2e494.tar.gz
sl0ppij-7141779153743cb98771c6582a1feff32ec2e494.tar.xz
sl0ppij-7141779153743cb98771c6582a1feff32ec2e494.zip
chore(deps): move from termion to termwiz for STDIN handling (#1249)
* fix(deps): switch from termion to termwiz for STDIN parsing * style(fmt): clippy * style(fmt): moar clippy * style(fmt): rustfmt * fix(tests): e2e mouse press * style(fmt): rustfmt * bring back polling * fmt fmt fmt * fix some e2e flakiness
-rw-r--r--Cargo.lock378
-rw-r--r--src/tests/e2e/cases.rs29
-rw-r--r--zellij-client/src/input_handler.rs70
-rw-r--r--zellij-client/src/lib.rs5
-rw-r--r--zellij-client/src/os_input_output.rs24
-rw-r--r--zellij-client/src/stdin_handler.rs92
-rw-r--r--zellij-client/src/unit/input_handler_tests.rs24
-rw-r--r--zellij-utils/Cargo.toml3
-rw-r--r--zellij-utils/src/input/mod.rs72
-rw-r--r--zellij-utils/src/input/mouse.rs88
-rw-r--r--zellij-utils/src/lib.rs2
11 files changed, 581 insertions, 206 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 32664a5b..5e2cab67 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -144,7 +144,7 @@ dependencies = [
"futures-lite",
"libc",
"once_cell",
- "signal-hook",
+ "signal-hook 0.3.13",
"winapi",
]
@@ -253,6 +253,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
+name = "block-buffer"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
name = "blocking"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -424,6 +433,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
+name = "cpufeatures"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "cranelift-bforest"
version = "0.68.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -645,6 +663,15 @@ dependencies = [
]
[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
name = "directories-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -655,6 +682,27 @@ dependencies = [
]
[[package]]
+name = "dirs"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
+dependencies = [
+ "cfg-if 0.1.10",
+ "dirs-sys",
+]
+
+[[package]]
+name = "dirs-sys"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi",
+]
+
+[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -729,6 +777,17 @@ dependencies = [
]
[[package]]
+name = "filedescriptor"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e"
+dependencies = [
+ "libc",
+ "thiserror",
+ "winapi",
+]
+
+[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -865,6 +924,16 @@ dependencies = [
]
[[package]]
+name = "generic-array"
+version = "0.14.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
name = "getopts"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -875,13 +944,24 @@ dependencies = [
[[package]]
name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "wasi 0.9.0+wasi-snapshot-preview1",
+]
+
+[[package]]
+name = "getrandom"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77"
dependencies = [
"cfg-if 1.0.0",
"libc",
- "wasi",
+ "wasi 0.10.0+wasi-snapshot-preview1",
]
[[package]]
@@ -955,6 +1035,12 @@ dependencies = [
]
[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
name = "highway"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1230,6 +1316,12 @@ dependencies = [
]
[[package]]
+name = "memmem"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15"
+
+[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1329,6 +1421,16 @@ dependencies = [
]
[[package]]
+name = "nom"
+version = "5.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
+dependencies = [
+ "memchr",
+ "version_check",
+]
+
+[[package]]
name = "ntapi"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1338,6 +1440,17 @@ dependencies = [
]
[[package]]
+name = "num-derive"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1367,12 +1480,6 @@ dependencies = [
]
[[package]]
-name = "numtoa"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
-
-[[package]]
name = "object"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1398,6 +1505,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
+[[package]]
name = "openssl-sys"
version = "0.9.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1472,6 +1585,53 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
+name = "pest"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
+dependencies = [
+ "ucd-trie",
+]
+
+[[package]]
+name = "phf"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
+dependencies = [
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_codegen"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
+dependencies = [
+ "phf_shared",
+ "rand 0.7.3",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
name = "pin-project-lite"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1585,17 +1745,41 @@ dependencies = [
[[package]]
name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom 0.1.16",
+ "libc",
+ "rand_chacha 0.2.2",
+ "rand_core 0.5.1",
+ "rand_hc",
+ "rand_pcg",
+]
+
+[[package]]
+name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
- "rand_chacha",
+ "rand_chacha 0.3.1",
"rand_core 0.6.3",
]
[[package]]
name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
@@ -1621,11 +1805,38 @@ checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]]
name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom 0.1.16",
+]
+
+[[package]]
+name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
- "getrandom",
+ "getrandom 0.2.5",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_pcg"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
+dependencies = [
+ "rand_core 0.5.1",
]
[[package]]
@@ -1678,21 +1889,12 @@ dependencies = [
]
[[package]]
-name = "redox_termios"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8440d8acb4fd3d277125b4bd01a6f38aee8d814b3b5fc09b3f2b825d37d3fe8f"
-dependencies = [
- "redox_syscall 0.2.11",
-]
-
-[[package]]
name = "redox_users"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7776223e2696f1aa4c6b0170e83212f47296a00424305117d013dfe86fb0fe55"
dependencies = [
- "getrandom",
+ "getrandom 0.2.5",
"redox_syscall 0.2.11",
"thiserror",
]
@@ -1771,6 +1973,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
+name = "semver"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
+dependencies = [
+ "semver-parser",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
+dependencies = [
+ "pest",
+]
+
+[[package]]
name = "serde"
version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1833,6 +2053,29 @@ dependencies = [
]
[[package]]
+name = "sha2"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
+dependencies = [
+ "block-buffer",
+ "cfg-if 1.0.0",
+ "cpufeatures",
+ "digest",
+ "opaque-debug",
+]
+
+[[package]]
+name = "signal-hook"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729"
+dependencies = [
+ "libc",
+ "signal-hook-registry",
+]
+
+[[package]]
name = "signal-hook"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1858,6 +2101,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3"
[[package]]
+name = "siphasher"
+version = "0.3.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
+
+[[package]]
name = "slab"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2084,15 +2333,57 @@ dependencies = [
]
[[package]]
-name = "termion"
-version = "1.5.6"
+name = "terminfo"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76971977e6121664ec1b960d1313aacfa75642adc93b9d4d53b247bd4cb1747e"
+dependencies = [
+ "dirs",
+ "fnv",
+ "nom",
+ "phf",
+ "phf_codegen",
+]
+
+[[package]]
+name = "termios"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "077185e2eac69c3f8379a4298e1e07cd36beb962290d4a51199acf0fdc10607e"
+checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b"
dependencies = [
"libc",
- "numtoa",
- "redox_syscall 0.2.11",
- "redox_termios",
+]
+
+[[package]]
+name = "termwiz"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31ef6892cc0348a9b3b8c377addba91e0f6365863d92354bf27559dca81ee8c5"
+dependencies = [
+ "anyhow",
+ "base64",
+ "bitflags",
+ "cfg-if 1.0.0",
+ "filedescriptor",
+ "hex",
+ "lazy_static",
+ "libc",
+ "log",
+ "memmem",
+ "num-derive",
+ "num-traits",
+ "ordered-float",
+ "regex",
+ "semver",
+ "sha2",
+ "signal-hook 0.1.17",
+ "terminfo",
+ "termios",
+ "thiserror",
+ "ucd-trie",
+ "unicode-segmentation",
+ "vtparse",
+ "winapi",
]
[[package]]
@@ -2150,7 +2441,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
- "wasi",
+ "wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
@@ -2218,6 +2509,12 @@ dependencies = [
]
[[package]]
+name = "typenum"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
+
+[[package]]
name = "typetag"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2242,6 +2539,12 @@ dependencies = [
]
[[package]]
+name = "ucd-trie"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
+
+[[package]]
name = "unicode-bidi"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2355,6 +2658,15 @@ dependencies = [
]
[[package]]
+name = "vtparse"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f41c9314c4dde1f43dd0c46c67bb5ae73850ce11eebaf7d8b912e178bda5401"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
name = "waker-fn"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2362,6 +2674,12 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]]
name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+
+[[package]]
+name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
@@ -2615,7 +2933,7 @@ dependencies = [
"bincode",
"byteorder",
"generational-arena",
- "getrandom",
+ "getrandom 0.2.5",
"libc",
"serde",
"thiserror",
@@ -2819,11 +3137,11 @@ dependencies = [
"serde",
"serde_json",
"serde_yaml",
- "signal-hook",
+ "signal-hook 0.3.13",
"strip-ansi-escapes",
"strum",
"tempfile",
- "termion",
+ "termwiz",
"thiserror",
"unicode-width",
"url",
diff --git a/src/tests/e2e/cases.rs b/src/tests/e2e/cases.rs
index 8bb4d898..19579f55 100644
--- a/src/tests/e2e/cases.rs
+++ b/src/tests/e2e/cases.rs
@@ -58,15 +58,16 @@ pub const BRACKETED_PASTE_START: [u8; 6] = [27, 91, 50, 48, 48, 126]; // \u{1b}[
pub const BRACKETED_PASTE_END: [u8; 6] = [27, 91, 50, 48, 49, 126]; // \u{1b}[201
pub const SLEEP: [u8; 0] = [];
-// simplified, slighty adapted version of alacritty mouse reporting code
-pub fn normal_mouse_report(position: Position, button: u8) -> Vec<u8> {
+pub fn sgr_mouse_report(position: Position, button: u8) -> Vec<u8> {
+ // button: (release is with lower case m, not supported here yet)
+ // 0 => left click
+ // 2 => right click
+ // 64 => scroll up
+ // 65 => scroll down
let Position { line, column } = position;
-
- let mut command = vec![b'\x1b', b'[', b'M', 32 + button];
- command.push(32 + 1 + column.0 as u8);
- command.push(32 + 1 + line.0 as u8);
-
- command
+ format!("\u{1b}[<{};{};{}M", button, column.0, line.0)
+ .as_bytes()
+ .to_vec()
}
// All the E2E tests are marked as "ignored" so that they can be run separately from the normal
@@ -247,7 +248,9 @@ pub fn scrolling_inside_a_pane() {
write!(&mut content_to_send, "{:0<58}", "line19 ").unwrap();
write!(&mut content_to_send, "{:0<57}", "line20 ").unwrap();
+ remote_terminal.send_key(&BRACKETED_PASTE_START);
remote_terminal.send_key(content_to_send.as_bytes());
+ remote_terminal.send_key(&BRACKETED_PASTE_END);
step_is_complete = true;
}
@@ -1030,7 +1033,7 @@ fn focus_pane_with_mouse() {
instruction: |mut remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(63, 2) && remote_terminal.tip_appears() {
- remote_terminal.send_key(&normal_mouse_report(Position::new(5, 2), 0));
+ remote_terminal.send_key(&sgr_mouse_report(Position::new(5, 2), 0));
step_is_complete = true;
}
step_is_complete
@@ -1121,7 +1124,7 @@ pub fn scrolling_inside_a_pane_with_mouse() {
let mut step_is_complete = false;
if remote_terminal.cursor_position_is(118, 20) {
// all lines have been written to the pane
- remote_terminal.send_key(&normal_mouse_report(Position::new(2, 64), 64));
+ remote_terminal.send_key(&sgr_mouse_report(Position::new(2, 64), 64));
step_is_complete = true;
}
step_is_complete
@@ -1638,8 +1641,10 @@ pub fn bracketed_paste() {
remote_terminal.send_key(&BRACKETED_PASTE_START);
remote_terminal.send_key(&TAB_MODE);
remote_terminal.send_key(&NEW_TAB_IN_TAB_MODE);
+ remote_terminal.send_key("a".as_bytes());
+ remote_terminal.send_key("b".as_bytes());
+ remote_terminal.send_key("c".as_bytes());
remote_terminal.send_key(&BRACKETED_PASTE_END);
- remote_terminal.send_key("abc".as_bytes());
step_is_complete = true;
}
step_is_complete
@@ -1651,7 +1656,7 @@ pub fn bracketed_paste() {
name: "Wait for terminal to render sent keys",
instruction: |remote_terminal: RemoteTerminal| -> bool {
let mut step_is_complete = false;
- if remote_terminal.cursor_position_is(9, 2) {
+ if remote_terminal.snapshot_contains("abc") {
// text has been entered into the only terminal pane
step_is_complete = true;
}
diff --git a/zellij-client/src/input_handler.rs b/zellij-client/src/input_handler.rs
index 020c5516..250485eb 100644
--- a/zellij-client/src/input_handler.rs
+++ b/zellij-client/src/input_handler.rs
@@ -5,7 +5,8 @@ use zellij_utils::{
mouse::{MouseButton, MouseEvent},
options::Options,
},
- termion, zellij_tile,
+ termwiz::input::InputEvent,
+ zellij_tile,
};
use crate::{
@@ -14,7 +15,7 @@ use crate::{
use zellij_utils::{
channels::{Receiver, SenderWithContext, OPENCALLS},
errors::{ContextType, ErrorContext},
- input::{actions::Action, cast_termion_key, config::Config, keybinds::Keybinds},
+ input::{actions::Action, cast_termwiz_key, config::Config, keybinds::Keybinds},
ipc::{ClientToServerMsg, ExitReason},
};
@@ -32,6 +33,7 @@ struct InputHandler {
send_client_instructions: SenderWithContext<ClientInstruction>,
should_exit: bool,
receive_input_instructions: Receiver<(InputInstruction, ErrorContext)>,
+ holding_mouse: bool,
}
impl InputHandler {
@@ -54,15 +56,15 @@ impl InputHandler {
send_client_instructions,
should_exit: false,
receive_input_instructions,
+ holding_mouse: false,
}
}
- /// Main input event loop. Interprets the terminal [`Event`](termion::event::Event)s
+ /// Main input event loop. Interprets the terminal Event
/// as [`Action`]s according to the current [`InputMode`], and dispatches those actions.
fn handle_input(&mut self) {
let mut err_ctx = OPENCALLS.with(|ctx| *ctx.borrow());
err_ctx.add_call(ContextType::StdinHandler);
- let alt_left_bracket = vec![27, 91];
let bracketed_paste_start = vec![27, 91, 50, 48, 48, 126]; // \u{1b}[200~
let bracketed_paste_end = vec![27, 91, 50, 48, 49, 126]; // \u{1b}[201~
if self.options.mouse_mode.unwrap_or(true) {
@@ -73,35 +75,27 @@ impl InputHandler {
break;
}
match self.receive_input_instructions.recv() {
- Ok((InputInstruction::KeyEvent(event, raw_bytes), _error_context)) => {
- match event {
- termion::event::Event::Key(key) => {
- let key = cast_termion_key(key);
+ Ok((InputInstruction::KeyEvent(input_event, raw_bytes), _error_context)) => {
+ match input_event {
+ InputEvent::Key(key_event) => {
+ let key = cast_termwiz_key(key_event, &raw_bytes);
self.handle_key(&key, raw_bytes);
}
- termion::event::Event::Mouse(me) => {
- let mouse_event = zellij_utils::input::mouse::MouseEvent::from(me);
+ InputEvent::Mouse(mouse_event) => {
+ let mouse_event =
+ zellij_utils::input::mouse::MouseEvent::from(mouse_event);
self.handle_mouse_event(&mouse_event);
}
- termion::event::Event::Unsupported(unsupported_key) => {
- // we have to do this because of a bug in termion
- // this should be a key event and not an unsupported event
- if unsupported_key == alt_left_bracket {
- let key = Key::Alt('[');
- self.handle_key(&key, raw_bytes);
- } else {
- // this is a hack because termion doesn't recognize certain keys
- // in this case we just forward it to the terminal
- self.handle_unknown_key(raw_bytes);
+ InputEvent::Paste(pasted_text) => {
+ if self.mode == InputMode::Normal || self.mode == InputMode::Locked {
+ self.dispatch_action(Action::Write(bracketed_paste_start.clone()));
+ self.dispatch_action(Action::Write(
+ pasted_text.as_bytes().to_vec(),
+ ));
+ self.dispatch_action(Action::Write(bracketed_paste_end.clone()));
}
}
- }
- }
- Ok((InputInstruction::PastedText(raw_bytes), _error_context)) => {
- if self.mode == InputMode::Normal || self.mode == InputMode::Locked {
- self.dispatch_action(Action::Write(bracketed_paste_start.clone()));
- self.dispatch_action(Action::Write(raw_bytes));
- self.dispatch_action(Action::Write(bracketed_paste_end.clone()));
+ _ => {}
}
}
Ok((InputInstruction::SwitchToMode(input_mode), _error_context)) => {
@@ -111,12 +105,6 @@ impl InputHandler {
}
}
}
- fn handle_unknown_key(&mut self, raw_bytes: Vec<u8>) {
- if self.mode == InputMode::Normal || self.mode == InputMode::Locked {
- let action = Action::Write(raw_bytes);
- self.dispatch_action(action);
- }
- }
fn handle_key(&mut self, key: &Key, raw_bytes: Vec<u8>) {
let keybinds = &self.config.keybinds;
for action in Keybinds::key_to_actions(key, raw_bytes, &self.mode, keybinds) {
@@ -136,18 +124,30 @@ impl InputHandler {
self.dispatch_action(Action::ScrollDownAt(point));
}
MouseButton::Left => {
- self.dispatch_action(Action::LeftClick(point));
+ if self.holding_mouse {
+ self.dispatch_action(Action::MouseHold(point));
+ } else {
+ self.dispatch_action(Action::LeftClick(point));
+ }
+ self.holding_mouse = true;
}
MouseButton::Right => {
- self.dispatch_action(Action::RightClick(point));
+ if self.holding_mouse {
+ self.dispatch_action(Action::MouseHold(point));
+ } else {
+ self.dispatch_action(Action::RightClick(point));
+ }
+ self.holding_mouse = true;
}
_ => {}
},
MouseEvent::Release(point) => {
self.dispatch_action(Action::MouseRelease(point));
+ self.holding_mouse = false;
}
MouseEvent::Hold(point) => {
self.dispatch_action(Action::MouseHold(point));
+ self.holding_mouse = true;
}
}
}
diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs
index 20721663..a1784532 100644
--- a/zellij-client/src/lib.rs
+++ b/zellij-client/src/lib.rs
@@ -24,7 +24,7 @@ use zellij_utils::{
errors::{ClientContext, ContextType, ErrorInstruction},
input::{actions::Action, config::Config, options::Options},
ipc::{ClientAttributes, ClientToServerMsg, ExitReason, ServerToClientMsg},
- termion,
+ termwiz::input::InputEvent,
};
use zellij_utils::{cli::CliArgs, input::layout::LayoutFromYaml};
@@ -106,9 +106,8 @@ impl ClientInfo {
#[derive(Debug, Clone)]
pub(crate) enum InputInstruction {
- KeyEvent(termion::event::Event, Vec<u8>),
+ KeyEvent(InputEvent, Vec<u8>),
SwitchToMode(InputMode),
- PastedText(Vec<u8>),
}
pub fn start_client(
diff --git a/zellij-client/src/os_input_output.rs b/zellij-client/src/os_input_output.rs
index 5d5fa5fe..136e89eb 100644
--- a/zellij-client/src/os_input_output.rs
+++ b/zellij-client/src/os_input_output.rs
@@ -1,5 +1,5 @@
use zellij_utils::pane_size::Size;
-use zellij_utils::{interprocess, libc, nix, signal_hook, termion, zellij_tile};
+use zellij_utils::{interprocess, libc, nix, signal_hook, zellij_tile};
use interprocess::local_socket::LocalSocketStream;
use mio::{unix::SourceFd, Events, Interest, Poll, Token};
@@ -20,6 +20,9 @@ use zellij_utils::{
const SIGWINCH_CB_THROTTLE_DURATION: time::Duration = time::Duration::from_millis(50);
+const ENABLE_MOUSE_SUPPORT: &str = "\u{1b}[?1000h\u{1b}[?1002h\u{1b}[?1015h\u{1b}[?1006h";
+const DISABLE_MOUSE_SUPPORT: &str = "\u{1b}[?1006l\u{1b}[?1015l\u{1b}[?1002l\u{1b}[?1000l";
+
fn into_raw_mode(pid: RawFd) {
let mut tio = termios::tcgetattr(pid).expect("could not get terminal attribute");
termios::cfmakeraw(&mut tio);
@@ -66,7 +69,6 @@ pub struct ClientOsInputOutput {
orig_termios: Arc<Mutex<termios::Termios>>,
send_instructions_to_server: Arc<Mutex<Option<IpcSenderWithContext<ClientToServerMsg>>>>,
receive_instructions_from_server: Arc<Mutex<Option<IpcReceiverWithContext<ServerToClientMsg>>>>,
- mouse_term: Arc<Mutex<Option<termion::input::MouseTerminal<std::io::Stdout>>>>,
}
/// The `ClientOsApi` trait represents an abstract interface to the features of an operating system that
@@ -204,17 +206,17 @@ impl ClientOsApi for ClientOsInputOutput {
default_palette()
}
fn enable_mouse(&self) {
- let mut mouse_term = self.mouse_term.lock().unwrap();
- if mouse_term.is_none() {
- *mouse_term = Some(termion::input::MouseTerminal::from(std::io::stdout()));
- }
+ let _ = self
+ .get_stdout_writer()
+ .write(ENABLE_MOUSE_SUPPORT.as_bytes())
+ .unwrap();
}
fn disable_mouse(&self) {
- let mut mouse_term = self.mouse_term.lock().unwrap();
- if mouse_term.is_some() {
- *mouse_term = None;
- }
+ let _ = self
+ .get_stdout_writer()
+ .write(DISABLE_MOUSE_SUPPORT.as_bytes())
+ .unwrap();
}
fn stdin_poller(&self) -> StdinPoller {
@@ -231,12 +233,10 @@ impl Clone for Box<dyn ClientOsApi> {
pub fn get_client_os_input() -> Result<ClientOsInputOutput, nix::Error> {
let current_termios = termios::tcgetattr(0)?;
let orig_termios = Arc::new(Mutex::new(current_termios));
- let mouse_term = Arc::new(Mutex::new(None));
Ok(ClientOsInputOutput {
orig_termios,
send_instructions_to_server: Arc::new(Mutex::new(None)),
receive_instructions_from_server: Arc::new(Mutex::new(None)),
- mouse_term,
})
}
diff --git a/zellij-client/src/stdin_handler.rs b/zellij-client/src/stdin_handler.rs
index 778a9029..d8321463 100644
--- a/zellij-client/src/stdin_handler.rs
+++ b/zellij-client/src/stdin_handler.rs
@@ -1,51 +1,25 @@
use crate::os_input_output::ClientOsApi;
use crate::InputInstruction;
-use termion::input::TermReadEventsAndRaw;
use zellij_utils::channels::SenderWithContext;
-use zellij_utils::input::mouse::MouseEvent;
-use zellij_utils::termion;
+use zellij_utils::input::mouse::{MouseButton, MouseEvent};
+
+use zellij_utils::termwiz::input::{InputEvent, InputParser};
pub(crate) fn stdin_loop(
os_input: Box<dyn ClientOsApi>,
send_input_instructions: SenderWithContext<InputInstruction>,
) {
- let mut pasting = false;
- let mut pasted_text = vec![];
- let bracketed_paste_start = termion::event::Event::Unsupported(vec![27, 91, 50, 48, 48, 126]); // \u{1b}[200~
- let bracketed_paste_end = termion::event::Event::Unsupported(vec![27, 91, 50, 48, 49, 126]); // \u{1b}[201~
- let csi_mouse_sgr_start = vec![27, 91, 60];
- for key_result in os_input.get_stdin_reader().events_and_raw() {
- let (key_event, mut raw_bytes) = key_result.unwrap();
-
- if key_event == bracketed_paste_start {
- pasting = true;
- continue;
- } else if pasting && key_event == bracketed_paste_end {
- pasting = false;
- let pasted_text: Vec<u8> = pasted_text.drain(..).collect();
- send_input_instructions
- .send(InputInstruction::PastedText(pasted_text))
- .unwrap();
- continue;
- } else if pasting {
- pasted_text.append(&mut raw_bytes);
- continue;
- }
-
- if let termion::event::Event::Mouse(me) = key_event {
- let mouse_event = zellij_utils::input::mouse::MouseEvent::from(me);
- if let MouseEvent::Hold(_) = mouse_event {
- // as long as the user is holding the mouse down (no other stdin, eg.
- // MouseRelease) we need to keep sending this instruction to the app,
- // because the app itself doesn't have an event loop in the proper
- // place
+ let mut holding_mouse = false;
+ let mut input_parser = InputParser::new();
+ let mut current_buffer = vec![];
+ loop {
+ let buf = os_input.read_from_stdin();
+ current_buffer.append(&mut buf.to_vec());
+ let maybe_more = false; // read_from_stdin should (hopefully) always empty the STDIN buffer completely
+ let parse_input_event = |input_event: InputEvent| {
+ holding_mouse = should_hold_mouse(input_event.clone());
+ if holding_mouse {
let mut poller = os_input.stdin_poller();
- send_input_instructions
- .send(InputInstruction::KeyEvent(
- key_event.clone(),
- raw_bytes.clone(),
- ))
- .unwrap();
loop {
let ready = poller.ready();
if ready {
@@ -53,29 +27,35 @@ pub(crate) fn stdin_loop(
}
send_input_instructions
.send(InputInstruction::KeyEvent(
- key_event.clone(),
- raw_bytes.clone(),
+ input_event.clone(),
+ current_buffer.clone(),
))
.unwrap();
}
- continue;
+ } else {
+ send_input_instructions
+ .send(InputInstruction::KeyEvent(
+ input_event,
+ current_buffer.drain(..).collect(),
+ ))
+ .unwrap();
}
- }
+ };
+ input_parser.parse(&buf, parse_input_event, maybe_more);
+ }
+}
- // FIXME: termion does not properly parse some csi sgr mouse sequences
- // like ctrl + click.
- // As a workaround, to avoid writing these sequences to tty stdin,
- // we discard them.
- if let termion::event::Event::Unsupported(_) = key_event {
- if raw_bytes.len() > csi_mouse_sgr_start.len()
- && raw_bytes[0..csi_mouse_sgr_start.len()] == csi_mouse_sgr_start
- {
- continue;
+fn should_hold_mouse(input_event: InputEvent) -> bool {
+ if let InputEvent::Mouse(mouse_event) = input_event {
+ let mouse_event = zellij_utils::input::mouse::MouseEvent::from(mouse_event);
+ if let MouseEvent::Press(button, _point) = mouse_event {
+ match button {
+ MouseButton::Left | MouseButton::Right => {
+ return true;
+ }
+ _ => {}
}
}
-
- send_input_instructions
- .send(InputInstruction::KeyEvent(key_event, raw_bytes))
- .unwrap();
}
+ false
}
diff --git a/zellij-client/src/unit/input_handler_tests.rs b/zellij-client/src/unit/input_handler_tests.rs
index 017ec8ab..a83719a9 100644
--- a/zellij-client/src/unit/input_handler_tests.rs
+++ b/zellij-client/src/unit/input_handler_tests.rs
@@ -3,8 +3,7 @@ use zellij_utils::input::actions::{Action, Direction};
use zellij_utils::input::config::Config;
use zellij_utils::input::options::Options;
use zellij_utils::pane_size::Size;
-use zellij_utils::termion::event::Event;
-use zellij_utils::termion::event::Key;
+use zellij_utils::termwiz::input::{InputEvent, KeyCode, KeyEvent, Modifiers};
use zellij_utils::zellij_tile::data::Palette;
use crate::InputInstruction;
@@ -158,7 +157,13 @@ fn extract_actions_sent_to_server(
#[test]
pub fn quit_breaks_input_loop() {
- let stdin_events = vec![(commands::QUIT.to_vec(), Event::Key(Key::Ctrl('q')))];
+ let stdin_events = vec![(
+ commands::QUIT.to_vec(),
+ InputEvent::Key(KeyEvent {
+ key: KeyCode::Char('q'),
+ modifiers: Modifiers::CTRL,
+ }),
+ )];
let events_sent_to_server = Arc::new(Mutex::new(vec![]));
let command_is_executing = CommandIsExecuting::new();
let client_os_api = Box::new(FakeClientOsApi::new(
@@ -206,9 +211,18 @@ pub fn move_focus_left_in_normal_mode() {
let stdin_events = vec![
(
commands::MOVE_FOCUS_LEFT_IN_NORMAL_MODE.to_vec(),
- Event::Key(Key::Alt('h')),
+ InputEvent::Key(KeyEvent {
+ key: KeyCode::Char('h'),
+ modifiers: Modifiers::ALT,
+ }),
+ ),
+ (
+ commands::QUIT.to_vec(),
+ InputEvent::Key(KeyEvent {
+ key: KeyCode::Char('q'),
+ modifiers: Modifiers::CTRL,
+ }),
),
- (commands::QUIT.to_vec(), Event::Key(Key::Ctrl('q'))),
];
let events_sent_to_server = Arc::new(Mutex::new(vec![]));
diff --git a/zellij-utils/Cargo.toml b/zellij-utils/Cargo.toml
index 383f0765..e65a432f 100644
--- a/zellij-utils/Cargo.toml
+++ b/zellij-utils/Cargo.toml
@@ -29,7 +29,6 @@ serde_json = "1.0"
signal-hook = "0.3"
strip-ansi-escapes = "0.1.0"
strum = "0.20.0"
-termion = "1.5.0"
thiserror = "1.0.30"
url = { version = "2.2.2", features = ["serde"] }
vte = "0.10.1"
@@ -38,6 +37,8 @@ log = "0.4.14"
log4rs = "1.0.0"
unicode-width = "0.1.8"
miette = { version = "3.3.0", features = ["fancy"] }
+termwiz = "0.15.0"
+
[dependencies.async-std]
version = "1.3.0"
diff --git a/zellij-utils/src/input/mod.rs b/zellij-utils/src/input/mod.rs
index 289e52ca..869c513a 100644
--- a/zellij-utils/src/input/mod.rs
+++ b/zellij-utils/src/input/mod.rs
@@ -11,7 +11,7 @@ pub mod plugins;
pub mod theme;
use crate::envs;
-use termion::input::TermRead;
+use termwiz::input::{InputEvent, InputParser, KeyCode, KeyEvent, Modifiers};
use zellij_tile::{
data::{InputMode, Key, ModeInfo, PluginCapabilities},
prelude::Style,
@@ -83,33 +83,57 @@ pub fn get_mode_info(mode: InputMode, style: Style, capabilities: PluginCapabili
}
pub fn parse_keys(input_bytes: &[u8]) -> Vec<Key> {
- input_bytes.keys().flatten().map(cast_termion_key).collect()
+ let mut ret = vec![];
+ let mut input_parser = InputParser::new(); // this is the termwiz InputParser
+ let maybe_more = false;
+ let parse_input_event = |input_event: InputEvent| {
+ if let InputEvent::Key(key_event) = input_event {
+ ret.push(cast_termwiz_key(key_event, input_bytes));
+ }
+ };
+ input_parser.parse(input_bytes, parse_input_event, maybe_more);
+ ret
}
// FIXME: This is an absolutely cursed function that should be destroyed as soon
// as an alternative that doesn't touch zellij-tile can be developed...
-pub fn cast_termion_key(event: termion::event::Key) -> Key {
- match event {
- termion::event::Key::Backspace => Key::Backspace,
- termion::event::Key::Left => Key::Left,
- termion::event::Key::Right => Key::Right,
- termion::event::Key::Up => Key::Up,
- termion::event::Key::Down => Key::Down,
- termion::event::Key::Home => Key::Home,
- termion::event::Key::End => Key::End,
- termion::event::Key::PageUp => Key::PageUp,
- termion::event::Key::PageDown => Key::PageDown,
- termion::event::Key::BackTab => Key::BackTab,
- termion::event::Key::Delete => Key::Delete,
- termion::event::Key::Insert => Key::Insert,
- termion::event::Key::F(n) => Key::F(n),
- termion::event::Key::Char(c) => Key::Char(c),
- termion::event::Key::Alt(c) => Key::Alt(c),
- termion::event::Key::Ctrl(c) => Key::Ctrl(c),
- termion::event::Key::Null => Key::Null,
- termion::event::Key::Esc => Key::Esc,
- _ => {
- unimplemented!("Encountered an unknown key!")
+pub fn cast_termwiz_key(event: KeyEvent, raw_bytes: &[u8]) -> Key {
+ let modifiers = event.modifiers;
+
+ // *** THIS IS WHERE WE SHOULD WORK AROUND ISSUES WITH TERMWIZ ***
+ if raw_bytes == [8] {
+ return Key::Ctrl('h');
+ };
+
+ match event.key {
+ KeyCode::Char(c) => {
+ if modifiers.contains(Modifiers::CTRL) {
+ Key::Ctrl(c.to_lowercase().next().unwrap_or_default())
+ } else if modifiers.contains(Modifiers::ALT) {
+ Key::Alt(c.to_lowercase().next().unwrap_or_default())
+ } else {
+ Key::Char(c)
+ }
}
+ KeyCode::Backspace => Key::Backspace,
+ KeyCode::LeftArrow => Key::Left,
+ KeyCode::ApplicationLeftArrow => Key::Left,
+ KeyCode::RightArrow => Key::Right,
+ KeyCode::ApplicationRightArrow => Key::Right,
+ KeyCode::UpArrow => Key::Up,
+ KeyCode::ApplicationUpArrow => Key::Up,
+ KeyCode::DownArrow => Key::Down,
+ KeyCode::ApplicationDownArrow => Key::Down,
+ KeyCode::Home => Key::Home,
+ KeyCode::End => Key::End,
+ KeyCode::PageUp => Key::PageUp,
+ KeyCode::PageDown => Key::PageDown,
+ KeyCode::Tab => Key::BackTab, // TODO: ???
+ KeyCode::Delete => Key::Delete,
+ KeyCode::Insert => Key::Insert,
+ KeyCode::Function(n) => Key::F(n),
+ KeyCode::Escape => Key::Esc,
+ KeyCode::Enter => Key::Char('\n'),
+ _ => Key::Esc, // there are other keys we can implement here, but we might need additional terminal support to implement them, not just exhausting this enum
}
}
diff --git a/zellij-utils/src/input/mouse.rs b/zellij-utils/src/input/mouse.rs
index d5dc4330..0a63ac2d 100644
--- a/zellij-utils/src/input/mouse.rs
+++ b/zellij-utils/src/input/mouse.rs
@@ -19,21 +19,67 @@ pub enum MouseEvent {
Hold(Position),
}
-impl From<termion::event::MouseEvent> for MouseEvent {
- fn from(event: termion::event::MouseEvent) -> Self {
- match event {
- termion::event::MouseEvent::Press(button, x, y) => Self::Press(
- MouseButton::from(button),
- Position::new((y.saturating_sub(1)) as i32, x.saturating_sub(1)),
- ),
- termion::event::MouseEvent::Release(x, y) => Self::Release(Position::new(
- (y.saturating_sub(1)) as i32,
- x.saturating_sub(1),
- )),
- termion::event::MouseEvent::Hold(x, y) => Self::Hold(Position::new(
- (y.saturating_sub(1)) as i32,
- x.saturating_sub(1),
- )),
+impl From<termwiz::input::MouseEvent> for MouseEvent {
+ fn from(event: termwiz::input::MouseEvent) -> Self {
+ #[allow(clippy::if_same_then_else)]
+ if event
+ .mouse_buttons
+ .contains(termwiz::input::MouseButtons::LEFT)
+ {
+ MouseEvent::Press(
+ MouseButton::Left,
+ Position::new(event.y.saturating_sub(1) as i32, event.x.saturating_sub(1)),
+ )
+ } else if event
+ .mouse_buttons
+ .contains(termwiz::input::MouseButtons::RIGHT)
+ {
+ MouseEvent::Press(
+ MouseButton::Right,
+ Position::new(event.y.saturating_sub(1) as i32, event.x.saturating_sub(1)),
+ )
+ } else if event
+ .mouse_buttons
+ .contains(termwiz::input::MouseButtons::MIDDLE)
+ {
+ MouseEvent::Press(
+ MouseButton::Middle,
+ Position::new(event.y.saturating_sub(1) as i32, event.x.saturating_sub(1)),
+ )
+ } else if event
+ .mouse_buttons
+ .contains(termwiz::input::MouseButtons::VERT_WHEEL)
+ {
+ if event
+ .mouse_buttons
+ .contains(termwiz::input::MouseButtons::WHEEL_POSITIVE)
+ {
+ MouseEvent::Press(
+ MouseButton::WheelUp,
+ Position::new(event.y.saturating_sub(1) as i32, event.x.saturating_sub(1)),
+ )
+ } else {
+ MouseEvent::Press(
+ MouseButton::WheelDown,
+ Position::new(event.y.saturating_sub(1) as i32, event.x.saturating_sub(1)),
+ )
+ }
+ } else if event
+ .mouse_buttons
+ .contains(termwiz::input::MouseButtons::NONE)
+ {
+ // release
+ MouseEvent::Release(Position::new(
+ event.y.saturating_sub(1) as i32,
+ event.x.saturating_sub(1),
+ ))
+ } else {
+ // this is an unsupported event, we just do this in order to send "something", but if
+ // something happens here, we might want to add more specific support
+ MouseEvent::Release(Position::new(
+ event.y.saturating_sub(1) as i32,
+ event.x.saturating_sub(1),
+ ))
}
}
}
@@ -55,15 +101,3 @@ pub enum MouseButton {
/// This event is typically only used with Mouse::Press.
WheelDown,
}
-
-impl From<termion::event::MouseButton> for MouseButton {
- fn from(button: termion::event::MouseButton) -> Self {
- match button {
- termion::event::MouseButton::Left => Self::Left,
- termion::event::MouseButton::Right => Self::Right,
- termion::event::MouseButton::Middle => Self::Middle,
- termion::event::MouseButton::WheelUp => Self::WheelUp,
- termion::event::MouseButton::WheelDown => Self::WheelDown,
- }
- }
-}
diff --git a/zellij-utils/src/lib.rs b/zellij-utils/src/lib.rs
index 7eb9825a..5e42edf1 100644
--- a/zellij-utils/src/lib.rs
+++ b/zellij-utils/src/lib.rs
@@ -20,6 +20,6 @@ pub use nix;
pub use serde;
pub use serde_yaml;
pub use signal_hook;
-pub use termion;
+pub use termwiz;
pub use vte;
pub use zellij_tile;