diff --git a/Cargo.lock b/Cargo.lock index 7fbab4ae5..303d18f1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,6 +29,17 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.18" @@ -40,9 +51,9 @@ dependencies = [ [[package]] name = "allo-isolate" -version = "0.1.13-beta.5" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c1a52c9b965fdaf940102bcb1a0aef4bc2f56489056f5872cef705651c7972e" +checksum = "ccb993621e6bf1b67591005b0adad126159a0ab31af379743906158aed5330d0" dependencies = [ "atomic", ] @@ -89,9 +100,9 @@ dependencies = [ [[package]] name = "android_logger" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b74b7ddf197de32e415d197aa21c1c0cb36e01e4794fd801302280ac7847ee02" +checksum = "b5e9dd62f37dea550caf48c77591dc50bd1a378ce08855be1a0c42a97b7550fb" dependencies = [ "android_log-sys", "env_logger 0.9.0", @@ -99,6 +110,15 @@ dependencies = [ "once_cell", ] +[[package]] +name = "android_system_properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7ed72e1635e121ca3e79420540282af22da58be50de153d36f81ddc6b83aa9e" +dependencies = [ + "libc", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -110,9 +130,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.57" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" +checksum = "1485d4d2cc45e7b201ee3767015c96faa5904387c9d87c6efdd0fb511f12d305" [[package]] name = "arboard" @@ -146,9 +166,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28" dependencies = [ "concurrent-queue", "event-listener", @@ -171,10 +191,11 @@ dependencies = [ [[package]] name = "async-io" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5e18f61464ae81cde0a23e713ae8fd299580c54d697a35820cfd0625b8b0e07" +checksum = "0ab006897723d9352f63e2b13047177c3982d8d79709d713ce7747a8f19fd1b0" dependencies = [ + "autocfg 1.1.0", "concurrent-queue", "futures-lite", "libc", @@ -183,7 +204,7 @@ dependencies = [ "parking", "polling", "slab", - "socket2 0.4.4", + "socket2 0.4.6", "waker-fn", "winapi 0.3.9", ] @@ -199,11 +220,12 @@ dependencies = [ [[package]] name = "async-process" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2c06e30a24e8c78a3987d07f0930edf76ef35e027e7bdb063fccafdad1f60c" +checksum = "02111fd8655a613c25069ea89fc8d9bb89331fa77486eb3bc059ee757cfa481c" dependencies = [ "async-io", + "autocfg 1.1.0", "blocking", "cfg-if 1.0.0", "event-listener", @@ -227,15 +249,15 @@ dependencies = [ [[package]] name = "async-task" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" +checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.53" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600" +checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" dependencies = [ "proc-macro2", "quote", @@ -250,7 +272,7 @@ checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" dependencies = [ "atk-sys", "bitflags", - "glib 0.15.11", + "glib 0.15.12", "libc", ] @@ -309,9 +331,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" dependencies = [ "addr2line", "cc", @@ -400,15 +422,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "bytemuck" -version = "1.9.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" +checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" [[package]] name = "byteorder" @@ -422,7 +444,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" dependencies = [ - "serde 1.0.137", + "serde 1.0.144", ] [[package]] @@ -433,13 +455,13 @@ checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" [[package]] name = "cairo-rs" -version = "0.15.11" +version = "0.15.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62be3562254e90c1c6050a72aa638f6315593e98c5cdaba9017cedbabf0a5dee" +checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" dependencies = [ "bitflags", "cairo-sys-rs", - "glib 0.15.11", + "glib 0.15.12", "libc", "thiserror", ] @@ -467,11 +489,11 @@ dependencies = [ [[package]] name = "camino" -version = "1.0.9" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412" +checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" dependencies = [ - "serde 1.0.137", + "serde 1.0.144", ] [[package]] @@ -480,7 +502,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" dependencies = [ - "serde 1.0.137", + "serde 1.0.144", ] [[package]] @@ -491,9 +513,9 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.9", - "serde 1.0.137", - "serde_json 1.0.81", + "semver 1.0.13", + "serde 1.0.144", + "serde_json 1.0.85", ] [[package]] @@ -502,14 +524,14 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b6d248e3ca02f3fbfabcb9284464c596baec223a26d91bbf44a5a62ddb0d900" dependencies = [ - "clap 3.1.18", + "clap 3.2.17", "heck 0.4.0", "indexmap", "log", "proc-macro2", "quote", - "serde 1.0.137", - "serde_json 1.0.81", + "serde 1.0.144", + "serde_json 1.0.85", "syn", "tempfile", "toml", @@ -562,11 +584,11 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" dependencies = [ - "libc", + "iana-time-zone", "num-integer", "num-traits 0.2.15", "winapi 0.3.9", @@ -600,16 +622,16 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.18" +version = "3.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" +checksum = "29e724a68d9319343bb3328c9cc2dfde263f4b3142ee1059a9980580171c954b" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", "indexmap", - "lazy_static", + "once_cell", "strsim 0.10.0", "termcolor", "textwrap 0.15.0", @@ -617,9 +639,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.18" +version = "3.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" +checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -630,9 +652,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.0" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ "os_str_bytes", ] @@ -644,16 +666,16 @@ dependencies = [ "cc", "hbb_common", "lazy_static", - "serde 1.0.137", + "serde 1.0.144", "serde_derive", "thiserror", ] [[package]] name = "clipboard-win" -version = "4.4.1" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3e1238132dc01f081e1cbb9dace14e5ef4c3a51ee244bd982275fb514605db" +checksum = "c4ab1b92798304eedc095b53942963240037c0516452cb11aeba709d420b2219" dependencies = [ "error-code", "str-buf", @@ -678,21 +700,6 @@ dependencies = [ "cc", ] -[[package]] -name = "cocoa" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "667fdc068627a2816b9ff831201dd9864249d6ee8d190b9532357f1fc0f61ea7" -dependencies = [ - "bitflags", - "block", - "core-foundation 0.9.3", - "core-graphics 0.21.0", - "foreign-types", - "libc", - "objc", -] - [[package]] name = "cocoa" version = "0.24.0" @@ -732,9 +739,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "combine" -version = "4.6.4" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ "bytes", "memchr", @@ -742,9 +749,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "1.2.2" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" dependencies = [ "cache-padded", ] @@ -755,7 +762,7 @@ version = "0.4.0" source = "git+https://github.com/open-trade/confy#630cc28a396cb7d01eefdd9f3824486fe4d8554b" dependencies = [ "directories-next", - "serde 1.0.137", + "serde 1.0.144", "thiserror", "toml", ] @@ -810,18 +817,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-graphics" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a67c4378cf203eace8fb6567847eb641fd6ff933c1145a115c6ee820ebb978" -dependencies = [ - "bitflags", - "core-foundation 0.9.3", - "foreign-types", - "libc", -] - [[package]] name = "core-graphics" version = "0.22.3" @@ -906,9 +901,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813" dependencies = [ "libc", ] @@ -922,25 +917,11 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "crossbeam" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - [[package]] name = "crossbeam-channel" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -948,9 +929,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", @@ -959,23 +940,23 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" dependencies = [ "autocfg 1.1.0", "cfg-if 1.0.0", "crossbeam-utils", - "lazy_static", "memoffset", + "once_cell", "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2" +checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -983,19 +964,19 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" dependencies = [ "cfg-if 1.0.0", - "lazy_static", + "once_cell", ] [[package]] name = "crypto-common" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -1003,9 +984,9 @@ dependencies = [ [[package]] name = "cstr_core" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644828c273c063ab0d39486ba42a5d1f3a499d35529c759e763a9c6cb8a0fb08" +checksum = "dd98742e4fdca832d40cab219dc2e3048de17d873248f83f17df47c1bea70956" dependencies = [ "cty", "memchr", @@ -1013,11 +994,11 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.2.2" +version = "3.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b37feaa84e6861e00a1f5e5aa8da3ee56d605c9992d33e082786754828e20865" +checksum = "1d91974fbbe88ec1df0c24a4f00f99583667a7e2e6272b2b92d294d81e462173" dependencies = [ - "nix 0.24.1", + "nix 0.25.0", "winapi 0.3.9", ] @@ -1200,9 +1181,9 @@ dependencies = [ [[package]] name = "dbus" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0a745c25b32caa56b82a3950f5fec7893a960f4c10ca3b02060b0c38d8c2ce" +checksum = "6f8bcdd56d2e5c4ed26a529c5a9029f5db8290d433497506f958eae3be148eb6" dependencies = [ "libc", "libdbus-sys", @@ -1347,7 +1328,7 @@ checksum = "7f3f119846c823f9eafcf953a8f6ffb6ed69bf6240883261a7f13b634579a51f" dependencies = [ "lazy_static", "regex", - "serde 1.0.137", + "serde 1.0.144", "strsim 0.10.0", ] @@ -1374,9 +1355,9 @@ dependencies = [ [[package]] name = "either" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "encoding_rs" @@ -1397,12 +1378,34 @@ dependencies = [ "log", "objc", "pkg-config", - "serde 1.0.137", + "rdev", + "serde 1.0.144", "serde_derive", + "tfc", "unicode-segmentation", "winapi 0.3.9", ] +[[package]] +name = "enum-map" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5a56d54c8dd9b3ad34752ed197a4eb2a6601bc010808eb097a04a58ae4c43e1" +dependencies = [ + "enum-map-derive", +] + +[[package]] +name = "enum-map-derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9045e2676cd5af83c3b167d917b0a5c90a4d8e266e2683d6631b235c457fc27" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "enum_dispatch" version = "0.3.8" @@ -1422,7 +1425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb" dependencies = [ "enumflags2_derive", - "serde 1.0.137", + "serde 1.0.144", ] [[package]] @@ -1516,9 +1519,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "failure" @@ -1531,9 +1534,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" dependencies = [ "instant", ] @@ -1550,14 +1553,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" +checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", - "winapi 0.3.9", + "windows-sys 0.36.1", ] [[package]] @@ -1572,14 +1575,15 @@ dependencies = [ [[package]] name = "flexi_logger" -version = "0.22.3" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969940c39bc718475391e53a3a59b0157e64929c80cf83ad5dde5f770ecdc423" +checksum = "0c76a80dd14a27fc3d8bc696502132cb52b3f227256fd8601166c3a35e45f409" dependencies = [ "ansi_term", "atty", "chrono", - "crossbeam", + "crossbeam-channel", + "crossbeam-queue", "glob", "lazy_static", "log", @@ -1618,7 +1622,7 @@ dependencies = [ "pathdiff", "quote", "regex", - "serde 1.0.137", + "serde 1.0.144", "serde_yaml", "structopt", "syn", @@ -1693,9 +1697,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "ab30e97ab6aacfe635fad58f22c2bb06c8b685f7421eb1e064a729e2a5f481fa" dependencies = [ "futures-channel", "futures-core", @@ -1708,9 +1712,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "2bfc52cbddcfd745bf1740338492bb0bd83d76c67b445f91c5fb29fae29ecaa1" dependencies = [ "futures-core", "futures-sink", @@ -1718,15 +1722,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "1d11aa21b5b587a64682c0094c2bdd4df0076c5324961a40cc3abd7f37930528" dependencies = [ "futures-core", "futures-task", @@ -1735,9 +1739,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "93a66fc6d035a26a3ae255a6d2bca35eda63ae4c5512bef54449113f7a1228e5" [[package]] name = "futures-lite" @@ -1756,9 +1760,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "0db9cce532b0eae2ccf2766ab246f114b56b9cf6d445e00c2549fbc100ca045d" dependencies = [ "proc-macro2", "quote", @@ -1767,21 +1771,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577" dependencies = [ "futures-channel", "futures-core", @@ -1815,7 +1819,7 @@ dependencies = [ "gdk-pixbuf", "gdk-sys", "gio", - "glib 0.15.11", + "glib 0.15.12", "libc", "pango", ] @@ -1829,7 +1833,7 @@ dependencies = [ "bitflags", "gdk-pixbuf-sys", "gio", - "glib 0.15.11", + "glib 0.15.12", "libc", ] @@ -1865,9 +1869,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", @@ -1885,33 +1889,33 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "gimli" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" [[package]] name = "gio" -version = "0.15.11" +version = "0.15.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f132be35e05d9662b9fa0fee3f349c6621f7782e0105917f4cc73c1bf47eceb" +checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" dependencies = [ "bitflags", "futures-channel", "futures-core", "futures-io", "gio-sys", - "glib 0.15.11", + "glib 0.15.12", "libc", "once_cell", "thiserror", @@ -1951,9 +1955,9 @@ dependencies = [ [[package]] name = "glib" -version = "0.15.11" +version = "0.15.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124026a2fa8c33a3d17a3fe59c103f2d9fa5bd92c19e029e037736729abeab" +checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" dependencies = [ "bitflags", "futures-channel", @@ -1993,7 +1997,7 @@ checksum = "25a68131a662b04931e71891fb14aaf65ee4b44d08e8abc10f49e77418c86c64" dependencies = [ "anyhow", "heck 0.4.0", - "proc-macro-crate 1.1.3", + "proc-macro-crate 1.2.1", "proc-macro-error", "proc-macro2", "quote", @@ -2195,7 +2199,7 @@ dependencies = [ "gdk", "gdk-pixbuf", "gio", - "glib 0.15.11", + "glib 0.15.12", "gtk-sys", "gtk3-macros", "libc", @@ -2229,7 +2233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24f518afe90c23fba585b2d7697856f9e6a7bbc62f65588035e66f6afb01a2e9" dependencies = [ "anyhow", - "proc-macro-crate 1.1.3", + "proc-macro-crate 1.2.1", "proc-macro-error", "proc-macro2", "quote", @@ -2238,9 +2242,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -2251,7 +2255,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.2", + "tokio-util", "tracing", ] @@ -2261,14 +2265,17 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" dependencies = [ - "ahash", + "ahash 0.4.7", ] [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] [[package]] name = "hbb_common" @@ -2292,15 +2299,15 @@ dependencies = [ "quinn", "rand 0.8.5", "regex", - "serde 1.0.137", + "serde 1.0.144", "serde_derive", - "serde_json 1.0.81", + "serde_json 1.0.85", "serde_with", "socket2 0.3.19", "sodiumoxide", "tokio", "tokio-socks", - "tokio-util 0.7.2", + "tokio-util", "toml", "winapi 0.3.9", "zstd", @@ -2344,13 +2351,13 @@ checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549" [[package]] name = "http" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff8670570af52249509a86f5e3e18a08c60b177071826898fde8997cf5f6bfbb" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", - "itoa 1.0.2", + "itoa 1.0.3", ] [[package]] @@ -2390,16 +2397,16 @@ dependencies = [ "bindgen", "cc", "log", - "serde 1.0.137", + "serde 1.0.144", "serde_derive", - "serde_json 1.0.81", + "serde_json 1.0.85", ] [[package]] name = "hyper" -version = "0.14.19" +version = "0.14.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" dependencies = [ "bytes", "futures-channel", @@ -2410,9 +2417,9 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.2", + "itoa 1.0.3", "pin-project-lite", - "socket2 0.4.4", + "socket2 0.4.6", "tokio", "tower-service", "tracing", @@ -2432,6 +2439,19 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad2bfd338099682614d3ee3fe0cd72e0b6a41ca6a87f6a74a3bd593c91650501" +dependencies = [ + "android_system_properties", + "core-foundation-sys 0.8.3", + "js-sys", + "wasm-bindgen", + "winapi 0.3.9", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -2486,12 +2506,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.2" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" dependencies = [ "autocfg 1.1.0", - "hashbrown 0.11.2", + "hashbrown 0.12.3", ] [[package]] @@ -2538,9 +2558,9 @@ checksum = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "jni" @@ -2579,9 +2599,9 @@ checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" dependencies = [ "wasm-bindgen", ] @@ -2610,11 +2630,11 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libappindicator" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b29fab3280d59f3d06725f75da9ef9a1b001b2c748b1abfebd1c966c61d7de" +checksum = "db2d3cb96d092b4824cb306c9e544c856a4cb6210c1081945187f7f1924b47e8" dependencies = [ - "glib 0.15.11", + "glib 0.15.12", "gtk", "gtk-sys", "libappindicator-sys", @@ -2623,9 +2643,9 @@ dependencies = [ [[package]] name = "libappindicator-sys" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83c2227727d7950ada2ae554613d35fd4e55b87f0a29b86d2368267d19b1d99" +checksum = "f1b3b6681973cea8cc3bce7391e6d7d5502720b80a581c9a95c9cbaf592826aa" dependencies = [ "gtk-sys", "libloading", @@ -2634,9 +2654,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.126" +version = "0.2.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" [[package]] name = "libdbus-sys" @@ -2728,9 +2748,9 @@ dependencies = [ [[package]] name = "linked-hash-map" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "lock_api" @@ -2894,13 +2914,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.36.1", ] @@ -3030,7 +3050,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" dependencies = [ "darling", - "proc-macro-crate 1.1.3", + "proc-macro-crate 1.2.1", "proc-macro2", "quote", "syn", @@ -3090,13 +3110,26 @@ dependencies = [ [[package]] name = "nix" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9" +checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" dependencies = [ "bitflags", "cfg-if 1.0.0", "libc", + "memoffset", +] + +[[package]] +name = "nix" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +dependencies = [ + "autocfg 1.1.0", + "bitflags", + "cfg-if 1.0.0", + "libc", ] [[package]] @@ -3120,9 +3153,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fbc387afefefd5e9e39493299f3069e14a140dd34dc19b4c1c1a8fddb6a790" +checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" dependencies = [ "num-traits 0.2.15", ] @@ -3213,7 +3246,7 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate 1.2.1", "proc-macro2", "quote", "syn", @@ -3259,9 +3292,9 @@ dependencies = [ [[package]] name = "object" -version = "0.28.4" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" dependencies = [ "memchr", ] @@ -3291,9 +3324,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" +checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e" [[package]] name = "openssl-probe" @@ -3323,9 +3356,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.1.0" +version = "6.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" [[package]] name = "padlock" @@ -3340,7 +3373,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f" dependencies = [ "bitflags", - "glib 0.15.11", + "glib 0.15.12", "libc", "once_cell", "pango-sys", @@ -3360,8 +3393,8 @@ dependencies = [ [[package]] name = "parity-tokio-ipc" -version = "0.7.3" -source = "git+https://github.com/open-trade/parity-tokio-ipc#52515618bd30ea8101bf46f6c7835e88cec9187f" +version = "0.7.3-1" +source = "git+https://github.com/open-trade/parity-tokio-ipc#20b2895910161605210657f3e751edd55321f698" dependencies = [ "futures", "libc", @@ -3429,9 +3462,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" +checksum = "9423e2b32f7a043629287a536f21951e8c6a82482d0acb1eeebfc90bc2225b22" [[package]] name = "pathdiff" @@ -3453,10 +3486,11 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pest" -version = "2.1.3" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +checksum = "4b0560d531d1febc25a3c9398a62a71256c0178f2e3443baedd9ad4bb8c9deb4" dependencies = [ + "thiserror", "ucd-trie", ] @@ -3500,18 +3534,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", @@ -3550,10 +3584,11 @@ dependencies = [ [[package]] name = "polling" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" +checksum = "899b00b9c8ab553c743b3e11e87c5c7d423b2a2de229ba95b24a756344748011" dependencies = [ + "autocfg 1.1.0", "cfg-if 1.0.0", "libc", "log", @@ -3575,9 +3610,9 @@ checksum = "bc5c99d529f0d30937f6f4b8a86d988047327bb88d04d2c4afc356de74722131" [[package]] name = "primal-check" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01419cee72c1a1ca944554e23d83e483e1bccf378753344e881de28b5487511d" +checksum = "8b264861209b0641a9b7571695029f516698bd3f2bf46eb61fca408675630b8c" dependencies = [ "num-integer", ] @@ -3593,10 +3628,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.1.3" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" dependencies = [ + "once_cell", "thiserror", "toml", ] @@ -3627,9 +3663,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.39" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ "unicode-ident", ] @@ -3701,9 +3737,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7542006acd6e057ff632307d219954c44048f818898da03113d6c0086bfddd9" +checksum = "5b435e71d9bfa0d8889927231970c51fb89c58fa63bffcab117c9c7a41e5ef8f" dependencies = [ "bytes", "futures-channel", @@ -3720,9 +3756,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a13a5c0a674c1ce7150c9df7bc4a1e46c2fbbe7c710f56c0dc78b1a810e779e" +checksum = "3fce546b9688f767a57530652488420d419a8b1f44a478b451c3d1ab6d992a55" dependencies = [ "bytes", "fxhash", @@ -3740,23 +3776,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3149f7237331015f1a6adf065c397d1be71e032fcf110ba41da52e7926b882f" +checksum = "9f832d8958db3e84d2ec93b5eb2272b45aa23cf7f8fe6e79f578896f4e6c231b" dependencies = [ "futures-util", "libc", "quinn-proto", - "socket2 0.4.4", + "socket2 0.4.6", "tokio", "tracing", ] [[package]] name = "quote" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] @@ -3938,17 +3974,19 @@ dependencies = [ [[package]] name = "rdev" -version = "0.5.0" -source = "git+https://github.com/open-trade/rdev#fbbefd0b5d87095a7349965aec9ecd33de7035ac" +version = "0.5.0-2" +source = "git+https://github.com/asur4s/rdev#895c8fb1a6106714793e8877d35d2b7a1c57ce9c" dependencies = [ - "cocoa 0.22.0", - "core-foundation 0.7.0", - "core-foundation-sys 0.7.0", - "core-graphics 0.19.2", + "cocoa", + "core-foundation 0.9.3", + "core-foundation-sys 0.8.3", + "core-graphics 0.22.3", + "enum-map", "lazy_static", "libc", + "widestring 1.0.2", "winapi 0.3.9", - "x11", + "x11 2.20.0", ] [[package]] @@ -3962,18 +4000,18 @@ dependencies = [ [[package]] name = "realfft" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a83b876fe55da7e1bf5deeacb93d6411edf81eba0e1a497e79c067734729053a" +checksum = "8028eb3fabd68ddf331f744ba9c25a939804e276d820f9b218ab25a4bd7b91b8" dependencies = [ "rustfft", ] [[package]] name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -3991,9 +4029,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.6" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "aho-corasick", "memchr", @@ -4002,9 +4040,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.26" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "remove_dir_all" @@ -4027,9 +4065,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a1f7aa4f35e5e8b4160449f51afc758f0ce6454315a9fa7d0d113e958c41eb" +checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" dependencies = [ "base64", "bytes", @@ -4049,12 +4087,13 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls", - "rustls-pemfile 0.3.0", - "serde 1.0.137", - "serde_json 1.0.81", + "rustls-pemfile 1.0.1", + "serde 1.0.144", + "serde_json 1.0.85", "serde_urlencoded", "tokio", "tokio-rustls", + "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -4164,7 +4203,7 @@ dependencies = [ name = "rustdesk" version = "1.1.10" dependencies = [ - "android_logger 0.11.0", + "android_logger 0.11.1", "arboard", "async-process", "async-trait", @@ -4172,9 +4211,9 @@ dependencies = [ "bytes", "cc", "cfg-if 1.0.0", - "clap 3.1.18", + "clap 3.2.17", "clipboard", - "cocoa 0.24.0", + "cocoa", "core-foundation 0.9.3", "core-graphics 0.22.3", "cpal", @@ -4214,9 +4253,9 @@ dependencies = [ "samplerate", "sciter-rs", "scrap", - "serde 1.0.137", + "serde 1.0.144", "serde_derive", - "serde_json 1.0.81", + "serde_json 1.0.85", "sha2", "simple_rc", "sys-locale", @@ -4268,7 +4307,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" dependencies = [ "openssl-probe", - "rustls-pemfile 1.0.0", + "rustls-pemfile 1.0.1", "schannel", "security-framework", ] @@ -4284,33 +4323,24 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "0.3.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee86d63972a7c661d1536fefe8c3c8407321c3df668891286de28abcd087360" -dependencies = [ - "base64", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" +checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" dependencies = [ "base64", ] [[package]] name = "rustversion" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" +checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "same-file" @@ -4385,8 +4415,8 @@ dependencies = [ "num_cpus", "quest", "repng", - "serde 1.0.137", - "serde_json 1.0.81", + "serde 1.0.144", + "serde_json 1.0.85", "target_build_utils", "tracing", "webm", @@ -4405,9 +4435,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" dependencies = [ "bitflags", "core-foundation 0.9.3", @@ -4437,11 +4467,11 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.9" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" +checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" dependencies = [ - "serde 1.0.137", + "serde 1.0.144", ] [[package]] @@ -4461,18 +4491,18 @@ checksum = "34b623917345a631dc9608d5194cc206b3fe6c3554cd1c75b937e55e285254af" [[package]] name = "serde" -version = "1.0.137" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" +checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.137" +version = "1.0.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" +checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00" dependencies = [ "proc-macro2", "quote", @@ -4493,13 +4523,13 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.81" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ - "itoa 1.0.2", + "itoa 1.0.3", "ryu", - "serde 1.0.137", + "serde 1.0.144", ] [[package]] @@ -4520,9 +4550,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.2", + "itoa 1.0.3", "ryu", - "serde 1.0.137", + "serde 1.0.144", ] [[package]] @@ -4531,7 +4561,7 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" dependencies = [ - "serde 1.0.137", + "serde 1.0.144", "serde_with_macros", ] @@ -4549,13 +4579,13 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.24" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707d15895415db6628332b737c838b88c598522e4dc70647e59b72312924aebc" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" dependencies = [ "indexmap", "ryu", - "serde 1.0.137", + "serde 1.0.144", "yaml-rust", ] @@ -4612,9 +4642,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f054c6c1a6e95179d6f23ed974060dcefb2d9388bb7256900badad682c499de4" +checksum = "f0ea32af43239f0d353a7dd75a22d94c329c8cdaafdcb4c1c1335aa10c298a4a" [[package]] name = "simple_rc" @@ -4622,7 +4652,7 @@ version = "0.1.0" dependencies = [ "confy", "hbb_common", - "serde 1.0.137", + "serde 1.0.144", "serde_derive", "walkdir", ] @@ -4635,15 +4665,18 @@ checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" [[package]] name = "slab" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg 1.1.0", +] [[package]] name = "smallvec" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" [[package]] name = "smithay-client-toolkit" @@ -4677,9 +4710,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "10c98bba371b9b22a71a9414e420f92ddeb2369239af08200816169d5e2dd7aa" dependencies = [ "libc", "winapi 0.3.9", @@ -4694,7 +4727,7 @@ dependencies = [ "ed25519", "libc", "libsodium-sys", - "serde 1.0.137", + "serde 1.0.144", ] [[package]] @@ -4783,9 +4816,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.95" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" dependencies = [ "proc-macro2", "quote", @@ -4806,13 +4839,15 @@ dependencies = [ [[package]] name = "sys-locale" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3913c5a3d30054d7f77cf07cdd800c8103ace15c6e44437c5db66a43dd3a92cf" +checksum = "658ee915b6c7b73ec4c1ffcd838506b5c5a4087eadc1ec8f862f1066cf2c8132" dependencies = [ "cc", "cstr_core", + "js-sys", "libc", + "wasm-bindgen", "web-sys", "winapi 0.3.9", ] @@ -4954,20 +4989,31 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +[[package]] +name = "tfc" +version = "0.6.1" +source = "git+https://github.com/asur4s/The-Fat-Controller#48303c5dacded6ea1873bc5d69bdde3175cf336a" +dependencies = [ + "core-graphics 0.22.3", + "unicode-segmentation", + "winapi 0.3.9", + "x11 2.19.0", +] + [[package]] name = "thiserror" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" dependencies = [ "proc-macro2", "quote", @@ -5000,7 +5046,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" dependencies = [ - "itoa 1.0.2", + "itoa 1.0.3", "libc", "num_threads", "time-macros", @@ -5037,22 +5083,22 @@ dependencies = [ "bytes", "libc", "memchr", - "mio 0.8.3", + "mio 0.8.4", "num_cpus", "once_cell", "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", - "socket2 0.4.4", + "socket2 0.4.6", "tokio-macros", "winapi 0.3.9", ] [[package]] name = "tokio-macros" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ "proc-macro2", "quote", @@ -5072,8 +5118,8 @@ dependencies = [ [[package]] name = "tokio-socks" -version = "0.5.1" -source = "git+https://github.com/open-trade/tokio-socks#3de8300fbce37e2cdaef042e016aa95058d007cf" +version = "0.5.1-1" +source = "git+https://github.com/open-trade/tokio-socks#7034e79263ce25c348be072808d7601d82cd892d" dependencies = [ "bytes", "either", @@ -5083,34 +5129,21 @@ dependencies = [ "pin-project", "thiserror", "tokio", - "tokio-util 0.6.10", + "tokio-util", ] [[package]] name = "tokio-util" -version = "0.6.10" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c" +checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" dependencies = [ "bytes", "futures-core", "futures-io", "futures-sink", "futures-util", + "hashbrown 0.12.3", "pin-project-lite", "slab", "tokio", @@ -5123,20 +5156,20 @@ version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ - "serde 1.0.137", + "serde 1.0.144", ] [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +checksum = "2fce9567bd60a67d08a16488756721ba392f24f29006402881e43b19aac64307" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", @@ -5146,9 +5179,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" +checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" dependencies = [ "proc-macro2", "quote", @@ -5157,11 +5190,11 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.26" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" +checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" dependencies = [ - "lazy_static", + "once_cell", ] [[package]] @@ -5180,7 +5213,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76863575f7842ed64fda361f417a787efa82811b4617267709066969cd4ccf3b" dependencies = [ - "cocoa 0.24.0", + "cocoa", "core-graphics 0.22.3", "gtk", "libappindicator", @@ -5215,9 +5248,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "ucd-trie" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c" [[package]] name = "uds_windows" @@ -5237,15 +5270,15 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" dependencies = [ "tinyvec", ] @@ -5288,9 +5321,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6d5d669b51467dcf7b2f1a796ce0f955f05f01cafda6c19d6e95f730df29238" +checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" dependencies = [ "getrandom", ] @@ -5326,7 +5359,7 @@ dependencies = [ "cc", "hbb_common", "lazy_static", - "serde 1.0.137", + "serde 1.0.144", "serde_derive", "thiserror", ] @@ -5358,12 +5391,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -5372,9 +5399,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -5382,13 +5409,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -5397,9 +5424,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.30" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f741de44b75e14c35df886aff5f1eb73aa114fa5d4d00dcd37b5e01259bf3b2" +checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -5409,9 +5436,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5419,9 +5446,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" dependencies = [ "proc-macro2", "quote", @@ -5432,20 +5459,20 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" [[package]] name = "wayland-client" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91223460e73257f697d9e23d401279123d36039a3f7a449e983f123292d4458f" +checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" dependencies = [ "bitflags", "downcast-rs", "libc", - "nix 0.22.3", + "nix 0.24.2", "scoped-tls", "wayland-commons", "wayland-scanner", @@ -5454,11 +5481,11 @@ dependencies = [ [[package]] name = "wayland-commons" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f6e5e340d7c13490eca867898c4cec5af56c27a5ffe5c80c6fc4708e22d33e" +checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" dependencies = [ - "nix 0.22.3", + "nix 0.24.2", "once_cell", "smallvec", "wayland-sys", @@ -5466,20 +5493,20 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c52758f13d5e7861fc83d942d3d99bf270c83269575e52ac29e5b73cb956a6bd" +checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" dependencies = [ - "nix 0.22.3", + "nix 0.24.2", "wayland-client", "xcursor", ] [[package]] name = "wayland-protocols" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60147ae23303402e41fe034f74fb2c35ad0780ee88a1c40ac09a3be1e7465741" +checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" dependencies = [ "bitflags", "wayland-client", @@ -5489,9 +5516,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a1ed3143f7a143187156a2ab52742e89dac33245ba505c17224df48939f9e0" +checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" dependencies = [ "proc-macro2", "quote", @@ -5500,9 +5527,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.29.4" +version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9341df79a8975679188e37dab3889bfa57c44ac2cb6da166f519a81cbe452d4" +checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" dependencies = [ "dlib", "lazy_static", @@ -5511,9 +5538,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.57" +version = "0.3.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" +checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -5549,18 +5576,18 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" +checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" dependencies = [ "webpki", ] [[package]] name = "weezl" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" [[package]] name = "wepoll-ffi" @@ -5608,6 +5635,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + [[package]] name = "winapi" version = "0.2.8" @@ -5681,7 +5714,7 @@ checksum = "0c643e10139d127d30d6d753398c8a6f0a43532e8370f6c9d29ebbff29b984ab" dependencies = [ "bitflags", "err-derive", - "widestring", + "widestring 0.4.3", "winapi 0.3.9", ] @@ -5808,7 +5841,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b43cc931d58b99461188607efd7acb2a093e65fc621f54cad78517a6063e73a" dependencies = [ "bitflags", - "cocoa 0.24.0", + "cocoa", "core-foundation 0.9.3", "core-graphics 0.22.3", "core-video-sys", @@ -5817,7 +5850,7 @@ dependencies = [ "lazy_static", "libc", "log", - "mio 0.8.3", + "mio 0.8.4", "ndk 0.5.0", "ndk-glue 0.5.2", "ndk-sys 0.2.2", @@ -5876,7 +5909,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7f97e69b28b256ccfb02472c25057132e234aa8368fea3bb0268def564ce1f2" dependencies = [ - "clap 3.1.18", + "clap 3.2.17", ] [[package]] @@ -5900,9 +5933,18 @@ dependencies = [ [[package]] name = "x11" -version = "2.19.1" +version = "2.19.0" +source = "git+https://github.com/bjornsnoen/x11-rs#c2e9bfaa7b196938f8700245564d8ac5d447786a" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11" +version = "2.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd0565fa8bfba8c5efe02725b14dff114c866724eff2cfd44d76cea74bcd87a" +checksum = "f7ae97874a928d821b061fce3d1fc52f08071dd53c89a6102bc06efcac3b2908" dependencies = [ "libc", "pkg-config", @@ -5910,9 +5952,9 @@ dependencies = [ [[package]] name = "x11-dl" -version = "2.19.1" +version = "2.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" +checksum = "0c83627bc137605acc00bb399c7b908ef460b621fc37c953db2b09f88c449ea6" dependencies = [ "lazy_static", "libc", @@ -5983,7 +6025,7 @@ dependencies = [ "once_cell", "ordered-stream", "rand 0.8.5", - "serde 1.0.137", + "serde 1.0.144", "serde_repr", "sha1", "static_assertions", @@ -6001,7 +6043,7 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f8fb5186d1c87ae88cf234974c240671238b4a679158ad3b94ec465237349a6" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate 1.2.1", "proc-macro2", "quote", "regex", @@ -6014,7 +6056,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41a408fd8a352695690f53906dc7fd036be924ec51ea5e05666ff42685ed0af5" dependencies = [ - "serde 1.0.137", + "serde 1.0.144", "static_assertions", "zvariant", ] @@ -6057,7 +6099,7 @@ dependencies = [ "byteorder", "enumflags2", "libc", - "serde 1.0.137", + "serde 1.0.144", "static_assertions", "zvariant_derive", ] @@ -6068,7 +6110,7 @@ version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08e977eaa3af652f63d479ce50d924254ad76722a6289ec1a1eac3231ca30430" dependencies = [ - "proc-macro-crate 1.1.3", + "proc-macro-crate 1.2.1", "proc-macro2", "quote", "syn", diff --git a/Cargo.toml b/Cargo.toml index f48ea2efb..bf5ab9669 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +75,7 @@ sciter-rs = { git = "https://github.com/open-trade/rust-sciter", branch = "dyn" sys-locale = "0.2" enigo = { path = "libs/enigo", features = [ "with_serde" ] } clipboard = { path = "libs/clipboard" } -rdev = { git = "https://github.com/open-trade/rdev" } +rdev = { git = "https://github.com/asur4s/rdev" } ctrlc = "3.2" arboard = "2.0" #minreq = { version = "2.4", features = ["punycode", "https-native"] } @@ -108,6 +108,7 @@ async-process = "1.3" mouce = { git="https://github.com/fufesou/mouce.git" } evdev = { git="https://github.com/fufesou/evdev" } + [target.'cfg(target_os = "android")'.dependencies] android_logger = "0.11" jni = "0.19" diff --git a/DEBIAN/postinst b/DEBIAN/postinst index 1c7697acc..d643c5caf 100755 --- a/DEBIAN/postinst +++ b/DEBIAN/postinst @@ -12,9 +12,6 @@ if [ "$1" = configure ]; then fi version=$(python3 -V 2>&1 | grep -Po '(?<=Python )(.+)') parsedVersion=$(echo "${version//./}") - if [[ "$parsedVersion" -gt "360" ]]; then - sudo -H pip3 install pynput - fi cp /usr/share/rustdesk/files/systemd/rustdesk.service /usr/lib/systemd/system/rustdesk.service systemctl daemon-reload systemctl enable rustdesk diff --git a/PKGBUILD b/PKGBUILD index 6fb65d48b..1d1956ede 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -26,6 +26,5 @@ package() { install -Dm 644 ${HBB}/libsciter-gtk.so -t "${pkgdir}/usr/lib/rustdesk" install -Dm 644 $HBB/rustdesk.service -t "${pkgdir}/usr/share/rustdesk/files" install -Dm 644 $HBB/rustdesk.desktop -t "${pkgdir}/usr/share/rustdesk/files" - install -Dm 644 $HBB/pynput_service.py -t "${pkgdir}/usr/share/rustdesk/files" install -Dm 644 $HBB/128x128@2x.png "${pkgdir}/usr/share/rustdesk/files/rustdesk.png" } diff --git a/README-AR.md b/README-AR.md index 2deb4914b..c0186037e 100644 --- a/README-AR.md +++ b/README-AR.md @@ -80,11 +80,6 @@ sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb- sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pulseaudio ``` -### pynput package تثبيت - -```sh -pip3 install pynput -``` ### vcpkg تثبيت diff --git a/README-CS.md b/README-CS.md index 4f2c0e80f..7ad86e08b 100644 --- a/README-CS.md +++ b/README-CS.md @@ -75,12 +75,6 @@ sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb- sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pulseaudio ``` -### Instalace balíčku pynput - -```sh -pip3 install pynput -``` - ### Instalace vcpkg ```sh diff --git a/README-FA.md b/README-FA.md index 5fd3c0d03..f7de9aa87 100644 --- a/README-FA.md +++ b/README-FA.md @@ -78,12 +78,6 @@ sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb- sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pulseaudio ``` -### بسته pynput را نصب کنید - -```sh -pip3 install pynput -``` - ### نرم افزار vcpkg را نصب کنید ```sh diff --git a/README-HU.md b/README-HU.md index 3960d8b40..cfc6c793d 100644 --- a/README-HU.md +++ b/README-HU.md @@ -81,12 +81,6 @@ sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb- sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pulseaudio ``` -### Telepítsd a pynput csomagot - -```sh -pip3 install pynput -``` - ### Telepítsd a vcpkg-t ```sh diff --git a/README-JP.md b/README-JP.md index c1722a90f..394fbc52a 100644 --- a/README-JP.md +++ b/README-JP.md @@ -80,12 +80,6 @@ sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb- sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pulseaudio ``` -### Install pynput package - -```sh -pip3 install pynput -``` - ### Install vcpkg ```sh diff --git a/README-KR.md b/README-KR.md index c7cf423da..9a87d8ab1 100644 --- a/README-KR.md +++ b/README-KR.md @@ -78,12 +78,6 @@ sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb- sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pulseaudio ``` -### Install pynput package - -```sh -pip3 install pynput -``` - ### Install vcpkg ```sh diff --git a/README-VN.md b/README-VN.md index 641b80ebd..b7b683e4f 100644 --- a/README-VN.md +++ b/README-VN.md @@ -82,12 +82,6 @@ sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb- sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pulseaudio ``` -### Cách tải về gói hàng pynput - -```sh -pip3 install pynput -``` - ### Cách cài vcpkg ```sh diff --git a/README.md b/README.md index 792357225..8abfbc9d3 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,9 @@ Please download sciter dynamic library yourself. ### Ubuntu 18 (Debian 10) ```sh -sudo apt install -y g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake +sudo apt install -y g++ gcc git curl wget nasm yasm libgtk-3-dev clang libxcb-randr0-dev libxdo-dev \ + libxfixes-dev libxcb-shape0-dev libxcb-xfixes0-dev libasound2-dev libpulse-dev cmake \ + libclang-dev ninja-build libayatana-appindicator3-1 libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libayatana-appindicator3-dev ``` ### Fedora 28 (CentOS 8) @@ -80,12 +82,6 @@ sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb- sudo pacman -Syu --needed unzip git cmake gcc curl wget yasm nasm zip make pkg-config clang gtk3 xdotool libxcb libxfixes alsa-lib pulseaudio ``` -### Install pynput package - -```sh -pip3 install pynput -``` - ### Install vcpkg ```sh @@ -128,6 +124,30 @@ VCPKG_ROOT=$HOME/vcpkg cargo run RustDesk does not support Wayland. Check [this](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) to configuring Xorg as the default GNOME session. +## Wayland support + +Wayland does not seem to provide any API for sending keypresses to other windows. Therefore, the rustdesk uses an API from a lower level, namely the `/dev/uinput` device (Linux kernel level). + +When wayland is the controlled side, you have to start in the following way: +```bash +# Start uinput service +$ sudo rustdesk --service +$ rustdesk +``` +**Notice**: Wayland screen recording uses different interfaces, currently currently only supports org.freedesktop.portal.ScreenCast. +```bash +$ dbus-send --session --print-reply \ + --dest=org.freedesktop.portal.Desktop \ + /org/freedesktop/portal/desktop \ + org.freedesktop.DBus.Properties.Get \ + string:org.freedesktop.portal.ScreenCast string:version +# Not support +Error org.freedesktop.DBus.Error.InvalidArgs: No such interface “org.freedesktop.portal.ScreenCast” +# Support +method return time=1662544486.931020 sender=:1.54 -> destination=:1.139 serial=257 reply_serial=2 + variant uint32 4 +``` + ## How to build with Docker Begin by cloning the repository and building the docker container: diff --git a/appimage/AppImageBuilder.yml b/appimage/AppImageBuilder.yml index 08a4f0786..cdaead908 100644 --- a/appimage/AppImageBuilder.yml +++ b/appimage/AppImageBuilder.yml @@ -9,8 +9,6 @@ script: # Download sciter.so - mkdir -p AppDir/usr/lib/rustdesk/ - pushd AppDir/usr/lib/rustdesk && wget https://github.com/c-smile/sciter-sdk/raw/29a598b6d20220b93848b5e8abab704619296857/bin.lnx/x64/libsciter-gtk.so && popd - # pynput_service.py - - cp ../pynput_service.py ./AppDir/usr/lib/rustdesk # Build rustdesk - pushd .. && python3 inline-sciter.py && cargo build --features inline,appimage --release && popd - mkdir -p AppDir/usr/bin diff --git a/appimage/requirements.txt b/appimage/requirements.txt deleted file mode 100644 index d632797e5..000000000 --- a/appimage/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pynput \ No newline at end of file diff --git a/build.py b/build.py index 6b03cb57b..095f8b7f1 100755 --- a/build.py +++ b/build.py @@ -140,8 +140,6 @@ def build_flutter_deb(version): 'cp rustdesk.service tmpdeb/usr/share/rustdesk/files/systemd/') os.system( 'cp rustdesk.service.user tmpdeb/usr/share/rustdesk/files/systemd/') - os.system( - 'cp ../pynput_service.py tmpdeb/usr/share/rustdesk/files/') os.system( 'cp ../128x128@2x.png tmpdeb/usr/share/rustdesk/files/rustdesk.png') os.system( @@ -150,7 +148,6 @@ def build_flutter_deb(version): os.system('cp -a ../DEBIAN/* tmpdeb/DEBIAN/') md5_file('usr/share/rustdesk/files/systemd/rustdesk.service') md5_file('usr/share/rustdesk/files/systemd/rustdesk.service.user') - md5_file('usr/share/rustdesk/files/pynput_service.py') os.system('dpkg-deb -b tmpdeb rustdesk.deb; /bin/rm -rf tmpdeb/') os.rename('rustdesk.deb', '../rustdesk-%s.deb' % version) os.chdir("..") @@ -285,15 +282,12 @@ def main(): 'cp rustdesk.service tmpdeb/usr/share/rustdesk/files/systemd/') os.system( 'cp rustdesk.service.user tmpdeb/usr/share/rustdesk/files/systemd/') - os.system( - 'cp pynput_service.py tmpdeb/usr/share/rustdesk/files/') os.system('cp -a DEBIAN/* tmpdeb/DEBIAN/') os.system('strip tmpdeb/usr/bin/rustdesk') os.system('mkdir -p tmpdeb/usr/lib/rustdesk') os.system('cp libsciter-gtk.so tmpdeb/usr/lib/rustdesk/') md5_file('usr/share/rustdesk/files/systemd/rustdesk.service') md5_file('usr/share/rustdesk/files/systemd/rustdesk.service.user') - md5_file('usr/share/rustdesk/files/pynput_service.py') md5_file('usr/lib/rustdesk/libsciter-gtk.so') os.system('dpkg-deb -b tmpdeb rustdesk.deb; /bin/rm -rf tmpdeb/') os.rename('rustdesk.deb', 'rustdesk-%s.deb' % version) diff --git a/build.rs b/build.rs index 860ebae77..01fe8ada1 100644 --- a/build.rs +++ b/build.rs @@ -116,4 +116,4 @@ fn main() { build_windows(); #[cfg(target_os = "macos")] println!("cargo:rustc-link-lib=framework=ApplicationServices"); -} +} \ No newline at end of file diff --git a/flutter/.gitignore b/flutter/.gitignore index ec3fef74e..3cbfc0f54 100644 --- a/flutter/.gitignore +++ b/flutter/.gitignore @@ -36,11 +36,9 @@ lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols - # Obfuscation related app.*.map.json jniLibs - .vscode # flutter rust bridge diff --git a/flutter/lib/desktop/pages/remote_page.dart b/flutter/lib/desktop/pages/remote_page.dart index 90c729abe..86372d868 100644 --- a/flutter/lib/desktop/pages/remote_page.dart +++ b/flutter/lib/desktop/pages/remote_page.dart @@ -41,6 +41,7 @@ class _RemotePageState extends State with AutomaticKeepAliveClientMixin { Timer? _timer; String _value = ''; + String keyboardMode = "legacy"; final _cursorOverImage = false.obs; late RxBool _showRemoteCursor; late RxBool _remoteCursorMoved; @@ -246,6 +247,92 @@ class _RemotePageState extends State ], child: buildBody(context))); } + KeyEventResult handleRawKeyEvent(FocusNode data, RawKeyEvent e) { + bind.sessionGetKeyboardName(id: widget.id).then((result) { + setState(() { + keyboardMode = result.toString(); + }); + }); + + if (keyboardMode == 'map') { + mapKeyboardMode(e); + } else if (keyboardMode == 'translate') { + legacyKeyboardMode(e); + } else { + legacyKeyboardMode(e); + } + + return KeyEventResult.handled; + } + + void mapKeyboardMode(RawKeyEvent e) { + int scanCode; + int keyCode; + bool down; + + if (e.data is RawKeyEventDataMacOs) { + RawKeyEventDataMacOs newData = e.data as RawKeyEventDataMacOs; + scanCode = newData.keyCode; + keyCode = newData.keyCode; + } else if (e.data is RawKeyEventDataWindows) { + RawKeyEventDataWindows newData = e.data as RawKeyEventDataWindows; + scanCode = newData.scanCode; + keyCode = newData.keyCode; + } else if (e.data is RawKeyEventDataLinux) { + RawKeyEventDataLinux newData = e.data as RawKeyEventDataLinux; + scanCode = newData.scanCode; + keyCode = newData.keyCode; + } else { + scanCode = -1; + keyCode = -1; + } + + if (e is RawKeyDownEvent) { + down = true; + } else { + down = false; + } + + _ffi.inputRawKey(e.character ?? "", keyCode, scanCode, down); + } + + void legacyKeyboardMode(RawKeyEvent e) { + final key = e.logicalKey; + if (e is RawKeyDownEvent) { + if (e.repeat) { + sendRawKey(e, press: true); + } else { + if (e.isAltPressed && !_ffi.alt) { + _ffi.alt = true; + } else if (e.isControlPressed && !_ffi.ctrl) { + _ffi.ctrl = true; + } else if (e.isShiftPressed && !_ffi.shift) { + _ffi.shift = true; + } else if (e.isMetaPressed && !_ffi.command) { + _ffi.command = true; + } + sendRawKey(e, down: true); + } + } + if (e is RawKeyUpEvent) { + if (key == LogicalKeyboardKey.altLeft || + key == LogicalKeyboardKey.altRight) { + _ffi.alt = false; + } else if (key == LogicalKeyboardKey.controlLeft || + key == LogicalKeyboardKey.controlRight) { + _ffi.ctrl = false; + } else if (key == LogicalKeyboardKey.shiftRight || + key == LogicalKeyboardKey.shiftLeft) { + _ffi.shift = false; + } else if (key == LogicalKeyboardKey.metaLeft || + key == LogicalKeyboardKey.metaRight || + key == LogicalKeyboardKey.superKey) { + _ffi.command = false; + } + sendRawKey(e); + } + } + Widget getRawPointerAndKeyBody(Widget child) { return FocusScope( autofocus: true, @@ -256,42 +343,7 @@ class _RemotePageState extends State onFocusChange: (bool v) { _imageFocused = v; }, - onKey: (data, e) { - final key = e.logicalKey; - if (e is RawKeyDownEvent) { - if (e.repeat) { - sendRawKey(e, press: true); - } else { - if (e.isAltPressed && !_ffi.alt) { - _ffi.alt = true; - } else if (e.isControlPressed && !_ffi.ctrl) { - _ffi.ctrl = true; - } else if (e.isShiftPressed && !_ffi.shift) { - _ffi.shift = true; - } else if (e.isMetaPressed && !_ffi.command) { - _ffi.command = true; - } - sendRawKey(e, down: true); - } - } - if (e is RawKeyUpEvent) { - if (key == LogicalKeyboardKey.altLeft || - key == LogicalKeyboardKey.altRight) { - _ffi.alt = false; - } else if (key == LogicalKeyboardKey.controlLeft || - key == LogicalKeyboardKey.controlRight) { - _ffi.ctrl = false; - } else if (key == LogicalKeyboardKey.shiftRight || - key == LogicalKeyboardKey.shiftLeft) { - _ffi.shift = false; - } else if (key == LogicalKeyboardKey.metaLeft || - key == LogicalKeyboardKey.metaRight) { - _ffi.command = false; - } - sendRawKey(e); - } - return KeyEventResult.handled; - }, + onKey: handleRawKeyEvent, child: child)); } @@ -304,7 +356,6 @@ class _RemotePageState extends State /// mouseMode only: /// DoubleFiner -> right click /// HoldDrag -> left drag - void _onPointHoverImage(PointerHoverEvent e) { if (e.kind != ui.PointerDeviceKind.mouse) return; if (!_isPhysicalMouse) { @@ -367,6 +418,19 @@ class _RemotePageState extends State } } + void enterView(PointerEnterEvent evt) { + if (!_imageFocused) { + _physicalFocusNode.requestFocus(); + } + _cursorOverImage.value = true; + _ffi.enterOrLeave(true); + } + + void leaveView(PointerExitEvent evt) { + _cursorOverImage.value = false; + _ffi.enterOrLeave(false); + } + Widget _buildImageListener(Widget child) { return Listener( onPointerHover: _onPointHoverImage, @@ -374,17 +438,8 @@ class _RemotePageState extends State onPointerUp: _onPointUpImage, onPointerMove: _onPointMoveImage, onPointerSignal: _onPointerSignalImage, - child: MouseRegion( - onEnter: (evt) { - if (!_imageFocused) { - _physicalFocusNode.requestFocus(); - } - _cursorOverImage.value = true; - }, - onExit: (evt) { - _cursorOverImage.value = false; - }, - child: child)); + child: + MouseRegion(onEnter: enterView, onExit: leaveView, child: child)); } Widget getBodyForDesktop(BuildContext context) { diff --git a/flutter/lib/desktop/widgets/remote_menubar.dart b/flutter/lib/desktop/widgets/remote_menubar.dart index 411c30e73..2dcc81d4d 100644 --- a/flutter/lib/desktop/widgets/remote_menubar.dart +++ b/flutter/lib/desktop/widgets/remote_menubar.dart @@ -93,6 +93,7 @@ class _RemoteMenubarState extends State { menubarItems.add(_buildMonitor(context)); menubarItems.add(_buildControl(context)); menubarItems.add(_buildDisplay(context)); + menubarItems.add(_buildKeyboard(context)); if (!isWeb) { menubarItems.add(_buildChat(context)); } @@ -264,6 +265,29 @@ class _RemoteMenubarState extends State { ); } + Widget _buildKeyboard(BuildContext context) { + return mod_menu.PopupMenuButton( + padding: EdgeInsets.zero, + icon: const Icon( + Icons.keyboard, + color: _MenubarTheme.commonColor, + ), + tooltip: translate('Keyboard Settings'), + position: mod_menu.PopupMenuPosition.under, + onSelected: (String item) {}, + itemBuilder: (BuildContext context) => _getKeyboardMenu() + .map((entry) => entry.build( + context, + const MenuConfig( + commonColor: _MenubarTheme.commonColor, + height: _MenubarTheme.height, + dividerHeight: _MenubarTheme.dividerHeight, + ))) + .expand((i) => i) + .toList(), + ); + } + Widget _buildClose(BuildContext context) { return IconButton( tooltip: translate('Close'), @@ -577,6 +601,28 @@ class _RemoteMenubarState extends State { return displayMenu; } + List> _getKeyboardMenu() { + final keyboardMenu = [ + MenuEntryRadios( + text: translate('Ratio'), + optionsGetter: () => [ + MenuEntryRadioOption( + text: translate('Legacy mode'), value: 'legacy'), + MenuEntryRadioOption(text: translate('Map mode'), value: 'map'), + ], + curOptionGetter: () async { + return await bind.sessionGetKeyboardName(id: widget.id) ?? 'legacy'; + }, + optionSetter: (String oldValue, String newValue) async { + await bind.sessionSetKeyboardMode( + id: widget.id, keyboardMode: newValue); + widget.ffi.canvasModel.updateViewStyle(); + }) + ]; + + return keyboardMenu; + } + MenuEntrySwitch _createSwitchMenuEntry(String text, String option) { return MenuEntrySwitch( text: translate(text), diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 9f9899553..c02cd1ee1 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -972,6 +972,28 @@ class FFI { msg: json.encode(modify({'type': type, 'buttons': button.value}))); } + // Raw Key + void inputRawKey(String name, int keyCode, int scanCode, bool down) { + bind.sessionHandleFlutterKeyEvent( + id: id, + name: name, + keycode: keyCode, + scancode: scanCode, + downOrUp: down); + } + + Future getKeyboardMode() { + return bind.sessionGetKeyboardName(id: id); + } + + void enterOrLeave(bool enter) { + // Fix status + if (!enter) { + resetModifiers(); + } + bind.sessionEnterOrLeave(id: id, enter: enter); + } + /// Send key stroke event. /// [down] indicates the key's state(down or up). /// [press] indicates a click event(down and up). diff --git a/flutter/lib/models/native_model.dart b/flutter/lib/models/native_model.dart index 2a8391723..0d356a7c2 100644 --- a/flutter/lib/models/native_model.dart +++ b/flutter/lib/models/native_model.dart @@ -97,7 +97,7 @@ class PlatformFFI { final dylib = Platform.isAndroid ? DynamicLibrary.open('librustdesk.so') : Platform.isLinux - ? DynamicLibrary.open("/usr/lib/rustdesk/librustdesk.so") + ? DynamicLibrary.open("librustdesk.so") : Platform.isWindows ? DynamicLibrary.open("librustdesk.dll") : Platform.isMacOS diff --git a/flutter/linux/CMakeLists.txt b/flutter/linux/CMakeLists.txt index 9f6d0ce52..8484ca5b6 100644 --- a/flutter/linux/CMakeLists.txt +++ b/flutter/linux/CMakeLists.txt @@ -74,6 +74,8 @@ corrosion_import_crate(MANIFEST_PATH ../../Cargo.toml # [FEATURES ... ] ) +set(BASE_RUSTDESK "librustdesk") + # Define the application target. To change its name, change BINARY_NAME above, # not the value here, or `flutter run` will no longer work. # @@ -91,8 +93,8 @@ apply_standard_settings(${BINARY_NAME}) # Add dependency libraries. Add any application-specific dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) - -target_link_libraries(${BINARY_NAME} PRIVATE librustdesk) +target_link_libraries(${BINARY_NAME} PRIVATE ${BASE_RUSTDESK}) +# target_link_libraries(${BINARY_NAME} PRIVATE librustdesk) # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) @@ -142,6 +144,8 @@ foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) COMPONENT Runtime) endforeach(bundled_library) +install(FILES $ DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime RENAME librustdesk.so) + # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") diff --git a/flutter/linux/main.cc b/flutter/linux/main.cc index 55fb650bc..e2ad70957 100644 --- a/flutter/linux/main.cc +++ b/flutter/linux/main.cc @@ -1,7 +1,8 @@ #include #include "my_application.h" -#define RUSTDESK_LIB_PATH "/usr/lib/rustdesk/librustdesk.so" +#define RUSTDESK_LIB_PATH "ibrustdesk.so" +// #define RUSTDESK_LIB_PATH "/usr/lib/rustdesk/librustdesk.so" typedef bool (*RustDeskCoreMain)(); bool flutter_rustdesk_core_main() { diff --git a/flutter/macos/Podfile.lock b/flutter/macos/Podfile.lock index a83616180..e417eb188 100644 --- a/flutter/macos/Podfile.lock +++ b/flutter/macos/Podfile.lock @@ -1,78 +1,84 @@ PODS: - - bitsdojo_window_macos (0.0.1): + - desktop_drop (0.0.1): - FlutterMacOS - desktop_multi_window (0.0.1): - FlutterMacOS - device_info_plus_macos (0.0.1): - FlutterMacOS - - Firebase/Analytics (8.15.0): + - Firebase/Analytics (9.4.0): - Firebase/Core - - Firebase/Core (8.15.0): + - Firebase/Core (9.4.0): - Firebase/CoreOnly - - FirebaseAnalytics (~> 8.15.0) - - Firebase/CoreOnly (8.15.0): - - FirebaseCore (= 8.15.0) - - firebase_analytics (9.1.9): - - Firebase/Analytics (= 8.15.0) + - FirebaseAnalytics (~> 9.4.0) + - Firebase/CoreOnly (9.4.0): + - FirebaseCore (= 9.4.0) + - firebase_analytics (9.3.3): + - Firebase/Analytics (= 9.4.0) - firebase_core - FlutterMacOS - - firebase_core (1.17.1): - - Firebase/CoreOnly (~> 8.15.0) + - firebase_core (1.21.1): + - Firebase/CoreOnly (~> 9.4.0) - FlutterMacOS - - FirebaseAnalytics (8.15.0): - - FirebaseAnalytics/AdIdSupport (= 8.15.0) - - FirebaseCore (~> 8.0) - - FirebaseInstallations (~> 8.0) + - FirebaseAnalytics (9.4.0): + - FirebaseAnalytics/AdIdSupport (= 9.4.0) + - FirebaseCore (~> 9.0) + - FirebaseInstallations (~> 9.0) - GoogleUtilities/AppDelegateSwizzler (~> 7.7) - GoogleUtilities/MethodSwizzler (~> 7.7) - GoogleUtilities/Network (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - - nanopb (~> 2.30908.0) - - FirebaseAnalytics/AdIdSupport (8.15.0): - - FirebaseCore (~> 8.0) - - FirebaseInstallations (~> 8.0) - - GoogleAppMeasurement (= 8.15.0) + - nanopb (< 2.30910.0, >= 2.30908.0) + - FirebaseAnalytics/AdIdSupport (9.4.0): + - FirebaseCore (~> 9.0) + - FirebaseInstallations (~> 9.0) + - GoogleAppMeasurement (= 9.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 7.7) - GoogleUtilities/MethodSwizzler (~> 7.7) - GoogleUtilities/Network (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - - nanopb (~> 2.30908.0) - - FirebaseCore (8.15.0): - - FirebaseCoreDiagnostics (~> 8.0) + - nanopb (< 2.30910.0, >= 2.30908.0) + - FirebaseCore (9.4.0): + - FirebaseCoreDiagnostics (~> 9.0) + - FirebaseCoreInternal (~> 9.0) - GoogleUtilities/Environment (~> 7.7) - GoogleUtilities/Logger (~> 7.7) - - FirebaseCoreDiagnostics (8.15.0): - - GoogleDataTransport (~> 9.1) + - FirebaseCoreDiagnostics (9.5.0): + - GoogleDataTransport (< 10.0.0, >= 9.1.4) - GoogleUtilities/Environment (~> 7.7) - GoogleUtilities/Logger (~> 7.7) - - nanopb (~> 2.30908.0) - - FirebaseInstallations (8.15.0): - - FirebaseCore (~> 8.0) + - nanopb (< 2.30910.0, >= 2.30908.0) + - FirebaseCoreInternal (9.5.0): + - "GoogleUtilities/NSData+zlib (~> 7.7)" + - FirebaseInstallations (9.5.0): + - FirebaseCore (~> 9.0) - GoogleUtilities/Environment (~> 7.7) - GoogleUtilities/UserDefaults (~> 7.7) - - PromisesObjC (< 3.0, >= 1.2) + - PromisesObjC (~> 2.1) - FlutterMacOS (1.0.0) - - GoogleAppMeasurement (8.15.0): - - GoogleAppMeasurement/AdIdSupport (= 8.15.0) + - FMDB (2.7.5): + - FMDB/standard (= 2.7.5) + - FMDB/standard (2.7.5) + - GoogleAppMeasurement (9.4.0): + - GoogleAppMeasurement/AdIdSupport (= 9.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 7.7) - GoogleUtilities/MethodSwizzler (~> 7.7) - GoogleUtilities/Network (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - - nanopb (~> 2.30908.0) - - GoogleAppMeasurement/AdIdSupport (8.15.0): - - GoogleAppMeasurement/WithoutAdIdSupport (= 8.15.0) + - nanopb (< 2.30910.0, >= 2.30908.0) + - GoogleAppMeasurement/AdIdSupport (9.4.0): + - GoogleAppMeasurement/WithoutAdIdSupport (= 9.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 7.7) - GoogleUtilities/MethodSwizzler (~> 7.7) - GoogleUtilities/Network (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - - nanopb (~> 2.30908.0) - - GoogleAppMeasurement/WithoutAdIdSupport (8.15.0): + - nanopb (< 2.30910.0, >= 2.30908.0) + - GoogleAppMeasurement/WithoutAdIdSupport (9.4.0): - GoogleUtilities/AppDelegateSwizzler (~> 7.7) - GoogleUtilities/MethodSwizzler (~> 7.7) - GoogleUtilities/Network (~> 7.7) - "GoogleUtilities/NSData+zlib (~> 7.7)" - - nanopb (~> 2.30908.0) - - GoogleDataTransport (9.1.4): + - nanopb (< 2.30910.0, >= 2.30908.0) + - GoogleDataTransport (9.2.0): - GoogleUtilities/Environment (~> 7.7) - nanopb (< 2.30910.0, >= 2.30908.0) - PromisesObjC (< 3.0, >= 1.2) @@ -95,18 +101,25 @@ PODS: - GoogleUtilities/Logger - GoogleUtilities/UserDefaults (7.7.0): - GoogleUtilities/Logger - - nanopb (2.30908.0): - - nanopb/decode (= 2.30908.0) - - nanopb/encode (= 2.30908.0) - - nanopb/decode (2.30908.0) - - nanopb/encode (2.30908.0) + - nanopb (2.30909.0): + - nanopb/decode (= 2.30909.0) + - nanopb/encode (= 2.30909.0) + - nanopb/decode (2.30909.0) + - nanopb/encode (2.30909.0) - package_info_plus_macos (0.0.1): - FlutterMacOS - path_provider_macos (0.0.1): - FlutterMacOS - - PromisesObjC (2.1.0) + - PromisesObjC (2.1.1) + - screen_retriever (0.0.1): + - FlutterMacOS - shared_preferences_macos (0.0.1): - FlutterMacOS + - sqflite (0.0.2): + - FlutterMacOS + - FMDB (>= 2.7.5) + - tray_manager (0.0.1): + - FlutterMacOS - url_launcher_macos (0.0.1): - FlutterMacOS - wakelock_macos (0.0.1): @@ -115,7 +128,7 @@ PODS: - FlutterMacOS DEPENDENCIES: - - bitsdojo_window_macos (from `Flutter/ephemeral/.symlinks/plugins/bitsdojo_window_macos/macos`) + - desktop_drop (from `Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos`) - desktop_multi_window (from `Flutter/ephemeral/.symlinks/plugins/desktop_multi_window/macos`) - device_info_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus_macos/macos`) - firebase_analytics (from `Flutter/ephemeral/.symlinks/plugins/firebase_analytics/macos`) @@ -123,7 +136,10 @@ DEPENDENCIES: - FlutterMacOS (from `Flutter/ephemeral`) - package_info_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos`) - path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`) + - screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`) - shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`) + - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) + - tray_manager (from `Flutter/ephemeral/.symlinks/plugins/tray_manager/macos`) - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) - wakelock_macos (from `Flutter/ephemeral/.symlinks/plugins/wakelock_macos/macos`) - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`) @@ -134,7 +150,9 @@ SPEC REPOS: - FirebaseAnalytics - FirebaseCore - FirebaseCoreDiagnostics + - FirebaseCoreInternal - FirebaseInstallations + - FMDB - GoogleAppMeasurement - GoogleDataTransport - GoogleUtilities @@ -142,8 +160,8 @@ SPEC REPOS: - PromisesObjC EXTERNAL SOURCES: - bitsdojo_window_macos: - :path: Flutter/ephemeral/.symlinks/plugins/bitsdojo_window_macos/macos + desktop_drop: + :path: Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos desktop_multi_window: :path: Flutter/ephemeral/.symlinks/plugins/desktop_multi_window/macos device_info_plus_macos: @@ -158,8 +176,14 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus_macos/macos path_provider_macos: :path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos + screen_retriever: + :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos shared_preferences_macos: :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos + sqflite: + :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos + tray_manager: + :path: Flutter/ephemeral/.symlinks/plugins/tray_manager/macos url_launcher_macos: :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos wakelock_macos: @@ -168,25 +192,30 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos SPEC CHECKSUMS: - bitsdojo_window_macos: 44e3b8fe3dd463820e0321f6256c5b1c16bb6a00 + desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898 desktop_multi_window: 566489c048b501134f9d7fb6a2354c60a9126486 device_info_plus_macos: 1ad388a1ef433505c4038e7dd9605aadd1e2e9c7 - Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d - firebase_analytics: d448483150504ed84f25c5437a34af2591a7929e - firebase_core: 7b87364e2d1eae70018a60698e89e7d6f5320bad - FirebaseAnalytics: 7761cbadb00a717d8d0939363eb46041526474fa - FirebaseCore: 5743c5785c074a794d35f2fff7ecc254a91e08b1 - FirebaseCoreDiagnostics: 92e07a649aeb66352b319d43bdd2ee3942af84cb - FirebaseInstallations: 40bd9054049b2eae9a2c38ef1c3dd213df3605cd + Firebase: 7703fc4022824b6d6db1bf7bea58d13b8e17ec46 + firebase_analytics: 57144bae6cd39d3be367a8767a1b8857a037cee5 + firebase_core: 822a1076483bf9764284322c9310daa98e1e6817 + FirebaseAnalytics: a1a24e72b7ba7f47045a4633f1abb545c07bd29c + FirebaseCore: 9a2b10270a854731c4d4d8a97d0aa8380ec3458d + FirebaseCoreDiagnostics: 17cbf4e72b1dbd64bfdc33d4b1f07bce4f16f1d8 + FirebaseCoreInternal: 50a8e39cae8abf72d5145d07ea34c3244f70862b + FirebaseInstallations: 41f811b530c41dd90973d0174381cdb3fcb5e839 FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 - GoogleAppMeasurement: 4c19f031220c72464d460c9daa1fb5d1acce958e - GoogleDataTransport: 5fffe35792f8b96ec8d6775f5eccd83c998d5a3b + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + GoogleAppMeasurement: 5d69e04287fc2c10cc43724bfa4bf31fc12c3dff + GoogleDataTransport: 1c8145da7117bd68bbbed00cf304edb6a24de00f GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1 - nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96 + nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 package_info_plus_macos: f010621b07802a241d96d01876d6705f15e77c1c path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19 - PromisesObjC: 99b6f43f9e1044bd87a95a60beff28c2c44ddb72 + PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb + screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38 shared_preferences_macos: a64dc611287ed6cbe28fd1297898db1336975727 + sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea + tray_manager: 9064e219c56d75c476e46b9a21182087930baf90 url_launcher_macos: 597e05b8e514239626bcf4a850fcf9ef5c856ec3 wakelock_macos: bc3f2a9bd8d2e6c89fee1e1822e7ddac3bd004a9 window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 diff --git a/flutter/macos/Runner/Release.entitlements b/flutter/macos/Runner/Release.entitlements index 852fa1a47..ee95ab7e5 100644 --- a/flutter/macos/Runner/Release.entitlements +++ b/flutter/macos/Runner/Release.entitlements @@ -4,5 +4,7 @@ com.apple.security.app-sandbox + com.apple.security.network.client + diff --git a/flutter/macos/rustdesk.xcodeproj/project.pbxproj b/flutter/macos/rustdesk.xcodeproj/project.pbxproj index bed41ae67..5e9d16659 100644 --- a/flutter/macos/rustdesk.xcodeproj/project.pbxproj +++ b/flutter/macos/rustdesk.xcodeproj/project.pbxproj @@ -33,7 +33,7 @@ /* Begin PBXFileReference section */ ADDEDBA66A6E1 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; }; - CA603C4309E13EF4668187A5 /* Cargo.toml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Cargo.toml; path = /Users/ruizruiz/Work/Code/Projects/RustDesk/rustdesk/Cargo.toml; sourceTree = ""; }; + CA603C4309E13EF4668187A5 /* Cargo.toml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Cargo.toml; path = /Users/mac/Documents/project/rustdesk/Cargo.toml; sourceTree = ""; }; CA604C7415FB2A3731F5016A /* liblibrustdesk_static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liblibrustdesk_static.a; sourceTree = BUILT_PRODUCTS_DIR; }; CA6071B5A0F5A7A3EF2297AA /* librustdesk.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = librustdesk.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; CA60D3BC5386B357B2AB834F /* rustdesk */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = rustdesk; sourceTree = BUILT_PRODUCTS_DIR; }; diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index b1c603ff0..586187be2 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -28,7 +28,7 @@ packages: name: animations url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.3" + version: "2.0.4" archive: dependency: transitive description: @@ -235,12 +235,10 @@ packages: dash_chat_2: dependency: "direct main" description: - path: "." - ref: feat_maxWidth - resolved-ref: "3946ecf86d3600b54632fd80d0eb0ef0e74f2d6a" - url: "https://github.com/fufesou/Dash-Chat-2" - source: git - version: "0.0.12" + name: dash_chat_2 + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.0.14" desktop_drop: dependency: "direct main" description: @@ -347,42 +345,42 @@ packages: name: firebase_analytics url: "https://pub.flutter-io.cn" source: hosted - version: "9.3.2" + version: "9.3.3" firebase_analytics_platform_interface: dependency: transitive description: name: firebase_analytics_platform_interface url: "https://pub.flutter-io.cn" source: hosted - version: "3.3.2" + version: "3.3.3" firebase_analytics_web: dependency: transitive description: name: firebase_analytics_web url: "https://pub.flutter-io.cn" source: hosted - version: "0.4.2+2" + version: "0.4.2+3" firebase_core: dependency: transitive description: name: firebase_core url: "https://pub.flutter-io.cn" source: hosted - version: "1.21.0" + version: "1.21.1" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface url: "https://pub.flutter-io.cn" source: hosted - version: "4.5.0" + version: "4.5.1" firebase_core_web: dependency: transitive description: name: firebase_core_web url: "https://pub.flutter-io.cn" source: hosted - version: "1.7.1" + version: "1.7.2" fixnum: dependency: transitive description: @@ -735,7 +733,7 @@ packages: name: path_provider_android url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.19" + version: "2.0.20" path_provider_ios: dependency: transitive description: @@ -849,7 +847,7 @@ packages: source: hosted version: "3.1.0" rxdart: - dependency: transitive + dependency: "direct main" description: name: rxdart url: "https://pub.flutter-io.cn" @@ -1257,7 +1255,7 @@ packages: name: xdg_directories url: "https://pub.flutter-io.cn" source: hosted - version: "0.2.0+1" + version: "0.2.0+2" xml: dependency: transitive description: diff --git a/libs/enigo/Cargo.toml b/libs/enigo/Cargo.toml index b0028b564..83c79e064 100644 --- a/libs/enigo/Cargo.toml +++ b/libs/enigo/Cargo.toml @@ -22,6 +22,8 @@ appveyor = { repository = "pythoneer/enigo-85xiy" } serde = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true } log = "0.4" +rdev = { git = "https://github.com/asur4s/rdev" } +tfc = { git = "https://github.com/asur4s/The-Fat-Controller" } hbb_common = { path = "../hbb_common" } [features] diff --git a/libs/enigo/src/lib.rs b/libs/enigo/src/lib.rs index 164fb1c17..01e9b67d2 100644 --- a/libs/enigo/src/lib.rs +++ b/libs/enigo/src/lib.rs @@ -257,7 +257,7 @@ pub enum Key { Backspace, /// caps lock key CapsLock, - #[deprecated(since = "0.0.12", note = "now renamed to Meta")] + // #[deprecated(since = "0.0.12", note = "now renamed to Meta")] /// command key on macOS (super key on Linux, windows key on Windows) Command, /// control key @@ -314,14 +314,14 @@ pub enum Key { Shift, /// space key Space, - #[deprecated(since = "0.0.12", note = "now renamed to Meta")] + // #[deprecated(since = "0.0.12", note = "now renamed to Meta")] /// super key on linux (command key on macOS, windows key on Windows) Super, /// tab key (tabulator) Tab, /// up arrow key UpArrow, - #[deprecated(since = "0.0.12", note = "now renamed to Meta")] + // #[deprecated(since = "0.0.12", note = "now renamed to Meta")] /// windows key on Windows (super key on Linux, command key on macOS) Windows, /// diff --git a/libs/enigo/src/linux/mod.rs b/libs/enigo/src/linux/mod.rs index 42e1dfebf..1f73004ad 100644 --- a/libs/enigo/src/linux/mod.rs +++ b/libs/enigo/src/linux/mod.rs @@ -1,5 +1,4 @@ mod nix_impl; -mod pynput; mod xdo; pub use self::nix_impl::Enigo; diff --git a/libs/enigo/src/linux/nix_impl.rs b/libs/enigo/src/linux/nix_impl.rs index 840290b2b..5fb67c5ee 100644 --- a/libs/enigo/src/linux/nix_impl.rs +++ b/libs/enigo/src/linux/nix_impl.rs @@ -1,12 +1,14 @@ -use super::{pynput::EnigoPynput, xdo::EnigoXdo}; +use super::xdo::EnigoXdo; use crate::{Key, KeyboardControllable, MouseButton, MouseControllable}; +use std::io::Read; +use tfc::{traits::*, Context as TFC_Context, Key as TFC_Key}; /// The main struct for handling the event emitting // #[derive(Default)] pub struct Enigo { xdo: EnigoXdo, - pynput: EnigoPynput, is_x11: bool, + tfc: TFC_Context, uinput_keyboard: Option>, uinput_mouse: Option>, } @@ -20,10 +22,6 @@ impl Enigo { pub fn set_delay(&mut self, delay: u64) { self.xdo.set_delay(delay) } - /// Reset pynput. - pub fn reset(&mut self) { - self.pynput.reset(); - } /// Set uinput keyboard. pub fn set_uinput_keyboard( &mut self, @@ -35,16 +33,51 @@ impl Enigo { pub fn set_uinput_mouse(&mut self, uinput_mouse: Option>) { self.uinput_mouse = uinput_mouse } + + fn tfc_key_down_or_up(&mut self, key: Key, down: bool, up: bool) -> bool { + if let Key::Layout(chr) = key { + if down { + if let Err(_) = self.tfc.unicode_char_down(chr) { + return false; + } + } + if up { + if let Err(_) = self.tfc.unicode_char_up(chr) { + return false; + } + } + return true; + } + + let key = match convert_to_tfc_key(key) { + Some(key) => key, + None => { + return false; + } + }; + + if down { + if let Err(_) = self.tfc.key_down(key) { + return false; + } + }; + if up { + if let Err(_) = self.tfc.key_up(key) { + return false; + } + }; + return true; + } } impl Default for Enigo { fn default() -> Self { Self { is_x11: "x11" == hbb_common::platform::linux::get_display_server(), + tfc: TFC_Context::new().expect("kbd context error"), uinput_keyboard: None, uinput_mouse: None, xdo: EnigoXdo::default(), - pynput: EnigoPynput::default(), } } } @@ -117,6 +150,26 @@ impl MouseControllable for Enigo { } } +fn get_led_state(key: Key) -> bool { + let led_file = match key { + Key::CapsLock => "/sys/class/leds/input1::capslock/brightness", + Key::NumLock => "/sys/class/leds/input1::numlock/brightness", + _ => { + return false; + } + }; + + let status = if let Ok(mut file) = std::fs::File::open(&led_file) { + let mut content = String::new(); + file.read_to_string(&mut content).ok(); + let status = content.trim_end().to_string().parse::().unwrap_or(0); + status + } else { + 0 + }; + status == 1 +} + impl KeyboardControllable for Enigo { fn get_key_state(&mut self, key: Key) -> bool { if self.is_x11 { @@ -125,7 +178,7 @@ impl KeyboardControllable for Enigo { if let Some(keyboard) = &mut self.uinput_keyboard { keyboard.get_key_state(key) } else { - false + get_led_state(key) } } } @@ -142,10 +195,12 @@ impl KeyboardControllable for Enigo { fn key_down(&mut self, key: Key) -> crate::ResultType { if self.is_x11 { - if self.pynput.send_pynput(&key, true) { - return Ok(()); + let has_down = self.tfc_key_down_or_up(key, true, false); + if !has_down { + self.xdo.key_down(key) + } else { + Ok(()) } - self.xdo.key_down(key) } else { if let Some(keyboard) = &mut self.uinput_keyboard { keyboard.key_down(key) @@ -156,10 +211,10 @@ impl KeyboardControllable for Enigo { } fn key_up(&mut self, key: Key) { if self.is_x11 { - if self.pynput.send_pynput(&key, false) { - return; + let has_down = self.tfc_key_down_or_up(key, false, true); + if !has_down { + self.xdo.key_up(key) } - self.xdo.key_up(key) } else { if let Some(keyboard) = &mut self.uinput_keyboard { keyboard.key_up(key) @@ -167,12 +222,76 @@ impl KeyboardControllable for Enigo { } } fn key_click(&mut self, key: Key) { - if self.is_x11 { - self.xdo.key_click(key) - } else { - if let Some(keyboard) = &mut self.uinput_keyboard { - keyboard.key_click(key) - } - } + self.key_down(key).ok(); + self.key_up(key); } } + +fn convert_to_tfc_key(key: Key) -> Option { + let key = match key { + Key::Alt => TFC_Key::Alt, + Key::Backspace => TFC_Key::DeleteOrBackspace, + Key::CapsLock => TFC_Key::CapsLock, + Key::Control => TFC_Key::Control, + Key::Delete => TFC_Key::ForwardDelete, + Key::DownArrow => TFC_Key::DownArrow, + Key::End => TFC_Key::End, + Key::Escape => TFC_Key::Escape, + Key::F1 => TFC_Key::F1, + Key::F10 => TFC_Key::F10, + Key::F11 => TFC_Key::F11, + Key::F12 => TFC_Key::F12, + Key::F2 => TFC_Key::F2, + Key::F3 => TFC_Key::F3, + Key::F4 => TFC_Key::F4, + Key::F5 => TFC_Key::F5, + Key::F6 => TFC_Key::F6, + Key::F7 => TFC_Key::F7, + Key::F8 => TFC_Key::F8, + Key::F9 => TFC_Key::F9, + Key::Home => TFC_Key::Home, + Key::LeftArrow => TFC_Key::LeftArrow, + Key::PageDown => TFC_Key::PageDown, + Key::PageUp => TFC_Key::PageUp, + Key::Return => TFC_Key::ReturnOrEnter, + Key::RightArrow => TFC_Key::RightArrow, + Key::Shift => TFC_Key::Shift, + Key::Space => TFC_Key::Space, + Key::Tab => TFC_Key::Tab, + Key::UpArrow => TFC_Key::UpArrow, + Key::Numpad0 => TFC_Key::N0, + Key::Numpad1 => TFC_Key::N1, + Key::Numpad2 => TFC_Key::N2, + Key::Numpad3 => TFC_Key::N3, + Key::Numpad4 => TFC_Key::N4, + Key::Numpad5 => TFC_Key::N5, + Key::Numpad6 => TFC_Key::N6, + Key::Numpad7 => TFC_Key::N7, + Key::Numpad8 => TFC_Key::N8, + Key::Numpad9 => TFC_Key::N9, + Key::Decimal => TFC_Key::NumpadDecimal, + Key::Clear => TFC_Key::NumpadClear, + Key::Pause => TFC_Key::PlayPause, + Key::Print => TFC_Key::Print, + Key::Snapshot => TFC_Key::PrintScreen, + Key::Insert => TFC_Key::Insert, + Key::Scroll => TFC_Key::ScrollLock, + Key::NumLock => TFC_Key::NumLock, + Key::RWin => TFC_Key::Meta, + Key::Apps => TFC_Key::Apps, + Key::Multiply => TFC_Key::NumpadMultiply, + Key::Add => TFC_Key::NumpadPlus, + Key::Subtract => TFC_Key::NumpadMinus, + Key::Divide => TFC_Key::NumpadDivide, + Key::Equals => TFC_Key::NumpadEquals, + Key::NumpadEnter => TFC_Key::NumpadEnter, + Key::RightShift => TFC_Key::RightShift, + Key::RightControl => TFC_Key::RightControl, + Key::RightAlt => TFC_Key::RightAlt, + Key::Command | Key::Super | Key::Windows | Key::Meta => TFC_Key::Meta, + _ => { + return None; + } + }; + Some(key) +} diff --git a/libs/enigo/src/linux/pynput.rs b/libs/enigo/src/linux/pynput.rs deleted file mode 100644 index 748b30105..000000000 --- a/libs/enigo/src/linux/pynput.rs +++ /dev/null @@ -1,280 +0,0 @@ -use crate::Key; -use std::{io::prelude::*, sync::mpsc}; - -enum PyMsg { - Char(char), - Str(&'static str), -} - -/// The main struct for handling the event emitting -pub(super) struct EnigoPynput { - tx: mpsc::Sender<(PyMsg, bool)>, -} - -impl Default for EnigoPynput { - fn default() -> Self { - let (tx, rx) = mpsc::channel(); - start_pynput_service(rx); - Self { tx } - } -} -impl EnigoPynput { - pub(super) fn reset(&mut self) { - self.tx.send((PyMsg::Char('\0'), true)).ok(); - } - - #[inline] - pub(super) fn send_pynput(&mut self, key: &Key, is_press: bool) -> bool { - if unsafe { PYNPUT_EXIT || !PYNPUT_REDAY } { - return false; - } - if let Key::Layout(c) = key { - return self.tx.send((PyMsg::Char(*c), is_press)).is_ok(); - } - if let Key::Raw(_) = key { - return false; - } - #[allow(deprecated)] - let s = match key { - Key::Alt => "Alt_L", - Key::Backspace => "BackSpace", - Key::CapsLock => "Caps_Lock", - Key::Control => "Control_L", - Key::Delete => "Delete", - Key::DownArrow => "Down", - Key::End => "End", - Key::Escape => "Escape", - Key::F1 => "F1", - Key::F10 => "F10", - Key::F11 => "F11", - Key::F12 => "F12", - Key::F2 => "F2", - Key::F3 => "F3", - Key::F4 => "F4", - Key::F5 => "F5", - Key::F6 => "F6", - Key::F7 => "F7", - Key::F8 => "F8", - Key::F9 => "F9", - Key::Home => "Home", - Key::LeftArrow => "Left", - Key::Option => "Option", - Key::PageDown => "Page_Down", - Key::PageUp => "Page_Up", - Key::Return => "Return", - Key::RightArrow => "Right", - Key::Shift => "Shift_L", - Key::Space => "space", - Key::Tab => "Tab", - Key::UpArrow => "Up", - Key::Numpad0 => "0", - Key::Numpad1 => "1", - Key::Numpad2 => "2", - Key::Numpad3 => "3", - Key::Numpad4 => "4", - Key::Numpad5 => "5", - Key::Numpad6 => "6", - Key::Numpad7 => "7", - Key::Numpad8 => "8", - Key::Numpad9 => "9", - Key::Decimal => "KP_Decimal", - Key::Cancel => "Cancel", - Key::Clear => "Clear", - Key::Pause => "Pause", - Key::Kana => "Kana", - Key::Hangul => "Hangul", - Key::Hanja => "Hanja", - Key::Kanji => "Kanji", - Key::Select => "Select", - Key::Print => "Print", - Key::Execute => "Execute", - Key::Snapshot => "3270_PrintScreen", - Key::Insert => "Insert", - Key::Help => "Help", - Key::Separator => "KP_Separator", - Key::Scroll => "Scroll_Lock", - Key::NumLock => "Num_Lock", - Key::RWin => "Super_R", - Key::Apps => "Menu", - Key::Multiply => "KP_Multiply", - Key::Add => "KP_Add", - Key::Subtract => "KP_Subtract", - Key::Divide => "KP_Divide", - Key::Equals => "KP_Equal", - Key::NumpadEnter => "KP_Enter", - Key::RightShift => "Shift_R", - Key::RightControl => "Control_R", - Key::RightAlt => "Mode_switch", - Key::Command | Key::Super | Key::Windows | Key::Meta => "Super_L", - _ => { - return true; - } - }; - log::info!("send pynput: {:?}", &s); - return self.tx.send((PyMsg::Str(s), is_press)).is_ok(); - } -} - -// impl MouseControllable for EnigoPynput { -// fn mouse_move_to(&mut self, _x: i32, _y: i32) { -// unimplemented!() -// } -// fn mouse_move_relative(&mut self, _x: i32, _y: i32) { -// unimplemented!() -// } -// fn mouse_down(&mut self, _button: MouseButton) -> crate::ResultType { -// unimplemented!() -// } -// fn mouse_up(&mut self, _button: MouseButton) { -// unimplemented!() -// } -// fn mouse_click(&mut self, _button: MouseButton) { -// unimplemented!() -// } -// fn mouse_scroll_x(&mut self, _length: i32) { -// unimplemented!() -// } -// fn mouse_scroll_y(&mut self, _length: i32) { -// unimplemented!() -// } -// } - -// impl KeyboardControllable for EnigoPynput { -// fn get_key_state(&mut self, _key: Key) -> bool { -// unimplemented!() -// } - -// fn key_sequence(&mut self, _sequence: &str) { -// unimplemented!() -// } -// fn key_down(&mut self, key: Key) -> crate::ResultType { -// let _ = self.send_pynput(&key, true); -// Ok(()) -// } -// fn key_up(&mut self, key: Key) { -// let _ = self.send_pynput(&key, false); -// } -// fn key_click(&mut self, _key: Key) { -// unimplemented!() -// } -// } - -static mut PYNPUT_EXIT: bool = false; -static mut PYNPUT_REDAY: bool = false; -static IPC_FILE: &'static str = "/tmp/RustDesk/pynput_service"; - -fn start_pynput_service(rx: mpsc::Receiver<(PyMsg, bool)>) { - let mut py = "./pynput_service.py".to_owned(); - if !std::path::Path::new(&py).exists() { - py = "/usr/share/rustdesk/files/pynput_service.py".to_owned(); - if !std::path::Path::new(&py).exists() { - py = "/usr/lib/rustdesk/pynput_service.py".to_owned(); - if !std::path::Path::new(&py).exists() { - log::error!("{} not exits", py); - } - } - } - log::info!("pynput service: {}", py); - std::thread::spawn(move || { - let username = std::env::var("PYNPUT_USERNAME").unwrap_or("".to_owned()); - let userid = std::env::var("PYNPUT_USERID").unwrap_or("".to_owned()); - let status = if username.is_empty() { - std::process::Command::new("python3") - .arg(&py) - .arg(IPC_FILE) - .status() - .map(|x| x.success()) - } else { - let mut status = Ok(true); - for i in 0..100 { - if i % 10 == 0 { - log::info!("#{} try to start pynput server", i); - } - status = std::process::Command::new("sudo") - .args(vec![ - "-E", - &format!("XDG_RUNTIME_DIR=/run/user/{}", userid) as &str, - "-u", - &username, - "python3", - &py, - IPC_FILE, - ]) - .status() - .map(|x| x.success()); - match status { - Ok(true) => break, - _ => {} - } - std::thread::sleep(std::time::Duration::from_millis(100)); - } - status - }; - log::info!( - "pynput server exit with username/id {}/{}: {:?}", - username, - userid, - status - ); - unsafe { - PYNPUT_EXIT = true; - } - }); - std::thread::spawn(move || { - for i in 0..300 { - std::thread::sleep(std::time::Duration::from_millis(100)); - let mut conn = match std::os::unix::net::UnixStream::connect(IPC_FILE) { - Ok(conn) => conn, - Err(err) => { - if i % 15 == 0 { - log::warn!("Failed to connect to {}: {}", IPC_FILE, err); - } - continue; - } - }; - if let Err(err) = conn.set_nonblocking(true) { - log::error!("Failed to set ipc nonblocking: {}", err); - return; - } - log::info!("Conntected to pynput server"); - let d = std::time::Duration::from_millis(30); - unsafe { - PYNPUT_REDAY = true; - } - let mut buf = [0u8; 1024]; - loop { - if unsafe { PYNPUT_EXIT } { - break; - } - match rx.recv_timeout(d) { - Ok((msg, is_press)) => { - let msg = match msg { - PyMsg::Char(chr) => { - format!("{}{}", if is_press { 'p' } else { 'r' }, chr) - } - PyMsg::Str(s) => format!("{}{}", if is_press { 'p' } else { 'r' }, s), - }; - let n = msg.len(); - buf[0] = n as _; - buf[1..(n + 1)].copy_from_slice(msg.as_bytes()); - if let Err(err) = conn.write_all(&buf[..n + 1]) { - log::error!("Failed to write to ipc: {}", err); - break; - } - } - Err(err) => match err { - mpsc::RecvTimeoutError::Disconnected => { - log::error!("pynput sender disconnecte"); - break; - } - _ => {} - }, - } - } - unsafe { - PYNPUT_REDAY = false; - } - break; - } - }); -} diff --git a/libs/enigo/src/linux/xdo.rs b/libs/enigo/src/linux/xdo.rs index 0e3b79ab3..ff687eee2 100644 --- a/libs/enigo/src/linux/xdo.rs +++ b/libs/enigo/src/linux/xdo.rs @@ -370,4 +370,19 @@ impl KeyboardControllable for EnigoXdo { } } } + + fn key_sequence_parse(&mut self, sequence: &str) + where + Self: Sized, + { + self.key_sequence_parse_try(sequence) + .expect("Could not parse sequence"); + } + + fn key_sequence_parse_try(&mut self, sequence: &str) -> Result<(), crate::dsl::ParseError> + where + Self: Sized, + { + crate::dsl::eval(self, sequence) + } } diff --git a/libs/enigo/src/macos/macos_impl.rs b/libs/enigo/src/macos/macos_impl.rs index 28c9362ed..520c9dca1 100644 --- a/libs/enigo/src/macos/macos_impl.rs +++ b/libs/enigo/src/macos/macos_impl.rs @@ -1,5 +1,4 @@ use core_graphics; - // TODO(dustin): use only the things i need use self::core_graphics::display::*; diff --git a/libs/enigo/src/win/win_impl.rs b/libs/enigo/src/win/win_impl.rs index ea1543faa..56fc4caef 100644 --- a/libs/enigo/src/win/win_impl.rs +++ b/libs/enigo/src/win/win_impl.rs @@ -1,9 +1,8 @@ -use winapi; - use self::winapi::ctypes::c_int; use self::winapi::shared::{basetsd::ULONG_PTR, minwindef::*, windef::*}; use self::winapi::um::winbase::*; use self::winapi::um::winuser::*; +use winapi; use crate::win::keycodes::*; use crate::{Key, KeyboardControllable, MouseButton, MouseControllable}; @@ -200,7 +199,7 @@ impl KeyboardControllable for Enigo { fn key_down(&mut self, key: Key) -> crate::ResultType { let code = self.key_to_keycode(key); if code == 0 || code == 65535 { - return Err("".into()); + return Err("".into()); } let res = keybd_event(0, code, 0); if res == 0 { @@ -227,7 +226,8 @@ impl KeyboardControllable for Enigo { } impl Enigo { - /// Gets the (width, height) of the main display in screen coordinates (pixels). + /// Gets the (width, height) of the main display in screen coordinates + /// (pixels). /// /// # Example /// diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index dec00f21e..e711f5826 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -105,6 +105,13 @@ message MouseEvent { repeated ControlKey modifiers = 4; } +enum KeyboardMode{ + Legacy = 0; + Map = 1; + Translate = 2; + Auto = 3; +} + enum ControlKey { Unknown = 0; Alt = 1; @@ -198,6 +205,7 @@ message KeyEvent { string seq = 6; } repeated ControlKey modifiers = 8; + KeyboardMode mode = 9; } message CursorData { diff --git a/pacman_install b/pacman_install index d22423574..cfd3bdd60 100644 --- a/pacman_install +++ b/pacman_install @@ -7,7 +7,7 @@ post_install() { # do something here cp /usr/share/rustdesk/files/rustdesk.service /etc/systemd/system/rustdesk.service cp /usr/share/rustdesk/files/rustdesk.desktop /usr/share/applications/ - sudo -H pip3 install pynput + sudo -H pip3 install systemctl daemon-reload systemctl enable rustdesk systemctl start rustdesk diff --git a/pynput_service.py b/pynput_service.py deleted file mode 100644 index c51e9a524..000000000 --- a/pynput_service.py +++ /dev/null @@ -1,236 +0,0 @@ -from pynput.keyboard import Key, Controller -from pynput.keyboard._xorg import KeyCode -from pynput._util.xorg import display_manager -import Xlib -from pynput._util.xorg import * -import Xlib -import os -import sys -import socket - -KeyCode._from_symbol("\0") # test - -DEAD_KEYS = { - '`': 65104, - '´': 65105, - '^': 65106, - '~': 65107, - '¯': 65108, - '˘': 65109, - '˙': 65110, - '¨': 65111, - '˚': 65112, - '˝': 65113, - 'ˇ': 65114, - '¸': 65115, - '˛': 65116, - '℩': 65117, # ? - '゛': 65118, # ? - '゚ ': 65119, - 'ٜ': 65120, - '↪': 65121, - ' ̛': 65122, -} - - - -def my_keyboard_mapping(display): - """Generates a mapping from *keysyms* to *key codes* and required - modifier shift states. - - :param Xlib.display.Display display: The display for which to retrieve the - keyboard mapping. - - :return: the keyboard mapping - """ - mapping = {} - - shift_mask = 1 << 0 - group_mask = alt_gr_mask(display) - - # Iterate over all keysym lists in the keyboard mapping - min_keycode = display.display.info.min_keycode - keycode_count = display.display.info.max_keycode - min_keycode + 1 - for index, keysyms in enumerate(display.get_keyboard_mapping( - min_keycode, keycode_count)): - key_code = index + min_keycode - - # Normalise the keysym list to yield a tuple containing the two groups - normalized = keysym_normalize(keysyms) - if not normalized: - continue - - # Iterate over the groups to extract the shift and modifier state - for groups, group in zip(normalized, (False, True)): - for keysym, shift in zip(groups, (False, True)): - - if not keysym: - continue - shift_state = 0 \ - | (shift_mask if shift else 0) \ - | (group_mask if group else 0) - - # !!!: Save all keycode combinations of keysym - if keysym in mapping: - mapping[keysym].append((key_code, shift_state)) - else: - mapping[keysym] = [(key_code, shift_state)] - return mapping - - -class MyController(Controller): - def _update_keyboard_mapping(self): - """Updates the keyboard mapping. - """ - with display_manager(self._display) as dm: - self._keyboard_mapping = my_keyboard_mapping(dm) - - def send_event(self, event, keycode, shift_state): - with display_manager(self._display) as dm, self.modifiers as modifiers: - # Under certain cimcumstances, such as when running under Xephyr, - # the value returned by dm.get_input_focus is an int - window = dm.get_input_focus().focus - send_event = getattr( - window, - 'send_event', - lambda event: dm.send_event(window, event)) - send_event(event( - detail=keycode, - state=shift_state | self._shift_mask(modifiers), - time=0, - root=dm.screen().root, - window=window, - same_screen=0, - child=Xlib.X.NONE, - root_x=0, root_y=0, event_x=0, event_y=0)) - - def fake_input(self, keycode, is_press): - with display_manager(self._display) as dm: - Xlib.ext.xtest.fake_input( - dm, - Xlib.X.KeyPress if is_press else Xlib.X.KeyRelease, - keycode) - - def _handle(self, key, is_press): - """Resolves a key identifier and sends a keyboard event. - :param event: The *X* keyboard event. - :param int keysym: The keysym to handle. - """ - event = Xlib.display.event.KeyPress if is_press \ - else Xlib.display.event.KeyRelease - keysym = self._keysym(key) - - if key.vk is not None: - keycode = self._display.keysym_to_keycode(key.vk) - self.fake_input(keycode, is_press) - # Otherwise use XSendEvent; we need to use this in the general case to - # work around problems with keyboard layouts - self._emit('_on_fake_event', key, is_press) - return - - # Make sure to verify that the key was resolved - if keysym is None: - raise self.InvalidKeyException(key) - - # There may be multiple keycodes for keysym in keyboard_mapping - keycode_flag = len(self.keyboard_mapping[keysym]) == 1 - if keycode_flag: - keycode, shift_state = self.keyboard_mapping[keysym][0] - else: - keycode, shift_state = self._display.keysym_to_keycode(keysym), 0 - - keycode_set = set(map(lambda x: x[0], self.keyboard_mapping[keysym])) - # The keycode of the dead key is inconsistent, The keysym has multiple combinations of a keycode. - if keycode != self._display.keysym_to_keycode(keysym) \ - or (keycode_flag == False and keycode == list(keycode_set)[0] and len(keycode_set) == 1): - deakkey_chr = str(key).replace("'", '') - keysym = DEAD_KEYS[deakkey_chr] - keycode, shift_state = self.keyboard_mapping[keysym][0] - - # If the key has a virtual key code, use that immediately with - # fake_input; fake input,being an X server extension, has access to - # more internal state that we do - - try: - with self.modifiers as modifiers: - alt_gr = Key.alt_gr in modifiers - # !!!: Send_event can't support lock screen, this condition cann't be modified - if alt_gr: - self.send_event( - event, keycode, shift_state) - else: - self.fake_input(keycode, is_press) - except KeyError: - with self._borrow_lock: - keycode, index, count = self._borrows[keysym] - self._send_key( - event, - keycode, - index_to_shift(self._display, index)) - count += 1 if is_press else -1 - self._borrows[keysym] = (keycode, index, count) - - # Notify any running listeners - self._emit('_on_fake_event', key, is_press) - - -keyboard = MyController() - -server_address = sys.argv[1] -if not os.path.exists(os.path.dirname(server_address)): - os.makedirs(os.path.dirname(server_address)) - -try: - os.unlink(server_address) -except OSError: - if os.path.exists(server_address): - raise - -server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) -server.bind(server_address) -server.listen(1) -clientsocket, address = server.accept() -os.system('chmod a+rw %s' % server_address) -print("Got pynput connection") - - -def loop(): - global keyboard - buf = [] - while True: - data = clientsocket.recv(1024) - if not data: - print("Connection broken") - break - buf.extend(data) - while buf: - n = buf[0] - n = n + 1 - if len(buf) < n: - break - msg = bytearray(buf[1:n]).decode("utf-8") - buf = buf[n:] - if len(msg) < 2: - continue - if msg[1] == "\0": - keyboard = MyController() - print("Keyboard reset") - continue - if len(msg) == 2: - name = msg[1] - else: - name = KeyCode._from_symbol(msg[1:]) - if str(name) == "<0>": - continue - try: - if msg[0] == "p": - keyboard.press(name) - else: - keyboard.release(name) - except Exception as e: - print('[x] error key',e) - - -loop() -clientsocket.close() -server.close() diff --git a/rpm-suse.spec b/rpm-suse.spec index 73a610c11..db4bfe66f 100644 --- a/rpm-suse.spec +++ b/rpm-suse.spec @@ -25,7 +25,6 @@ install $HBB/libsciter-gtk.so %{buildroot}/usr/lib/rustdesk/libsciter-gtk.so install $HBB/rustdesk.service %{buildroot}/usr/share/rustdesk/files/ install $HBB/128x128@2x.png %{buildroot}/usr/share/rustdesk/files/rustdesk.png install $HBB/rustdesk.desktop %{buildroot}/usr/share/rustdesk/files/ -install $HBB/pynput_service.py %{buildroot}/usr/share/rustdesk/files/ %files /usr/bin/rustdesk @@ -33,7 +32,6 @@ install $HBB/pynput_service.py %{buildroot}/usr/share/rustdesk/files/ /usr/share/rustdesk/files/rustdesk.service /usr/share/rustdesk/files/rustdesk.png /usr/share/rustdesk/files/rustdesk.desktop -/usr/share/rustdesk/files/pynput_service.py %changelog # let's skip this for now @@ -54,7 +52,6 @@ esac %post cp /usr/share/rustdesk/files/rustdesk.service /etc/systemd/system/rustdesk.service cp /usr/share/rustdesk/files/rustdesk.desktop /usr/share/applications/ -sudo -H pip3 install pynput systemctl daemon-reload systemctl enable rustdesk systemctl start rustdesk diff --git a/rpm.spec b/rpm.spec index c61db5d0b..37e8ea4cc 100644 --- a/rpm.spec +++ b/rpm.spec @@ -25,7 +25,6 @@ install $HBB/libsciter-gtk.so %{buildroot}/usr/lib/rustdesk/libsciter-gtk.so install $HBB/rustdesk.service %{buildroot}/usr/share/rustdesk/files/ install $HBB/128x128@2x.png %{buildroot}/usr/share/rustdesk/files/rustdesk.png install $HBB/rustdesk.desktop %{buildroot}/usr/share/rustdesk/files/ -install $HBB/pynput_service.py %{buildroot}/usr/share/rustdesk/files/ %files /usr/bin/rustdesk @@ -33,7 +32,6 @@ install $HBB/pynput_service.py %{buildroot}/usr/share/rustdesk/files/ /usr/share/rustdesk/files/rustdesk.service /usr/share/rustdesk/files/rustdesk.png /usr/share/rustdesk/files/rustdesk.desktop -/usr/share/rustdesk/files/pynput_service.py /usr/share/rustdesk/files/__pycache__/* %changelog @@ -55,7 +53,6 @@ esac %post cp /usr/share/rustdesk/files/rustdesk.service /etc/systemd/system/rustdesk.service cp /usr/share/rustdesk/files/rustdesk.desktop /usr/share/applications/ -sudo -H pip3 install pynput systemctl daemon-reload systemctl enable rustdesk systemctl start rustdesk diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 05dfa3270..24c182fd3 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.62.0" +channel = "1.62.0" \ No newline at end of file diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 310c6f3f6..24882ce4f 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -108,13 +108,7 @@ parts: plugin: nil override-pull: | mkdir -p ${SNAPCRAFT_PART_INSTALL}/usr/share/rustdesk/files/systemd/ - cp ${SNAPCRAFT_PART_SRC}/../../rustdesk/src/pynput_service.py ${SNAPCRAFT_PART_INSTALL}/usr/share/rustdesk/files/ cp ${SNAPCRAFT_PART_SRC}/../../rustdesk/src/rustdesk.service ${SNAPCRAFT_PART_INSTALL}/usr/share/rustdesk/files/systemd/ - - python3-deps: - plugin: python - python-packages: - - pynput == 1.7.6 layout: /usr/share/rustdesk: diff --git a/src/client.rs b/src/client.rs index a4a864846..a625efb31 100644 --- a/src/client.rs +++ b/src/client.rs @@ -154,7 +154,8 @@ impl Client { return Err(err); } } - Ok(x) => Ok(x), + Ok(x) => { + Ok(x)}, } } @@ -1707,7 +1708,7 @@ pub enum Data { } /// Keycode for key events. -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum Key { ControlKey(ControlKey), Chr(u32), diff --git a/src/common.rs b/src/common.rs index 471d6d4e2..68656853a 100644 --- a/src/common.rs +++ b/src/common.rs @@ -666,3 +666,14 @@ pub fn make_privacy_mode_msg(state: back_notification::PrivacyModeState) -> Mess msg_out.set_misc(misc); msg_out } + +#[cfg(not(target_os = "linux"))] +lazy_static::lazy_static! { + pub static ref IS_X11: Mutex = Mutex::new(false); + +} + +#[cfg(target_os = "linux")] +lazy_static::lazy_static! { + pub static ref IS_X11: Mutex = Mutex::new("x11" == hbb_common::platform::linux::get_display_server()); +} \ No newline at end of file diff --git a/src/flutter.rs b/src/flutter.rs index 1c4ed8869..4be998027 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -475,4 +475,4 @@ pub fn make_fd_flutter(id: i32, entries: &Vec, only_count: bool) -> S } m.insert("total_size".into(), json!(n as f64)); serde_json::to_string(&m).unwrap_or("".into()) -} +} \ No newline at end of file diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 04d8619c1..977c03197 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -17,7 +17,7 @@ use crate::flutter::{self, SESSIONS}; use crate::start_server; use crate::ui_interface; #[cfg(not(any(target_os = "android", target_os = "ios")))] -use crate::ui_interface::{change_id, check_connect_status, is_ok_change_id}; +use crate::ui_interface::change_id; use crate::ui_interface::{ check_mouse_time, check_super_user_permission, discover, forget_password, get_api_server, get_app_name, get_async_job_status, get_connect_status, get_fav, get_id, get_lan_peers, @@ -104,9 +104,9 @@ pub fn stop_global_event_stream(app_type: String) { .remove(&app_type); } -pub fn host_stop_system_key_propagate(stopped: bool) { +pub fn host_stop_system_key_propagate(_stopped: bool) { #[cfg(windows)] - crate::platform::windows::stop_system_key_propagate(stopped); + crate::platform::windows::stop_system_key_propagate(_stopped); } // FIXME: -> ResultType<()> cannot be parsed by frb_codegen @@ -233,6 +233,28 @@ pub fn session_switch_display(id: String, value: i32) { } } +pub fn session_handle_flutter_key_event( + id: String, + name: String, + keycode: i32, + scancode: i32, + down_or_up: bool, +) { + if let Some(session) = SESSIONS.read().unwrap().get(&id) { + session.handle_flutter_key_event(&name, keycode, scancode, down_or_up); + } +} + +pub fn session_enter_or_leave(id: String, enter: bool) { + if let Some(session) = SESSIONS.read().unwrap().get(&id) { + if enter { + session.enter(); + } else { + session.leave(); + } + } +} + pub fn session_input_key( id: String, name: String, @@ -274,6 +296,19 @@ pub fn session_get_peer_option(id: String, name: String) -> String { "".to_string() } +pub fn session_get_keyboard_name(id: String) -> String { + if let Some(session) = SESSIONS.read().unwrap().get(&id) { + return session.get_keyboard_mode(); + } + "legacy".to_string() +} + +pub fn session_set_keyboard_mode(id: String, keyboard_mode: String) { + if let Some(session) = SESSIONS.read().unwrap().get(&id) { + session.save_keyboard_mode(keyboard_mode); + } +} + pub fn session_input_os_password(id: String, value: String) { if let Some(session) = SESSIONS.read().unwrap().get(&id) { session.input_os_password(value, true); diff --git a/src/lang/cn.rs b/src/lang/cn.rs index c6efaee85..ae55b9fab 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", "忽略电池优化"), ("android_open_battery_optimizations_tip", "如需关闭此功能,请在接下来的RustDesk应用设置页面中,找到并进入 [电源] 页面,取消勾选 [不受限制]"), ("Connection not allowed", "对方不允许连接"), + ("Legacy mode", "传统模式"), + ("Map mode", "1:1传输"), + ("Translate mode", "翻译模式"), ("Use temporary password", "使用临时密码"), ("Use permanent password", "使用固定密码"), ("Use both passwords", "同时使用两种密码"), diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 99d0ae694..4f49cb113 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", ""), ("android_open_battery_optimizations_tip", ""), ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", ""), ("Use permanent password", ""), ("Use both passwords", ""), diff --git a/src/lang/da.rs b/src/lang/da.rs index 883ef27a5..78db47875 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", ""), ("android_open_battery_optimizations_tip", ""), ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", ""), ("Use permanent password", ""), ("Use both passwords", ""), diff --git a/src/lang/de.rs b/src/lang/de.rs index 649199f0d..60caecdd4 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", "Batterieoptimierung ignorieren"), ("android_open_battery_optimizations_tip", "Möchten Sie die Batterieopimierungs-Einstellungen öffnen?"), ("Connection not allowed", "Verbindung abgelehnt"), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", "Temporäres Passwort verwenden"), ("Use permanent password", "Dauerhaftes Passwort verwenden"), ("Use both passwords", "Beide Passwörter verwenden"), diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 34b89c350..95fda5e90 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", ""), ("android_open_battery_optimizations_tip", ""), ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", ""), ("Use permanent password", ""), ("Use both passwords", ""), diff --git a/src/lang/es.rs b/src/lang/es.rs index 82395dd7a..17147a0cf 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -289,6 +289,22 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Keep RustDesk background service", "Dejar RustDesk como Servicio en 2do plano"), ("Ignore Battery Optimizations", "Ignorar optimizacioens de bateria"), ("android_open_battery_optimizations_tip", ""), + ("Random Password After Session", ""), + ("Keep", ""), + ("Update", ""), + ("Disable", ""), + ("Onetime Password", ""), + ("Verification Method", ""), + ("Enable security password", ""), + ("Enable random password", ""), + ("Enable onetime password", ""), + ("Disable onetime password", ""), + ("Activate onetime password", ""), + ("Set security password", ""), + ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Connection not allowed", "Conexión no disponible"), ("Use temporary password", "Usar contraseña temporal"), ("Use permanent password", "Usar contraseña permamente"), diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 00cfe3a3c..8df98de48 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", ""), ("android_open_battery_optimizations_tip", ""), ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", ""), ("Use permanent password", ""), ("Use both passwords", ""), diff --git a/src/lang/hu.rs b/src/lang/hu.rs index d1a259119..84d030eb0 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", ""), ("android_open_battery_optimizations_tip", ""), ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", ""), ("Use permanent password", ""), ("Use both passwords", ""), diff --git a/src/lang/id.rs b/src/lang/id.rs index 3447d3388..a80dd6c22 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -289,6 +289,22 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Keep RustDesk background service", "Pertahankan RustDesk berjalan pada background service"), ("Ignore Battery Optimizations", "Abaikan Pengoptimalan Baterai"), ("android_open_battery_optimizations_tip", ""), + ("Random Password After Session", ""), + ("Keep", ""), + ("Update", ""), + ("Disable", ""), + ("Onetime Password", ""), + ("Verification Method", ""), + ("Enable security password", ""), + ("Enable random password", ""), + ("Enable onetime password", ""), + ("Disable onetime password", ""), + ("Activate onetime password", ""), + ("Set security password", ""), + ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Connection not allowed", "Koneksi tidak dijinkan"), ("Use temporary password", "Gunakan kata sandi sementara"), ("Use permanent password", "Gunakan kata sandi permanaen"), diff --git a/src/lang/it.rs b/src/lang/it.rs index 65cdd4b3d..8bf455d8e 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -318,5 +318,8 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Insecure Connection", "Connessione insicura"), ("Scale original", "Scala originale"), ("Scale adaptive", "Scala adattiva"), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index cbe31bf9f..0c9b6c54d 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -288,6 +288,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", "バッテリーの最適化を無効にする"), ("android_open_battery_optimizations_tip", "この機能を使わない場合は、次のRestDeskアプリ設定ページから「バッテリー」に進み、「制限なし」の選択を外してください"), ("Connection not allowed", "接続が許可されていません"), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", "使い捨てのパスワードを使用"), ("Use permanent password", "固定のパスワードを使用"), ("Use both passwords", "どちらのパスワードも使用"), diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index cdd4128b5..b9d3cad70 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", ""), ("android_open_battery_optimizations_tip", ""), ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", ""), ("Use permanent password", ""), ("Use both passwords", ""), diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 5bbdd846d..4a0c8413c 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", "Игнорировать оптимизацию батареи"), ("android_open_battery_optimizations_tip", "Перейдите на следующую страницу настроек "), ("Connection not allowed", "Подключение не разрешено"), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", "Использовать временный пароль"), ("Use permanent password", "Использовать постоянный пароль"), ("Use both passwords", "Использовать оба пароля"), diff --git a/src/lang/sk.rs b/src/lang/sk.rs index b92d0aca6..1d083d2cc 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", ""), ("android_open_battery_optimizations_tip", ""), ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", ""), ("Use permanent password", ""), ("Use both passwords", ""), diff --git a/src/lang/template.rs b/src/lang/template.rs index 8cf46a196..dcb2a9566 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", ""), ("android_open_battery_optimizations_tip", ""), ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", ""), ("Use permanent password", ""), ("Use both passwords", ""), diff --git a/src/lang/tr.rs b/src/lang/tr.rs index c5ec537b4..01de89909 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -289,6 +289,22 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Keep RustDesk background service", ""), ("Ignore Battery Optimizations", ""), ("android_open_battery_optimizations_tip", ""), + ("Random Password After Session", ""), + ("Keep", ""), + ("Update", ""), + ("Disable", ""), + ("Onetime Password", ""), + ("Verification Method", ""), + ("Enable security password", ""), + ("Enable random password", ""), + ("Enable onetime password", ""), + ("Disable onetime password", ""), + ("Activate onetime password", ""), + ("Set security password", ""), + ("Connection not allowed", ""), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Connection not allowed", "bağlantıya izin verilmedi"), ("Use temporary password", "Geçici şifre kullan"), ("Use permanent password", "Kalıcı şifre kullan"), diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 836b5ad12..84002b163 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", "忽略電池優化"), ("android_open_battery_optimizations_tip", "如需關閉此功能,請在接下來的RustDesk應用設置頁面中,找到並進入 [電源] 頁面,取消勾選 [不受限制]"), ("Connection not allowed", "對方不允許連接"), + ("Legacy mode", "傳統模式"), + ("Map mode", "1:1傳輸"), + ("Translate mode", "翻譯模式"), ("Use temporary password", "使用臨時密碼"), ("Use permanent password", "使用固定密碼"), ("Use both passwords", "同時使用兩種密碼"), diff --git a/src/lang/vn.rs b/src/lang/vn.rs index ba9e4cb86..a9bc04946 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -290,6 +290,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Ignore Battery Optimizations", "Bỏ qua các tối ưu pin"), ("android_open_battery_optimizations_tip", "Nếu bạn muốn tắt tính năng này, vui lòng chuyển đến trang cài đặt ứng dụng RustDesk tiếp theo, tìm và nhập [Pin], Bỏ chọn [Không hạn chế]"), ("Connection not allowed", "Kết nối không đuợc phép"), + ("Legacy mode", ""), + ("Map mode", ""), + ("Translate mode", ""), ("Use temporary password", "Sử dụng mật khẩu tạm thời"), ("Use permanent password", "Sử dụng mật khẩu vĩnh viễn"), ("Use both passwords", "Sử dụng cả hai mật khẩu"), diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 08a1316f0..9fc59816f 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use std::{ net::SocketAddr, sync::{ @@ -10,12 +9,10 @@ use std::{ use uuid::Uuid; -use hbb_common::config::DiscoveryPeer; use hbb_common::tcp::FramedStream; use hbb_common::{ allow_err, anyhow::bail, - config, config::{Config, REG_INTERVAL, RENDEZVOUS_PORT, RENDEZVOUS_TIMEOUT}, futures::future::join_all, log, @@ -571,6 +568,7 @@ pub fn get_mac() -> String { "".to_owned() } +#[allow(dead_code)] fn lan_discovery() -> ResultType<()> { let addr = SocketAddr::from(([0, 0, 0, 0], get_broadcast_port())); let socket = std::net::UdpSocket::bind(addr)?; @@ -640,7 +638,7 @@ pub async fn query_online_states, Vec)>(ids: Vec ResultType { - let (mut rendezvous_server, servers, contained) = crate::get_rendezvous_server(1_000).await; + let (rendezvous_server, _servers, _contained) = crate::get_rendezvous_server(1_000).await; let tmp: Vec<&str> = rendezvous_server.split(":").collect(); if tmp.len() != 2 { bail!("Invalid server address: {}", rendezvous_server); diff --git a/src/server/connection.rs b/src/server/connection.rs index d4e353a16..d93d6d775 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -448,11 +448,12 @@ impl Connection { handle_mouse(&msg, id); } MessageInput::Key((mut msg, press)) => { - if press { + // todo: press and down have similar meanings. + if press && msg.mode.unwrap() == KeyboardMode::Legacy { msg.down = true; } handle_key(&msg); - if press { + if press && msg.mode.unwrap() == KeyboardMode::Legacy { msg.down = false; handle_key(&msg); } @@ -632,7 +633,7 @@ impl Connection { let mut pi = PeerInfo { username: username.clone(), conn_id: self.inner.id, - version: crate::VERSION.to_owned(), + version: VERSION.to_owned(), ..Default::default() }; diff --git a/src/server/input_service.rs b/src/server/input_service.rs index e63b6290e..d78441a18 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -1,8 +1,10 @@ use super::*; +use crate::common::IS_X11; #[cfg(target_os = "macos")] use dispatch::Queue; use enigo::{Enigo, Key, KeyboardControllable, MouseButton, MouseControllable}; use hbb_common::{config::COMPRESS_LEVEL, protobuf::EnumOrUnknown}; +use rdev::{simulate, EventType, Key as RdevKey}; use std::{ convert::TryFrom, sync::atomic::{AtomicBool, Ordering}, @@ -21,8 +23,6 @@ impl super::service::Reset for StateCursor { *self = Default::default(); crate::platform::reset_input_cache(); fix_key_down_timeout(true); - #[cfg(target_os = "linux")] - ENIGO.lock().unwrap().reset(); } } @@ -145,7 +145,8 @@ fn run_cursor(sp: MouseCursorService, state: &mut StateCursor) -> ResultType<()> msg = cached.clone(); } else { let mut data = crate::get_cursor_data(hcursor)?; - data.colors = hbb_common::compress::compress(&data.colors[..], COMPRESS_LEVEL).into(); + data.colors = + hbb_common::compress::compress(&data.colors[..], COMPRESS_LEVEL).into(); let mut tmp = Message::new(); tmp.set_cursor_data(data); msg = Arc::new(tmp); @@ -166,13 +167,6 @@ fn run_cursor(sp: MouseCursorService, state: &mut StateCursor) -> ResultType<()> lazy_static::lazy_static! { static ref ENIGO: Arc> = { - #[cfg(target_os = "linux")] - { - if crate::platform::is_root() { - std::env::set_var("PYNPUT_USERNAME", crate::platform::linux::get_active_username()); - std::env::set_var("PYNPUT_USERID", crate::platform::linux::get_active_userid()); - } - } Arc::new(Mutex::new(Enigo::new())) }; static ref KEYS_DOWN: Arc>> = Default::default(); @@ -466,10 +460,14 @@ pub async fn lock_screen() { // loginctl lock-session also not work, they both work run rustdesk from cmd std::thread::spawn(|| { let mut key_event = KeyEvent::new(); - key_event.down = true; + key_event.set_chr('l' as _); key_event.modifiers.push(ControlKey::Meta.into()); + key_event.mode = KeyboardMode::Legacy.into(); + + key_event.down = true; handle_key(&key_event); + key_event.down = false; handle_key(&key_event); }); @@ -477,10 +475,13 @@ pub async fn lock_screen() { // CGSession -suspend not real lock screen, it is user switch std::thread::spawn(|| { let mut key_event = KeyEvent::new(); - key_event.down = true; + key_event.set_chr('q' as _); key_event.modifiers.push(ControlKey::Meta.into()); key_event.modifiers.push(ControlKey::Control.into()); + key_event.mode = KeyboardMode::Legacy.into(); + + key_event.down = true; handle_key(&key_event); key_event.down = false; handle_key(&key_event); @@ -597,25 +598,125 @@ pub fn handle_key(evt: &KeyEvent) { handle_key_(evt); } -fn handle_key_(evt: &KeyEvent) { - if EXITING.load(Ordering::SeqCst) { +fn rdev_key_down_or_up(key: RdevKey, down_or_up: bool) { + let event_type = match down_or_up { + true => EventType::KeyPress(key), + false => EventType::KeyRelease(key), + }; + let delay = std::time::Duration::from_millis(20); + match simulate(&event_type) { + Ok(()) => (), + Err(_simulate_error) => { + log::error!("Could not send {:?}", &event_type); + } + } + // Let ths OS catchup (at least MacOS) + std::thread::sleep(delay); +} + +fn rdev_key_click(key: RdevKey) { + rdev_key_down_or_up(key, true); + rdev_key_down_or_up(key, false); +} + +fn sync_status(evt: &KeyEvent) -> (bool, bool) { + let mut en = ENIGO.lock().unwrap(); + + // remote caps status + let caps_locking = evt + .modifiers + .iter() + .position(|&r| r == ControlKey::CapsLock.into()) + .is_some(); + // remote numpad status + let num_locking = evt + .modifiers + .iter() + .position(|&r| r == ControlKey::NumLock.into()) + .is_some(); + + let click_capslock = (caps_locking && !en.get_key_state(enigo::Key::CapsLock)) + || (!caps_locking && en.get_key_state(enigo::Key::CapsLock)); + let click_numlock = (num_locking && !en.get_key_state(enigo::Key::NumLock)) + || (!num_locking && en.get_key_state(enigo::Key::NumLock)); + return (click_capslock, click_numlock); +} + +fn map_keyboard_mode(evt: &KeyEvent) { + // map mode(1): Send keycode according to the peer platform. + let (click_capslock, click_numlock) = sync_status(evt); + + // Wayland + #[cfg(target_os = "linux")] + if !*IS_X11.lock().unwrap() { + let mut en = ENIGO.lock().unwrap(); + let code = evt.chr() as u16; + + #[cfg(not(target_os = "macos"))] + if click_capslock { + en.key_click(enigo::Key::CapsLock); + } + #[cfg(not(target_os = "macos"))] + if click_numlock { + en.key_click(enigo::Key::NumLock); + } + #[cfg(target_os = "macos")] + en.key_down(enigo::Key::CapsLock); + + if evt.down { + en.key_down(enigo::Key::Raw(code)).ok(); + } else { + en.key_up(enigo::Key::Raw(code)); + } return; } + + #[cfg(not(target_os = "macos"))] + if click_capslock { + rdev_key_click(RdevKey::CapsLock); + } + #[cfg(not(target_os = "macos"))] + if click_numlock { + rdev_key_click(RdevKey::NumLock); + } + #[cfg(target_os = "macos")] + if evt.down && click_capslock { + rdev_key_down_or_up(RdevKey::CapsLock, evt.down); + } + + rdev_key_down_or_up(RdevKey::Unknown(evt.chr()), evt.down); + return; +} + +fn legacy_keyboard_mode(evt: &KeyEvent) { + let (click_capslock, click_numlock) = sync_status(evt); + #[cfg(windows)] crate::platform::windows::try_change_desktop(); let mut en = ENIGO.lock().unwrap(); + if click_capslock { + en.key_click(Key::CapsLock); + } + if click_numlock { + en.key_click(Key::NumLock); + } // disable numlock if press home etc when numlock is on, // because we will get numpad value (7,8,9 etc) if not #[cfg(windows)] let mut disable_numlock = false; #[cfg(target_os = "macos")] en.reset_flag(); + // When long-pressed the command key, then press and release + // the Tab key, there should be CGEventFlagCommand in the flag. + #[cfg(target_os = "macos")] + for ck in evt.modifiers.iter() { + if let Some(key) = KEY_MAP.get(&ck.value()) { + en.add_flag(key); + } + } #[cfg(not(target_os = "macos"))] let mut to_release = Vec::new(); - #[cfg(not(target_os = "macos"))] - let mut has_cap = false; - #[cfg(windows)] - let mut has_numlock = false; + if evt.down { let ck = if let Some(key_event::Union::ControlKey(ck)) = evt.union { ck.value() @@ -637,40 +738,16 @@ fn handle_key_(evt: &KeyEvent) { continue; } } - #[cfg(target_os = "macos")] - en.add_flag(key); #[cfg(not(target_os = "macos"))] - { - if key == &Key::CapsLock { - has_cap = true; - } else if key == &Key::NumLock { - #[cfg(windows)] - { - has_numlock = true; - } - } else { - if !get_modifier_state(key.clone(), &mut en) { - en.key_down(key.clone()).ok(); - modifier_sleep(); - to_release.push(key); - } - } + if !get_modifier_state(key.clone(), &mut en) { + en.key_down(key.clone()).ok(); + modifier_sleep(); + to_release.push(key); } } } } - #[cfg(not(target_os = "macos"))] - if has_cap != en.get_key_state(Key::CapsLock) { - en.key_down(Key::CapsLock).ok(); - en.key_up(Key::CapsLock); - } - #[cfg(windows)] - if crate::common::valid_for_numlock(evt) { - if has_numlock != en.get_key_state(Key::NumLock) { - en.key_down(Key::NumLock).ok(); - en.key_up(Key::NumLock); - } - } + match evt.union { Some(key_event::Union::ControlKey(ck)) => { if let Some(key) = KEY_MAP.get(&ck.value()) { @@ -683,7 +760,7 @@ fn handle_key_(evt: &KeyEvent) { } } if evt.down { - allow_err!(en.key_down(key.clone())); + en.key_down(key.clone()).ok(); KEYS_DOWN .lock() .unwrap() @@ -719,6 +796,10 @@ fn handle_key_(evt: &KeyEvent) { en.key_sequence(&x); } } + KEYS_DOWN + .lock() + .unwrap() + .insert(chr as u64 + KEY_CHAR_START, Instant::now()); } else { en.key_up(get_layout(chr)); KEYS_DOWN @@ -741,10 +822,26 @@ fn handle_key_(evt: &KeyEvent) { for key in to_release { en.key_up(key.clone()); } - #[cfg(windows)] - if disable_numlock { - en.key_down(Key::NumLock).ok(); - en.key_up(Key::NumLock); +} + +fn handle_key_(evt: &KeyEvent) { + if EXITING.load(Ordering::SeqCst) { + return; + } + + match evt.mode.unwrap() { + KeyboardMode::Legacy => { + legacy_keyboard_mode(evt); + } + KeyboardMode::Map => { + map_keyboard_mode(evt); + } + KeyboardMode::Translate => { + legacy_keyboard_mode(evt); + } + _ => { + legacy_keyboard_mode(evt); + } } } @@ -759,3 +856,52 @@ async fn send_sas() -> ResultType<()> { timeout(1000, stream.send(&crate::ipc::Data::SAS)).await??; Ok(()) } + +#[cfg(test)] +mod test { + use super::*; + use rdev::{listen, Event, EventType, Key}; + use std::sync::mpsc; + + #[test] + fn test_handle_key() { + // listen + let (tx, rx) = mpsc::channel(); + std::thread::spawn(move || { + std::env::set_var("KEYBOARD_ONLY", "y"); + let func = move |event: Event| { + tx.send(event).ok(); + }; + if let Err(error) = listen(func) { + println!("Error: {:?}", error); + } + }); + // set key/char base on char + let mut evt = KeyEvent::new(); + evt.set_chr(66); + evt.mode = KeyboardMode::Legacy.into(); + + evt.modifiers.push(ControlKey::CapsLock.into()); + + // press + evt.down = true; + handle_key(&evt); + if let Ok(listen_evt) = rx.recv() { + assert_eq!(listen_evt.event_type, EventType::KeyPress(Key::Num1)) + } + // release + evt.down = false; + handle_key(&evt); + if let Ok(listen_evt) = rx.recv() { + assert_eq!(listen_evt.event_type, EventType::KeyRelease(Key::Num1)) + } + } + #[test] + fn test_get_key_state() { + let mut en = ENIGO.lock().unwrap(); + println!( + "[*] test_get_key_state: {:?}", + en.get_key_state(enigo::Key::NumLock) + ); + } +} diff --git a/src/server/uinput.rs b/src/server/uinput.rs index 7a6d47cff..5051d548d 100644 --- a/src/server/uinput.rs +++ b/src/server/uinput.rs @@ -350,6 +350,14 @@ pub mod service { DataKeyboard::Sequence(_seq) => { // ignore } + DataKeyboard::KeyDown(enigo::Key::Raw(code)) => { + let down_event = InputEvent::new(EventType::KEY, *code - 8, 1); + allow_err!(keyboard.emit(&[down_event])); + } + DataKeyboard::KeyUp(enigo::Key::Raw(code)) => { + let down_event = InputEvent::new(EventType::KEY, *code - 8, 0); + allow_err!(keyboard.emit(&[down_event])); + } DataKeyboard::KeyDown(key) => { if let Ok(k) = map_key(key) { let down_event = InputEvent::new(EventType::KEY, k.code(), 1); @@ -378,6 +386,14 @@ pub mod service { false } } + } else if enigo::Key::NumLock == *key { + match keyboard.get_led_state() { + Ok(leds) => leds.contains(evdev::LedType::LED_NUML), + Err(_e) => { + // log::debug!("Failed to get led state {}", &_e); + false + } + } } else { match keyboard.get_key_state() { Ok(keys) => match key { @@ -393,7 +409,6 @@ pub mod service { keys.contains(evdev::Key::KEY_LEFTALT) || keys.contains(evdev::Key::KEY_RIGHTALT) } - enigo::Key::NumLock => keys.contains(evdev::Key::KEY_NUMLOCK), enigo::Key::Meta => { keys.contains(evdev::Key::KEY_LEFTMETA) || keys.contains(evdev::Key::KEY_RIGHTMETA) diff --git a/src/ui.rs b/src/ui.rs index 96cf21f20..25ad18521 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -9,17 +9,16 @@ use sciter::Value; use hbb_common::{ allow_err, - config::{self, Config, LocalConfig, PeerConfig, RENDEZVOUS_PORT, RENDEZVOUS_TIMEOUT}, + config::{self, Config, PeerConfig, RENDEZVOUS_PORT, RENDEZVOUS_TIMEOUT}, futures::future::join_all, log, protobuf::Message as _, rendezvous_proto::*, - sleep, tcp::FramedStream, tokio::{self, sync::mpsc, time}, }; -use crate::common::{get_app_name, SOFTWARE_UPDATE_URL}; +use crate::common::{get_app_name}; use crate::ipc; use crate::ui_interface::{ check_mouse_time, closing, create_shortcut, current_is_wayland, fix_login_wayland, @@ -59,6 +58,27 @@ lazy_static::lazy_static! { struct UIHostHandler; +fn check_connect_status( + reconnect: bool, +) -> ( + Arc>, + Arc>>, + mpsc::UnboundedSender, + Arc>, +) { + let status = Arc::new(Mutex::new((0, false, 0, "".to_owned()))); + let options = Arc::new(Mutex::new(Config::get_options())); + let cloned = status.clone(); + let cloned_options = options.clone(); + let (tx, rx) = mpsc::unbounded_channel::(); + let password = Arc::new(Mutex::new(String::default())); + let cloned_password = password.clone(); + std::thread::spawn(move || { + crate::ui_interface::check_connect_status_(reconnect, rx) + }); + (status, options, tx, password) +} + pub fn start(args: &mut [String]) { #[cfg(target_os = "macos")] if args.len() == 1 && args[0] == "--server" { @@ -87,7 +107,7 @@ pub fn start(args: &mut [String]) { } #[cfg(windows)] if args.len() > 0 && args[0] == "--tray" { - let options = crate::ui_interface::check_connect_status(false).1; + let options = check_connect_status(false).1; crate::tray::start_tray(options); return; } diff --git a/src/ui/common.tis b/src/ui/common.tis index aae950c2d..69e5565f0 100644 --- a/src/ui/common.tis +++ b/src/ui/common.tis @@ -155,6 +155,7 @@ var svg_send = var svg_chat = ; +var svg_keyboard = ; function scrollToBottom(el) { var y = el.box(#height, #content) - el.box(#height, #client); diff --git a/src/ui/header.tis b/src/ui/header.tis index 7ff160e6d..b274b0464 100644 --- a/src/ui/header.tis +++ b/src/ui/header.tis @@ -139,11 +139,22 @@ class Header: Reactor.Component { {svg_chat} {svg_action} {svg_display} + {svg_keyboard} + {this.renderKeyboardPop()} {this.renderDisplayPop()} {this.renderActionPop()} ; } + function renderKeyboardPop(){ + return + +
  • {svg_checkmark}{translate('Legacy mode')}
  • +
  • {svg_checkmark}{translate('Map mode')}
  • + +
    ; + } + function renderDisplayPop() { var codecs = handler.supported_hwcodec(); var show_codec = handler.has_hwcodec() && (codecs[0] || codecs[1]); @@ -263,6 +274,11 @@ class Header: Reactor.Component { me.popup(menu); } + event click $(#keyboard) (_, me) { + var menu = $(menu#keyboard-options); + me.popup(menu); + } + event click $(#screen) (_, me) { if (pi.current_display == me.index) return; handler.switch_display(me.index); @@ -352,6 +368,17 @@ class Header: Reactor.Component { toggleMenuState(); } } + + event click $(menu#keyboard-options>li) (_, me) { + if (me.id == "legacy") { + handler.save_keyboard_mode("legacy"); + } else if (me.id == "map") { + handler.save_keyboard_mode("map"); + } else if (me.id == "translate") { + handler.save_keyboard_mode("translate"); + } + toggleMenuState() + } } function handle_custom_image_quality() { @@ -375,12 +402,17 @@ function toggleMenuState() { var s = handler.get_view_style(); if (!s) s = "original"; values.push(s); + var k = handler.get_keyboard_mode(); + values.push(k); var c = handler.get_option("codec-preference"); if (!c) c = "auto"; values.push(c); for (var el in $$(menu#display-options li)) { el.attributes.toggleClass("selected", values.indexOf(el.id) >= 0); } + for (var el in $$(menu#keyboard-options>li)) { + el.attributes.toggleClass("selected", values.indexOf(el.id) >= 0); + } for (var id in ["show-remote-cursor", "show-quality-monitor", "disable-audio", "enable-file-transfer", "disable-clipboard", "lock-after-session-end"]) { var el = self.select('#' + id); if (el) { diff --git a/src/ui/remote.rs b/src/ui/remote.rs index c6a36f5c6..9cf04b69a 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -1,7 +1,7 @@ use std::{ collections::HashMap, ops::{Deref, DerefMut}, - sync::{atomic::Ordering, Arc, Mutex}, + sync::{Arc, Mutex}, }; use sciter::{ @@ -28,7 +28,7 @@ use hbb_common::{ use crate::clipboard_file::*; use crate::{ client::*, - ui_session_interface::{InvokeUiSession, Session, IS_IN}, + ui_session_interface::{InvokeUiSession, Session}, }; type Video = AssetPtr; @@ -399,6 +399,8 @@ impl sciter::EventHandler for SciterSession { fn get_remember(); fn peer_platform(); fn set_write_override(i32, i32, bool, bool, bool); + fn get_keyboard_mode(); + fn save_keyboard_mode(String); fn has_hwcodec(); fn supported_hwcodec(); fn change_prefer_codec(); @@ -560,18 +562,6 @@ impl SciterSession { self.close_state.insert(k, v); } - fn enter(&mut self) { - #[cfg(windows)] - crate::platform::windows::stop_system_key_propagate(true); - IS_IN.store(true, Ordering::SeqCst); - } - - fn leave(&mut self) { - #[cfg(windows)] - crate::platform::windows::stop_system_key_propagate(false); - IS_IN.store(false, Ordering::SeqCst); - } - fn get_key_event(&self, down_or_up: i32, name: &str, code: i32) -> Option { let mut key_event = KeyEvent::new(); if down_or_up == 2 { @@ -732,4 +722,4 @@ pub fn make_fd(id: i32, entries: &Vec, only_count: bool) -> Value { m.set_item("num_entries", entries.len() as i32); m.set_item("total_size", n as f64); m -} +} \ No newline at end of file diff --git a/src/ui_interface.rs b/src/ui_interface.rs index b8d59ac8f..186381ce4 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -683,6 +683,7 @@ pub fn check_super_user_permission() -> bool { true } +#[allow(dead_code)] pub fn check_zombie(childs: Childs) { let mut deads = Vec::new(); loop { @@ -714,7 +715,7 @@ pub(crate) fn check_connect_status(reconnect: bool) -> mpsc::UnboundedSender) { +pub(crate) async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver) { let mut key_confirmed = false; let mut rx = rx; let mut mouse_time = 0; diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index f1444f4c3..7eabe1510 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -6,18 +6,16 @@ use crate::client::{ load_config, send_mouse, start_video_audio_threads, FileManager, Key, LoginConfigHandler, QualityStatus, KEY_MAP, SERVER_KEYBOARD_ENABLED, }; -use crate::common; use crate::{client::Data, client::Interface}; use async_trait::async_trait; - use hbb_common::config::{Config, LocalConfig, PeerConfig}; - use hbb_common::rendezvous_proto::ConnType; use hbb_common::tokio::{self, sync::mpsc}; +use rdev::{Event, EventType::*, Key as RdevKey, Keyboard as RdevKeyboard, KeyboardState}; use hbb_common::{allow_err, message_proto::*}; use hbb_common::{fs, get_version_number, log, Stream}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::ops::{Deref, DerefMut}; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::{Arc, Mutex, RwLock}; @@ -29,6 +27,12 @@ static KEYBOARD_HOOKED: AtomicBool = AtomicBool::new(false); #[cfg(windows)] static mut IS_ALT_GR: bool = false; +#[cfg(not(any(target_os = "android", target_os = "ios")))] +lazy_static::lazy_static! { + static ref TO_RELEASE: Arc>> = Arc::new(Mutex::new(HashSet::::new())); + static ref KEYBOARD: Arc> = Arc::new(Mutex::new(RdevKeyboard::new().unwrap())); +} + #[derive(Clone, Default)] pub struct Session { pub cmd: String, @@ -49,12 +53,21 @@ impl Session { pub fn get_image_quality(&self) -> String { self.lc.read().unwrap().image_quality.clone() } - /// Get custom image quality. pub fn get_custom_image_quality(&self) -> Vec { self.lc.read().unwrap().custom_image_quality.clone() } + pub fn get_keyboard_mode(&self) -> String { + return std::env::var("KEYBOARD_MODE") + .unwrap_or(String::from("legacy")) + .to_lowercase(); + } + + pub fn save_keyboard_mode(&self, value: String) { + std::env::set_var("KEYBOARD_MODE", value); + } + pub fn save_view_style(&mut self, value: String) { self.lc.write().unwrap().save_view_style(value); } @@ -233,25 +246,144 @@ impl Session { if self.peer_platform() == "Windows" { let mut key_event = KeyEvent::new(); key_event.set_control_key(ControlKey::CtrlAltDel); - self.key_down_or_up(1, key_event, false, false, false, false); + // todo + key_event.down = true; + self.send_key_event(key_event, KeyboardMode::Legacy); } else { let mut key_event = KeyEvent::new(); key_event.set_control_key(ControlKey::Delete); - self.key_down_or_up(3, key_event, true, true, false, false); + self.legacy_modifiers(&mut key_event, true, true, false, false); + // todo + key_event.press = true; + self.send_key_event(key_event, KeyboardMode::Legacy); } } - pub fn key_down_or_up( + fn send_key_event(&self, mut evt: KeyEvent, keyboard_mode: KeyboardMode) { + // mode: legacy(0), map(1), translate(2), auto(3) + evt.mode = keyboard_mode.into(); + let mut msg_out = Message::new(); + msg_out.set_key_event(evt); + self.send(Data::Message(msg_out)); + } + + #[allow(dead_code)] + fn convert_numpad_keys(&self, key: RdevKey) -> RdevKey { + if get_key_state(enigo::Key::NumLock) { + return key; + } + match key { + RdevKey::Kp0 => RdevKey::Insert, + RdevKey::KpDecimal => RdevKey::Delete, + RdevKey::Kp1 => RdevKey::End, + RdevKey::Kp2 => RdevKey::DownArrow, + RdevKey::Kp3 => RdevKey::PageDown, + RdevKey::Kp4 => RdevKey::LeftArrow, + RdevKey::Kp5 => RdevKey::Clear, + RdevKey::Kp6 => RdevKey::RightArrow, + RdevKey::Kp7 => RdevKey::Home, + RdevKey::Kp8 => RdevKey::UpArrow, + RdevKey::Kp9 => RdevKey::PageUp, + _ => key, + } + } + + fn map_keyboard_mode(&self, down_or_up: bool, key: RdevKey, _evt: Option) { + // map mode(1): Send keycode according to the peer platform. + #[cfg(target_os = "windows")] + let key = if let Some(e) = _evt { + rdev::get_win_key(e.code.into(), e.scan_code) + } else { + key + }; + #[cfg(not(windows))] + let key = self.convert_numpad_keys(key); + + let peer = self.peer_platform(); + let mut key_event = KeyEvent::new(); + // According to peer platform. + let keycode: u32 = if peer == "Linux" { + rdev::linux_keycode_from_key(key).unwrap_or_default().into() + } else if peer == "Windows" { + rdev::win_keycode_from_key(key).unwrap_or_default().into() + } else { + // Without Clear Key on Mac OS + if key == rdev::Key::Clear { + return; + } + rdev::macos_keycode_from_key(key).unwrap_or_default().into() + }; + + key_event.set_chr(keycode); + key_event.down = down_or_up; + + if get_key_state(enigo::Key::CapsLock) { + key_event.modifiers.push(ControlKey::CapsLock.into()); + } + if get_key_state(enigo::Key::NumLock) { + key_event.modifiers.push(ControlKey::NumLock.into()); + } + + self.send_key_event(key_event, KeyboardMode::Map); + } + + fn translate_keyboard_mode(&self, down_or_up: bool, key: RdevKey, evt: Event) { + // translate mode(2): locally generated characters are send to the peer. + + // get char + let string = match KEYBOARD.lock() { + Ok(mut keyboard) => { + let string = keyboard.add(&evt.event_type).unwrap_or_default(); + if keyboard.is_dead() && string == "" && down_or_up == true { + return; + } + string + } + Err(_) => "".to_owned(), + }; + + // maybe two string + let chars = if string == "" { + None + } else { + let chars: Vec = string.chars().collect(); + Some(chars) + }; + + if let Some(chars) = chars { + for chr in chars { + let mut key_event = KeyEvent::new(); + key_event.set_chr(chr as _); + key_event.down = true; + key_event.press = false; + + self.send_key_event(key_event, KeyboardMode::Translate); + } + } else { + let success = if down_or_up == true { + TO_RELEASE.lock().unwrap().insert(key) + } else { + TO_RELEASE.lock().unwrap().remove(&key) + }; + + // AltGr && LeftControl(SpecialKey) without action + if key == RdevKey::AltGr || evt.scan_code == 541 { + return; + } + if success { + self.map_keyboard_mode(down_or_up, key, None); + } + } + } + + fn legacy_modifiers( &self, - down_or_up: i32, - evt: KeyEvent, + key_event: &mut KeyEvent, alt: bool, ctrl: bool, shift: bool, command: bool, ) { - let mut key_event = evt; - if alt && !crate::is_control_key(&key_event, &ControlKey::Alt) && !crate::is_control_key(&key_event, &ControlKey::RAlt) @@ -276,25 +408,253 @@ impl Session { { key_event.modifiers.push(ControlKey::Meta.into()); } - #[cfg(not(any(target_os = "android", target_os = "ios")))] + if get_key_state(enigo::Key::CapsLock) { key_event.modifiers.push(ControlKey::CapsLock.into()); } - #[cfg(not(any(target_os = "android", target_os = "ios")))] if self.peer_platform() != "Mac OS" { - if get_key_state(enigo::Key::NumLock) && common::valid_for_numlock(&key_event) { + if get_key_state(enigo::Key::NumLock) { key_event.modifiers.push(ControlKey::NumLock.into()); } } - if down_or_up == 1 { - key_event.down = true; - } else if down_or_up == 3 { - key_event.press = true; + } + + fn legacy_keyboard_mode(&self, down_or_up: bool, key: RdevKey, evt: Event) { + // legacy mode(0): Generate characters locally, look for keycode on other side. + let peer = self.peer_platform(); + let is_win = peer == "Windows"; + + let alt = get_key_state(enigo::Key::Alt); + #[cfg(windows)] + let ctrl = { + let mut tmp = + get_key_state(enigo::Key::Control) || get_key_state(enigo::Key::RightControl); + unsafe { + if IS_ALT_GR { + if alt || key == RdevKey::AltGr { + if tmp { + tmp = false; + } + } else { + IS_ALT_GR = false; + } + } + } + tmp + }; + #[cfg(not(windows))] + let ctrl = get_key_state(enigo::Key::Control) || get_key_state(enigo::Key::RightControl); + let shift = get_key_state(enigo::Key::Shift) || get_key_state(enigo::Key::RightShift); + #[cfg(windows)] + let command = crate::platform::windows::get_win_key_state(); + #[cfg(not(windows))] + let command = get_key_state(enigo::Key::Meta); + let control_key = match key { + RdevKey::Alt => Some(ControlKey::Alt), + RdevKey::AltGr => Some(ControlKey::RAlt), + RdevKey::Backspace => Some(ControlKey::Backspace), + RdevKey::ControlLeft => { + // when pressing AltGr, an extra VK_LCONTROL with a special + // scancode with bit 9 set is sent, let's ignore this. + #[cfg(windows)] + if evt.scan_code & 0x200 != 0 { + unsafe { + IS_ALT_GR = true; + } + return; + } + Some(ControlKey::Control) + } + RdevKey::ControlRight => Some(ControlKey::RControl), + RdevKey::DownArrow => Some(ControlKey::DownArrow), + RdevKey::Escape => Some(ControlKey::Escape), + RdevKey::F1 => Some(ControlKey::F1), + RdevKey::F10 => Some(ControlKey::F10), + RdevKey::F11 => Some(ControlKey::F11), + RdevKey::F12 => Some(ControlKey::F12), + RdevKey::F2 => Some(ControlKey::F2), + RdevKey::F3 => Some(ControlKey::F3), + RdevKey::F4 => Some(ControlKey::F4), + RdevKey::F5 => Some(ControlKey::F5), + RdevKey::F6 => Some(ControlKey::F6), + RdevKey::F7 => Some(ControlKey::F7), + RdevKey::F8 => Some(ControlKey::F8), + RdevKey::F9 => Some(ControlKey::F9), + RdevKey::LeftArrow => Some(ControlKey::LeftArrow), + RdevKey::MetaLeft => Some(ControlKey::Meta), + RdevKey::MetaRight => Some(ControlKey::RWin), + RdevKey::Return => Some(ControlKey::Return), + RdevKey::RightArrow => Some(ControlKey::RightArrow), + RdevKey::ShiftLeft => Some(ControlKey::Shift), + RdevKey::ShiftRight => Some(ControlKey::RShift), + RdevKey::Space => Some(ControlKey::Space), + RdevKey::Tab => Some(ControlKey::Tab), + RdevKey::UpArrow => Some(ControlKey::UpArrow), + RdevKey::Delete => { + if is_win && ctrl && alt { + self.ctrl_alt_del(); + return; + } + Some(ControlKey::Delete) + } + RdevKey::Apps => Some(ControlKey::Apps), + RdevKey::Cancel => Some(ControlKey::Cancel), + RdevKey::Clear => Some(ControlKey::Clear), + RdevKey::Kana => Some(ControlKey::Kana), + RdevKey::Hangul => Some(ControlKey::Hangul), + RdevKey::Junja => Some(ControlKey::Junja), + RdevKey::Final => Some(ControlKey::Final), + RdevKey::Hanja => Some(ControlKey::Hanja), + RdevKey::Hanji => Some(ControlKey::Hanja), + RdevKey::Convert => Some(ControlKey::Convert), + RdevKey::Print => Some(ControlKey::Print), + RdevKey::Select => Some(ControlKey::Select), + RdevKey::Execute => Some(ControlKey::Execute), + RdevKey::PrintScreen => Some(ControlKey::Snapshot), + RdevKey::Help => Some(ControlKey::Help), + RdevKey::Sleep => Some(ControlKey::Sleep), + RdevKey::Separator => Some(ControlKey::Separator), + RdevKey::KpReturn => Some(ControlKey::NumpadEnter), + RdevKey::Kp0 => Some(ControlKey::Numpad0), + RdevKey::Kp1 => Some(ControlKey::Numpad1), + RdevKey::Kp2 => Some(ControlKey::Numpad2), + RdevKey::Kp3 => Some(ControlKey::Numpad3), + RdevKey::Kp4 => Some(ControlKey::Numpad4), + RdevKey::Kp5 => Some(ControlKey::Numpad5), + RdevKey::Kp6 => Some(ControlKey::Numpad6), + RdevKey::Kp7 => Some(ControlKey::Numpad7), + RdevKey::Kp8 => Some(ControlKey::Numpad8), + RdevKey::Kp9 => Some(ControlKey::Numpad9), + RdevKey::KpDivide => Some(ControlKey::Divide), + RdevKey::KpMultiply => Some(ControlKey::Multiply), + RdevKey::KpDecimal => Some(ControlKey::Decimal), + RdevKey::KpMinus => Some(ControlKey::Subtract), + RdevKey::KpPlus => Some(ControlKey::Add), + RdevKey::CapsLock | RdevKey::NumLock | RdevKey::ScrollLock => { + return; + } + RdevKey::Home => Some(ControlKey::Home), + RdevKey::End => Some(ControlKey::End), + RdevKey::Insert => Some(ControlKey::Insert), + RdevKey::PageUp => Some(ControlKey::PageUp), + RdevKey::PageDown => Some(ControlKey::PageDown), + RdevKey::Pause => Some(ControlKey::Pause), + _ => None, + }; + let mut key_event = KeyEvent::new(); + if let Some(k) = control_key { + key_event.set_control_key(k); + } else { + let mut chr = match evt.name { + Some(ref s) => { + if s.len() <= 2 { + // exclude chinese characters + s.chars().next().unwrap_or('\0') + } else { + '\0' + } + } + _ => '\0', + }; + if chr == '·' { + // special for Chinese + chr = '`'; + } + if chr == '\0' { + chr = match key { + RdevKey::Num1 => '1', + RdevKey::Num2 => '2', + RdevKey::Num3 => '3', + RdevKey::Num4 => '4', + RdevKey::Num5 => '5', + RdevKey::Num6 => '6', + RdevKey::Num7 => '7', + RdevKey::Num8 => '8', + RdevKey::Num9 => '9', + RdevKey::Num0 => '0', + RdevKey::KeyA => 'a', + RdevKey::KeyB => 'b', + RdevKey::KeyC => 'c', + RdevKey::KeyD => 'd', + RdevKey::KeyE => 'e', + RdevKey::KeyF => 'f', + RdevKey::KeyG => 'g', + RdevKey::KeyH => 'h', + RdevKey::KeyI => 'i', + RdevKey::KeyJ => 'j', + RdevKey::KeyK => 'k', + RdevKey::KeyL => 'l', + RdevKey::KeyM => 'm', + RdevKey::KeyN => 'n', + RdevKey::KeyO => 'o', + RdevKey::KeyP => 'p', + RdevKey::KeyQ => 'q', + RdevKey::KeyR => 'r', + RdevKey::KeyS => 's', + RdevKey::KeyT => 't', + RdevKey::KeyU => 'u', + RdevKey::KeyV => 'v', + RdevKey::KeyW => 'w', + RdevKey::KeyX => 'x', + RdevKey::KeyY => 'y', + RdevKey::KeyZ => 'z', + RdevKey::Comma => ',', + RdevKey::Dot => '.', + RdevKey::SemiColon => ';', + RdevKey::Quote => '\'', + RdevKey::LeftBracket => '[', + RdevKey::RightBracket => ']', + RdevKey::BackSlash => '\\', + RdevKey::Minus => '-', + RdevKey::Equal => '=', + RdevKey::BackQuote => '`', + _ => '\0', + } + } + if chr != '\0' { + if chr == 'l' && is_win && command { + self.lock_screen(); + return; + } + key_event.set_chr(chr as _); + } else { + log::error!("Unknown key {:?}", evt); + return; + } + } + + self.legacy_modifiers(&mut key_event, alt, ctrl, shift, command); + + if down_or_up == true { + key_event.down = true; + } + self.send_key_event(key_event, KeyboardMode::Legacy) + } + + fn key_down_or_up(&self, down_or_up: bool, key: RdevKey, evt: Event) { + // Call different functions according to keyboard mode. + let mode = match self.get_keyboard_mode().as_str() { + "map" => KeyboardMode::Map, + "legacy" => KeyboardMode::Legacy, + "translate" => KeyboardMode::Translate, + _ => KeyboardMode::Legacy, + }; + + match mode { + KeyboardMode::Map => { + if down_or_up == true { + TO_RELEASE.lock().unwrap().insert(key); + } else { + TO_RELEASE.lock().unwrap().remove(&key); + } + self.map_keyboard_mode(down_or_up, key, Some(evt)); + } + KeyboardMode::Legacy => self.legacy_keyboard_mode(down_or_up, key, evt), + KeyboardMode::Translate => { + self.translate_keyboard_mode(down_or_up, key, evt); + } + _ => self.legacy_keyboard_mode(down_or_up, key, evt), } - let mut msg_out = Message::new(); - msg_out.set_key_event(key_event); - log::debug!("{:?}", msg_out); - self.send(Data::Message(msg_out)); } pub fn get_platform(&self, is_remote: bool) -> String { @@ -350,7 +710,59 @@ impl Session { pub fn lock_screen(&self) { let mut key_event = KeyEvent::new(); key_event.set_control_key(ControlKey::LockScreen); - self.key_down_or_up(1, key_event, false, false, false, false); + // todo + key_event.down = true; + self.send_key_event(key_event, KeyboardMode::Legacy); + } + + pub fn enter(&self) { + #[cfg(windows)] + crate::platform::windows::stop_system_key_propagate(true); + IS_IN.store(true, Ordering::SeqCst); + } + + pub fn leave(&self) { + for key in TO_RELEASE.lock().unwrap().iter() { + self.map_keyboard_mode(false, *key, None) + } + #[cfg(windows)] + crate::platform::windows::stop_system_key_propagate(false); + IS_IN.store(false, Ordering::SeqCst); + } + + pub fn handle_flutter_key_event( + &self, + name: &str, + keycode: i32, + scancode: i32, + down_or_up: bool, + ) { + if scancode < 0 || keycode < 0 { + return; + } + let keycode: u32 = keycode as u32; + let scancode: u32 = scancode as u32; + + #[cfg(not(target_os = "windows"))] + let key = rdev::key_from_scancode(scancode) as RdevKey; + // Windows requires special handling + #[cfg(target_os = "windows")] + let key = rdev::get_win_key(keycode, scancode); + + let event_type = if down_or_up { + KeyPress(key) + } else { + KeyRelease(key) + }; + let evt = Event { + time: std::time::SystemTime::now(), + name: Option::Some(name.to_owned()), + code: keycode as _, + scan_code: scancode as _, + event_type: event_type, + }; + + self.key_down_or_up(down_or_up, key, evt) } // flutter only TODO new input @@ -426,7 +838,14 @@ impl Session { } } - self.key_down_or_up(v, key_event, alt, ctrl, shift, command); + self.legacy_modifiers(&mut key_event, alt, ctrl, shift, command); + if v == 1 { + key_event.down = true; + } else if v == 3 { + key_event.press = true; + } + + self.send_key_event(key_event, KeyboardMode::Legacy); } pub fn send_mouse( @@ -752,222 +1171,52 @@ impl Session { } log::info!("keyboard hooked"); let me = self.clone(); - let peer = self.peer_platform(); - let is_win = peer == "Windows"; #[cfg(windows)] crate::platform::windows::enable_lowlevel_keyboard(std::ptr::null_mut() as _); std::thread::spawn(move || { // This will block. - std::env::set_var("KEYBOARD_ONLY", "y"); // pass to rdev - use rdev::{EventType::*, *}; + std::env::set_var("KEYBOARD_ONLY", "y"); + lazy_static::lazy_static! { + static ref MUTEX_SPECIAL_KEYS: Mutex> = { + let mut m = HashMap::new(); + m.insert(RdevKey::ShiftLeft, false); + m.insert(RdevKey::ShiftRight, false); + m.insert(RdevKey::ControlLeft, false); + m.insert(RdevKey::ControlRight, false); + m.insert(RdevKey::Alt, false); + m.insert(RdevKey::AltGr, false); + m.insert(RdevKey::MetaLeft, false); + m.insert(RdevKey::MetaRight, false); + Mutex::new(m) + }; + } + let func = move |evt: Event| { if !IS_IN.load(Ordering::SeqCst) || !SERVER_KEYBOARD_ENABLED.load(Ordering::SeqCst) { return; } - let (key, down) = match evt.event_type { - KeyPress(k) => (k, 1), - KeyRelease(k) => (k, 0), + let (_key, down) = match evt.event_type { + KeyPress(k) => { + // keyboard long press + if MUTEX_SPECIAL_KEYS.lock().unwrap().contains_key(&k) { + if *MUTEX_SPECIAL_KEYS.lock().unwrap().get(&k).unwrap() { + return; + } + MUTEX_SPECIAL_KEYS.lock().unwrap().insert(k, true); + } + (k, true) + } + KeyRelease(k) => { + // keyboard long press + if MUTEX_SPECIAL_KEYS.lock().unwrap().contains_key(&k) { + MUTEX_SPECIAL_KEYS.lock().unwrap().insert(k, false); + } + (k, false) + } _ => return, }; - let alt = get_key_state(enigo::Key::Alt); - #[cfg(windows)] - let ctrl = { - let mut tmp = get_key_state(enigo::Key::Control); - unsafe { - if IS_ALT_GR { - if alt || key == Key::AltGr { - if tmp { - tmp = false; - } - } else { - IS_ALT_GR = false; - } - } - } - tmp - }; - #[cfg(not(windows))] - let ctrl = get_key_state(enigo::Key::Control); - let shift = get_key_state(enigo::Key::Shift); - #[cfg(windows)] - let command = crate::platform::windows::get_win_key_state(); - #[cfg(not(windows))] - let command = get_key_state(enigo::Key::Meta); - let control_key = match key { - Key::Alt => Some(ControlKey::Alt), - Key::AltGr => Some(ControlKey::RAlt), - Key::Backspace => Some(ControlKey::Backspace), - Key::ControlLeft => { - // when pressing AltGr, an extra VK_LCONTROL with a special - // scancode with bit 9 set is sent, let's ignore this. - #[cfg(windows)] - if evt.scan_code & 0x200 != 0 { - unsafe { - IS_ALT_GR = true; - } - return; - } - Some(ControlKey::Control) - } - Key::ControlRight => Some(ControlKey::RControl), - Key::DownArrow => Some(ControlKey::DownArrow), - Key::Escape => Some(ControlKey::Escape), - Key::F1 => Some(ControlKey::F1), - Key::F10 => Some(ControlKey::F10), - Key::F11 => Some(ControlKey::F11), - Key::F12 => Some(ControlKey::F12), - Key::F2 => Some(ControlKey::F2), - Key::F3 => Some(ControlKey::F3), - Key::F4 => Some(ControlKey::F4), - Key::F5 => Some(ControlKey::F5), - Key::F6 => Some(ControlKey::F6), - Key::F7 => Some(ControlKey::F7), - Key::F8 => Some(ControlKey::F8), - Key::F9 => Some(ControlKey::F9), - Key::LeftArrow => Some(ControlKey::LeftArrow), - Key::MetaLeft => Some(ControlKey::Meta), - Key::MetaRight => Some(ControlKey::RWin), - Key::Return => Some(ControlKey::Return), - Key::RightArrow => Some(ControlKey::RightArrow), - Key::ShiftLeft => Some(ControlKey::Shift), - Key::ShiftRight => Some(ControlKey::RShift), - Key::Space => Some(ControlKey::Space), - Key::Tab => Some(ControlKey::Tab), - Key::UpArrow => Some(ControlKey::UpArrow), - Key::Delete => { - if is_win && ctrl && alt { - me.ctrl_alt_del(); - return; - } - Some(ControlKey::Delete) - } - Key::Apps => Some(ControlKey::Apps), - Key::Cancel => Some(ControlKey::Cancel), - Key::Clear => Some(ControlKey::Clear), - Key::Kana => Some(ControlKey::Kana), - Key::Hangul => Some(ControlKey::Hangul), - Key::Junja => Some(ControlKey::Junja), - Key::Final => Some(ControlKey::Final), - Key::Hanja => Some(ControlKey::Hanja), - Key::Hanji => Some(ControlKey::Hanja), - Key::Convert => Some(ControlKey::Convert), - Key::Print => Some(ControlKey::Print), - Key::Select => Some(ControlKey::Select), - Key::Execute => Some(ControlKey::Execute), - Key::PrintScreen => Some(ControlKey::Snapshot), - Key::Help => Some(ControlKey::Help), - Key::Sleep => Some(ControlKey::Sleep), - Key::Separator => Some(ControlKey::Separator), - Key::KpReturn => Some(ControlKey::NumpadEnter), - Key::Kp0 => Some(ControlKey::Numpad0), - Key::Kp1 => Some(ControlKey::Numpad1), - Key::Kp2 => Some(ControlKey::Numpad2), - Key::Kp3 => Some(ControlKey::Numpad3), - Key::Kp4 => Some(ControlKey::Numpad4), - Key::Kp5 => Some(ControlKey::Numpad5), - Key::Kp6 => Some(ControlKey::Numpad6), - Key::Kp7 => Some(ControlKey::Numpad7), - Key::Kp8 => Some(ControlKey::Numpad8), - Key::Kp9 => Some(ControlKey::Numpad9), - Key::KpDivide => Some(ControlKey::Divide), - Key::KpMultiply => Some(ControlKey::Multiply), - Key::KpDecimal => Some(ControlKey::Decimal), - Key::KpMinus => Some(ControlKey::Subtract), - Key::KpPlus => Some(ControlKey::Add), - Key::CapsLock | Key::NumLock | Key::ScrollLock => { - return; - } - Key::Home => Some(ControlKey::Home), - Key::End => Some(ControlKey::End), - Key::Insert => Some(ControlKey::Insert), - Key::PageUp => Some(ControlKey::PageUp), - Key::PageDown => Some(ControlKey::PageDown), - Key::Pause => Some(ControlKey::Pause), - _ => None, - }; - let mut key_event = KeyEvent::new(); - if let Some(k) = control_key { - key_event.set_control_key(k); - } else { - let mut chr = match evt.name { - Some(ref s) => { - if s.len() <= 2 { - // exclude chinese characters - s.chars().next().unwrap_or('\0') - } else { - '\0' - } - } - _ => '\0', - }; - if chr == '·' { - // special for Chinese - chr = '`'; - } - if chr == '\0' { - chr = match key { - Key::Num1 => '1', - Key::Num2 => '2', - Key::Num3 => '3', - Key::Num4 => '4', - Key::Num5 => '5', - Key::Num6 => '6', - Key::Num7 => '7', - Key::Num8 => '8', - Key::Num9 => '9', - Key::Num0 => '0', - Key::KeyA => 'a', - Key::KeyB => 'b', - Key::KeyC => 'c', - Key::KeyD => 'd', - Key::KeyE => 'e', - Key::KeyF => 'f', - Key::KeyG => 'g', - Key::KeyH => 'h', - Key::KeyI => 'i', - Key::KeyJ => 'j', - Key::KeyK => 'k', - Key::KeyL => 'l', - Key::KeyM => 'm', - Key::KeyN => 'n', - Key::KeyO => 'o', - Key::KeyP => 'p', - Key::KeyQ => 'q', - Key::KeyR => 'r', - Key::KeyS => 's', - Key::KeyT => 't', - Key::KeyU => 'u', - Key::KeyV => 'v', - Key::KeyW => 'w', - Key::KeyX => 'x', - Key::KeyY => 'y', - Key::KeyZ => 'z', - Key::Comma => ',', - Key::Dot => '.', - Key::SemiColon => ';', - Key::Quote => '\'', - Key::LeftBracket => '[', - Key::RightBracket => ']', - Key::BackSlash => '\\', - Key::Minus => '-', - Key::Equal => '=', - Key::BackQuote => '`', - _ => '\0', - } - } - if chr != '\0' { - if chr == 'l' && is_win && command { - me.lock_screen(); - return; - } - key_event.set_chr(chr as _); - } else { - log::error!("Unknown key {:?}", evt); - return; - } - } - me.key_down_or_up(down, key_event, alt, ctrl, shift, command); // TODO + me.key_down_or_up(down, _key, evt); }; if let Err(error) = rdev::listen(func) { log::error!("rdev: {:?}", error);