diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cd8282187..aa1f5595b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -78,7 +78,7 @@ jobs:
shell: bash
run: |
case ${{ matrix.job.target }} in
- x86_64-unknown-linux-gnu) sudo apt-get -y update ; 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 ;;
+ x86_64-unknown-linux-gnu) sudo apt-get -y update ; 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 libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev ;;
# arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
# aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
esac
diff --git a/.gitignore b/.gitignore
index 5b26711c5..53bd9cf94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
.vscode
.idea
.DS_Store
+libsciter-gtk.so
src/ui/inline.rs
extractor
__pycache__
diff --git a/Cargo.lock b/Cargo.lock
index 6a32a7a89..107c4400a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,12 +2,6 @@
# It is not intended for manual editing.
version = 3
-[[package]]
-name = "ab_glyph_rasterizer"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a13739d7177fbd22bb0ed28badfff9f372f8bef46c863db4e1c6248f6b223b6e"
-
[[package]]
name = "addr2line"
version = "0.17.0"
@@ -29,6 +23,17 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
+[[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"
@@ -69,19 +74,6 @@ dependencies = [
"pkg-config",
]
-[[package]]
-name = "andrew"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c4afb09dd642feec8408e33f92f3ffc4052946f6b20f32fb99c1f58cd4fa7cf"
-dependencies = [
- "bitflags",
- "rusttype",
- "walkdir",
- "xdg",
- "xml-rs",
-]
-
[[package]]
name = "android_log-sys"
version = "0.2.0"
@@ -195,9 +187,9 @@ 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"
@@ -218,7 +210,7 @@ checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd"
dependencies = [
"atk-sys",
"bitflags",
- "glib 0.15.11",
+ "glib 0.15.12",
"libc",
]
@@ -277,9 +269,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",
@@ -325,6 +317,18 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+[[package]]
+name = "bitvec"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1489fcb93a5bb47da0462ca93ad252ad6af2145cce58d10d46a83931ba9f016b"
+dependencies = [
+ "funty",
+ "radium",
+ "tap",
+ "wyz",
+]
+
[[package]]
name = "block"
version = "0.1.6"
@@ -362,9 +366,9 @@ checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
[[package]]
name = "bytemuck"
-version = "1.9.1"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc"
+checksum = "c53dfa917ec274df8ed3c572698f381a24eef2efba9492d797301b72b6db408a"
[[package]]
name = "byteorder"
@@ -386,13 +390,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",
]
@@ -410,12 +414,12 @@ dependencies = [
[[package]]
name = "calloop"
-version = "0.6.5"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b036167e76041694579972c28cf4877b4f92da222560ddb49008937b6a6727c"
+checksum = "bf2eec61efe56aa1e813f5126959296933cf0700030e4314786c48779a66ab82"
dependencies = [
"log",
- "nix 0.18.0",
+ "nix 0.22.3",
]
[[package]]
@@ -424,7 +428,7 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412"
dependencies = [
- "serde 1.0.137",
+ "serde 1.0.139",
]
[[package]]
@@ -433,7 +437,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.139",
]
[[package]]
@@ -444,25 +448,25 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
dependencies = [
"camino",
"cargo-platform",
- "semver 1.0.10",
- "serde 1.0.137",
- "serde_json 1.0.81",
+ "semver 1.0.12",
+ "serde 1.0.139",
+ "serde_json 1.0.82",
]
[[package]]
name = "cbindgen"
-version = "0.24.3"
+version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb"
+checksum = "5b6d248e3ca02f3fbfabcb9284464c596baec223a26d91bbf44a5a62ddb0d900"
dependencies = [
- "clap 3.2.6",
+ "clap 3.2.12",
"heck 0.4.0",
"indexmap",
"log",
"proc-macro2",
"quote",
- "serde 1.0.137",
- "serde_json 1.0.81",
+ "serde 1.0.139",
+ "serde_json 1.0.82",
"syn",
"tempfile",
"toml",
@@ -533,7 +537,7 @@ checksum = "5a050e2153c5be08febd6734e29298e844fdb0fa21aeddd63b4eb7baa106c69b"
dependencies = [
"glob",
"libc",
- "libloading 0.7.3",
+ "libloading",
]
[[package]]
@@ -553,24 +557,39 @@ dependencies = [
[[package]]
name = "clap"
-version = "3.2.6"
+version = "3.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f1fe12880bae935d142c8702d500c63a4e8634b6c3c57ad72bf978fc7b6249a"
+checksum = "ab8b79fe3946ceb4a0b1c080b4018992b8d27e9ff363644c1c9b6387c854614d"
dependencies = [
"atty",
"bitflags",
+ "clap_derive",
"clap_lex",
"indexmap",
+ "once_cell",
"strsim 0.10.0",
"termcolor",
"textwrap 0.15.0",
]
[[package]]
-name = "clap_lex"
-version = "0.2.3"
+name = "clap_derive"
+version = "3.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4"
+checksum = "759bf187376e1afa7b85b959e6a664a3e7a95203415dba952ad19139e798f902"
+dependencies = [
+ "heck 0.4.0",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
@@ -582,16 +601,16 @@ dependencies = [
"cc",
"hbb_common",
"lazy_static",
- "serde 1.0.137",
+ "serde 1.0.139",
"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",
@@ -680,9 +699,9 @@ dependencies = [
[[package]]
name = "concurrent-queue"
-version = "1.2.2"
+version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
+checksum = "83827793632c72fa4f73c2edb31e7a997527dd8ffe7077344621fc62c5478157"
dependencies = [
"cache-padded",
]
@@ -693,7 +712,7 @@ version = "0.4.0"
source = "git+https://github.com/open-trade/confy#630cc28a396cb7d01eefdd9f3824486fe4d8554b"
dependencies = [
"directories-next",
- "serde 1.0.137",
+ "serde 1.0.139",
"thiserror",
"toml",
]
@@ -860,20 +879,6 @@ 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.5"
@@ -931,9 +936,9 @@ dependencies = [
[[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",
@@ -955,7 +960,7 @@ version = "3.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b37feaa84e6861e00a1f5e5aa8da3ee56d605c9992d33e082786754828e20865"
dependencies = [
- "nix 0.24.1",
+ "nix 0.24.2",
"winapi 0.3.9",
]
@@ -965,38 +970,14 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
-[[package]]
-name = "darling"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
-dependencies = [
- "darling_core 0.10.2",
- "darling_macro 0.10.2",
-]
-
[[package]]
name = "darling"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
dependencies = [
- "darling_core 0.13.4",
- "darling_macro 0.13.4",
-]
-
-[[package]]
-name = "darling_core"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
-dependencies = [
- "fnv",
- "ident_case",
- "proc-macro2",
- "quote",
- "strsim 0.9.3",
- "syn",
+ "darling_core",
+ "darling_macro",
]
[[package]]
@@ -1013,24 +994,13 @@ dependencies = [
"syn",
]
-[[package]]
-name = "darling_macro"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
-dependencies = [
- "darling_core 0.10.2",
- "quote",
- "syn",
-]
-
[[package]]
name = "darling_macro"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
dependencies = [
- "darling_core 0.13.4",
+ "darling_core",
"quote",
"syn",
]
@@ -1156,15 +1126,27 @@ 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",
"winapi 0.3.9",
]
+[[package]]
+name = "default-net"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05e70d471b0ba4e722c85651b3bb04b6880dfdb1224a43ade80c1295314db646"
+dependencies = [
+ "libc",
+ "memalloc",
+ "system-configuration",
+ "windows",
+]
+
[[package]]
name = "deflate"
version = "0.8.6"
@@ -1195,15 +1177,6 @@ dependencies = [
"dirs-sys-next",
]
-[[package]]
-name = "dirs"
-version = "4.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
-dependencies = [
- "dirs-sys",
-]
-
[[package]]
name = "dirs-next"
version = "2.0.0"
@@ -1214,17 +1187,6 @@ dependencies = [
"dirs-sys-next",
]
-[[package]]
-name = "dirs-sys"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
-dependencies = [
- "libc",
- "redox_users",
- "winapi 0.3.9",
-]
-
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
@@ -1242,22 +1204,13 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
-[[package]]
-name = "dlib"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b11f15d1e3268f140f68d390637d5e76d849782d971ae7063e0da69fe9709a76"
-dependencies = [
- "libloading 0.6.7",
-]
-
[[package]]
name = "dlib"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794"
dependencies = [
- "libloading 0.7.3",
+ "libloading",
]
[[package]]
@@ -1268,7 +1221,7 @@ checksum = "7f3f119846c823f9eafcf953a8f6ffb6ed69bf6240883261a7f13b634579a51f"
dependencies = [
"lazy_static",
"regex",
- "serde 1.0.137",
+ "serde 1.0.139",
"strsim 0.10.0",
]
@@ -1295,9 +1248,9 @@ dependencies = [
[[package]]
name = "either"
-version = "1.6.1"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
[[package]]
name = "encoding_rs"
@@ -1313,12 +1266,13 @@ name = "enigo"
version = "0.0.14"
dependencies = [
"core-graphics 0.22.3",
+ "hbb_common",
"libc",
"log",
"objc",
"pkg-config",
"rdev",
- "serde 1.0.137",
+ "serde 1.0.139",
"serde_derive",
"unicode-segmentation",
"winapi 0.3.9",
@@ -1403,6 +1357,16 @@ dependencies = [
"str-buf",
]
+[[package]]
+name = "evdev"
+version = "0.11.5"
+source = "git+https://github.com/fufesou/evdev#cec616e37790293d2cd2aa54a96601ed6b1b35a9"
+dependencies = [
+ "bitvec",
+ "libc",
+ "nix 0.23.1",
+]
+
[[package]]
name = "event-listener"
version = "2.5.2"
@@ -1439,14 +1403,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]]
@@ -1481,9 +1445,9 @@ dependencies = [
[[package]]
name = "flutter_rust_bridge"
-version = "1.34.2"
+version = "1.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d56ac4e92d08407968b7efba9cda734935f6ebbffd521f9255b8f516d8c2cede"
+checksum = "b7e7e4af55d6a36aad9573737a12fba774999e4d6dd5e668e29c25bb473f85f3"
dependencies = [
"allo-isolate",
"anyhow",
@@ -1495,9 +1459,9 @@ dependencies = [
[[package]]
name = "flutter_rust_bridge_codegen"
-version = "1.34.2"
+version = "1.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b2bd4b68e21ce08b9afe3332c37c1eef2799bc36c0521890f5aaa303942b7df2"
+checksum = "3209735fd687b06b8d770ec008874119b91f7f46b4a73d17226d5c337435bb74"
dependencies = [
"anyhow",
"cargo_metadata",
@@ -1510,7 +1474,7 @@ dependencies = [
"pathdiff",
"quote",
"regex",
- "serde 1.0.137",
+ "serde 1.0.139",
"serde_yaml",
"structopt",
"syn",
@@ -1521,9 +1485,9 @@ dependencies = [
[[package]]
name = "flutter_rust_bridge_macros"
-version = "1.34.2"
+version = "1.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d4540ab97380ed5af0212f8b18ff84a5f32acc8247f8f731311516dd105363f"
+checksum = "13652b9b71bc3bf4ea3bbb5cadc9bc2350fe0fba5145f6a949309fc452576d6d"
[[package]]
name = "fnv"
@@ -1578,6 +1542,12 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
+[[package]]
+name = "funty"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
+
[[package]]
name = "futures"
version = "0.3.21"
@@ -1702,7 +1672,7 @@ dependencies = [
"gdk-pixbuf",
"gdk-sys",
"gio",
- "glib 0.15.11",
+ "glib 0.15.12",
"libc",
"pango",
]
@@ -1716,7 +1686,7 @@ dependencies = [
"bitflags",
"gdk-pixbuf-sys",
"gio",
- "glib 0.15.11",
+ "glib 0.15.12",
"libc",
]
@@ -1783,22 +1753,22 @@ dependencies = [
[[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",
@@ -1838,9 +1808,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",
@@ -2082,7 +2052,7 @@ dependencies = [
"gdk",
"gdk-pixbuf",
"gio",
- "glib 0.15.11",
+ "glib 0.15.12",
"gtk-sys",
"gtk3-macros",
"libc",
@@ -2138,15 +2108,18 @@ dependencies = [
"indexmap",
"slab",
"tokio",
- "tokio-util 0.7.3",
+ "tokio-util",
"tracing",
]
[[package]]
name = "hashbrown"
-version = "0.12.1"
+version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+dependencies = [
+ "ahash",
+]
[[package]]
name = "hbb_common"
@@ -2164,19 +2137,21 @@ dependencies = [
"lazy_static",
"log",
"mac_address",
+ "machine-uid",
"protobuf",
- "protobuf-codegen-pure",
+ "protobuf-codegen",
"quinn",
"rand 0.8.5",
"regex",
- "serde 1.0.137",
+ "serde 1.0.139",
"serde_derive",
- "serde_json 1.0.81",
+ "serde_json 1.0.82",
+ "serde_with",
"socket2 0.3.19",
"sodiumoxide",
"tokio",
"tokio-socks",
- "tokio-util 0.6.10",
+ "tokio-util",
"toml",
"winapi 0.3.9",
"zstd",
@@ -2255,21 +2230,21 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hwcodec"
version = "0.1.0"
-source = "git+https://github.com/21pages/hwcodec#bfc558d2375928b0a59336cfc72336415db27066"
+source = "git+https://github.com/21pages/hwcodec#91d1cd327c88490f917457072aeef0676ddb2be7"
dependencies = [
"bindgen",
"cc",
"log",
- "serde 1.0.137",
+ "serde 1.0.139",
"serde_derive",
- "serde_json 1.0.81",
+ "serde_json 1.0.82",
]
[[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",
@@ -2371,6 +2346,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if 1.0.0",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
]
[[package]]
@@ -2477,11 +2455,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",
@@ -2490,12 +2468,12 @@ dependencies = [
[[package]]
name = "libappindicator-sys"
-version = "0.7.2"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a0e019ae1a736a858f4c52b58af2ca6e797f27d7fe534e8a56776d74a8f2535"
+checksum = "f1b3b6681973cea8cc3bce7391e6d7d5502720b80a581c9a95c9cbaf592826aa"
dependencies = [
"gtk-sys",
- "libloading 0.7.3",
+ "libloading",
"once_cell",
]
@@ -2514,16 +2492,6 @@ dependencies = [
"pkg-config",
]
-[[package]]
-name = "libloading"
-version = "0.6.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883"
-dependencies = [
- "cfg-if 1.0.0",
- "winapi 0.3.9",
-]
-
[[package]]
name = "libloading"
version = "0.7.3"
@@ -2680,6 +2648,12 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
+[[package]]
+name = "memalloc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df39d232f5c40b0891c10216992c2f250c054105cb1e56f0fc9032db6203ecc1"
+
[[package]]
name = "memchr"
version = "2.5.0"
@@ -2688,9 +2662,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memmap2"
-version = "0.1.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b70ca2a6103ac8b665dc150b142ef0e4e89df640c9e6cf295d189c3caebe5a"
+checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357"
dependencies = [
"libc",
]
@@ -2763,19 +2737,6 @@ dependencies = [
"winapi 0.2.8",
]
-[[package]]
-name = "mio"
-version = "0.7.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
-dependencies = [
- "libc",
- "log",
- "miow 0.3.7",
- "ntapi",
- "winapi 0.3.9",
-]
-
[[package]]
name = "mio"
version = "0.8.4"
@@ -2788,18 +2749,6 @@ dependencies = [
"windows-sys 0.36.1",
]
-[[package]]
-name = "mio-misc"
-version = "1.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b47412f3a52115b936ff2a229b803498c7b4d332adeb87c2f1498c9da54c398c"
-dependencies = [
- "crossbeam",
- "crossbeam-queue",
- "log",
- "mio 0.7.14",
-]
-
[[package]]
name = "mio-named-pipes"
version = "0.1.7"
@@ -2842,6 +2791,15 @@ dependencies = [
"windows-sys 0.28.0",
]
+[[package]]
+name = "mouce"
+version = "0.2.1"
+source = "git+https://github.com/fufesou/mouce.git#26da8d4b0009b7f96996799c2a5c0990a8dbf08b"
+dependencies = [
+ "glob",
+ "libc",
+]
+
[[package]]
name = "muldiv"
version = "0.2.1"
@@ -2850,10 +2808,11 @@ checksum = "0419348c027fa7be448d2ae7ea0e4e04c2334c31dc4e74ab29f00a2a7ca69204"
[[package]]
name = "ndk"
-version = "0.3.0"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8794322172319b972f528bf90c6b467be0079f1fa82780ffb431088e741a73ab"
+checksum = "96d868f654c72e75f8687572699cdabe755f03effbb62542768e995d5b8d699d"
dependencies = [
+ "bitflags",
"jni-sys",
"ndk-sys 0.2.2",
"num_enum",
@@ -2881,15 +2840,16 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
[[package]]
name = "ndk-glue"
-version = "0.3.0"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5caf0c24d51ac1c905c27d4eda4fa0635bbe0de596b8f79235e0b17a4d29385"
+checksum = "c71bee8ea72d685477e28bd004cfe1bf99c754d688cd78cad139eae4089484d4"
dependencies = [
"lazy_static",
"libc",
"log",
- "ndk 0.3.0",
- "ndk-macro 0.2.0",
+ "ndk 0.5.0",
+ "ndk-context",
+ "ndk-macro",
"ndk-sys 0.2.2",
]
@@ -2904,30 +2864,17 @@ dependencies = [
"log",
"ndk 0.6.0",
"ndk-context",
- "ndk-macro 0.3.0",
+ "ndk-macro",
"ndk-sys 0.3.0",
]
-[[package]]
-name = "ndk-macro"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d"
-dependencies = [
- "darling 0.10.2",
- "proc-macro-crate 0.1.5",
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "ndk-macro"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c"
dependencies = [
- "darling 0.13.4",
+ "darling",
"proc-macro-crate 1.1.3",
"proc-macro2",
"quote",
@@ -2960,30 +2907,6 @@ dependencies = [
"winapi 0.3.9",
]
-[[package]]
-name = "nix"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055"
-dependencies = [
- "bitflags",
- "cc",
- "cfg-if 0.1.10",
- "libc",
-]
-
-[[package]]
-name = "nix"
-version = "0.20.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a"
-dependencies = [
- "bitflags",
- "cc",
- "cfg-if 1.0.0",
- "libc",
-]
-
[[package]]
name = "nix"
version = "0.22.3"
@@ -3012,9 +2935,9 @@ 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",
@@ -3181,9 +3104,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",
]
@@ -3213,9 +3136,9 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.12.0"
+version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
+checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "openssl-probe"
@@ -3225,18 +3148,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "os_str_bytes"
-version = "6.1.0"
+version = "6.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa"
-
-[[package]]
-name = "owned_ttf_parser"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3"
-dependencies = [
- "ttf-parser",
-]
+checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4"
[[package]]
name = "padlock"
@@ -3251,7 +3165,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",
@@ -3271,8 +3185,8 @@ dependencies = [
[[package]]
name = "parity-tokio-ipc"
-version = "0.7.3"
-source = "git+https://github.com/open-trade/parity-tokio-ipc#64d5b6b11464d01bfe75b3b79a49bd455b79e352"
+version = "0.7.3-1"
+source = "git+https://github.com/open-trade/parity-tokio-ipc#20b2895910161605210657f3e751edd55321f698"
dependencies = [
"futures",
"libc",
@@ -3411,18 +3325,18 @@ dependencies = [
[[package]]
name = "pin-project"
-version = "1.0.10"
+version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
+checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
-version = "1.0.10"
+version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
+checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74"
dependencies = [
"proc-macro2",
"quote",
@@ -3547,60 +3461,56 @@ dependencies = [
[[package]]
name = "protobuf"
-version = "3.0.0-alpha.2"
+version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d5ef59c35c7472ce5e1b6c5924b87585143d1fc2cf39eae0009bba6c4df62f1"
+checksum = "4ee4a7d8b91800c8f167a6268d1a1026607368e1adc84e98fe044aeb905302f7"
+dependencies = [
+ "bytes",
+ "once_cell",
+ "protobuf-support",
+ "thiserror",
+]
[[package]]
name = "protobuf-codegen"
-version = "3.0.0-alpha.2"
+version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89100ee819f69b77a4cab389fec9dd155a305af4c615e6413ec1ef9341f333ef"
+checksum = "07b893e5e7d3395545d5244f8c0d33674025bd566b26c03bfda49b82c6dec45e"
dependencies = [
"anyhow",
+ "once_cell",
"protobuf",
"protobuf-parse",
- "thiserror",
-]
-
-[[package]]
-name = "protobuf-codegen-pure"
-version = "3.0.0-alpha.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79453e74d08190551e821533ee42c447f9e21ca26f83520e120e6e8af27f6879"
-dependencies = [
- "anyhow",
- "protobuf",
- "protobuf-codegen",
- "protobuf-parse",
- "thiserror",
-]
-
-[[package]]
-name = "protobuf-parse"
-version = "3.0.0-alpha.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c265ffc69976efc3056955b881641add3186ad0be893ef10622482d80d1d2b68"
-dependencies = [
- "anyhow",
- "protobuf",
- "protoc",
+ "regex",
"tempfile",
"thiserror",
]
[[package]]
-name = "protoc"
-version = "3.0.0-alpha.2"
+name = "protobuf-parse"
+version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f1f8b318a54d18fbe542513331e058f4f8ce6502e542e057c50c7e5e803fdab"
+checksum = "9b1447dd751c434cc1b415579837ebd0411ed7d67d465f38010da5d7cd33af4d"
dependencies = [
"anyhow",
+ "indexmap",
"log",
+ "protobuf",
+ "protobuf-support",
+ "tempfile",
"thiserror",
"which 4.2.5",
]
+[[package]]
+name = "protobuf-support"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ca157fe12fc7ee2e315f2f735e27df41b3d97cdd70ea112824dac1ffb08ee1c"
+dependencies = [
+ "thiserror",
+]
+
[[package]]
name = "quest"
version = "0.3.0"
@@ -3676,6 +3586,12 @@ dependencies = [
"proc-macro2",
]
+[[package]]
+name = "radium"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
+
[[package]]
name = "rand"
version = "0.6.5"
@@ -3812,16 +3728,6 @@ dependencies = [
"rand_core 0.3.1",
]
-[[package]]
-name = "raw-window-handle"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e28f55143d0548dad60bb4fbdc835a3d7ac6acc3324506450c5fdd6e42903a76"
-dependencies = [
- "libc",
- "raw-window-handle 0.4.3",
-]
-
[[package]]
name = "raw-window-handle"
version = "0.4.3"
@@ -3911,9 +3817,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",
@@ -3922,9 +3828,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"
@@ -3970,8 +3876,8 @@ dependencies = [
"pin-project-lite",
"rustls",
"rustls-pemfile 1.0.0",
- "serde 1.0.137",
- "serde_json 1.0.81",
+ "serde 1.0.139",
+ "serde_json 1.0.82",
"serde_urlencoded",
"tokio",
"tokio-rustls",
@@ -4012,13 +3918,11 @@ dependencies = [
[[package]]
name = "rpassword"
-version = "6.0.1"
+version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bf099a1888612545b683d2661a1940089f6c2e5a8e38979b2159da876bfd956"
+checksum = "26b763cb66df1c928432cc35053f8bd4cec3335d8559fc16010017d16b3c1680"
dependencies = [
"libc",
- "serde 1.0.137",
- "serde_json 1.0.81",
"winapi 0.3.9",
]
@@ -4084,7 +3988,7 @@ dependencies = [
"base64",
"cc",
"cfg-if 1.0.0",
- "clap 3.2.6",
+ "clap 3.2.12",
"clipboard",
"cocoa 0.24.0",
"core-foundation 0.9.3",
@@ -4092,8 +3996,10 @@ dependencies = [
"cpal",
"ctrlc",
"dasp",
+ "default-net",
"dispatch",
"enigo",
+ "evdev",
"flexi_logger",
"flutter_rust_bridge",
"flutter_rust_bridge_codegen",
@@ -4108,22 +4014,23 @@ dependencies = [
"mac_address",
"machine-uid",
"magnum-opus",
+ "mouce",
"num_cpus",
"objc",
"parity-tokio-ipc",
"rdev",
"repng",
"reqwest",
- "rpassword 6.0.1",
+ "rpassword 7.0.0",
"rubato",
"runas",
"rust-pulsectl",
"samplerate",
"sciter-rs",
"scrap",
- "serde 1.0.137",
+ "serde 1.0.139",
"serde_derive",
- "serde_json 1.0.81",
+ "serde_json 1.0.82",
"sha2",
"simple_rc",
"sys-locale",
@@ -4138,6 +4045,7 @@ dependencies = [
"winit",
"winreg 0.10.1",
"winres",
+ "wol-rs",
]
[[package]]
@@ -4196,21 +4104,11 @@ dependencies = [
"base64",
]
-[[package]]
-name = "rusttype"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59"
-dependencies = [
- "ab_glyph_rasterizer",
- "owned_ttf_parser",
-]
-
[[package]]
name = "rustversion"
-version = "1.0.7"
+version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf"
+checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8"
[[package]]
name = "ryu"
@@ -4291,8 +4189,8 @@ dependencies = [
"num_cpus",
"quest",
"repng",
- "serde 1.0.137",
- "serde_json 1.0.81",
+ "serde 1.0.139",
+ "serde_json 1.0.82",
"target_build_utils",
"tracing",
"webm",
@@ -4343,11 +4241,11 @@ dependencies = [
[[package]]
name = "semver"
-version = "1.0.10"
+version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c"
+checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
dependencies = [
- "serde 1.0.137",
+ "serde 1.0.139",
]
[[package]]
@@ -4367,18 +4265,18 @@ checksum = "34b623917345a631dc9608d5194cc206b3fe6c3554cd1c75b937e55e285254af"
[[package]]
name = "serde"
-version = "1.0.137"
+version = "1.0.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
+checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.137"
+version = "1.0.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
+checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb"
dependencies = [
"proc-macro2",
"quote",
@@ -4399,13 +4297,13 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.81"
+version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
+checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
dependencies = [
"itoa 1.0.2",
"ryu",
- "serde 1.0.137",
+ "serde 1.0.139",
]
[[package]]
@@ -4417,18 +4315,40 @@ dependencies = [
"form_urlencoded",
"itoa 1.0.2",
"ryu",
- "serde 1.0.137",
+ "serde 1.0.139",
+]
+
+[[package]]
+name = "serde_with"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff"
+dependencies = [
+ "serde 1.0.139",
+ "serde_with_macros",
+]
+
+[[package]]
+name = "serde_with_macros"
+version = "1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn",
]
[[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.139",
"yaml-rust",
]
@@ -4480,7 +4400,7 @@ version = "0.1.0"
dependencies = [
"confy",
"hbb_common",
- "serde 1.0.137",
+ "serde 1.0.139",
"serde_derive",
"walkdir",
]
@@ -4499,24 +4419,24 @@ checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32"
[[package]]
name = "smallvec"
-version = "1.8.1"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc88c725d61fc6c3132893370cac4a0200e3fedf5da8331c570664b1987f5ca2"
+checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
[[package]]
name = "smithay-client-toolkit"
-version = "0.12.3"
+version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4750c76fd5d3ac95fa3ed80fe667d6a3d8590a960e5b575b98eea93339a80b80"
+checksum = "8a28f16a97fa0e8ce563b2774d1e732dd5d4025d2772c5dba0a41a0f90a29da3"
dependencies = [
- "andrew",
"bitflags",
"calloop",
- "dlib 0.4.2",
+ "dlib",
"lazy_static",
"log",
"memmap2",
- "nix 0.18.0",
+ "nix 0.22.3",
+ "pkg-config",
"wayland-client",
"wayland-cursor",
"wayland-protocols",
@@ -4552,7 +4472,7 @@ dependencies = [
"ed25519",
"libc",
"libsodium-sys",
- "serde 1.0.137",
+ "serde 1.0.139",
]
[[package]]
@@ -4585,12 +4505,6 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
-[[package]]
-name = "strsim"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
-
[[package]]
name = "strsim"
version = "0.10.0"
@@ -4679,9 +4593,9 @@ dependencies = [
[[package]]
name = "sysinfo"
-version = "0.23.13"
+version = "0.24.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3977ec2e0520829be45c8a2df70db2bf364714d8a748316a10c3c35d4d2b01c9"
+checksum = "0b6e19da72a8d75be4d40e4dd4686afca31507f26c3ffdf6bd3073278d9de0a0"
dependencies = [
"cfg-if 1.0.0",
"core-foundation-sys 0.8.3",
@@ -4692,6 +4606,27 @@ dependencies = [
"winapi 0.3.9",
]
+[[package]]
+name = "system-configuration"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d75182f12f490e953596550b65ee31bda7c8e043d9386174b353bda50838c3fd"
+dependencies = [
+ "bitflags",
+ "core-foundation 0.9.3",
+ "system-configuration-sys",
+]
+
+[[package]]
+name = "system-configuration-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
+dependencies = [
+ "core-foundation-sys 0.8.3",
+ "libc",
+]
+
[[package]]
name = "system-deps"
version = "1.3.2"
@@ -4720,6 +4655,12 @@ dependencies = [
"version-compare 0.1.0",
]
+[[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
[[package]]
name = "target_build_utils"
version = "0.3.1"
@@ -4853,10 +4794,11 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
-version = "1.19.2"
+version = "1.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439"
+checksum = "57aec3cfa4c296db7255446efb4928a6be304b431a806216105542a67b6ca82e"
dependencies = [
+ "autocfg 1.1.0",
"bytes",
"libc",
"memchr",
@@ -4895,8 +4837,8 @@ dependencies = [
[[package]]
name = "tokio-socks"
-version = "0.5.1"
-source = "git+https://github.com/open-trade/tokio-socks#c34272f219b24dc6508f13fa81eff9850e616ce2"
+version = "0.5.1-1"
+source = "git+https://github.com/open-trade/tokio-socks#7034e79263ce25c348be072808d7601d82cd892d"
dependencies = [
"bytes",
"either",
@@ -4906,23 +4848,7 @@ dependencies = [
"pin-project",
"thiserror",
"tokio",
- "tokio-util 0.6.10",
-]
-
-[[package]]
-name = "tokio-util"
-version = "0.6.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507"
-dependencies = [
- "bytes",
- "futures-core",
- "futures-io",
- "futures-sink",
- "log",
- "pin-project-lite",
- "slab",
- "tokio",
+ "tokio-util",
]
[[package]]
@@ -4933,8 +4859,12 @@ checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45"
dependencies = [
"bytes",
"futures-core",
+ "futures-io",
"futures-sink",
+ "futures-util",
+ "hashbrown",
"pin-project-lite",
+ "slab",
"tokio",
"tracing",
]
@@ -4945,7 +4875,7 @@ version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
dependencies = [
- "serde 1.0.137",
+ "serde 1.0.139",
]
[[package]]
@@ -4968,9 +4898,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",
@@ -5016,9 +4946,8 @@ dependencies = [
[[package]]
name = "trayicon"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c367fd7cdcdf19234aa104f7e03abe1be526018e4282af9f275bf436b9c9ad23"
+version = "0.1.3-1"
+source = "git+https://github.com/open-trade/trayicon-rs#8d9c4489287752cc5be4a35c103198f7111112f9"
dependencies = [
"winapi 0.3.9",
"winit",
@@ -5030,12 +4959,6 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
-[[package]]
-name = "ttf-parser"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc"
-
[[package]]
name = "typenum"
version = "1.15.0"
@@ -5044,9 +4967,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 = "unicode-bidi"
@@ -5056,15 +4979,15 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
+checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
[[package]]
name = "unicode-normalization"
-version = "0.1.20"
+version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81dee68f85cab8cf68dec42158baf3a79a1cdc065a8b103025965d6ccb7f6cbd"
+checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6"
dependencies = [
"tinyvec",
]
@@ -5145,7 +5068,7 @@ dependencies = [
"cc",
"hbb_common",
"lazy_static",
- "serde 1.0.137",
+ "serde 1.0.139",
"serde_derive",
"thiserror",
]
@@ -5251,14 +5174,14 @@ checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be"
[[package]]
name = "wayland-client"
-version = "0.28.6"
+version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3ab332350e502f159382201394a78e3cc12d0f04db863429260164ea40e0355"
+checksum = "91223460e73257f697d9e23d401279123d36039a3f7a449e983f123292d4458f"
dependencies = [
"bitflags",
"downcast-rs",
"libc",
- "nix 0.20.0",
+ "nix 0.22.3",
"scoped-tls",
"wayland-commons",
"wayland-scanner",
@@ -5267,11 +5190,11 @@ dependencies = [
[[package]]
name = "wayland-commons"
-version = "0.28.6"
+version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a21817947c7011bbd0a27e11b17b337bfd022e8544b071a2641232047966fbda"
+checksum = "94f6e5e340d7c13490eca867898c4cec5af56c27a5ffe5c80c6fc4708e22d33e"
dependencies = [
- "nix 0.20.0",
+ "nix 0.22.3",
"once_cell",
"smallvec",
"wayland-sys",
@@ -5279,20 +5202,20 @@ dependencies = [
[[package]]
name = "wayland-cursor"
-version = "0.28.6"
+version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be610084edd1586d45e7bdd275fe345c7c1873598caa464c4fb835dee70fa65a"
+checksum = "c52758f13d5e7861fc83d942d3d99bf270c83269575e52ac29e5b73cb956a6bd"
dependencies = [
- "nix 0.20.0",
+ "nix 0.22.3",
"wayland-client",
"xcursor",
]
[[package]]
name = "wayland-protocols"
-version = "0.28.6"
+version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "286620ea4d803bacf61fa087a4242ee316693099ee5a140796aaba02b29f861f"
+checksum = "60147ae23303402e41fe034f74fb2c35ad0780ee88a1c40ac09a3be1e7465741"
dependencies = [
"bitflags",
"wayland-client",
@@ -5302,9 +5225,9 @@ dependencies = [
[[package]]
name = "wayland-scanner"
-version = "0.28.6"
+version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce923eb2deb61de332d1f356ec7b6bf37094dc5573952e1c8936db03b54c03f1"
+checksum = "39a1ed3143f7a143187156a2ab52742e89dac33245ba505c17224df48939f9e0"
dependencies = [
"proc-macro2",
"quote",
@@ -5313,11 +5236,11 @@ dependencies = [
[[package]]
name = "wayland-sys"
-version = "0.28.6"
+version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d841fca9aed7febf9bed2e9796c49bf58d4152ceda8ac949ebe00868d8f0feb8"
+checksum = "d9341df79a8975679188e37dab3889bfa57c44ac2cb6da166f519a81cbe452d4"
dependencies = [
- "dlib 0.5.0",
+ "dlib",
"lazy_static",
"pkg-config",
]
@@ -5362,18 +5285,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"
@@ -5473,6 +5396,19 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+[[package]]
+name = "windows"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b749ebd2304aa012c5992d11a25d07b406bdbe5f79d371cb7a918ce501a19eb0"
+dependencies = [
+ "windows_aarch64_msvc 0.30.0",
+ "windows_i686_gnu 0.30.0",
+ "windows_i686_msvc 0.30.0",
+ "windows_x86_64_gnu 0.30.0",
+ "windows_x86_64_msvc 0.30.0",
+]
+
[[package]]
name = "windows-service"
version = "0.4.0"
@@ -5517,6 +5453,12 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52695a41e536859d5308cc613b4a022261a274390b25bd29dfff4bf08505f3c2"
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca"
+
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
@@ -5529,6 +5471,12 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f54725ac23affef038fecb177de6c9bf065787c2f432f79e3c373da92f3e1d8a"
+[[package]]
+name = "windows_i686_gnu"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8"
+
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
@@ -5541,6 +5489,12 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d5158a43cc43623c0729d1ad6647e62fa384a3d135fd15108d37c683461f64"
+[[package]]
+name = "windows_i686_msvc"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6"
+
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
@@ -5553,6 +5507,12 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc31f409f565611535130cfe7ee8e6655d3fa99c1c61013981e491921b5ce954"
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a"
+
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
@@ -5565,6 +5525,12 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f2b8c7cbd3bfdddd9ab98769f9746a7fad1bca236554cd032b78d768bc0e89f"
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1"
+
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
@@ -5573,9 +5539,9 @@ checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "winit"
-version = "0.25.0"
+version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79610794594d5e86be473ef7763f604f2159cbac8c94debd00df8fb41e86c2f8"
+checksum = "9b43cc931d58b99461188607efd7acb2a093e65fc621f54cad78517a6063e73a"
dependencies = [
"bitflags",
"cocoa 0.24.0",
@@ -5587,18 +5553,19 @@ dependencies = [
"lazy_static",
"libc",
"log",
- "mio 0.7.14",
- "mio-misc",
- "ndk 0.3.0",
- "ndk-glue 0.3.0",
+ "mio 0.8.4",
+ "ndk 0.5.0",
+ "ndk-glue 0.5.2",
"ndk-sys 0.2.2",
"objc",
"parking_lot 0.11.2",
"percent-encoding",
- "raw-window-handle 0.3.4",
- "scopeguard",
+ "raw-window-handle",
"smithay-client-toolkit",
+ "wasm-bindgen",
"wayland-client",
+ "wayland-protocols",
+ "web-sys",
"winapi 0.3.9",
"x11-dl",
]
@@ -5630,6 +5597,15 @@ dependencies = [
"toml",
]
+[[package]]
+name = "wol-rs"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7f97e69b28b256ccfb02472c25057132e234aa8368fea3bb0268def564ce1f2"
+dependencies = [
+ "clap 3.2.12",
+]
+
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
@@ -5640,6 +5616,15 @@ dependencies = [
"winapi-build",
]
+[[package]]
+name = "wyz"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e"
+dependencies = [
+ "tap",
+]
+
[[package]]
name = "x11"
version = "2.19.1"
@@ -5682,15 +5667,6 @@ dependencies = [
"nom",
]
-[[package]]
-name = "xdg"
-version = "2.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c4583db5cbd4c4c0303df2d15af80f0539db703fa1c68802d4cbbd2dd0f88f6"
-dependencies = [
- "dirs",
-]
-
[[package]]
name = "xml-rs"
version = "0.8.4"
diff --git a/Cargo.toml b/Cargo.toml
index 264c82940..61005f304 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,7 +31,7 @@ default = ["use_dasp"]
[dependencies]
whoami = "1.2"
-scrap = { path = "libs/scrap" }
+scrap = { path = "libs/scrap", features = ["wayland"] }
hbb_common = { path = "libs/hbb_common" }
serde_derive = "1.0"
serde = "1.0"
@@ -51,10 +51,12 @@ samplerate = { version = "0.2", optional = true }
async-trait = "0.1"
uuid = { version = "1.0", features = ["v4"] }
clap = "3.0"
-rpassword = "6.0"
+rpassword = "7.0"
base64 = "0.13"
-sysinfo = "0.23"
+sysinfo = "0.24"
num_cpus = "1.13"
+default-net = "0.11.0"
+wol-rs = "0.9.1"
[target.'cfg(not(target_os = "linux"))'.dependencies]
reqwest = { version = "0.11", features = ["json", "rustls-tls"], default-features=false }
@@ -67,7 +69,7 @@ machine-uid = "0.2"
mac_address = "1.1"
sciter-rs = { git = "https://github.com/open-trade/rust-sciter", branch = "dyn" }
sys-locale = "0.2"
-enigo = { path = "libs/enigo" }
+enigo = { path = "libs/enigo", features = [ "with_serde" ] }
clipboard = { path = "libs/clipboard" }
rdev = { git = "https://github.com/asur4s/rdev" }
ctrlc = "3.2"
@@ -76,9 +78,8 @@ arboard = "2.0"
[target.'cfg(target_os = "windows")'.dependencies]
#systray = { git = "https://github.com/open-trade/systray-rs" }
-trayicon = { version = "0.1", features = ["winit"] }
-# > 0.25 not work with trayicon
-winit = "0.25"
+trayicon = { git = "https://github.com/open-trade/trayicon-rs", features = ["winit"] }
+winit = "0.26"
winapi = { version = "0.3", features = ["winuser"] }
winreg = "0.10"
windows-service = "0.4"
@@ -98,13 +99,15 @@ psimple = { package = "libpulse-simple-binding", version = "2.25" }
pulse = { package = "libpulse-binding", version = "2.26" }
rust-pulsectl = { git = "https://github.com/open-trade/pulsectl" }
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.0"
+jni = "0.19"
[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies]
-flutter_rust_bridge = "1.30.0"
+flutter_rust_bridge = "=1.30.0"
[workspace]
members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/simple_rc"]
@@ -122,7 +125,7 @@ winapi = { version = "0.3", features = [ "winnt" ] }
cc = "1.0"
hbb_common = { path = "libs/hbb_common" }
simple_rc = { path = "libs/simple_rc", optional = true }
-flutter_rust_bridge_codegen = "1.30.0"
+flutter_rust_bridge_codegen = "=1.30.0"
[dev-dependencies]
hound = "3.4"
diff --git a/DEBIAN/postinst b/DEBIAN/postinst
old mode 100644
new mode 100755
index 5899bd4df..1c7697acc
--- a/DEBIAN/postinst
+++ b/DEBIAN/postinst
@@ -8,16 +8,20 @@ if [ "$1" = configure ]; then
if [ "systemd" == "$INITSYS" ]; then
if [ -e /etc/systemd/system/rustdesk.service ]; then
- rm /etc/systemd/system/rustdesk.service
+ rm /etc/systemd/system/rustdesk.service /usr/lib/systemd/system/rustdesk.service /usr/lib/systemd/user/rustdesk.service >/dev/null 2>&1
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 /etc/systemd/system/rustdesk.service
+ cp /usr/share/rustdesk/files/systemd/rustdesk.service /usr/lib/systemd/system/rustdesk.service
systemctl daemon-reload
systemctl enable rustdesk
systemctl start rustdesk
+
+ cp /usr/share/rustdesk/files/systemd/rustdesk.service.user /usr/lib/systemd/user/rustdesk.service
+ curUser=$(who | awk '{print $1}' | head -1)
+ systemctl --machine=${curUser}@.host --user daemon-reload
fi
fi
diff --git a/DEBIAN/postrm b/DEBIAN/postrm
old mode 100644
new mode 100755
diff --git a/DEBIAN/preinst b/DEBIAN/preinst
old mode 100644
new mode 100755
index 8b73e9962..7fbedca4a
--- a/DEBIAN/preinst
+++ b/DEBIAN/preinst
@@ -7,6 +7,13 @@ case $1 in
INITSYS=$(ls -al /proc/1/exe | awk -F' ' '{print $NF}' | awk -F'/' '{print $NF}')
if [ "systemd" == "${INITSYS}" ]; then
service rustdesk stop || true
+
+ serverUser=$(ps -ef | grep -E 'rustdesk +--server' | awk '{print $1}' | head -1)
+ if [ "$serverUser" != "" ] && [ "$serverUser" != "root" ]
+ then
+ systemctl --machine=${serverUser}@.host --user stop rustdesk || true
+ fi
+
sleep 1
rm -rf /usr/bin/libsciter-gtk.so
fi
diff --git a/DEBIAN/prerm b/DEBIAN/prerm
old mode 100644
new mode 100755
index 865b689ab..3bb453198
--- a/DEBIAN/prerm
+++ b/DEBIAN/prerm
@@ -8,7 +8,14 @@ case $1 in
if [ "systemd" == "${INITSYS}" ]; then
systemctl stop rustdesk || true
systemctl disable rustdesk || true
- rm /etc/systemd/system/rustdesk.service || true
+
+ serverUser=$(ps -ef | grep -E 'rustdesk +--server' | awk '{print $1}' | head -1)
+ if [ "$serverUser" != "" ] && [ "$serverUser" != "root" ]
+ then
+ systemctl --machine=${serverUser}@.host --user stop rustdesk || true
+ fi
+
+ rm /etc/systemd/system/rustdesk.service /usr/lib/systemd/system/rustdesk.service /usr/lib/systemd/user/rustdesk.service || true
fi
;;
esac
diff --git a/README-AR.md b/README-AR.md
index 055a654d2..636d2611e 100644
--- a/README-AR.md
+++ b/README-AR.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [česky] | [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
لغتك الأم, Doc و RustDesk UI, README نحن بحاجة إلى مساعدتك لترجمة هذا
diff --git a/README-CS.md b/README-CS.md
index 1dd5463a1..ac4567a0f 100644
--- a/README-CS.md
+++ b/README-CS.md
@@ -5,7 +5,7 @@
Docker •
Struktura •
Ukázky
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Potřebujeme Vaši pomoc s překláním textů tohoto ČTIMNE, uživatelského rozhraní aplikace RustDesk a dokumentace k ní do vašeho jazyka
diff --git a/README-DE.md b/README-DE.md
index 3f770d226..0df001e3f 100644
--- a/README-DE.md
+++ b/README-DE.md
@@ -5,11 +5,11 @@
Docker •
Dateistruktur •
Screenshots
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Wir brauchen deine Hilfe um diese README Datei zu verbessern und aktualisieren
-Rede mit uns: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+Rede mit uns: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-EO.md b/README-EO.md
index 21a4f9521..b532aa4de 100644
--- a/README-EO.md
+++ b/README-EO.md
@@ -5,11 +5,11 @@
Docker •
Strukturo •
Ekrankopio
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Ni bezonas helpon traduki tiun README kaj la interfacon al via denaska lingvo
-Babili kun ni: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+Babili kun ni: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-ES.md b/README-ES.md
index ce8601fa0..3d8f019a4 100644
--- a/README-ES.md
+++ b/README-ES.md
@@ -5,7 +5,7 @@
Docker •
Estructura •
Captura de pantalla
- [česky] | [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Necesitamos tu ayuda para traducir este README a tu idioma
diff --git a/README-FA.md b/README-FA.md
index 0f7ca1a95..0aac205a8 100644
--- a/README-FA.md
+++ b/README-FA.md
@@ -5,11 +5,11 @@
داکر •
ساخت •
سرور
- [česky] | [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
برای ترجمه این RustDesk UI ،README و Doc به زبان مادری شما به کمکتون نیاز داریم
-با ما گپ بزنید: [Reddit](https://www.reddit.com/r/rustdesk) | [Twitter](https://twitter.com/rustdesk) | [Discord](https://discord.gg/nDceKgxnkV)
+با ما گپ بزنید: [Reddit](https://www.reddit.com/r/rustdesk) | [Twitter](https://twitter.com/rustdesk) | [Discord](https://discord.gg/nDceKgxnkV)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-FI.md b/README-FI.md
index a2d7534e0..ca846007f 100644
--- a/README-FI.md
+++ b/README-FI.md
@@ -5,11 +5,11 @@
Docker •
Rakenne •
Tilannevedos
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Tarvitsemme apua tämän README-tiedoston kääntämiseksi äidinkielellesi
-Juttele meidän kanssa: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+Juttele meidän kanssa: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-FR.md b/README-FR.md
index b1f8e3670..5d421b97d 100644
--- a/README-FR.md
+++ b/README-FR.md
@@ -5,11 +5,11 @@
Docker -
Structure -
Images
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Nous avons besoin de votre aide pour traduire ce README dans votre langue maternelle.
-Chattez avec nous : [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+Chattez avec nous : [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-HU.md b/README-HU.md
new file mode 100644
index 000000000..eeeaaa37d
--- /dev/null
+++ b/README-HU.md
@@ -0,0 +1,182 @@
+
+ 
+ Szerverek •
+ Építés •
+ Docker •
+ Struktúra •
+ Képernyőképek
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ Kell a segítséged, hogy lefordítsuk ezt a README-t, a RustDesk UI-t és a Dokumentációt az anyanyelvedre
+
+
+Beszélgess velünk: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
+
+[](https://ko-fi.com/I2I04VU09)
+
+A RustDesk egy távoli elérésű asztali szoftver, Rust-ban írva. Működik mindenféle konfiguráció nélkül, feltelepítéssel, vagy anélkül. Az adataidat teljesen te kezeled, nincs szükség aggódásra a harmadik felek miatt. Használhatod a RustDesk punblikus randevú/relay szervereit, [hostolhatsz sajátot](https://rustdesk.com/server), vagy akár [írhatsz is egyet](https://github.com/rustdesk/rustdesk-server-demo).
+
+
+
+A RustDesk szívesen fogad minden contributiont, támogatást mindenkitől. Lásd a [`CONTRIBUTING.md`](CONTRIBUTING.md) fájlt a kezdéshez.
+
+[**Hogyan működik a RustDesk?**](https://github.com/rustdesk/rustdesk/wiki/How-does-RustDesk-work%3F)
+
+[**BINARY LELTÖLTÉS**](https://github.com/rustdesk/rustdesk/releases)
+
+[
](https://f-droid.org/en/packages/com.carriez.flutter_hbb)
+
+## Ingyenes publikus szerverek
+
+Ezalatt az üzenet alatt találhatóak azok a publikus szerverek, amelyeket ingyen használhatsz. Ezek a szerverek változhatnak a jövőben, illetve a hálózatuk lehet hogy lassú lehet.
+| Hely | Host | Specifikáció |
+| --------- | ------------- | ------------------ |
+| Seoul | AWS lightsail | 1 VCPU / 0.5GB RAM |
+| Singapore | Vultr | 1 VCPU / 1GB RAM |
+| Dallas | Vultr | 1 VCPU / 1GB RAM | |
+
+## Dependencies
+
+Az asztali verziók [sciter](https://sciter.com/)-t használnak a GUI-hoz, kérlek telepítsd a dynamikus könyvtárat magad.
+
+[Windows](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.win/x64/sciter.dll) |
+[Linux](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so) |
+[MacOS](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.osx/libsciter.dylib)
+
+A telefonos verziók Flutter-t hasznának. Később lehetséges hogy Sciterről Flutterre migrálunk az asztali verziókban is.
+
+## Építési pontok
+
+- Készítsd elő a Rust, C++ fejlesztői környezetet (env)
+
+- Telepítsd a [vcpkg](https://github.com/microsoft/vcpkg)-t, és állítsd be a `VCPKG_ROOT` környezeti változót helyesen
+
+ - Windows: vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static
+ - Linux/MacOS: vcpkg install libvpx libyuv opus
+
+- Futtasd a `cargo run` parancsot
+
+## [Építés](https://rustdesk.com/docs/hu/dev/build/)
+
+## Hogyan építs Linuxon
+
+### 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
+```
+
+### Fedora 28 (CentOS 8)
+
+```sh
+sudo yum -y install gcc-c++ git curl wget nasm yasm gcc gtk3-devel clang libxcb-devel libxdo-devel libXfixes-devel pulseaudio-libs-devel cmake alsa-lib-devel
+```
+
+### Arch (Manjaro)
+
+```sh
+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
+git clone https://github.com/microsoft/vcpkg
+cd vcpkg
+git checkout 2021.12.01
+cd ..
+vcpkg/bootstrap-vcpkg.sh
+export VCPKG_ROOT=$HOME/vcpkg
+vcpkg/vcpkg install libvpx libyuv opus
+```
+
+### Fixeld a libvpx-t (Fedora-n csak)
+
+```sh
+cd vcpkg/buildtrees/libvpx/src
+cd *
+./configure
+sed -i 's/CFLAGS+=-I/CFLAGS+=-fPIC -I/g' Makefile
+sed -i 's/CXXFLAGS+=-I/CXXFLAGS+=-fPIC -I/g' Makefile
+make
+cp libvpx.a $HOME/vcpkg/installed/x64-linux/lib/
+cd
+```
+
+### Építés
+
+```sh
+curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+source $HOME/.cargo/env
+git clone https://github.com/rustdesk/rustdesk
+cd rustdesk
+mkdir -p target/debug
+wget https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so
+mv libsciter-gtk.so target/debug
+VCPKG_ROOT=$HOME/vcpkg cargo run
+```
+
+### Válts Wayland-ról X11-re (Xorg)
+
+A RustDesk nem támogatja a Waylendet. [Itt](https://docs.fedoraproject.org/en-US/quick-docs/configuring-xorg-as-default-gnome-session/) található egy tutorial amelynek segítségével beállíthatod a Xorg-ot mint alap GNOME session.
+
+## Hogyan építs Dockerrel
+
+Kezdjünk a repo clónozásával, majd pedig a Docker container megépítésével:
+
+```sh
+git clone https://github.com/rustdesk/rustdesk
+cd rustdesk
+docker build -t "rustdesk-builder" .
+```
+
+Ezután, minden egyes alkalommal amikor meg kell építened a RustDesk-et, futtasd a kövezkező parancsot:
+
+```sh
+docker run --rm -it -v $PWD:/home/user/rustdesk -v rustdesk-git-cache:/home/user/.cargo/git -v rustdesk-registry-cache:/home/user/.cargo/registry -e PUID="$(id -u)" -e PGID="$(id -g)" rustdesk-builder
+```
+
+Fontos, hogy az első építés lehet hogy több ideig fog tartani mint a következőek, mivel a dependenciek még nincsenek cachelve. Emelett, ha esetleg szeretnél valamilyen argumentumot hozzáadni az építő parancshoz, akkor megteheted a paracssor végén, a `` argumentum használatával. Például ha egy optimalizált release éptést szeretnél megépíteni, akkor add hozzá a fenti parancsorhoz a `--release` opciót. A futtatható binary elérhető lesz a target mappában a rendszereden, futtatni a következőképpen tudod:
+
+```sh
+target/debug/rustdesk
+```
+
+Vagy ha release binary, akkor:
+
+```sh
+target/release/rustdesk
+```
+
+Kérlek mindenképpen nézd meg hogy ezeket a parancsokat a root RustDesk mappában futtatod e, különben a RustDesk lehet hogy nem fogja megtalálni az építéshez szükséges elemeket. Fontos az is, hogy jelenleg más cargo subparancsok, például `install`vagy `run` nem támogatottak, mivel egy Dockeres építés esetén elindítanák a programot a containeren belül.
+
+
+## Fájl Struktúra
+
+- **[libs/hbb_common](https://github.com/rustdesk/rustdesk/tree/master/libs/hbb_common)**: video codec, config, tcp/udp wrapper, protobuf, fs functions for file transfer, and some other utility functions
+- **[libs/scrap](https://github.com/rustdesk/rustdesk/tree/master/libs/scrap)**: screen capture
+- **[libs/enigo](https://github.com/rustdesk/rustdesk/tree/master/libs/enigo)**: platform specific keyboard/mouse control
+- **[src/ui](https://github.com/rustdesk/rustdesk/tree/master/src/ui)**: GUI
+- **[src/server](https://github.com/rustdesk/rustdesk/tree/master/src/server)**: audio/clipboard/input/video services, and network connections
+- **[src/client.rs](https://github.com/rustdesk/rustdesk/tree/master/src/client.rs)**: start a peer connection
+- **[src/rendezvous_mediator.rs](https://github.com/rustdesk/rustdesk/tree/master/src/rendezvous_mediator.rs)**: Communicate with [rustdesk-server](https://github.com/rustdesk/rustdesk-server), wait for remote direct (TCP hole punching) or relayed connection
+- **[src/platform](https://github.com/rustdesk/rustdesk/tree/master/src/platform)**: platform specific code
+- **[flutter](https://github.com/rustdesk/rustdesk/tree/master/flutter)**: Flutter code for mobile
+- **[flutter/web/js](https://github.com/rustdesk/rustdesk/tree/master/flutter/web/js)**: Javascript for Flutter web client
+
+## Képernyőképek
+
+
+
+
+
+
+
+
diff --git a/README-ID.md b/README-ID.md
index 624336f45..6dc00f6fd 100644
--- a/README-ID.md
+++ b/README-ID.md
@@ -5,11 +5,11 @@
Docker •
Structure •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Kami membutuhkan bantuan Anda untuk menerjemahkan README ini dan RustDesk UI ke bahasa asli anda
-Birbincang bersama kami: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+Birbincang bersama kami: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-IT.md b/README-IT.md
index 7eba7860a..6d3aaf5ee 100644
--- a/README-IT.md
+++ b/README-IT.md
@@ -5,11 +5,11 @@
Docker •
Struttura •
Screenshots
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Abbiamo bisogno del tuo aiuto per tradurre questo README e la RustDesk UI nella tua lingua nativa
-Chatta con noi: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+Chatta con noi: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-JP.md b/README-JP.md
index 60816a5d5..a912d3cf3 100644
--- a/README-JP.md
+++ b/README-JP.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
このREADMEをあなたの母国語に翻訳するために、あなたの助けが必要です。
diff --git a/README-KR.md b/README-KR.md
index 750cf91bd..11eed8ab2 100644
--- a/README-KR.md
+++ b/README-KR.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
README를 모국어로 번역하기 위한 당신의 도움의 필요합니다.
diff --git a/README-ML.md b/README-ML.md
index c479d0496..d72d14c02 100644
--- a/README-ML.md
+++ b/README-ML.md
@@ -5,11 +5,11 @@
Docker •
Structure •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
ഈ README നിങ്ങളുടെ മാതൃഭാഷയിലേക്ക് വിവർത്തനം ചെയ്യാൻ ഞങ്ങൾക്ക് നിങ്ങളുടെ സഹായം ആവശ്യമാണ്
-ഞങ്ങളുമായി ചാറ്റ് ചെയ്യുക: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+ഞങ്ങളുമായി ചാറ്റ് ചെയ്യുക: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-NL.md b/README-NL.md
index 2d87504db..cce863b6d 100644
--- a/README-NL.md
+++ b/README-NL.md
@@ -5,11 +5,11 @@
Docker •
Structuur •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
We hebben je hulp nodig om deze README te vertalen naar jouw moedertaal
-Praat met ons: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+Praat met ons: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-PL.md b/README-PL.md
index 162ca7648..d21461fee 100644
--- a/README-PL.md
+++ b/README-PL.md
@@ -5,11 +5,11 @@
Docker •
Struktura •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Potrzebujemy twojej pomocy w tłumaczeniu README na twój ojczysty język
-Porozmawiaj z nami na: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+Porozmawiaj z nami na: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-PTBR.md b/README-PTBR.md
index 76b360283..11986df55 100644
--- a/README-PTBR.md
+++ b/README-PTBR.md
@@ -5,11 +5,11 @@
Docker •
Estrutura •
Screenshots
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Precisamos de sua ajuda para traduzir este README e a UI do RustDesk para sua língua nativa
-Converse conosco: [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
+Converse conosco: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[](https://ko-fi.com/I2I04VU09)
diff --git a/README-RU.md b/README-RU.md
index 755d91ca3..3b01b8749 100644
--- a/README-RU.md
+++ b/README-RU.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Нам нужна ваша помощь для перевода этого README и RustDesk UI на ваш родной язык
diff --git a/README-ZH.md b/README-ZH.md
index cd1a332c3..cce3841ee 100644
--- a/README-ZH.md
+++ b/README-ZH.md
@@ -5,7 +5,7 @@
Docker •
结构 •
截图
- [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
Chat with us: [知乎](https://www.zhihu.com/people/rustdesk) | [Discord](https://discord.gg/nDceKgxnkV) | [Reddit](https://www.reddit.com/r/rustdesk)
diff --git a/README.md b/README.md
index 2166073a7..c00212991 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
Docker •
Structure •
Snapshot
- [česky] | [中文] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
+ [česky] | [中文] | | [Magyar] | [Español] | [فارسی] | [Français] | [Deutsch] | [Polski] | [Indonesian] | [Suomi] | [മലയാളം] | [日本語] | [Nederlands] | [Italiano] | [Русский] | [Português (Brasil)] | [Esperanto] | [한국어] | [العربي]
We need your help to translate this README, RustDesk UI and Doc to your native language
diff --git a/build.py b/build.py
index 2b7cd3f27..efa6f7831 100644
--- a/build.py
+++ b/build.py
@@ -209,12 +209,15 @@ rcodesign notarize --api-issuer 69a6de7d-2907-47e3-e053-5b8c7c11a4d1 --api-key 9
os.system('mkdir -p tmpdeb/usr/share/rustdesk/files/systemd/')
os.system(
'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 DEBIAN/* tmpdeb/DEBIAN/')
+ 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/')
diff --git a/flutter/android/app/src/main/AndroidManifest.xml b/flutter/android/app/src/main/AndroidManifest.xml
index 1759a1ac0..04b2ccc9a 100644
--- a/flutter/android/app/src/main/AndroidManifest.xml
+++ b/flutter/android/app/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
package="com.carriez.flutter_hbb">
+
diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
index 76068eee5..905a2734d 100644
--- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
+++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt
@@ -8,14 +8,14 @@ package com.carriez.flutter_hbb
import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.GestureDescription
-import android.content.Context
import android.graphics.Path
import android.os.Build
import android.util.Log
import android.view.accessibility.AccessibilityEvent
-import androidx.annotation.Keep
import androidx.annotation.RequiresApi
import java.util.*
+import kotlin.math.abs
+import kotlin.math.max
const val LIFT_DOWN = 9
const val LIFT_MOVE = 8
@@ -49,28 +49,40 @@ class InputService : AccessibilityService() {
private val wheelActionsQueue = LinkedList()
private var isWheelActionsPolling = false
+ private var isWaitingLongPress = false
@RequiresApi(Build.VERSION_CODES.N)
fun onMouseInput(mask: Int, _x: Int, _y: Int) {
- val x = if (_x < 0) {
- 0
- } else {
- _x
- }
-
- val y = if (_y < 0) {
- 0
- } else {
- _y
- }
+ val x = max(0, _x)
+ val y = max(0, _y)
if (mask == 0 || mask == LIFT_MOVE) {
+ val oldX = mouseX
+ val oldY = mouseY
mouseX = x * SCREEN_INFO.scale
mouseY = y * SCREEN_INFO.scale
+ if (isWaitingLongPress) {
+ val delta = abs(oldX - mouseX) + abs(oldY - mouseY)
+ Log.d(logTag,"delta:$delta")
+ if (delta > 8) {
+ isWaitingLongPress = false
+ }
+ }
}
// left button down ,was up
if (mask == LIFT_DOWN) {
+ isWaitingLongPress = true
+ timer.schedule(object : TimerTask() {
+ override fun run() {
+ if (isWaitingLongPress) {
+ isWaitingLongPress = false
+ leftIsDown = false
+ endGesture(mouseX, mouseY)
+ }
+ }
+ }, LONG_TAP_DELAY * 4)
+
leftIsDown = true
startGesture(mouseX, mouseY)
return
@@ -83,9 +95,12 @@ class InputService : AccessibilityService() {
// left up ,was down
if (mask == LIFT_UP) {
- leftIsDown = false
- endGesture(mouseX, mouseY)
- return
+ if (leftIsDown) {
+ leftIsDown = false
+ isWaitingLongPress = false
+ endGesture(mouseX, mouseY)
+ return
+ }
}
if (mask == RIGHT_UP) {
diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt
index 3cc105bfa..fd340f7ed 100644
--- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt
+++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/MainActivity.kt
@@ -192,7 +192,6 @@ class MainActivity : FlutterActivity() {
override fun onResume() {
super.onResume()
val inputPer = InputService.isOpen
- Log.d(logTag, "onResume inputPer:$inputPer")
activity.runOnUiThread {
flutterMethodChannel.invokeMethod(
"on_state_changed",
diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt
index 7ce7d3ecc..4bf244a06 100644
--- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt
+++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/common.kt
@@ -2,20 +2,26 @@ package com.carriez.flutter_hbb
import android.annotation.SuppressLint
import android.content.Context
+import android.content.Intent
import android.media.AudioRecord
import android.media.AudioRecord.READ_BLOCKING
import android.media.MediaCodecList
import android.media.MediaFormat
+import android.net.Uri
import android.os.Build
import android.os.Handler
import android.os.Looper
-import android.util.Log
+import android.os.PowerManager
+import android.provider.Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS
+import android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
import androidx.annotation.RequiresApi
+import androidx.core.content.ContextCompat.getSystemService
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import java.nio.ByteBuffer
import java.util.*
+
@SuppressLint("ConstantLocale")
val LOCAL_NAME = Locale.getDefault().toString()
val SCREEN_INFO = Info(0, 0, 1, 200)
@@ -38,8 +44,31 @@ fun testVP9Support(): Boolean {
return res != null
}
+@RequiresApi(Build.VERSION_CODES.M)
fun requestPermission(context: Context, type: String) {
val permission = when (type) {
+ "ignore_battery_optimizations" -> {
+ try {
+ context.startActivity(Intent(ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
+ data = Uri.parse("package:" + context.packageName)
+ })
+ } catch (e:Exception) {
+ e.printStackTrace()
+ }
+ return
+ }
+ "application_details_settings" -> {
+ try {
+ context.startActivity(Intent().apply {
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ action = "android.settings.APPLICATION_DETAILS_SETTINGS"
+ data = Uri.parse("package:" + context.packageName)
+ })
+ } catch (e:Exception) {
+ e.printStackTrace()
+ }
+ return
+ }
"audio" -> {
Permission.RECORD_AUDIO
}
@@ -52,7 +81,7 @@ fun requestPermission(context: Context, type: String) {
}
XXPermissions.with(context)
.permission(permission)
- .request { permissions, all ->
+ .request { _, all ->
if (all) {
Handler(Looper.getMainLooper()).post {
MainActivity.flutterMethodChannel.invokeMethod(
@@ -64,8 +93,13 @@ fun requestPermission(context: Context, type: String) {
}
}
+@RequiresApi(Build.VERSION_CODES.M)
fun checkPermission(context: Context, type: String): Boolean {
val permission = when (type) {
+ "ignore_battery_optimizations" -> {
+ val pw = context.getSystemService(Context.POWER_SERVICE) as PowerManager
+ return pw.isIgnoringBatteryOptimizations(context.packageName)
+ }
"audio" -> {
Permission.RECORD_AUDIO
}
diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart
index d6be51986..a7c5dfea0 100644
--- a/flutter/lib/common.dart
+++ b/flutter/lib/common.dart
@@ -260,7 +260,12 @@ class PermissionManager {
static Timer? _timer;
static var _current = "";
- static final permissions = ["audio", "file"];
+ static final permissions = [
+ "audio",
+ "file",
+ "ignore_battery_optimizations",
+ "application_details_settings"
+ ];
static bool isWaitingFile() {
if (_completer != null) {
@@ -279,9 +284,12 @@ class PermissionManager {
if (!permissions.contains(type))
return Future.error("Wrong permission!$type");
+ FFI.invokeMethod("request_permission", type);
+ if (type == "ignore_battery_optimizations") {
+ return Future.value(false);
+ }
_current = type;
_completer = Completer();
- FFI.invokeMethod("request_permission", type);
// timeout
_timer?.cancel();
diff --git a/flutter/lib/pages/remote_page.dart b/flutter/lib/pages/remote_page.dart
index c383bc361..7a3e489b0 100644
--- a/flutter/lib/pages/remote_page.dart
+++ b/flutter/lib/pages/remote_page.dart
@@ -262,7 +262,6 @@ class _RemotePageState extends State {
: SafeArea(child:
OrientationBuilder(builder: (ctx, orientation) {
if (_currentOrientation != orientation) {
- debugPrint("on orientation changed");
Timer(Duration(milliseconds: 200), () {
resetMobileActionsOverlay();
_currentOrientation = orientation;
@@ -1061,6 +1060,8 @@ void showOptions() {
getRadio('Optimize reaction time', 'low', quality, setQuality),
Divider(color: MyTheme.border),
getToggle(setState, 'show-remote-cursor', 'Show remote cursor'),
+ getToggle(
+ setState, 'show-quality-monitor', 'Show quality monitor'),
] +
more),
actions: [],
diff --git a/flutter/lib/pages/settings_page.dart b/flutter/lib/pages/settings_page.dart
index 2c8b7fe9a..30eb88b7b 100644
--- a/flutter/lib/pages/settings_page.dart
+++ b/flutter/lib/pages/settings_page.dart
@@ -1,3 +1,5 @@
+import 'dart:async';
+
import 'package:settings_ui/settings_ui.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
@@ -24,13 +26,100 @@ class SettingsPage extends StatefulWidget implements PageShape {
_SettingsState createState() => _SettingsState();
}
-class _SettingsState extends State {
+class _SettingsState extends State with WidgetsBindingObserver {
static const url = 'https://rustdesk.com/';
+ final _hasIgnoreBattery = androidVersion >= 26;
+ var _ignoreBatteryOpt = false;
+
+ @override
+ void initState() {
+ super.initState();
+ WidgetsBinding.instance.addObserver(this);
+ if (_hasIgnoreBattery) {
+ updateIgnoreBatteryStatus();
+ }
+ }
+
+ @override
+ void dispose() {
+ WidgetsBinding.instance.removeObserver(this);
+ super.dispose();
+ }
+
+ @override
+ void didChangeAppLifecycleState(AppLifecycleState state) {
+ if (state == AppLifecycleState.resumed) {
+ updateIgnoreBatteryStatus();
+ }
+ }
+
+ Future updateIgnoreBatteryStatus() async {
+ final res = await PermissionManager.check("ignore_battery_optimizations");
+ if (_ignoreBatteryOpt != res) {
+ setState(() {
+ _ignoreBatteryOpt = res;
+ });
+ return true;
+ } else {
+ return false;
+ }
+ }
@override
Widget build(BuildContext context) {
Provider.of(context);
final username = getUsername();
+ final enableAbr = FFI.getByName("option", "enable-abr") != 'N';
+ final enhancementsTiles = [
+ SettingsTile.switchTile(
+ title: Text(translate('Adaptive Bitrate') + '(beta)'),
+ initialValue: enableAbr,
+ onToggle: (v) {
+ final msg = Map()
+ ..["name"] = "enable-abr"
+ ..["value"] = "";
+ if (!v) {
+ msg["value"] = "N";
+ }
+ FFI.setByName("option", json.encode(msg));
+ setState(() {});
+ },
+ )
+ ];
+ if (_hasIgnoreBattery) {
+ enhancementsTiles.insert(
+ 0,
+ SettingsTile.switchTile(
+ initialValue: _ignoreBatteryOpt,
+ title: Text(translate('Keep RustDesk background service')),
+ description:
+ Text('* ${translate('Ignore Battery Optimizations')}'),
+ onToggle: (v) async {
+ if (v) {
+ PermissionManager.request("ignore_battery_optimizations");
+ } else {
+ final res = await DialogManager.show(
+ (setState, close) => CustomAlertDialog(
+ title: Text(translate("Open System Setting")),
+ content: Text(translate(
+ "android_open_battery_optimizations_tip")),
+ actions: [
+ TextButton(
+ onPressed: () => close(),
+ child: Text(translate("Cancel"))),
+ ElevatedButton(
+ onPressed: () => close(true),
+ child:
+ Text(translate("Open System Setting"))),
+ ],
+ ));
+ if (res == true) {
+ PermissionManager.request("application_details_settings");
+ }
+ }
+ }));
+ }
+
return SettingsList(
sections: [
SettingsSection(
@@ -51,17 +140,17 @@ class _SettingsState extends State {
),
],
),
- SettingsSection(
- title: Text(translate("Settings")),
- tiles: [
- SettingsTile.navigation(
+ SettingsSection(title: Text(translate("Settings")), tiles: [
+ SettingsTile.navigation(
title: Text(translate('ID/Relay Server')),
leading: Icon(Icons.cloud),
onPressed: (context) {
showServerSettings();
- },
- ),
- ],
+ })
+ ]),
+ SettingsSection(
+ title: Text(translate("Enhancements")),
+ tiles: enhancementsTiles,
),
SettingsSection(
title: Text(translate("About")),
diff --git a/libs/enigo/Cargo.toml b/libs/enigo/Cargo.toml
index e97f000a6..fec03d34e 100644
--- a/libs/enigo/Cargo.toml
+++ b/libs/enigo/Cargo.toml
@@ -23,6 +23,7 @@ serde = { version = "1.0", optional = true }
serde_derive = { version = "1.0", optional = true }
log = "0.4"
rdev = { git = "https://github.com/asur4s/rdev" }
+hbb_common = { path = "../hbb_common" }
[features]
with_serde = ["serde", "serde_derive"]
diff --git a/libs/enigo/src/lib.rs b/libs/enigo/src/lib.rs
index 10cde9cbe..164fb1c17 100644
--- a/libs/enigo/src/lib.rs
+++ b/libs/enigo/src/lib.rs
@@ -249,7 +249,7 @@ pub trait MouseControllable {
/// For alphabetical keys, use Key::Layout for a system independent key.
/// If a key is missing, you can use the raw keycode with Key::Raw.
#[cfg_attr(feature = "with_serde", derive(Serialize, Deserialize))]
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Key {
/// alt key on Linux and Windows (option key on macOS)
Alt,
diff --git a/libs/enigo/src/linux/mod.rs b/libs/enigo/src/linux/mod.rs
new file mode 100644
index 000000000..42e1dfebf
--- /dev/null
+++ b/libs/enigo/src/linux/mod.rs
@@ -0,0 +1,5 @@
+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
new file mode 100644
index 000000000..840290b2b
--- /dev/null
+++ b/libs/enigo/src/linux/nix_impl.rs
@@ -0,0 +1,178 @@
+use super::{pynput::EnigoPynput, xdo::EnigoXdo};
+use crate::{Key, KeyboardControllable, MouseButton, MouseControllable};
+
+/// The main struct for handling the event emitting
+// #[derive(Default)]
+pub struct Enigo {
+ xdo: EnigoXdo,
+ pynput: EnigoPynput,
+ is_x11: bool,
+ uinput_keyboard: Option>,
+ uinput_mouse: Option>,
+}
+
+impl Enigo {
+ /// Get delay of xdo implementation.
+ pub fn delay(&self) -> u64 {
+ self.xdo.delay()
+ }
+ /// Set delay of xdo implemetation.
+ 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,
+ uinput_keyboard: Option>,
+ ) {
+ self.uinput_keyboard = uinput_keyboard
+ }
+ /// Set uinput mouse.
+ pub fn set_uinput_mouse(&mut self, uinput_mouse: Option>) {
+ self.uinput_mouse = uinput_mouse
+ }
+}
+
+impl Default for Enigo {
+ fn default() -> Self {
+ Self {
+ is_x11: "x11" == hbb_common::platform::linux::get_display_server(),
+ uinput_keyboard: None,
+ uinput_mouse: None,
+ xdo: EnigoXdo::default(),
+ pynput: EnigoPynput::default(),
+ }
+ }
+}
+
+impl MouseControllable for Enigo {
+ fn mouse_move_to(&mut self, x: i32, y: i32) {
+ if self.is_x11 {
+ self.xdo.mouse_move_to(x, y);
+ } else {
+ if let Some(mouse) = &mut self.uinput_mouse {
+ mouse.mouse_move_to(x, y)
+ }
+ }
+ }
+ fn mouse_move_relative(&mut self, x: i32, y: i32) {
+ if self.is_x11 {
+ self.xdo.mouse_move_relative(x, y);
+ } else {
+ if let Some(mouse) = &mut self.uinput_mouse {
+ mouse.mouse_move_relative(x, y)
+ }
+ }
+ }
+ fn mouse_down(&mut self, button: MouseButton) -> crate::ResultType {
+ if self.is_x11 {
+ self.xdo.mouse_down(button)
+ } else {
+ if let Some(mouse) = &mut self.uinput_mouse {
+ mouse.mouse_down(button)
+ } else {
+ Ok(())
+ }
+ }
+ }
+ fn mouse_up(&mut self, button: MouseButton) {
+ if self.is_x11 {
+ self.xdo.mouse_up(button)
+ } else {
+ if let Some(mouse) = &mut self.uinput_mouse {
+ mouse.mouse_up(button)
+ }
+ }
+ }
+ fn mouse_click(&mut self, button: MouseButton) {
+ if self.is_x11 {
+ self.xdo.mouse_click(button)
+ } else {
+ if let Some(mouse) = &mut self.uinput_mouse {
+ mouse.mouse_click(button)
+ }
+ }
+ }
+ fn mouse_scroll_x(&mut self, length: i32) {
+ if self.is_x11 {
+ self.xdo.mouse_scroll_x(length)
+ } else {
+ if let Some(mouse) = &mut self.uinput_mouse {
+ mouse.mouse_scroll_x(length)
+ }
+ }
+ }
+ fn mouse_scroll_y(&mut self, length: i32) {
+ if self.is_x11 {
+ self.xdo.mouse_scroll_y(length)
+ } else {
+ if let Some(mouse) = &mut self.uinput_mouse {
+ mouse.mouse_scroll_y(length)
+ }
+ }
+ }
+}
+
+impl KeyboardControllable for Enigo {
+ fn get_key_state(&mut self, key: Key) -> bool {
+ if self.is_x11 {
+ self.xdo.get_key_state(key)
+ } else {
+ if let Some(keyboard) = &mut self.uinput_keyboard {
+ keyboard.get_key_state(key)
+ } else {
+ false
+ }
+ }
+ }
+
+ fn key_sequence(&mut self, sequence: &str) {
+ if self.is_x11 {
+ self.xdo.key_sequence(sequence)
+ } else {
+ if let Some(keyboard) = &mut self.uinput_keyboard {
+ keyboard.key_sequence(sequence)
+ }
+ }
+ }
+
+ fn key_down(&mut self, key: Key) -> crate::ResultType {
+ if self.is_x11 {
+ if self.pynput.send_pynput(&key, true) {
+ return Ok(());
+ }
+ self.xdo.key_down(key)
+ } else {
+ if let Some(keyboard) = &mut self.uinput_keyboard {
+ keyboard.key_down(key)
+ } else {
+ Ok(())
+ }
+ }
+ }
+ fn key_up(&mut self, key: Key) {
+ if self.is_x11 {
+ if self.pynput.send_pynput(&key, false) {
+ return;
+ }
+ self.xdo.key_up(key)
+ } else {
+ if let Some(keyboard) = &mut self.uinput_keyboard {
+ keyboard.key_up(key)
+ }
+ }
+ }
+ 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)
+ }
+ }
+ }
+}
diff --git a/libs/enigo/src/linux/pynput.rs b/libs/enigo/src/linux/pynput.rs
new file mode 100644
index 000000000..748b30105
--- /dev/null
+++ b/libs/enigo/src/linux/pynput.rs
@@ -0,0 +1,280 @@
+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.rs b/libs/enigo/src/linux/xdo.rs
similarity index 56%
rename from libs/enigo/src/linux.rs
rename to libs/enigo/src/linux/xdo.rs
index de06923f3..541dbe81f 100644
--- a/libs/enigo/src/linux.rs
+++ b/libs/enigo/src/linux/xdo.rs
@@ -4,6 +4,7 @@ use crate::{Key, KeyboardControllable, MouseButton, MouseControllable};
use self::libc::{c_char, c_int, c_void, useconds_t};
use std::{borrow::Cow, ffi::CString, io::prelude::*, ptr, sync::mpsc};
+
const CURRENT_WINDOW: c_int = 0;
const DEFAULT_DELAY: u64 = 12000;
type Window = c_int;
@@ -59,34 +60,25 @@ fn mousebutton(button: MouseButton) -> c_int {
}
}
-enum PyMsg {
- Char(char),
- Str(&'static str),
-}
-
/// The main struct for handling the event emitting
-pub struct Enigo {
+pub(super) struct EnigoXdo {
xdo: Xdo,
delay: u64,
- tx: mpsc::Sender<(PyMsg, bool)>,
}
// This is safe, we have a unique pointer.
// TODO: use Unique once stable.
-unsafe impl Send for Enigo {}
+unsafe impl Send for EnigoXdo {}
-impl Default for Enigo {
- /// Create a new Enigo instance
+impl Default for EnigoXdo {
+ /// Create a new EnigoXdo instance
fn default() -> Self {
- let (tx, rx) = mpsc::channel();
- start_pynput_service(rx);
Self {
xdo: unsafe { xdo_new(ptr::null()) },
delay: DEFAULT_DELAY,
- tx,
}
}
}
-impl Enigo {
+impl EnigoXdo {
/// Get the delay per keypress.
/// Default value is 12000.
/// This is Linux-specific.
@@ -98,102 +90,8 @@ impl Enigo {
pub fn set_delay(&mut self, delay: u64) {
self.delay = delay;
}
- ///
- pub fn reset(&mut self) {
- self.tx.send((PyMsg::Char('\0'), true)).ok();
- }
-
- #[inline]
- 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;
- }
- };
- return self.tx.send((PyMsg::Str(s), is_press)).is_ok();
- }
}
-impl Drop for Enigo {
+impl Drop for EnigoXdo {
fn drop(&mut self) {
if self.xdo.is_null() {
return;
@@ -203,7 +101,7 @@ impl Drop for Enigo {
}
}
}
-impl MouseControllable for Enigo {
+impl MouseControllable for EnigoXdo {
fn mouse_move_to(&mut self, x: i32, y: i32) {
if self.xdo.is_null() {
return;
@@ -378,7 +276,7 @@ fn keysequence<'a>(key: Key) -> Cow<'a, str> {
_ => "",
})
}
-impl KeyboardControllable for Enigo {
+impl KeyboardControllable for EnigoXdo {
fn get_key_state(&mut self, key: Key) -> bool {
if self.xdo.is_null() {
return false;
@@ -431,9 +329,6 @@ impl KeyboardControllable for Enigo {
if self.xdo.is_null() {
return Ok(());
}
- if self.send_pynput(&key, true) {
- return Ok(());
- }
let string = CString::new(&*keysequence(key))?;
unsafe {
xdo_send_keysequence_window_down(
@@ -449,9 +344,6 @@ impl KeyboardControllable for Enigo {
if self.xdo.is_null() {
return;
}
- if self.send_pynput(&key, false) {
- return;
- }
if let Ok(string) = CString::new(&*keysequence(key)) {
unsafe {
xdo_send_keysequence_window_up(
@@ -494,128 +386,3 @@ impl KeyboardControllable for Enigo {
crate::dsl::eval(self, sequence)
}
}
-
-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() {
- // enigo libs, not rustdesk root project, so skip using appimage features
- py = std::env::var("APPDIR").unwrap_or("".to_string())
- + "/usr/lib/rustdesk/pynput_service.py";
- if !std::path::Path::new(&py).exists() {
- log::error!("{} not exists", 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/hbb_common/Cargo.toml b/libs/hbb_common/Cargo.toml
index bc31223cc..b8db8d508 100644
--- a/libs/hbb_common/Cargo.toml
+++ b/libs/hbb_common/Cargo.toml
@@ -7,9 +7,9 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-protobuf = "3.0.0-alpha.2"
-tokio = { version = "1.15", features = ["full"] }
-tokio-util = { version = "0.6", features = ["full"] }
+protobuf = { version = "3.1", features = ["with-bytes"] }
+tokio = { version = "1.20", features = ["full"] }
+tokio-util = { version = "0.7", features = ["full"] }
futures = "0.3"
bytes = "1.1"
log = "0.4"
@@ -23,6 +23,7 @@ directories-next = "2.0"
rand = "0.8"
serde_derive = "1.0"
serde = "1.0"
+serde_with = "1.14.0"
lazy_static = "1.4"
confy = { git = "https://github.com/open-trade/confy" }
dirs-next = "2.0"
@@ -33,12 +34,13 @@ tokio-socks = { git = "https://github.com/open-trade/tokio-socks" }
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
mac_address = "1.1"
+machine-uid = "0.2"
[features]
quic = []
[build-dependencies]
-protobuf-codegen-pure = "3.0.0-alpha.2"
+protobuf-codegen = { version = "3.1" }
[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3", features = ["winuser"] }
diff --git a/libs/hbb_common/build.rs b/libs/hbb_common/build.rs
index 99dacb7ec..5c1c6af22 100644
--- a/libs/hbb_common/build.rs
+++ b/libs/hbb_common/build.rs
@@ -1,6 +1,7 @@
fn main() {
std::fs::create_dir_all("src/protos").unwrap();
- protobuf_codegen_pure::Codegen::new()
+ protobuf_codegen::Codegen::new()
+ .pure()
.out_dir("src/protos")
.inputs(&["protos/rendezvous.proto", "protos/message.proto"])
.include("protos")
diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto
index 2282bf43a..009996655 100644
--- a/libs/hbb_common/protos/message.proto
+++ b/libs/hbb_common/protos/message.proto
@@ -63,6 +63,7 @@ message LoginRequest {
PortForward port_forward = 8;
}
bool video_ack_required = 9;
+ uint64 session_id = 10;
}
message ChatMessage { string text = 1; }
diff --git a/libs/hbb_common/src/config.rs b/libs/hbb_common/src/config.rs
index b4d8eaff3..787ffe5ee 100644
--- a/libs/hbb_common/src/config.rs
+++ b/libs/hbb_common/src/config.rs
@@ -1,4 +1,11 @@
-use crate::log;
+use crate::{
+ log,
+ password_security::config::{
+ decrypt_str_or_original, decrypt_vec_or_original, encrypt_str_or_original,
+ encrypt_vec_or_original,
+ },
+};
+use anyhow::Result;
use directories_next::ProjectDirs;
use rand::Rng;
use serde_derive::{Deserialize, Serialize};
@@ -17,6 +24,7 @@ pub const CONNECT_TIMEOUT: u64 = 18_000;
pub const REG_INTERVAL: i64 = 12_000;
pub const COMPRESS_LEVEL: i32 = 3;
const SERIAL: i32 = 3;
+const PASSWORD_ENC_VERSION: &'static str = "00";
// 128x128
#[cfg(target_os = "macos")] // 128x128 on 160x160 canvas, then shrink to 128, mac looks better with padding
pub const ICON: &str = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAAyVBMVEUAAAAAcf8Acf8Acf8Acv8Acf8Acf8Acf8Acf8AcP8Acf8Ab/8AcP8Acf////8AaP/z+f/o8v/k7v/5/v/T5f8AYP/u9v/X6f+hx/+Kuv95pP8Aef/B1/+TwP9xoP8BdP/g6P+Irv9ZmP8Bgf/E3f98q/9sn/+01f+Es/9nm/9Jif8hhv8off/M4P+syP+avP86iP/c7f+xy/9yqf9Om/9hk/9Rjv+60P99tv9fpf88lv8yjf8Tgf8deP+kvP8BiP8NeP8hkP80gP8oj2VLAAAADXRSTlMA7o7qLvnaxZ1FOxYPjH9HWgAABHJJREFUeNrtm+tW4jAQgBfwuu7MtIUWsOUiCCioIIgLiqvr+z/UHq/LJKVkmwTcc/r9E2nzlU4mSTP9lpGRkZGR8VX5cZjfL+yCEXYL+/nDH//U/Pd8DgyTy39Xbv7oIAcWyB0cqbW/sweW2NtRaj8H1sgpGOwUIAH7Bkd7YJW9dXFwAJY5WNP/cmCZQnJvzIN18on5LwfWySXlxEPYAIcad8D6PdiHDbCfIFCADVBIENiFDbCbIACKPPXrZ+cP8E6/0znvP4EymgIEravIRcTxu8HxNSJ60a8W0AYECKrlAN+YwAthCd9wm1Ug6wKzIn5SgRduXfwkqDasCjx0XFzi9PV6zwNcIuhcWBOg+ikySq8C9UD4dEKWBCoOcspvAuLHTo9sCDQiFPHotRM48j8G5gVur1FdAN2uaYEuiz7xFsgEJ2RUoMUakXuBTHHoGxQYOBhHjeUBAefEnMAowFhaLBOKuOemBBbxLRQrH2PBCgMvNCPQGMeevTb9zLrPxz2Mo+QbEaijzPUcOOHMQZkKGRAIPem39+bypREMPTkQW/oCfk866zAkiIFG4yIKRE/aAnfiSd0WrORY6pFdXQEqi9mvAQm0RIOSnoCcZ8vJoz3diCnjRk+g8VP4/fuQDJ2Lxr6WwG0gXs9aTpDzW0vgDBlVUpixR8gYk44AD8FrUKHr8JQJGgIDnoDqoALxmWPQSi9AVVzm8gKUuEPGr/QCvptwJkbSYT/TC4S8C96DGjTj86aHtAI0x2WaBIq0eSYYpRa4EsdWVVwWu9O0Aj6f6dyBMnwEraeOgSYu0wZlauzA47QCbT7DgAQSE+hZWoEBF/BBmWOewNMK3BsSqKUW4MGcWqCSVmDkbvkXGKQOwg6PAUO9oL3xXhA20yaiCjuwYygRVQlUOTWTCf2SuNJTxeFjgaHByGuAIvd8ItdPLTDhS7IuqEE1YSKVOgbayLhSFQhMzYh8hwfBs1r7c505YVIQYEdNoKwxK06MJiyrpUFHiF0NAfCQUVHoiRclIXJIR6C2fqG37pBHvcWpgwzvAtYwkR5UGV2e42UISdBJETl3mg8ouo54Rcnti1/vaT+iuUQBt500Cgo4U10BeHSkk57FB0JjWkKRMWgLUA0lLodtImAQdaMiiri3+gIAPZQoutHNsgKF1aaDMhMyIdBf8Th+Bh8MTjGWCpl5Wv43tDmnF+IUVMrcZgRoiAxhtrloYizNkZaAnF5leglbNhj0wYCAbCDvGb0mP4nib7O7ZlcYQ2m1gPtIZgVgGNNMeaVAaWR+57TrqgtUnm3sHQ+kYeE6fufUubG1ez50FXbPnWgBlgSABmN3TTcsRl2yWkHRrwbiunvk/W2+Mg1hPZplPDeXRbZzStFH15s1QIVd3UImP5z/bHpeeQLvRJ7XLFUffQIlCvqlXETQbgN9/rlYABGosv+Vi9m2Xs639YLGrZd0br+odetlvdsvbN56abfd4vbCzv9Q3v/ygoOV21A4OPpfXvH4Ai+5ZGRkZGRkbJA/t/I0QMzoMiEAAAAASUVORK5CYII=
@@ -114,7 +122,7 @@ pub struct Config2 {
pub options: HashMap,
}
-#[derive(Debug, Default, Serialize, Deserialize, Clone)]
+#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
pub struct PeerConfig {
#[serde(default)]
pub password: Vec,
@@ -168,7 +176,7 @@ pub struct PeerInfoSerde {
pub platform: String,
}
-#[derive(Debug, Default, Serialize, Deserialize, Clone)]
+#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
pub struct TransferSerde {
#[serde(default)]
pub write_jobs: Vec,
@@ -207,7 +215,16 @@ fn patch(path: PathBuf) -> PathBuf {
impl Config2 {
fn load() -> Config2 {
- Config::load_::("2")
+ let mut config = Config::load_::("2");
+ if let Some(mut socks) = config.socks {
+ let (password, store) = decrypt_str_or_original(&socks.password, PASSWORD_ENC_VERSION);
+ socks.password = password;
+ config.socks = Some(socks);
+ if store {
+ config.store();
+ }
+ }
+ config
}
pub fn file() -> PathBuf {
@@ -215,7 +232,12 @@ impl Config2 {
}
fn store(&self) {
- Config::store_(self, "2");
+ let mut config = self.clone();
+ if let Some(mut socks) = config.socks {
+ socks.password = encrypt_str_or_original(&socks.password, PASSWORD_ENC_VERSION);
+ config.socks = Some(socks);
+ }
+ Config::store_(&config, "2");
}
pub fn get() -> Config2 {
@@ -267,11 +289,19 @@ impl Config {
}
fn load() -> Config {
- Config::load_::("")
+ let mut config = Config::load_::("");
+ let (password, store) = decrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION);
+ config.password = password;
+ if store {
+ config.store();
+ }
+ config
}
fn store(&self) {
- Config::store_(self, "");
+ let mut config = self.clone();
+ config.password = encrypt_str_or_original(&config.password, PASSWORD_ENC_VERSION);
+ Config::store_(&config, "");
}
pub fn file() -> PathBuf {
@@ -627,7 +657,7 @@ impl Config {
log::info!("id updated from {} to {}", id, new_id);
}
- pub fn set_password(password: &str) {
+ pub fn set_security_password(password: &str) {
let mut config = CONFIG.write().unwrap();
if password == config.password {
return;
@@ -636,13 +666,8 @@ impl Config {
config.store();
}
- pub fn get_password() -> String {
- let mut password = CONFIG.read().unwrap().password.clone();
- if password.is_empty() {
- password = Config::get_auto_password();
- Config::set_password(&password);
- }
- password
+ pub fn get_security_password() -> String {
+ CONFIG.read().unwrap().password.clone()
}
pub fn set_salt(salt: &str) {
@@ -714,7 +739,28 @@ impl PeerConfig {
pub fn load(id: &str) -> PeerConfig {
let _ = CONFIG.read().unwrap(); // for lock
match confy::load_path(&Self::path(id)) {
- Ok(config) => config,
+ Ok(config) => {
+ let mut config: PeerConfig = config;
+ let mut store = false;
+ let (password, store2) =
+ decrypt_vec_or_original(&config.password, PASSWORD_ENC_VERSION);
+ config.password = password;
+ store = store || store2;
+ config.options.get_mut("rdp_password").map(|v| {
+ let (password, store2) = decrypt_str_or_original(v, PASSWORD_ENC_VERSION);
+ *v = password;
+ store = store || store2;
+ });
+ config.options.get_mut("os-password").map(|v| {
+ let (password, store2) = decrypt_str_or_original(v, PASSWORD_ENC_VERSION);
+ *v = password;
+ store = store || store2;
+ });
+ if store {
+ config.store(id);
+ }
+ config
+ }
Err(err) => {
log::error!("Failed to load config: {}", err);
Default::default()
@@ -724,7 +770,17 @@ impl PeerConfig {
pub fn store(&self, id: &str) {
let _ = CONFIG.read().unwrap(); // for lock
- if let Err(err) = confy::store_path(Self::path(id), self) {
+ let mut config = self.clone();
+ config.password = encrypt_vec_or_original(&config.password, PASSWORD_ENC_VERSION);
+ config
+ .options
+ .get_mut("rdp_password")
+ .map(|v| *v = encrypt_str_or_original(v, PASSWORD_ENC_VERSION));
+ config
+ .options
+ .get_mut("os-password")
+ .map(|v| *v = encrypt_str_or_original(v, PASSWORD_ENC_VERSION));
+ if let Err(err) = confy::store_path(Self::path(id), config) {
log::error!("Failed to store config: {}", err);
}
}
@@ -856,10 +912,26 @@ impl LocalConfig {
}
}
+#[derive(Debug, Default, Serialize, Deserialize, Clone)]
+pub struct DiscoveryPeer {
+ pub id: String,
+ #[serde(with = "serde_with::rust::map_as_tuple_list")]
+ pub ip_mac: HashMap,
+ pub username: String,
+ pub hostname: String,
+ pub platform: String,
+ pub online: bool,
+}
+
+impl DiscoveryPeer {
+ pub fn is_same_peer(&self, other: &DiscoveryPeer) -> bool {
+ self.id == other.id && self.username == other.username
+ }
+}
+
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct LanPeers {
- #[serde(default)]
- pub peers: String,
+ pub peers: Vec,
}
impl LanPeers {
@@ -874,8 +946,10 @@ impl LanPeers {
}
}
- pub fn store(peers: String) {
- let f = LanPeers { peers };
+ pub fn store(peers: &Vec) {
+ let f = LanPeers {
+ peers: peers.clone(),
+ };
if let Err(err) = confy::store_path(Config::file_("_lan_peers"), f) {
log::error!("Failed to store lan peers: {}", err);
}
diff --git a/libs/hbb_common/src/fs.rs b/libs/hbb_common/src/fs.rs
index 4512ce940..4880b4622 100644
--- a/libs/hbb_common/src/fs.rs
+++ b/libs/hbb_common/src/fs.rs
@@ -573,7 +573,7 @@ impl TransferJob {
log::info!("file num truncated, ignoring");
} else {
match r.union {
- Some(file_transfer_send_confirm_request::Union::skip(s)) => {
+ Some(file_transfer_send_confirm_request::Union::Skip(s)) => {
if s {
log::debug!("skip file id:{}, file_num:{}", r.id, r.file_num);
self.skip_current_file();
@@ -581,7 +581,7 @@ impl TransferJob {
self.set_file_confirmed(true);
}
}
- Some(file_transfer_send_confirm_request::Union::offset_blk(_offset)) => {
+ Some(file_transfer_send_confirm_request::Union::OffsetBlk(_offset)) => {
self.set_file_confirmed(true);
}
_ => {}
diff --git a/libs/hbb_common/src/lib.rs b/libs/hbb_common/src/lib.rs
index 0a9dace0c..a5443db0f 100644
--- a/libs/hbb_common/src/lib.rs
+++ b/libs/hbb_common/src/lib.rs
@@ -1,9 +1,10 @@
pub mod compress;
-#[path = "./protos/message.rs"]
-pub mod message_proto;
-#[path = "./protos/rendezvous.rs"]
-pub mod rendezvous_proto;
+pub mod protos;
+pub mod platform;
+pub use protos::message as message_proto;
+pub use protos::rendezvous as rendezvous_proto;
pub use bytes;
+use config::Config;
pub use futures;
pub use protobuf;
use std::{
@@ -27,6 +28,7 @@ pub use anyhow::{self, bail};
pub use futures_util;
pub mod config;
pub mod fs;
+pub use lazy_static;
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub use mac_address;
pub use rand;
@@ -35,7 +37,7 @@ pub use sodiumoxide;
pub use tokio_socks;
pub use tokio_socks::IntoTargetAddr;
pub use tokio_socks::TargetAddr;
-pub use lazy_static;
+pub mod password_security;
#[cfg(feature = "quic")]
pub type Stream = quic::Connection;
@@ -200,6 +202,14 @@ pub fn get_modified_time(path: &std::path::Path) -> SystemTime {
.unwrap_or(UNIX_EPOCH)
}
+pub fn get_uuid() -> Vec {
+ #[cfg(not(any(target_os = "android", target_os = "ios")))]
+ if let Ok(id) = machine_uid::get() {
+ return id.into();
+ }
+ Config::get_key_pair().1
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/libs/hbb_common/src/password_security.rs b/libs/hbb_common/src/password_security.rs
new file mode 100644
index 000000000..ed6376ff9
--- /dev/null
+++ b/libs/hbb_common/src/password_security.rs
@@ -0,0 +1,330 @@
+pub mod password {
+ use crate::config::Config;
+ use std::{
+ fmt::Display,
+ str::FromStr,
+ sync::{Arc, RwLock},
+ };
+
+ lazy_static::lazy_static! {
+ pub static ref RANDOM_PASSWORD:Arc> = Arc::new(RwLock::new(Config::get_auto_password()));
+ }
+
+ const SECURITY_ENABLED: &'static str = "security-password-enabled";
+ const RANDOM_ENABLED: &'static str = "random-password-enabled";
+ const ONETIME_ENABLED: &'static str = "onetime-password-enabled";
+ const ONETIME_ACTIVATED: &'static str = "onetime-password-activated";
+ const UPDATE_METHOD: &'static str = "random-password-update-method";
+
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub enum UpdateMethod {
+ KEEP,
+ UPDATE,
+ DISABLE,
+ }
+
+ impl FromStr for UpdateMethod {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result {
+ if s == "KEEP" {
+ Ok(Self::KEEP)
+ } else if s == "UPDATE" {
+ Ok(Self::UPDATE)
+ } else if s == "DISABLE" {
+ Ok(Self::DISABLE)
+ } else {
+ Err(())
+ }
+ }
+ }
+
+ impl Display for UpdateMethod {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ UpdateMethod::KEEP => write!(f, "KEEP"),
+ UpdateMethod::UPDATE => write!(f, "UPDATE"),
+ UpdateMethod::DISABLE => write!(f, "DISABLE"),
+ }
+ }
+ }
+
+ pub fn set_random_password(password: &str) {
+ *RANDOM_PASSWORD.write().unwrap() = password.to_owned();
+ }
+
+ pub fn random_password() -> String {
+ let mut password = RANDOM_PASSWORD.read().unwrap().clone();
+ if password.is_empty() {
+ password = Config::get_auto_password();
+ set_random_password(&password);
+ }
+ password
+ }
+
+ pub fn random_password_valid() -> bool {
+ if random_enabled() {
+ onetime_password_activated() || !onetime_password_enabled()
+ } else {
+ false
+ }
+ }
+
+ pub fn passwords() -> Vec {
+ let mut v = vec![];
+ if random_password_valid() {
+ v.push(random_password());
+ }
+ if security_enabled() {
+ v.push(Config::get_security_password());
+ }
+ v
+ }
+
+ pub fn after_session(authorized: bool) {
+ if authorized && random_enabled() {
+ UpdateMethod::from_str(&update_method())
+ .map(|method| match method {
+ UpdateMethod::KEEP => {}
+ UpdateMethod::UPDATE => set_random_password(&Config::get_auto_password()),
+ UpdateMethod::DISABLE => set_random_enabled(false),
+ })
+ .ok();
+ }
+ }
+
+ pub fn update_method() -> String {
+ let mut method = Config::get_option(UPDATE_METHOD);
+ if UpdateMethod::from_str(&method).is_err() {
+ method = UpdateMethod::KEEP.to_string(); // default is keep
+ set_update_method(&method);
+ }
+ method
+ }
+
+ pub fn set_update_method(method: &str) {
+ Config::set_option(UPDATE_METHOD.to_owned(), method.to_owned());
+ }
+
+ pub fn random_enabled() -> bool {
+ str2bool(RANDOM_ENABLED, true, || {
+ set_onetime_password_activated(false);
+ set_random_password(&Config::get_auto_password());
+ })
+ }
+
+ pub fn set_random_enabled(enabled: bool) {
+ if enabled != random_enabled() {
+ Config::set_option(RANDOM_ENABLED.to_owned(), bool2str(enabled));
+ set_onetime_password_activated(false);
+ if enabled {
+ set_random_password(&Config::get_auto_password());
+ }
+ }
+ }
+
+ pub fn security_enabled() -> bool {
+ str2bool(SECURITY_ENABLED, true, || {})
+ }
+
+ pub fn set_security_enabled(enabled: bool) {
+ if enabled != security_enabled() {
+ Config::set_option(SECURITY_ENABLED.to_owned(), bool2str(enabled));
+ }
+ }
+
+ pub fn onetime_password_enabled() -> bool {
+ str2bool(ONETIME_ENABLED, false, || {
+ set_onetime_password_activated(false);
+ set_random_password(&Config::get_auto_password());
+ })
+ }
+
+ pub fn set_onetime_password_enabled(enabled: bool) {
+ if enabled != onetime_password_enabled() {
+ Config::set_option(ONETIME_ENABLED.to_owned(), bool2str(enabled));
+ set_onetime_password_activated(false);
+ set_random_password(&Config::get_auto_password());
+ }
+ }
+
+ pub fn onetime_password_activated() -> bool {
+ str2bool(ONETIME_ACTIVATED, false, || {})
+ }
+
+ pub fn set_onetime_password_activated(activated: bool) {
+ if activated != onetime_password_activated() {
+ Config::set_option(ONETIME_ACTIVATED.to_owned(), bool2str(activated));
+ if activated {
+ set_random_password(&Config::get_auto_password());
+ }
+ }
+ }
+
+ // notice: Function nesting
+ fn str2bool(key: &str, default: bool, default_set: impl Fn()) -> bool {
+ let option = Config::get_option(key);
+ if option == "Y" {
+ true
+ } else if option == "N" {
+ false
+ } else {
+ Config::set_option(key.to_owned(), bool2str(default));
+ default_set();
+ default
+ }
+ }
+
+ fn bool2str(option: bool) -> String {
+ if option { "Y" } else { "N" }.to_owned()
+ }
+}
+
+pub mod config {
+ use super::base64::decrypt as decrypt00;
+ use super::base64::encrypt as encrypt00;
+
+ const VERSION_LEN: usize = 2;
+
+ pub fn encrypt_str_or_original(s: &str, version: &str) -> String {
+ if version.len() == VERSION_LEN {
+ if version == "00" {
+ if let Ok(s) = encrypt00(s.as_bytes()) {
+ return version.to_owned() + &s;
+ }
+ }
+ }
+
+ s.to_owned()
+ }
+
+ // bool: whether should store to re-encrypt when load
+ pub fn decrypt_str_or_original(s: &str, current_version: &str) -> (String, bool) {
+ if s.len() > VERSION_LEN {
+ let version = &s[..VERSION_LEN];
+ if version == "00" {
+ if let Ok(v) = decrypt00(&s[VERSION_LEN..].as_bytes()) {
+ return (
+ String::from_utf8_lossy(&v).to_string(),
+ version != current_version,
+ );
+ }
+ }
+ }
+
+ (s.to_owned(), !s.is_empty())
+ }
+
+ pub fn encrypt_vec_or_original(v: &[u8], version: &str) -> Vec {
+ if version.len() == VERSION_LEN {
+ if version == "00" {
+ if let Ok(s) = encrypt00(v) {
+ let mut version = version.to_owned().into_bytes();
+ version.append(&mut s.into_bytes());
+ return version;
+ }
+ }
+ }
+
+ v.to_owned()
+ }
+
+ // bool: whether should store to re-encrypt when load
+ pub fn decrypt_vec_or_original(v: &[u8], current_version: &str) -> (Vec, bool) {
+ if v.len() > VERSION_LEN {
+ let version = String::from_utf8_lossy(&v[..VERSION_LEN]);
+ if version == "00" {
+ if let Ok(v) = decrypt00(&v[VERSION_LEN..]) {
+ return (v, version != current_version);
+ }
+ }
+ }
+
+ (v.to_owned(), !v.is_empty())
+ }
+
+ mod test {
+
+ #[test]
+ fn test() {
+ use crate::password_security::config::*;
+
+ println!("test str");
+ let data = "Hello World";
+ let encrypted = encrypt_str_or_original(data, "00");
+ let (decrypted, store) = decrypt_str_or_original(&encrypted, "00");
+ println!("data: {}", data);
+ println!("encrypted: {}", encrypted);
+ println!("decrypted: {}", decrypted);
+ assert_eq!(data, decrypted);
+ assert_eq!("00", &encrypted[..2]);
+ assert_eq!(store, false);
+ let (_, store2) = decrypt_str_or_original(&encrypted, "01");
+ assert_eq!(store2, true);
+
+ println!("test vec");
+ let data: Vec = vec![1, 2, 3, 4];
+ let encrypted = encrypt_vec_or_original(&data, "00");
+ let (decrypted, store) = decrypt_vec_or_original(&encrypted, "00");
+ println!("data: {:?}", data);
+ println!("encrypted: {:?}", encrypted);
+ println!("decrypted: {:?}", decrypted);
+ assert_eq!(data, decrypted);
+ assert_eq!("00".as_bytes(), &encrypted[..2]);
+ assert_eq!(store, false);
+ let (_, store2) = decrypt_vec_or_original(&encrypted, "01");
+ assert_eq!(store2, true);
+
+ println!("test old");
+ let data = "00Hello World";
+ let (decrypted, store) = decrypt_str_or_original(&data, "00");
+ assert_eq!(data, decrypted);
+ assert_eq!(store, true);
+ let data: Vec = vec!['0' as u8, '0' as u8, 1, 2, 3, 4];
+ let (decrypted, store) = decrypt_vec_or_original(&data, "00");
+ assert_eq!(data, decrypted);
+ assert_eq!(store, true);
+ let (_, store) = decrypt_str_or_original("", "00");
+ assert_eq!(store, false);
+ let (_, store) = decrypt_vec_or_original(&vec![], "00");
+ assert_eq!(store, false);
+ }
+ }
+}
+
+mod base64 {
+ use super::symmetric_crypt;
+ use sodiumoxide::base64;
+
+ pub fn encrypt(v: &[u8]) -> Result {
+ if v.len() > 0 {
+ symmetric_crypt(v, true).map(|v| base64::encode(v, base64::Variant::Original))
+ } else {
+ Err(())
+ }
+ }
+
+ pub fn decrypt(v: &[u8]) -> Result, ()> {
+ if v.len() > 0 {
+ base64::decode(v, base64::Variant::Original).and_then(|v| symmetric_crypt(&v, false))
+ } else {
+ Err(())
+ }
+ }
+}
+
+fn symmetric_crypt(data: &[u8], encrypt: bool) -> Result, ()> {
+ use sodiumoxide::crypto::secretbox;
+ use std::convert::TryInto;
+
+ let mut keybuf = crate::get_uuid();
+ keybuf.resize(secretbox::KEYBYTES, 0);
+ let key = secretbox::Key(keybuf.try_into().map_err(|_| ())?);
+ let nonce = secretbox::Nonce([0; secretbox::NONCEBYTES]);
+
+ if encrypt {
+ Ok(secretbox::seal(data, &nonce, &key))
+ } else {
+ secretbox::open(data, &nonce, &key)
+ }
+}
diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs
new file mode 100644
index 000000000..da79e9e39
--- /dev/null
+++ b/libs/hbb_common/src/platform/linux.rs
@@ -0,0 +1,102 @@
+use crate::ResultType;
+
+pub fn get_display_server() -> String {
+ let session = get_value_of_seat0(0);
+ get_display_server_of_session(&session)
+}
+
+fn get_display_server_of_session(session: &str) -> String {
+ if let Ok(output) = std::process::Command::new("loginctl")
+ .args(vec!["show-session", "-p", "Type", session])
+ .output()
+ // Check session type of the session
+ {
+ let display_server = String::from_utf8_lossy(&output.stdout)
+ .replace("Type=", "")
+ .trim_end()
+ .into();
+ if display_server == "tty" {
+ // If the type is tty...
+ if let Ok(output) = std::process::Command::new("loginctl")
+ .args(vec!["show-session", "-p", "TTY", session])
+ .output()
+ // Get the tty number
+ {
+ let tty: String = String::from_utf8_lossy(&output.stdout)
+ .replace("TTY=", "")
+ .trim_end()
+ .into();
+ if let Ok(xorg_results) = run_cmds(format!("ps -e | grep \"{}.\\\\+Xorg\"", tty))
+ // And check if Xorg is running on that tty
+ {
+ if xorg_results.trim_end().to_string() != "" {
+ // If it is, manually return "x11", otherwise return tty
+ "x11".to_owned()
+ } else {
+ display_server
+ }
+ } else {
+ // If any of these commands fail just fall back to the display server
+ display_server
+ }
+ } else {
+ display_server
+ }
+ } else {
+ // If the session is not a tty, then just return the type as usual
+ display_server
+ }
+ } else {
+ "".to_owned()
+ }
+}
+
+pub fn get_value_of_seat0(i: usize) -> String {
+ if let Ok(output) = std::process::Command::new("loginctl").output() {
+ for line in String::from_utf8_lossy(&output.stdout).lines() {
+ if line.contains("seat0") {
+ if let Some(sid) = line.split_whitespace().nth(0) {
+ if is_active(sid) {
+ if let Some(uid) = line.split_whitespace().nth(i) {
+ return uid.to_owned();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // some case, there is no seat0 https://github.com/rustdesk/rustdesk/issues/73
+ if let Ok(output) = std::process::Command::new("loginctl").output() {
+ for line in String::from_utf8_lossy(&output.stdout).lines() {
+ if let Some(sid) = line.split_whitespace().nth(0) {
+ let d = get_display_server_of_session(sid);
+ if is_active(sid) && d != "tty" {
+ if let Some(uid) = line.split_whitespace().nth(i) {
+ return uid.to_owned();
+ }
+ }
+ }
+ }
+ }
+
+ return "".to_owned();
+}
+
+fn is_active(sid: &str) -> bool {
+ if let Ok(output) = std::process::Command::new("loginctl")
+ .args(vec!["show-session", "-p", "State", sid])
+ .output()
+ {
+ String::from_utf8_lossy(&output.stdout).contains("active")
+ } else {
+ false
+ }
+}
+
+pub fn run_cmds(cmds: String) -> ResultType {
+ let output = std::process::Command::new("sh")
+ .args(vec!["-c", &cmds])
+ .output()?;
+ Ok(String::from_utf8_lossy(&output.stdout).to_string())
+}
diff --git a/libs/hbb_common/src/platform/mod.rs b/libs/hbb_common/src/platform/mod.rs
new file mode 100644
index 000000000..8daba257f
--- /dev/null
+++ b/libs/hbb_common/src/platform/mod.rs
@@ -0,0 +1,2 @@
+#[cfg(target_os = "linux")]
+pub mod linux;
diff --git a/libs/hbb_common/src/udp.rs b/libs/hbb_common/src/udp.rs
index 4213392a5..3532dd1e0 100644
--- a/libs/hbb_common/src/udp.rs
+++ b/libs/hbb_common/src/udp.rs
@@ -27,6 +27,8 @@ fn new_socket(addr: SocketAddr, reuse: bool, buf_size: usize) -> Result 0 {
socket.set_recv_buffer_size(buf_size).ok();
}
diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs
index e06c0e29a..1d9deba68 100644
--- a/libs/scrap/src/common/codec.rs
+++ b/libs/scrap/src/common/codec.rs
@@ -251,11 +251,11 @@ impl Decoder {
rgb: &mut Vec,
) -> ResultType {
match frame {
- video_frame::Union::vp9s(vp9s) => {
+ video_frame::Union::Vp9s(vp9s) => {
Decoder::handle_vp9s_video_frame(&mut self.vpx, vp9s, rgb)
}
#[cfg(feature = "hwcodec")]
- video_frame::Union::h264s(h264s) => {
+ video_frame::Union::H264s(h264s) => {
if let Some(decoder) = &mut self.hw.h264 {
Decoder::handle_hw_video_frame(decoder, h264s, rgb, &mut self.i420)
} else {
@@ -263,7 +263,7 @@ impl Decoder {
}
}
#[cfg(feature = "hwcodec")]
- video_frame::Union::h265s(h265s) => {
+ video_frame::Union::H265s(h265s) => {
if let Some(decoder) = &mut self.hw.h265 {
Decoder::handle_hw_video_frame(decoder, h265s, rgb, &mut self.i420)
} else {
diff --git a/libs/scrap/src/common/dxgi.rs b/libs/scrap/src/common/dxgi.rs
index 1a8c39885..855ac7ac3 100644
--- a/libs/scrap/src/common/dxgi.rs
+++ b/libs/scrap/src/common/dxgi.rs
@@ -21,6 +21,10 @@ impl Capturer {
})
}
+ pub fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.inner.set_use_yuv(use_yuv);
+ }
+
pub fn is_gdi(&self) -> bool {
self.inner.is_gdi()
}
@@ -41,8 +45,8 @@ impl Capturer {
self.height
}
- pub fn frame<'a>(&'a mut self, timeout_ms: Duration) -> io::Result> {
- match self.inner.frame(timeout_ms.as_millis() as _) {
+ pub fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result> {
+ match self.inner.frame(timeout.as_millis() as _) {
Ok(frame) => Ok(Frame(frame)),
Err(ref error) if error.kind() == TimedOut => Err(WouldBlock.into()),
Err(error) => Err(error),
@@ -129,6 +133,11 @@ impl CapturerMag {
data: Vec::new(),
})
}
+
+ pub fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.inner.set_use_yuv(use_yuv)
+ }
+
pub fn exclude(&mut self, cls: &str, name: &str) -> io::Result {
self.inner.exclude(cls, name)
}
diff --git a/libs/scrap/src/common/linux.rs b/libs/scrap/src/common/linux.rs
index 50bab092c..8498ab7ff 100644
--- a/libs/scrap/src/common/linux.rs
+++ b/libs/scrap/src/common/linux.rs
@@ -2,7 +2,7 @@ use crate::common::{
wayland,
x11::{self, Frame},
};
-use std::io;
+use std::{io, time::Duration};
pub enum Capturer {
X11(x11::Capturer),
@@ -17,6 +17,13 @@ impl Capturer {
})
}
+ pub fn set_use_yuv(&mut self, use_yuv: bool) {
+ match self {
+ Capturer::X11(d) => d.set_use_yuv(use_yuv),
+ Capturer::WAYLAND(d) => d.set_use_yuv(use_yuv),
+ }
+ }
+
pub fn width(&self) -> usize {
match self {
Capturer::X11(d) => d.width(),
@@ -31,10 +38,10 @@ impl Capturer {
}
}
- pub fn frame<'a>(&'a mut self, timeout_ms: u32) -> io::Result> {
+ pub fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result> {
match self {
- Capturer::X11(d) => d.frame(timeout_ms),
- Capturer::WAYLAND(d) => d.frame(timeout_ms),
+ Capturer::X11(d) => d.frame(timeout),
+ Capturer::WAYLAND(d) => d.frame(timeout),
}
}
}
@@ -45,31 +52,30 @@ pub enum Display {
}
#[inline]
-fn is_wayland() -> bool {
- std::env::var("IS_WAYLAND").is_ok()
- || std::env::var("XDG_SESSION_TYPE") == Ok("wayland".to_owned())
+pub fn is_x11() -> bool {
+ "x11" == hbb_common::platform::linux::get_display_server()
}
impl Display {
pub fn primary() -> io::Result {
- Ok(if is_wayland() {
- Display::WAYLAND(wayland::Display::primary()?)
- } else {
+ Ok(if is_x11() {
Display::X11(x11::Display::primary()?)
+ } else {
+ Display::WAYLAND(wayland::Display::primary()?)
})
}
pub fn all() -> io::Result> {
- Ok(if is_wayland() {
- wayland::Display::all()?
- .drain(..)
- .map(|x| Display::WAYLAND(x))
- .collect()
- } else {
+ Ok(if is_x11() {
x11::Display::all()?
.drain(..)
.map(|x| Display::X11(x))
.collect()
+ } else {
+ wayland::Display::all()?
+ .drain(..)
+ .map(|x| Display::WAYLAND(x))
+ .collect()
})
}
diff --git a/libs/scrap/src/common/mod.rs b/libs/scrap/src/common/mod.rs
index 792ea14e1..9115bfd3a 100644
--- a/libs/scrap/src/common/mod.rs
+++ b/libs/scrap/src/common/mod.rs
@@ -11,6 +11,7 @@ cfg_if! {
mod wayland;
mod x11;
pub use self::linux::*;
+ pub use self::x11::Frame;
} else {
mod x11;
pub use self::x11::*;
diff --git a/libs/scrap/src/common/wayland.rs b/libs/scrap/src/common/wayland.rs
index ff6bf8022..05bb08744 100644
--- a/libs/scrap/src/common/wayland.rs
+++ b/libs/scrap/src/common/wayland.rs
@@ -1,6 +1,6 @@
use crate::common::x11::Frame;
use crate::wayland::{capturable::*, *};
-use std::io;
+use std::{io, time::Duration};
pub struct Capturer(Display, Box, bool, Vec);
@@ -14,6 +14,10 @@ impl Capturer {
Ok(Capturer(display, r, yuv, Default::default()))
}
+ pub fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.2 = use_yuv;
+ }
+
pub fn width(&self) -> usize {
self.0.width()
}
@@ -22,8 +26,8 @@ impl Capturer {
self.0.height()
}
- pub fn frame<'a>(&'a mut self, timeout_ms: u32) -> io::Result> {
- match self.1.capture(timeout_ms as _).map_err(map_err)? {
+ pub fn frame<'a>(&'a mut self, timeout: Duration) -> io::Result> {
+ match self.1.capture(timeout.as_millis() as _).map_err(map_err)? {
PixelProvider::BGR0(w, h, x) => Ok(Frame(if self.2 {
crate::common::bgra_to_i420(w as _, h as _, &x, &mut self.3);
&self.3[..]
diff --git a/libs/scrap/src/common/x11.rs b/libs/scrap/src/common/x11.rs
index 255819902..c1a25c8d6 100644
--- a/libs/scrap/src/common/x11.rs
+++ b/libs/scrap/src/common/x11.rs
@@ -8,6 +8,10 @@ impl Capturer {
x11::Capturer::new(display.0, yuv).map(Capturer)
}
+ pub fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.0.set_use_yuv(use_yuv);
+ }
+
pub fn width(&self) -> usize {
self.0.display().rect().w as usize
}
diff --git a/libs/scrap/src/dxgi/mag.rs b/libs/scrap/src/dxgi/mag.rs
index 9adf26cdb..78f14194c 100644
--- a/libs/scrap/src/dxgi/mag.rs
+++ b/libs/scrap/src/dxgi/mag.rs
@@ -446,6 +446,10 @@ impl CapturerMag {
Ok(s)
}
+ pub(crate) fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.use_yuv = use_yuv;
+ }
+
pub(crate) fn exclude(&mut self, cls: &str, name: &str) -> Result {
let name_c = CString::new(name).unwrap();
unsafe {
diff --git a/libs/scrap/src/dxgi/mod.rs b/libs/scrap/src/dxgi/mod.rs
index 46692535d..6b60b256d 100644
--- a/libs/scrap/src/dxgi/mod.rs
+++ b/libs/scrap/src/dxgi/mod.rs
@@ -156,6 +156,10 @@ impl Capturer {
})
}
+ pub fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.use_yuv = use_yuv;
+ }
+
pub fn is_gdi(&self) -> bool {
self.gdi_capturer.is_some()
}
diff --git a/libs/scrap/src/x11/capturer.rs b/libs/scrap/src/x11/capturer.rs
index 890b9db63..ed424c35a 100644
--- a/libs/scrap/src/x11/capturer.rs
+++ b/libs/scrap/src/x11/capturer.rs
@@ -74,6 +74,10 @@ impl Capturer {
Ok(c)
}
+ pub fn set_use_yuv(&mut self, use_yuv: bool) {
+ self.use_yuv = use_yuv;
+ }
+
pub fn display(&self) -> &Display {
&self.display
}
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
new file mode 100644
index 000000000..05dfa3270
--- /dev/null
+++ b/rust-toolchain.toml
@@ -0,0 +1,2 @@
+[toolchain]
+channel = "1.62.0"
diff --git a/rustdesk.service b/rustdesk.service
index af4a3c411..e703b056f 100644
--- a/rustdesk.service
+++ b/rustdesk.service
@@ -6,7 +6,7 @@ After=systemd-user-sessions.service
[Service]
Type=simple
ExecStart=/usr/bin/rustdesk --service
-PIDFile=/var/run/rustdesk.pid
+PIDFile=/run/rustdesk.pid
KillMode=mixed
TimeoutStopSec=30
User=root
diff --git a/rustdesk.service.user b/rustdesk.service.user
new file mode 100644
index 000000000..f6c7454c9
--- /dev/null
+++ b/rustdesk.service.user
@@ -0,0 +1,15 @@
+[Unit]
+Description=RustDesk user service (--server)
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/rustdesk --server
+PIDFile=/run/rustdesk.user.pid
+KillMode=mixed
+TimeoutStopSec=30
+LimitNOFILE=100000
+Restart=on-failure
+RestartSec=3
+
+[Install]
+WantedBy=multi-user.target
diff --git a/src/client.rs b/src/client.rs
index d63ce970c..28101896e 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -28,6 +28,7 @@ use hbb_common::{
log,
message_proto::{option_message::BoolOption, *},
protobuf::Message as _,
+ rand,
rendezvous_proto::*,
socket_client,
sodiumoxide::crypto::{box_, secretbox, sign},
@@ -148,11 +149,25 @@ impl Client {
true,
));
}
- let rendezvous_server = crate::get_rendezvous_server(1_000).await;
- log::info!("rendezvous server: {}", rendezvous_server);
-
+ let (mut rendezvous_server, servers, contained) = crate::get_rendezvous_server(1_000).await;
let mut socket =
- socket_client::connect_tcp(&*rendezvous_server, any_addr, RENDEZVOUS_TIMEOUT).await?;
+ socket_client::connect_tcp(&*rendezvous_server, any_addr, RENDEZVOUS_TIMEOUT).await;
+ debug_assert!(!servers.contains(&rendezvous_server));
+ if socket.is_err() && !servers.is_empty() {
+ log::info!("try the other servers: {:?}", servers);
+ for server in servers {
+ socket = socket_client::connect_tcp(&*server, any_addr, RENDEZVOUS_TIMEOUT).await;
+ if socket.is_ok() {
+ rendezvous_server = server;
+ break;
+ }
+ }
+ crate::refresh_rendezvous_server();
+ } else if !contained {
+ crate::refresh_rendezvous_server();
+ }
+ log::info!("rendezvous server: {}", rendezvous_server);
+ let mut socket = socket?;
let my_addr = socket.local_addr();
let mut signed_id_pk = Vec::new();
let mut relay_server = "".to_owned();
@@ -165,7 +180,7 @@ impl Client {
for i in 1..=3 {
log::info!("#{} punch attempt with {}, id: {}", i, my_addr, peer);
let mut msg_out = RendezvousMessage::new();
- use hbb_common::protobuf::ProtobufEnum;
+ use hbb_common::protobuf::Enum;
let nat_type = NatType::from_i32(my_nat_type).unwrap_or(NatType::UNKNOWN_NAT);
msg_out.set_punch_hole_request(PunchHoleRequest {
id: peer.to_owned(),
@@ -179,7 +194,7 @@ impl Client {
if let Some(Ok(bytes)) = socket.next_timeout(i * 6000).await {
if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
match msg_in.union {
- Some(rendezvous_message::Union::punch_hole_response(ph)) => {
+ Some(rendezvous_message::Union::PunchHoleResponse(ph)) => {
if ph.socket_addr.is_empty() {
if !ph.other_failure.is_empty() {
bail!(ph.other_failure);
@@ -199,8 +214,8 @@ impl Client {
}
}
} else {
- peer_nat_type = ph.get_nat_type();
- is_local = ph.get_is_local();
+ peer_nat_type = ph.nat_type();
+ is_local = ph.is_local();
signed_id_pk = ph.pk;
relay_server = ph.relay_server;
peer_addr = AddrMangle::decode(&ph.socket_addr);
@@ -208,13 +223,13 @@ impl Client {
break;
}
}
- Some(rendezvous_message::Union::relay_response(rr)) => {
+ Some(rendezvous_message::Union::RelayResponse(rr)) => {
log::info!(
"relay requested from peer, time used: {:?}, relay_server: {}",
start.elapsed(),
rr.relay_server
);
- signed_id_pk = rr.get_pk().into();
+ signed_id_pk = rr.pk().into();
let mut conn =
Self::create_relay(peer, rr.uuid, rr.relay_server, key, conn_type)
.await?;
@@ -383,7 +398,7 @@ impl Client {
Some(res) => {
let bytes = res?;
if let Ok(msg_in) = Message::parse_from_bytes(&bytes) {
- if let Some(message::Union::signed_id(si)) = msg_in.union {
+ if let Some(message::Union::SignedId(si)) = msg_in.union {
if let Ok((id, their_pk_b)) = decode_id_pk(&si.id, &sign_pk) {
if id == peer_id {
let their_pk_b = box_::PublicKey(their_pk_b);
@@ -466,7 +481,7 @@ impl Client {
socket.send(&msg_out).await?;
if let Some(Ok(bytes)) = socket.next_timeout(CONNECT_TIMEOUT).await {
if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
- if let Some(rendezvous_message::Union::relay_response(rs)) = msg_in.union {
+ if let Some(rendezvous_message::Union::RelayResponse(rs)) = msg_in.union {
if !rs.refuse_reason.is_empty() {
bail!(rs.refuse_reason);
}
@@ -768,6 +783,7 @@ pub struct LoginConfigHandler {
pub version: i64,
pub conn_id: i32,
features: Option,
+ session_id: u64,
}
impl Deref for LoginConfigHandler {
@@ -791,6 +807,7 @@ impl LoginConfigHandler {
let config = self.load_config();
self.remember = !config.password.is_empty();
self.config = config;
+ self.session_id = rand::random();
}
pub fn should_auto_login(&self) -> String {
@@ -1126,6 +1143,7 @@ impl LoginConfigHandler {
my_id,
my_name: crate::username(),
option: self.get_option_message(true).into(),
+ session_id: self.session_id,
..Default::default()
};
if self.is_file_transfer {
diff --git a/src/client/helper.rs b/src/client/helper.rs
index ea12cb7ee..26dc37ba4 100644
--- a/src/client/helper.rs
+++ b/src/client/helper.rs
@@ -69,9 +69,9 @@ pub enum CodecFormat {
impl From<&VideoFrame> for CodecFormat {
fn from(it: &VideoFrame) -> Self {
match it.union {
- Some(video_frame::Union::vp9s(_)) => CodecFormat::VP9,
- Some(video_frame::Union::h264s(_)) => CodecFormat::H264,
- Some(video_frame::Union::h265s(_)) => CodecFormat::H265,
+ Some(video_frame::Union::Vp9s(_)) => CodecFormat::VP9,
+ Some(video_frame::Union::H264s(_)) => CodecFormat::H264,
+ Some(video_frame::Union::H265s(_)) => CodecFormat::H265,
_ => CodecFormat::Unknown,
}
}
diff --git a/src/clipboard_file.rs b/src/clipboard_file.rs
index 39b2eb766..2f35065c9 100644
--- a/src/clipboard_file.rs
+++ b/src/clipboard_file.rs
@@ -17,8 +17,8 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
});
}
Message {
- union: Some(message::Union::cliprdr(Cliprdr {
- union: Some(cliprdr::Union::format_list(CliprdrServerFormatList {
+ union: Some(message::Union::Cliprdr(Cliprdr {
+ union: Some(cliprdr::Union::FormatList(CliprdrServerFormatList {
conn_id,
formats,
..Default::default()
@@ -29,8 +29,8 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
}
}
ClipbaordFile::ServerFormatListResponse { conn_id, msg_flags } => Message {
- union: Some(message::Union::cliprdr(Cliprdr {
- union: Some(cliprdr::Union::format_list_response(
+ union: Some(message::Union::Cliprdr(Cliprdr {
+ union: Some(cliprdr::Union::FormatListResponse(
CliprdrServerFormatListResponse {
conn_id,
msg_flags,
@@ -45,8 +45,8 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
conn_id,
requested_format_id,
} => Message {
- union: Some(message::Union::cliprdr(Cliprdr {
- union: Some(cliprdr::Union::format_data_request(
+ union: Some(message::Union::Cliprdr(Cliprdr {
+ union: Some(cliprdr::Union::FormatDataRequest(
CliprdrServerFormatDataRequest {
conn_id,
requested_format_id,
@@ -62,8 +62,8 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
msg_flags,
format_data,
} => Message {
- union: Some(message::Union::cliprdr(Cliprdr {
- union: Some(cliprdr::Union::format_data_response(
+ union: Some(message::Union::Cliprdr(Cliprdr {
+ union: Some(cliprdr::Union::FormatDataResponse(
CliprdrServerFormatDataResponse {
conn_id,
msg_flags,
@@ -86,8 +86,8 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
have_clip_data_id,
clip_data_id,
} => Message {
- union: Some(message::Union::cliprdr(Cliprdr {
- union: Some(cliprdr::Union::file_contents_request(
+ union: Some(message::Union::Cliprdr(Cliprdr {
+ union: Some(cliprdr::Union::FileContentsRequest(
CliprdrFileContentsRequest {
conn_id,
stream_id,
@@ -111,8 +111,8 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
stream_id,
requested_data,
} => Message {
- union: Some(message::Union::cliprdr(Cliprdr {
- union: Some(cliprdr::Union::file_contents_response(
+ union: Some(message::Union::Cliprdr(Cliprdr {
+ union: Some(cliprdr::Union::FileContentsResponse(
CliprdrFileContentsResponse {
conn_id,
msg_flags,
@@ -130,7 +130,7 @@ pub fn clip_2_msg(clip: ClipbaordFile) -> Message {
pub fn msg_2_clip(msg: Cliprdr) -> Option {
match msg.union {
- Some(cliprdr::Union::format_list(data)) => {
+ Some(cliprdr::Union::FormatList(data)) => {
let mut format_list: Vec<(i32, String)> = Vec::new();
for v in data.formats.iter() {
format_list.push((v.id, v.format.clone()));
@@ -140,26 +140,26 @@ pub fn msg_2_clip(msg: Cliprdr) -> Option {
format_list,
})
}
- Some(cliprdr::Union::format_list_response(data)) => {
+ Some(cliprdr::Union::FormatListResponse(data)) => {
Some(ClipbaordFile::ServerFormatListResponse {
conn_id: data.conn_id,
msg_flags: data.msg_flags,
})
}
- Some(cliprdr::Union::format_data_request(data)) => {
+ Some(cliprdr::Union::FormatDataRequest(data)) => {
Some(ClipbaordFile::ServerFormatDataRequest {
conn_id: data.conn_id,
requested_format_id: data.requested_format_id,
})
}
- Some(cliprdr::Union::format_data_response(data)) => {
+ Some(cliprdr::Union::FormatDataResponse(data)) => {
Some(ClipbaordFile::ServerFormatDataResponse {
conn_id: data.conn_id,
msg_flags: data.msg_flags,
format_data: data.format_data,
})
}
- Some(cliprdr::Union::file_contents_request(data)) => {
+ Some(cliprdr::Union::FileContentsRequest(data)) => {
Some(ClipbaordFile::FileContentsRequest {
conn_id: data.conn_id,
stream_id: data.stream_id,
@@ -172,7 +172,7 @@ pub fn msg_2_clip(msg: Cliprdr) -> Option {
clip_data_id: data.clip_data_id,
})
}
- Some(cliprdr::Union::file_contents_response(data)) => {
+ Some(cliprdr::Union::FileContentsResponse(data)) => {
Some(ClipbaordFile::FileContentsResponse {
conn_id: data.conn_id,
msg_flags: data.msg_flags,
diff --git a/src/common.rs b/src/common.rs
index 667dd3e7e..d9eab5d99 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -8,11 +8,10 @@ use hbb_common::{
get_version_number, log,
message_proto::*,
protobuf::Message as _,
- protobuf::ProtobufEnum,
+ protobuf::Enum,
rendezvous_proto::*,
sleep, socket_client, tokio, ResultType,
};
-#[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
use hbb_common::{config::RENDEZVOUS_PORT, futures::future::join_all};
use std::sync::{Arc, Mutex};
@@ -32,7 +31,7 @@ lazy_static::lazy_static! {
#[inline]
pub fn valid_for_numlock(evt: &KeyEvent) -> bool {
- if let Some(key_event::Union::control_key(ck)) = evt.union {
+ if let Some(key_event::Union::ControlKey(ck)) = evt.union {
let v = ck.value();
(v >= ControlKey::Numpad0.value() && v <= ControlKey::Numpad9.value())
|| v == ControlKey::Decimal.value()
@@ -247,7 +246,7 @@ async fn test_nat_type_() -> ResultType {
return Ok(true);
}
let start = std::time::Instant::now();
- let rendezvous_server = get_rendezvous_server(1_000).await;
+ let (rendezvous_server, _, _) = get_rendezvous_server(1_000).await;
let server1 = rendezvous_server;
let tmp: Vec<&str> = server1.split(":").collect();
if tmp.len() != 2 {
@@ -284,7 +283,7 @@ async fn test_nat_type_() -> ResultType {
socket.send(&msg_out).await?;
if let Some(Ok(bytes)) = socket.next_timeout(RENDEZVOUS_TIMEOUT).await {
if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
- if let Some(rendezvous_message::Union::test_nat_response(tnr)) = msg_in.union {
+ if let Some(rendezvous_message::Union::TestNatResponse(tnr)) = msg_in.union {
if i == 0 {
port1 = tnr.port;
} else {
@@ -316,31 +315,62 @@ async fn test_nat_type_() -> ResultType {
Ok(ok)
}
-#[cfg(any(target_os = "android", target_os = "ios"))]
-pub async fn get_rendezvous_server(_ms_timeout: u64) -> String {
- Config::get_rendezvous_server()
+pub async fn get_rendezvous_server(ms_timeout: u64) -> (String, Vec, bool) {
+ #[cfg(any(target_os = "android", target_os = "ios"))]
+ let (mut a, mut b) = get_rendezvous_server_(ms_timeout);
+ #[cfg(not(any(target_os = "android", target_os = "ios")))]
+ let (mut a, mut b) = get_rendezvous_server_(ms_timeout).await;
+ let mut b: Vec = b
+ .drain(..)
+ .map(|x| {
+ if !x.contains(":") {
+ format!("{}:{}", x, config::RENDEZVOUS_PORT)
+ } else {
+ x
+ }
+ })
+ .collect();
+ let c = if b.contains(&a) {
+ b = b.drain(..).filter(|x| x != &a).collect();
+ true
+ } else {
+ a = b.pop().unwrap_or(a);
+ false
+ };
+ (a, b, c)
}
+#[inline]
+#[cfg(any(target_os = "android", target_os = "ios"))]
+fn get_rendezvous_server_(_ms_timeout: u64) -> (String, Vec) {
+ (
+ Config::get_rendezvous_server(),
+ Config::get_rendezvous_servers(),
+ )
+}
+
+#[inline]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
-pub async fn get_rendezvous_server(ms_timeout: u64) -> String {
+async fn get_rendezvous_server_(ms_timeout: u64) -> (String, Vec) {
crate::ipc::get_rendezvous_server(ms_timeout).await
}
+#[inline]
#[cfg(any(target_os = "android", target_os = "ios"))]
pub async fn get_nat_type(_ms_timeout: u64) -> i32 {
Config::get_nat_type()
}
+#[inline]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub async fn get_nat_type(ms_timeout: u64) -> i32 {
crate::ipc::get_nat_type(ms_timeout).await
}
-#[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
#[tokio::main(flavor = "current_thread")]
async fn test_rendezvous_server_() {
let servers = Config::get_rendezvous_servers();
- hbb_common::config::ONLINE.lock().unwrap().clear();
+ Config::reset_online();
let mut futs = Vec::new();
for host in servers {
futs.push(tokio::spawn(async move {
@@ -363,11 +393,21 @@ async fn test_rendezvous_server_() {
join_all(futs).await;
}
-#[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
pub fn test_rendezvous_server() {
std::thread::spawn(test_rendezvous_server_);
}
+pub fn refresh_rendezvous_server() {
+ #[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))]
+ test_rendezvous_server();
+ #[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))]
+ std::thread::spawn(|| {
+ if crate::ipc::test_rendezvous_server().is_err() {
+ test_rendezvous_server();
+ }
+ });
+}
+
#[inline]
pub fn get_time() -> i64 {
std::time::SystemTime::now()
@@ -412,7 +452,7 @@ pub const POSTFIX_SERVICE: &'static str = "_service";
#[inline]
pub fn is_control_key(evt: &KeyEvent, key: &ControlKey) -> bool {
- if let Some(key_event::Union::control_key(ck)) = evt.union {
+ if let Some(key_event::Union::ControlKey(ck)) = evt.union {
ck.value() == key.value()
} else {
false
@@ -421,7 +461,7 @@ pub fn is_control_key(evt: &KeyEvent, key: &ControlKey) -> bool {
#[inline]
pub fn is_modifier(evt: &KeyEvent) -> bool {
- if let Some(key_event::Union::control_key(ck)) = evt.union {
+ if let Some(key_event::Union::ControlKey(ck)) = evt.union {
let v = ck.value();
v == ControlKey::Alt.value()
|| v == ControlKey::Shift.value()
@@ -437,14 +477,15 @@ pub fn is_modifier(evt: &KeyEvent) -> bool {
}
pub fn check_software_update() {
- std::thread::spawn(move || allow_err!(_check_software_update()));
+ std::thread::spawn(move || allow_err!(check_software_update_()));
}
#[tokio::main(flavor = "current_thread")]
-async fn _check_software_update() -> hbb_common::ResultType<()> {
+async fn check_software_update_() -> hbb_common::ResultType<()> {
sleep(3.).await;
- let rendezvous_server = socket_client::get_target_addr(&get_rendezvous_server(1_000).await)?;
+ let rendezvous_server =
+ socket_client::get_target_addr(&format!("rs-sg.rustdesk.com:{}", config::RENDEZVOUS_PORT))?;
let mut socket =
socket_client::new_udp(Config::get_any_listen_addr(), RENDEZVOUS_TIMEOUT).await?;
@@ -457,7 +498,7 @@ async fn _check_software_update() -> hbb_common::ResultType<()> {
use hbb_common::protobuf::Message;
if let Some(Ok((bytes, _))) = socket.next_timeout(30_000).await {
if let Ok(msg_in) = RendezvousMessage::parse_from_bytes(&bytes) {
- if let Some(rendezvous_message::Union::software_update(su)) = msg_in.union {
+ if let Some(rendezvous_message::Union::SoftwareUpdate(su)) = msg_in.union {
let version = hbb_common::get_version_from_url(&su.url);
if get_version_number(&version) > get_version_number(crate::VERSION) {
*SOFTWARE_UPDATE_URL.lock().unwrap() = su.url;
@@ -496,14 +537,6 @@ pub fn is_setup(name: &str) -> bool {
name.to_lowercase().ends_with("setdown.exe") || name.to_lowercase().ends_with("安装.exe")
}
-pub fn get_uuid() -> Vec {
- #[cfg(not(any(target_os = "android", target_os = "ios")))]
- if let Ok(id) = machine_uid::get() {
- return id.into();
- }
- Config::get_key_pair().1
-}
-
pub fn get_custom_rendezvous_server(custom: String) -> String {
if !custom.is_empty() {
return custom;
diff --git a/src/ipc.rs b/src/ipc.rs
index 24a156eba..a5615ce6a 100644
--- a/src/ipc.rs
+++ b/src/ipc.rs
@@ -7,7 +7,9 @@ use hbb_common::{
config::{self, Config, Config2},
futures::StreamExt as _,
futures_util::sink::SinkExt,
- log, timeout, tokio,
+ log,
+ password_security::password,
+ timeout, tokio,
tokio::io::{AsyncRead, AsyncWrite},
tokio_util::codec::Framed,
ResultType,
@@ -20,6 +22,16 @@ use std::{collections::HashMap, sync::atomic::Ordering};
#[cfg(not(windows))]
use std::{fs::File, io::prelude::*};
+const STR_RANDOM_PASSWORD: &'static str = "random-password";
+const STR_SECURITY_PASSWORD: &'static str = "security-password";
+const STR_RANDOM_PASSWORD_UPDATE_METHOD: &'static str = "random-password-update-method";
+const STR_RANDOM_PASSWORD_ENABLED: &'static str = "random-password-enabled";
+const STR_SECURITY_PASSWORD_ENABLED: &'static str = "security-password-enabled";
+const STR_ONETIME_PASSWORD_ENABLED: &'static str = "onetime-password-enabled";
+const STR_ONETIME_PASSWORD_ACTIVATED: &'static str = "onetime-password-activated";
+const STR_RANDOM_PASSWORD_VALID: &'static str = "random-password-valid";
+pub const STR_PASSWORD_DESCRIPTION: &'static str = "password-description";
+
// State with timestamp, because std::time::Instant cannot be serialized
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
#[serde(tag = "t", content = "c")]
@@ -84,6 +96,45 @@ pub enum FS {
},
}
+#[derive(Debug, Serialize, Deserialize, Clone)]
+#[serde(tag = "t", content = "c")]
+pub enum DataKeyboard {
+ Sequence(String),
+ KeyDown(enigo::Key),
+ KeyUp(enigo::Key),
+ KeyClick(enigo::Key),
+ GetKeyState(enigo::Key),
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+#[serde(tag = "t", content = "c")]
+pub enum DataKeyboardResponse {
+ GetKeyState(bool),
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+#[serde(tag = "t", content = "c")]
+pub enum DataMouse {
+ MoveTo(i32, i32),
+ MoveRelative(i32, i32),
+ Down(enigo::MouseButton),
+ Up(enigo::MouseButton),
+ Click(enigo::MouseButton),
+ ScrollX(i32),
+ ScrollY(i32),
+}
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+#[serde(tag = "t", content = "c")]
+pub enum DataControl {
+ Resolution {
+ minx: i32,
+ maxx: i32,
+ miny: i32,
+ maxy: i32,
+ },
+}
+
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(tag = "t", content = "c")]
pub enum Data {
@@ -127,6 +178,13 @@ pub enum Data {
ClipbaordFile(ClipbaordFile),
ClipboardFileEnabled(bool),
PrivacyModeState((i32, PrivacyModeState)),
+ TestRendezvousServer,
+ Bool((String, Option)),
+ Keyboard(DataKeyboard),
+ KeyboardResponse(DataKeyboardResponse),
+ Mouse(DataMouse),
+ Control(DataControl),
+ Empty,
}
#[tokio::main(flavor = "current_thread")]
@@ -281,12 +339,28 @@ async fn handle(data: Data, stream: &mut Connection) {
let value;
if name == "id" {
value = Some(Config::get_id());
- } else if name == "password" {
- value = Some(Config::get_password());
+ } else if name == STR_RANDOM_PASSWORD {
+ value = Some(password::random_password());
+ } else if name == STR_SECURITY_PASSWORD {
+ value = Some(Config::get_security_password());
+ } else if name == STR_RANDOM_PASSWORD_UPDATE_METHOD {
+ value = Some(password::update_method().to_string());
+ } else if name == STR_PASSWORD_DESCRIPTION {
+ value = Some(
+ password::random_password()
+ + &password::security_enabled().to_string()
+ + &password::random_enabled().to_string()
+ + &password::onetime_password_enabled().to_string()
+ + &password::onetime_password_activated().to_string(),
+ );
} else if name == "salt" {
value = Some(Config::get_salt());
} else if name == "rendezvous_server" {
- value = Some(Config::get_rendezvous_server());
+ value = Some(format!(
+ "{},{}",
+ Config::get_rendezvous_server(),
+ Config::get_rendezvous_servers().join(",")
+ ));
} else if name == "rendezvous_servers" {
value = Some(Config::get_rendezvous_servers().join(","));
} else {
@@ -298,8 +372,12 @@ async fn handle(data: Data, stream: &mut Connection) {
if name == "id" {
Config::set_key_confirmed(false);
Config::set_id(&value);
- } else if name == "password" {
- Config::set_password(&value);
+ } else if name == STR_RANDOM_PASSWORD {
+ password::set_random_password(&value);
+ } else if name == STR_SECURITY_PASSWORD {
+ Config::set_security_password(&value);
+ } else if name == STR_RANDOM_PASSWORD_UPDATE_METHOD {
+ password::set_update_method(&value);
} else if name == "salt" {
Config::set_salt(&value);
} else {
@@ -336,7 +414,39 @@ async fn handle(data: Data, stream: &mut Connection) {
.await
);
}
-
+ Data::TestRendezvousServer => {
+ crate::test_rendezvous_server();
+ }
+ Data::Bool((name, value)) => match value {
+ None => {
+ let value;
+ if name == STR_SECURITY_PASSWORD_ENABLED {
+ value = Some(password::security_enabled());
+ } else if name == STR_RANDOM_PASSWORD_ENABLED {
+ value = Some(password::random_enabled());
+ } else if name == STR_ONETIME_PASSWORD_ENABLED {
+ value = Some(password::onetime_password_enabled());
+ } else if name == STR_ONETIME_PASSWORD_ACTIVATED {
+ value = Some(password::onetime_password_activated());
+ } else if name == STR_RANDOM_PASSWORD_VALID {
+ value = Some(password::random_password_valid());
+ } else {
+ return;
+ }
+ allow_err!(stream.send(&Data::Bool((name, value))).await);
+ }
+ Some(value) => {
+ if name == STR_SECURITY_PASSWORD_ENABLED {
+ password::set_security_enabled(value);
+ } else if name == STR_RANDOM_PASSWORD_ENABLED {
+ password::set_random_enabled(value);
+ } else if name == STR_ONETIME_PASSWORD_ENABLED {
+ password::set_onetime_password_enabled(value);
+ } else if name == STR_ONETIME_PASSWORD_ACTIVATED {
+ password::set_onetime_password_activated(value);
+ }
+ }
+ },
_ => {}
}
}
@@ -419,6 +529,10 @@ where
.await
}
+ async fn send_bool(&mut self, name: &str, value: bool) -> ResultType<()> {
+ self.send(&Data::Bool((name.to_owned(), Some(value)))).await
+ }
+
pub async fn next_timeout(&mut self, ms_timeout: u64) -> ResultType