restructure, add workspace

add custom key
This commit is contained in:
Alexander Mohr 2025-05-04 20:52:42 +02:00
parent 96455074e9
commit 23173343af
13 changed files with 2688 additions and 143 deletions

400
Cargo.lock generated
View file

@ -63,9 +63,9 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.97" version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]] [[package]]
name = "atty" name = "atty"
@ -96,6 +96,15 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
[[package]]
name = "block2"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
dependencies = [
"objc2",
]
[[package]] [[package]]
name = "cairo-rs" name = "cairo-rs"
version = "0.20.7" version = "0.20.7"
@ -168,9 +177,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.35" version = "4.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@ -178,9 +187,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.35" version = "4.5.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -197,7 +206,7 @@ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.100", "syn 2.0.101",
] ]
[[package]] [[package]]
@ -221,6 +230,46 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "core-foundation"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "core-graphics"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1"
dependencies = [
"bitflags 2.9.0",
"core-foundation",
"core-graphics-types",
"foreign-types",
"libc",
]
[[package]]
name = "core-graphics-types"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb"
dependencies = [
"bitflags 2.9.0",
"core-foundation",
"libc",
]
[[package]] [[package]]
name = "crossbeam" name = "crossbeam"
version = "0.8.4" version = "0.8.4"
@ -236,9 +285,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-channel" name = "crossbeam-channel"
version = "0.5.14" version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
dependencies = [ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
@ -322,6 +371,25 @@ dependencies = [
"phf", "phf",
] ]
[[package]]
name = "enigo"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cf6f550bbbdd5fe66f39d429cb2604bcdacbf00dca0f5bbe2e9306a0009b7c6"
dependencies = [
"core-foundation",
"core-graphics",
"foreign-types-shared",
"libc",
"log",
"objc2",
"objc2-app-kit",
"objc2-foundation",
"windows",
"xkbcommon",
"xkeysym",
]
[[package]] [[package]]
name = "env_filter" name = "env_filter"
version = "0.1.3" version = "0.1.3"
@ -395,6 +463,33 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foreign-types"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
dependencies = [
"foreign-types-macros",
"foreign-types-shared",
]
[[package]]
name = "foreign-types-macros"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "foreign-types-shared"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
[[package]] [[package]]
name = "freedesktop-file-parser" name = "freedesktop-file-parser"
version = "0.1.3" version = "0.1.3"
@ -445,7 +540,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.100", "syn 2.0.101",
] ]
[[package]] [[package]]
@ -548,9 +643,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.15" version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -650,7 +745,7 @@ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.100", "syn 2.0.101",
] ]
[[package]] [[package]]
@ -786,7 +881,7 @@ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.100", "syn 2.0.101",
] ]
[[package]] [[package]]
@ -816,9 +911,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.15.2" version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
[[package]] [[package]]
name = "heck" name = "heck"
@ -852,7 +947,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.15.2", "hashbrown 0.15.3",
] ]
[[package]] [[package]]
@ -878,9 +973,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]] [[package]]
name = "jiff" name = "jiff"
version = "0.2.5" version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260" checksum = "d07d8d955d798e7a4d6f9c58cd1f1916e790b42b092758a9ef6e16fef9f1b3fd"
dependencies = [ dependencies = [
"jiff-static", "jiff-static",
"log", "log",
@ -891,13 +986,13 @@ dependencies = [
[[package]] [[package]]
name = "jiff-static" name = "jiff-static"
version = "0.2.5" version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c" checksum = "f244cfe006d98d26f859c7abd1318d85327e1882dc9cef80f62daeeb0adcf300"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.100", "syn 2.0.101",
] ]
[[package]] [[package]]
@ -914,9 +1009,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.171" version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]] [[package]]
name = "libredox" name = "libredox"
@ -958,6 +1053,15 @@ version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "memmap2"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "memoffset" name = "memoffset"
version = "0.9.1" version = "0.9.1"
@ -985,9 +1089,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]] [[package]]
name = "nix" name = "nix"
version = "0.30.0" version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "537bc3c4a347b87fd52ac6c03a02ab1302962cfd93373c5d7a112cdc337854cc" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [ dependencies = [
"bitflags 2.9.0", "bitflags 2.9.0",
"cfg-if", "cfg-if",
@ -1011,6 +1115,105 @@ dependencies = [
"minimal-lexical", "minimal-lexical",
] ]
[[package]]
name = "objc-sys"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
[[package]]
name = "objc2"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
dependencies = [
"objc-sys",
"objc2-encode",
]
[[package]]
name = "objc2-app-kit"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
dependencies = [
"bitflags 2.9.0",
"block2",
"libc",
"objc2",
"objc2-core-data",
"objc2-core-image",
"objc2-foundation",
"objc2-quartz-core",
]
[[package]]
name = "objc2-core-data"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
dependencies = [
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-core-image"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
dependencies = [
"block2",
"objc2",
"objc2-foundation",
"objc2-metal",
]
[[package]]
name = "objc2-encode"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
[[package]]
name = "objc2-foundation"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [
"bitflags 2.9.0",
"block2",
"libc",
"objc2",
]
[[package]]
name = "objc2-metal"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
dependencies = [
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-foundation",
]
[[package]]
name = "objc2-quartz-core"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
dependencies = [
"bitflags 2.9.0",
"block2",
"objc2",
"objc2-foundation",
"objc2-metal",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.21.3" version = "1.21.3"
@ -1176,9 +1379,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.94" version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -1294,7 +1497,7 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
dependencies = [ dependencies = [
"getrandom 0.2.15", "getrandom 0.2.16",
"libredox", "libredox",
"thiserror", "thiserror",
] ]
@ -1352,9 +1555,9 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "1.0.5" version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
dependencies = [ dependencies = [
"bitflags 2.9.0", "bitflags 2.9.0",
"errno", "errno",
@ -1392,7 +1595,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.100", "syn 2.0.101",
] ]
[[package]] [[package]]
@ -1468,9 +1671,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.100" version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1505,7 +1708,7 @@ dependencies = [
"fastrand", "fastrand",
"getrandom 0.3.2", "getrandom 0.3.2",
"once_cell", "once_cell",
"rustix 1.0.5", "rustix 1.0.7",
"windows-sys", "windows-sys",
] ]
@ -1541,7 +1744,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.100", "syn 2.0.101",
] ]
[[package]] [[package]]
@ -1562,9 +1765,9 @@ checksum = "e004df4c5f0805eb5f55883204a514cfa43a6d924741be29e871753a53d5565a"
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.8.20" version = "0.8.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae"
dependencies = [ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
@ -1574,26 +1777,33 @@ dependencies = [
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.8" version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3"
dependencies = [ dependencies = [
"serde", "serde",
] ]
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.22.24" version = "0.22.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e"
dependencies = [ dependencies = [
"indexmap 2.9.0", "indexmap 2.9.0",
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"toml_write",
"winnow", "winnow",
] ]
[[package]]
name = "toml_write"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
[[package]] [[package]]
name = "tree_magic_mini" name = "tree_magic_mini"
version = "3.1.6" version = "3.1.6"
@ -1724,7 +1934,7 @@ checksum = "24d643ce3fd3e5b54854602a080f34fb10ab75e0b813ee32d00ca2b44fa74762"
dependencies = [ dependencies = [
"either", "either",
"env_home", "env_home",
"rustix 1.0.5", "rustix 1.0.7",
"winsafe", "winsafe",
] ]
@ -1759,6 +1969,70 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
dependencies = [
"windows-core",
"windows-targets",
]
[[package]]
name = "windows-core"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
dependencies = [
"windows-implement",
"windows-interface",
"windows-result",
"windows-strings",
"windows-targets",
]
[[package]]
name = "windows-implement"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "windows-interface"
version = "0.58.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "windows-result"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-strings"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
"windows-result",
"windows-targets",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.59.0" version = "0.59.0"
@ -1834,9 +2108,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.7.4" version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -1880,7 +2154,7 @@ name = "worf"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap 4.5.35", "clap 4.5.37",
"crossbeam", "crossbeam",
"dirs", "dirs",
"emoji", "emoji",
@ -1905,6 +2179,15 @@ dependencies = [
"wl-clipboard-rs", "wl-clipboard-rs",
] ]
[[package]]
name = "worf-warden"
version = "0.1.0"
dependencies = [
"anyhow",
"enigo",
"worf",
]
[[package]] [[package]]
name = "xdgkit" name = "xdgkit"
version = "3.2.5" version = "3.2.5"
@ -1918,10 +2201,27 @@ dependencies = [
] ]
[[package]] [[package]]
name = "xml-rs" name = "xkbcommon"
version = "0.8.25" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4" checksum = "8d66ca9352cbd4eecbbc40871d8a11b4ac8107cfc528a6e14d7c19c69d0e1ac9"
dependencies = [
"libc",
"memmap2",
"xkeysym",
]
[[package]]
name = "xkeysym"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56"
[[package]]
name = "xml-rs"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda"
[[package]] [[package]]
name = "yaml-rust" name = "yaml-rust"
@ -1949,5 +2249,5 @@ checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.100", "syn 2.0.101",
] ]

View file

@ -1,51 +1,7 @@
[package] [workspace]
name = "worf" members = [
version = "0.1.0" "worf",
edition = "2024" "examples/worf-warden",
]
[lints.clippy] resolver = "3"
# enable pedantic
pedantic = { level = "warn", priority = -1 }
## exclude some too pedantic lints for now
similar_names = "allow"
# additional lints
clone_on_ref_ptr = "warn"
[lib]
name = "worf_lib"
path = "src/lib/mod.rs"
[[bin]]
name = "worf"
path = "src/main.rs"
[package.metadata.docs.rs]
no-deps = true
[dependencies]
gtk4 = { version = "0.9.5", default-features = true, features = ["v4_6"] }
gtk4-layer-shell = "0.5.0"
gdk4 = "0.9.6"
anyhow = "1.0.97"
env_logger = "0.11.8"
log = "0.4.27"
regex = "1.11.1"
clap = { version = "4.5.35", features = ["derive"] }
thiserror = "2.0.12"
serde = { version = "1.0.219", features = ["derive"] }
toml = "0.8.20"
serde_json = "1.0.140"
crossbeam = "0.8.4"
libc = "0.2.171"
freedesktop-file-parser = "0.1.3"
strsim = "0.11.1"
dirs = "6.0.0"
which = "7.0.3"
meval = "0.2.0"
tree_magic_mini = "3.1.6"
rayon = "1.10.0"
nix = { version = "0.30.0", features = ["process"] }
emoji = "0.2.1"
wl-clipboard-rs = "0.9.2"

View file

@ -2091,7 +2091,6 @@ name = "worf-warden"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"enigo", "enigo",
"gdk4",
"worf", "worf",
] ]

View file

@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
gdk4 = "0.9.6" worf = {path = "../../worf"}
worf = {path = "../.."} enigo = "0.3.0"
enigo = "0.1.3" anyhow = "1.0.98"

View file

@ -2,11 +2,11 @@ use std::process::Command;
use std::thread; use std::thread;
use std::thread::sleep; use std::thread::sleep;
use std::time::Duration; use std::time::Duration;
use enigo::{Enigo, Key, KeyboardControllable}; use enigo::{Enigo, Keyboard};
use worf_lib::{config, gui, Error}; use worf_lib::{config, gui, Error};
use worf_lib::config::Config; use worf_lib::config::Config;
use worf_lib::gui::{CustomKey, ItemProvider, MenuItem}; use worf_lib::gui::{KeyBinding, ItemProvider, MenuItem, Modifier, Key};
#[derive(Clone)] #[derive(Clone)]
struct PasswordProvider { struct PasswordProvider {
@ -64,43 +64,84 @@ fn rbw_get_password(name: &str) -> String {
rbw_get(name, "password") rbw_get(name, "password")
} }
fn main() { fn main() -> anyhow::Result<()> {
let args = config::parse_args(); let args = config::parse_args();
let config = config::load_config(Some(&args)).unwrap_or(args); let config = config::load_config(Some(&args)).unwrap_or(args);
// todo eventually use a propper rust client for this, for now rbw is good enough // todo eventually use a propper rust client for this, for now rbw is good enough
let provider = PasswordProvider::new(&config); let provider = PasswordProvider::new(&config);
let type_all = CustomKey { let type_all = KeyBinding {
key: gdk4::Key::_1, // todo do not expose gdk4 key: Key::Num1,
modifiers: gdk4::ModifierType::ALT_MASK, modifiers: Modifier::Alt,
label: "<b>Alt+1</b> Type All".to_string(), label: "<b>Alt+1</b> Type All".to_string(),
}; };
let type_user = CustomKey { let type_user = KeyBinding {
key: gdk4::Key::_2, // todo do not expose gdk4 key: Key::Num2,
modifiers: gdk4::ModifierType::ALT_MASK, modifiers: Modifier::Alt,
label: "<b>Alt+2</b> Type All".to_string(), label: "<b>Alt+2</b> Type All".to_string(),
}; };
match gui::show(config, provider, false, None, Some(vec![type_all.clone(), type_user])) { let type_totp = KeyBinding {
key: Key::Num3,
modifiers: Modifier::Alt,
label: "<b>Alt+3</b> Sync".to_string(),
};
let reload = KeyBinding {
key: Key::R,
modifiers: Modifier::Alt,
label: "<b>Alt+r</b> Sync".to_string(),
};
let urls = KeyBinding {
key: Key::U, // switch view to urls
modifiers: Modifier::Alt,
label: "<b>Alt+u</b> Sync".to_string(),
};
let names = KeyBinding {
key: Key::N, // switch view to names
modifiers: Modifier::Alt,
label: "<b>Alt+n</b> Sync".to_string(),
};
let folders = KeyBinding {
key: Key::C, // switch view to folders
modifiers: Modifier::Alt,
label: "<b>Alt+c</b> Sync".to_string(),
};
let totp = KeyBinding {
key: Key::T,
modifiers: Modifier::Alt, // switch view to totp
label: "<b>Alt+t</b> Sync".to_string(),
};
let lock = KeyBinding {
key: Key::L,
modifiers: Modifier::Alt,
label: "<b>Alt+l</b> Sync".to_string(),
};
match gui::show(config, provider, false, None, Some(vec![type_all.clone(), type_user, type_totp, reload, urls, names, folders, totp, lock])) {
Ok(selection) => { Ok(selection) => {
let mut enigo = Enigo::new(); let mut enigo = Enigo::new(&enigo::Settings::default())?;
let id = selection.menu.label.replace("\n", ""); let id = selection.menu.label.replace("\n", "");
sleep(Duration::from_millis(250)); sleep(Duration::from_millis(250));
if let Some(key) = selection.custom_key { if let Some(key) = selection.custom_key {
if key.label == type_all.label { if key.label == type_all.label {
enigo.key_sequence(&rbw_get_user(&id)); enigo.text(&rbw_get_user(&id))?;
enigo.key_down(Key::Tab); enigo.key(enigo::Key::Tab, enigo::Direction::Press)?;
enigo.key_up(Key::Tab); enigo.key(enigo::Key::Tab, enigo::Direction::Release)?;
enigo.key_sequence(&rbw_get_password(&id)); enigo.text(&rbw_get_password(&id))?;
} }
} }
} }
Err(e) => { Err(e) => {
if e.ne(&Error::NoSelection) { return Err(anyhow::anyhow!(e))
println!("Error occurred: {e}")
}
} }
} }
Ok(())
} }

1953
worf/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

53
worf/Cargo.toml Normal file
View file

@ -0,0 +1,53 @@
[package]
name = "worf"
version = "0.1.0"
edition = "2024"
[lints.clippy]
# enable pedantic
pedantic = { level = "warn", priority = -1 }
## exclude some too pedantic lints for now
similar_names = "allow"
# additional lints
clone_on_ref_ptr = "warn"
[lib]
name = "worf_lib"
path = "src/lib/mod.rs"
[[bin]]
name = "worf"
path = "src/main.rs"
[features]
default = []
[package.metadata.docs.rs]
no-deps = true
[dependencies]
gtk4 = { version = "0.9.5", default-features = true, features = ["v4_6"] }
gtk4-layer-shell = "0.5.0"
gdk4 = "0.9.6"
anyhow = "1.0.97"
env_logger = "0.11.8"
log = "0.4.27"
regex = "1.11.1"
clap = { version = "4.5.35", features = ["derive"] }
thiserror = "2.0.12"
serde = { version = "1.0.219", features = ["derive"] }
toml = "0.8.20"
serde_json = "1.0.140"
crossbeam = "0.8.4"
libc = "0.2.171"
freedesktop-file-parser = "0.1.3"
strsim = "0.11.1"
dirs = "6.0.0"
which = "7.0.3"
meval = "0.2.0"
tree_magic_mini = "3.1.6"
rayon = "1.10.0"
nix = { version = "0.30.0", features = ["process"] }
emoji = "0.2.1"
wl-clipboard-rs = "0.9.2"

View file

@ -2,7 +2,6 @@ use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
use std::thread::sleep;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use crossbeam::channel; use crossbeam::channel;
@ -10,7 +9,7 @@ use crossbeam::channel::Sender;
use gdk4::gio::File; use gdk4::gio::File;
use gdk4::glib::{Propagation, timeout_add_local}; use gdk4::glib::{Propagation, timeout_add_local};
use gdk4::prelude::{Cast, DisplayExt, MonitorExt, SurfaceExt}; use gdk4::prelude::{Cast, DisplayExt, MonitorExt, SurfaceExt};
use gdk4::{Display, Key, ModifierType}; use gdk4::{Display, ModifierType};
use gtk4::glib::ControlFlow; use gtk4::glib::ControlFlow;
use gtk4::prelude::{ use gtk4::prelude::{
ApplicationExt, ApplicationExtManual, BoxExt, EditableExt, FlowBoxChildExt, GestureSingleExt, ApplicationExt, ApplicationExtManual, BoxExt, EditableExt, FlowBoxChildExt, GestureSingleExt,
@ -35,7 +34,7 @@ type ArcProvider<T> = Arc<Mutex<dyn ItemProvider<T> + Send>>;
pub struct Selection<T: Clone + Send> { pub struct Selection<T: Clone + Send> {
pub menu: MenuItem<T>, pub menu: MenuItem<T>,
pub custom_key: Option<CustomKey>, pub custom_key: Option<KeyBinding>,
} }
type SelectionSender<T> = Sender<Result<Selection<T>, Error>>; type SelectionSender<T> = Sender<Result<Selection<T>, Error>>;
@ -110,10 +109,253 @@ pub struct MenuItem<T: Clone> {
visible: bool, visible: bool,
} }
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Key {
None,
// Letters
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
// Numbers
Num0,
Num1,
Num2,
Num3,
Num4,
Num5,
Num6,
Num7,
Num8,
Num9,
// Function Keys
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
// Navigation / Editing
Escape,
Enter,
Space,
Tab,
Backspace,
Insert,
Delete,
Home,
End,
PageUp,
PageDown,
Left,
Right,
Up,
Down,
// Special characters
Exclamation, // !
At, // @
Hash, // #
Dollar, // $
Percent, // %
Caret, // ^
Ampersand, // &
Asterisk, // *
LeftParen, // (
RightParen, // )
Minus, // -
Underscore, // _
Equal, // =
Plus, // +
LeftBracket, // [
RightBracket, // ]
LeftBrace, // {
RightBrace, // }
Backslash, // \
Pipe, // |
Semicolon, // ;
Colon, // :
Apostrophe, // '
Quote, // "
Comma, // ,
Period, // .
Slash, // /
Question, // ?
Grave, // `
Tilde, // ~
}
impl Into<Key> for gdk::Key {
fn into(self) -> Key {
match self {
// Letters
gdk4::Key::A => Key::A,
gdk4::Key::B => Key::B,
gdk4::Key::C => Key::C,
gdk4::Key::D => Key::D,
gdk4::Key::E => Key::E,
gdk4::Key::F => Key::F,
gdk4::Key::G => Key::G,
gdk4::Key::H => Key::H,
gdk4::Key::I => Key::I,
gdk4::Key::J => Key::J,
gdk4::Key::K => Key::K,
gdk4::Key::L => Key::L,
gdk4::Key::M => Key::M,
gdk4::Key::N => Key::N,
gdk4::Key::O => Key::O,
gdk4::Key::P => Key::P,
gdk4::Key::Q => Key::Q,
gdk4::Key::R => Key::R,
gdk4::Key::S => Key::S,
gdk4::Key::T => Key::T,
gdk4::Key::U => Key::U,
gdk4::Key::V => Key::V,
gdk4::Key::W => Key::W,
gdk4::Key::X => Key::X,
gdk4::Key::Y => Key::Y,
gdk4::Key::Z => Key::Z,
// Numbers
gdk4::Key::_0 => Key::Num0,
gdk4::Key::_1 => Key::Num1,
gdk4::Key::_2 => Key::Num2,
gdk4::Key::_3 => Key::Num3,
gdk4::Key::_4 => Key::Num4,
gdk4::Key::_5 => Key::Num5,
gdk4::Key::_6 => Key::Num6,
gdk4::Key::_7 => Key::Num7,
gdk4::Key::_8 => Key::Num8,
gdk4::Key::_9 => Key::Num9,
// Function Keys
gdk4::Key::F1 => Key::F1,
gdk4::Key::F2 => Key::F2,
gdk4::Key::F3 => Key::F3,
gdk4::Key::F4 => Key::F4,
gdk4::Key::F5 => Key::F5,
gdk4::Key::F6 => Key::F6,
gdk4::Key::F7 => Key::F7,
gdk4::Key::F8 => Key::F8,
gdk4::Key::F9 => Key::F9,
gdk4::Key::F10 => Key::F10,
gdk4::Key::F11 => Key::F11,
gdk4::Key::F12 => Key::F12,
// Navigation / Editing
gdk4::Key::Escape => Key::Escape,
gdk4::Key::Return => Key::Enter,
gdk4::Key::space => Key::Space,
gdk4::Key::Tab => Key::Tab,
gdk4::Key::BackSpace => Key::Backspace,
gdk4::Key::Insert => Key::Insert,
gdk4::Key::Delete => Key::Delete,
gdk4::Key::Home => Key::Home,
gdk4::Key::End => Key::End,
gdk4::Key::Page_Up => Key::PageUp,
gdk4::Key::Page_Down => Key::PageDown,
gdk4::Key::Left => Key::Left,
gdk4::Key::Right => Key::Right,
gdk4::Key::Up => Key::Up,
gdk4::Key::Down => Key::Down,
// Special characters
gdk4::Key::exclam => Key::Exclamation,
gdk4::Key::at => Key::At,
gdk4::Key::numbersign => Key::Hash,
gdk4::Key::dollar => Key::Dollar,
gdk4::Key::percent => Key::Percent,
gdk4::Key::asciicircum => Key::Caret,
gdk4::Key::ampersand => Key::Ampersand,
gdk4::Key::asterisk => Key::Asterisk,
gdk4::Key::parenleft => Key::LeftParen,
gdk4::Key::parenright => Key::RightParen,
gdk4::Key::minus => Key::Minus,
gdk4::Key::underscore => Key::Underscore,
gdk4::Key::equal => Key::Equal,
gdk4::Key::plus => Key::Plus,
gdk4::Key::bracketleft => Key::LeftBracket,
gdk4::Key::bracketright => Key::RightBracket,
gdk4::Key::braceleft => Key::LeftBrace,
gdk4::Key::braceright => Key::RightBrace,
gdk4::Key::backslash => Key::Backslash,
gdk4::Key::bar => Key::Pipe,
gdk4::Key::semicolon => Key::Semicolon,
gdk4::Key::colon => Key::Colon,
gdk4::Key::apostrophe => Key::Apostrophe,
gdk4::Key::quotedbl => Key::Quote,
gdk4::Key::comma => Key::Comma,
gdk4::Key::period => Key::Period,
gdk4::Key::slash => Key::Slash,
gdk4::Key::question => Key::Question,
gdk4::Key::grave => Key::Grave,
gdk4::Key::asciitilde => Key::Tilde,
_ => Key::None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Modifier {
Shift,
Control,
Alt,
Super,
Meta,
CapsLock,
None,
}
impl Into<Modifier> for gdk::ModifierType {
fn into(self) -> Modifier {
match self {
ModifierType::SHIFT_MASK => Modifier::Shift,
ModifierType::CONTROL_MASK => Modifier::Control,
ModifierType::ALT_MASK => Modifier::Alt,
ModifierType::SUPER_MASK => Modifier::Super,
ModifierType::META_MASK => Modifier::Meta,
ModifierType::LOCK_MASK => Modifier::CapsLock,
_ => Modifier::None,
}
}
}
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
pub struct CustomKey { pub struct KeyBinding {
pub key: Key, pub key: Key,
pub modifiers: ModifierType, // acts as a mask, so multiple things can be set. pub modifiers: Modifier, // todo support masks
pub label: String, pub label: String,
} }
@ -174,7 +416,7 @@ pub fn show<T, P>(
item_provider: P, item_provider: P,
new_on_empty: bool, new_on_empty: bool,
search_ignored_words: Option<Vec<Regex>>, search_ignored_words: Option<Vec<Regex>>,
custom_keys: Option<Vec<CustomKey>>, custom_keys: Option<Vec<KeyBinding>>,
) -> Result<Selection<T>, Error> ) -> Result<Selection<T>, Error>
where where
T: Clone + 'static + Send, T: Clone + 'static + Send,
@ -222,7 +464,7 @@ fn build_ui<T, P>(
app: Application, app: Application,
new_on_empty: bool, new_on_empty: bool,
search_ignored_words: Option<Vec<Regex>>, search_ignored_words: Option<Vec<Regex>>,
custom_keys: Option<Vec<CustomKey>>, custom_keys: Option<Vec<KeyBinding>>,
) where ) where
T: Clone + 'static + Send, T: Clone + 'static + Send,
P: ItemProvider<T> + 'static + Send, P: ItemProvider<T> + 'static + Send,
@ -261,7 +503,7 @@ fn build_ui<T, P>(
}); });
// handle keys as soon as possible // handle keys as soon as possible
setup_key_event_handler(&ui_elements, &meta, &custom_keys); setup_key_event_handler(&ui_elements, &meta, custom_keys.as_ref());
log::debug!("keyboard ready after {:?}", start.elapsed()); log::debug!("keyboard ready after {:?}", start.elapsed());
@ -387,7 +629,7 @@ fn build_search_entry<T: Clone + Send>(
fn build_custom_key_view<T>( fn build_custom_key_view<T>(
config: &Config, config: &Config,
ui: &Rc<UiElements<T>>, ui: &Rc<UiElements<T>>,
custom_keys: &Option<Vec<CustomKey>>, custom_keys: &Option<Vec<KeyBinding>>,
outer_box: &gtk4::Box, outer_box: &gtk4::Box,
) where ) where
T: 'static + Clone + Send, T: 'static + Clone + Send,
@ -492,13 +734,13 @@ fn build_ui_from_menu_items<T: Clone + 'static + Send>(
fn setup_key_event_handler<T: Clone + 'static + Send>( fn setup_key_event_handler<T: Clone + 'static + Send>(
ui: &Rc<UiElements<T>>, ui: &Rc<UiElements<T>>,
meta: &Rc<MetaData<T>>, meta: &Rc<MetaData<T>>,
custom_keys: &Option<Vec<CustomKey>>, custom_keys: Option<&Vec<KeyBinding>>,
) { ) {
let key_controller = EventControllerKey::new(); let key_controller = EventControllerKey::new();
let ui_clone = Rc::clone(ui); let ui_clone = Rc::clone(ui);
let meta_clone = Rc::clone(meta); let meta_clone = Rc::clone(meta);
let keys_clone = custom_keys.clone(); let keys_clone = custom_keys.map(|s| s.clone());
key_controller.connect_key_pressed(move |_, key_value, _, modifier| { key_controller.connect_key_pressed(move |_, key_value, _, modifier| {
handle_key_press( handle_key_press(
&ui_clone, &ui_clone,
@ -511,12 +753,14 @@ fn setup_key_event_handler<T: Clone + 'static + Send>(
ui.window.add_controller(key_controller); ui.window.add_controller(key_controller);
} }
#[allow(clippy::too_many_lines)] // todo fix this.
fn handle_key_press<T: Clone + 'static + Send>( fn handle_key_press<T: Clone + 'static + Send>(
ui: &Rc<UiElements<T>>, ui: &Rc<UiElements<T>>,
meta: &Rc<MetaData<T>>, meta: &Rc<MetaData<T>>,
keyboard_key: Key, keyboard_key: gdk4::Key,
modifier_type: ModifierType, modifier_type: ModifierType,
custom_keys: Option<&Vec<CustomKey>>, custom_keys: Option<&Vec<KeyBinding>>,
) -> Propagation { ) -> Propagation {
let update_view = |query: &String| { let update_view = |query: &String| {
let mut lock = ui.menu_rows.lock().unwrap(); let mut lock = ui.menu_rows.lock().unwrap();
@ -535,13 +779,13 @@ fn handle_key_press<T: Clone + 'static + Send>(
if changed { if changed {
build_ui_from_menu_items(ui, meta, filtered_list); build_ui_from_menu_items(ui, meta, filtered_list);
} }
update_view(query); update_view(query);
}; };
if let Some(custom_keys) = custom_keys { if let Some(custom_keys) = custom_keys {
for custom_key in custom_keys { for custom_key in custom_keys {
if custom_key.key == keyboard_key && custom_key.modifiers == modifier_type { if custom_key.key == keyboard_key.into() && custom_key.modifiers == modifier_type.into()
{
let search_lock = ui.search_text.lock().unwrap(); let search_lock = ui.search_text.lock().unwrap();
if let Err(e) = handle_selected_item( if let Err(e) = handle_selected_item(
ui, ui,
@ -558,13 +802,13 @@ fn handle_key_press<T: Clone + 'static + Send>(
} }
match keyboard_key { match keyboard_key {
Key::Escape => { gdk4::Key::Escape => {
if let Err(e) = meta.selected_sender.send(Err(Error::NoSelection)) { if let Err(e) = meta.selected_sender.send(Err(Error::NoSelection)) {
log::error!("failed to send message {e}"); log::error!("failed to send message {e}");
} }
close_gui(&ui.app); close_gui(&ui.app);
} }
Key::Return => { gdk4::Key::Return => {
let search_lock = ui.search_text.lock().unwrap(); let search_lock = ui.search_text.lock().unwrap();
if let Err(e) = if let Err(e) =
handle_selected_item(ui, meta, Some(&search_lock), None, meta.new_on_empty, None) handle_selected_item(ui, meta, Some(&search_lock), None, meta.new_on_empty, None)
@ -572,7 +816,7 @@ fn handle_key_press<T: Clone + 'static + Send>(
log::error!("{e}"); log::error!("{e}");
} }
} }
Key::BackSpace => { gdk4::Key::BackSpace => {
let mut query = ui.search_text.lock().unwrap().to_string(); let mut query = ui.search_text.lock().unwrap().to_string();
if !query.is_empty() { if !query.is_empty() {
query.pop(); query.pop();
@ -581,7 +825,7 @@ fn handle_key_press<T: Clone + 'static + Send>(
update_view_from_provider(&query); update_view_from_provider(&query);
} }
} }
Key::Tab => { gdk4::Key::Tab => {
if let Some(fb) = ui.main_box.selected_children().first() { if let Some(fb) = ui.main_box.selected_children().first() {
if let Some(child) = fb.child() { if let Some(child) = fb.child() {
let expander = child.downcast::<Expander>().ok(); let expander = child.downcast::<Expander>().ok();
@ -625,7 +869,6 @@ fn handle_key_press<T: Clone + 'static + Send>(
} }
} }
} }
Propagation::Proceed Propagation::Proceed
} }
@ -704,7 +947,7 @@ fn handle_selected_item<T>(
query: Option<&str>, query: Option<&str>,
item: Option<MenuItem<T>>, item: Option<MenuItem<T>>,
new_on_empty: bool, new_on_empty: bool,
custom_key: Option<&CustomKey>, custom_key: Option<&KeyBinding>,
) -> Result<(), String> ) -> Result<(), String>
where where
T: Clone + Send, T: Clone + Send,