This commit is contained in:
Javier Feliz 2025-09-07 15:02:23 -04:00
parent f70e4c3006
commit 4ecfe9c6f1
10 changed files with 653 additions and 80 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@
# direnv cache (should not be committed) # direnv cache (should not be committed)
.direnv/ .direnv/
waycast_cache waycast_cache
waycast.toml

479
Cargo.lock generated
View File

@ -17,6 +17,23 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "arraydeque"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
[[package]]
name = "async-trait"
version = "0.1.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.5.0" version = "1.5.0"
@ -38,6 +55,12 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]] [[package]]
name = "bincode" name = "bincode"
version = "1.3.3" version = "1.3.3"
@ -69,9 +92,21 @@ dependencies = [
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.9.3" version = "2.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
dependencies = [
"serde",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]] [[package]]
name = "cairo-rs" name = "cairo-rs"
@ -112,6 +147,90 @@ 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 = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "config"
version = "0.15.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0faa974509d38b33ff89282db9c3295707ccf031727c0de9772038ec526852ba"
dependencies = [
"async-trait",
"convert_case",
"json5",
"pathdiff",
"ron",
"rust-ini",
"serde",
"serde-untagged",
"serde_json",
"toml 0.9.5",
"winnow",
"yaml-rust2",
]
[[package]]
name = "const-random"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
dependencies = [
"const-random-macro",
]
[[package]]
name = "const-random-macro"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
"getrandom 0.2.16",
"once_cell",
"tiny-keccak",
]
[[package]]
name = "convert_case"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crunchy"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]] [[package]]
name = "directories" name = "directories"
version = "6.0.0" version = "6.0.0"
@ -130,7 +249,25 @@ dependencies = [
"libc", "libc",
"option-ext", "option-ext",
"redox_users", "redox_users",
"windows-sys 0.60.2", "windows-sys 0.61.0",
]
[[package]]
name = "dlv-list"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f"
dependencies = [
"const-random",
]
[[package]]
name = "encoding_rs"
version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
dependencies = [
"cfg-if",
] ]
[[package]] [[package]]
@ -139,6 +276,16 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "erased-serde"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"
dependencies = [
"serde",
"typeid",
]
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.13" version = "0.3.13"
@ -165,6 +312,12 @@ dependencies = [
"rustc_version", "rustc_version",
] ]
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.31" version = "0.3.31"
@ -286,6 +439,16 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.16" version = "0.2.16"
@ -497,9 +660,9 @@ dependencies = [
[[package]] [[package]]
name = "gtk4-layer-shell" name = "gtk4-layer-shell"
version = "0.6.1" version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f448a3a5593fb2ba018a946474beec09366c01f40ec788fc4a879981d16c91" checksum = "17d5ba7dda5e307469217249a980136e393d13063d4d97dd34ef30ebe1955dd2"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"gdk4", "gdk4",
@ -554,11 +717,29 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.15.5" version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"foldhash",
]
[[package]]
name = "hashlink"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
dependencies = [
"hashbrown 0.15.5",
]
[[package]] [[package]]
name = "heck" name = "heck"
@ -573,7 +754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown 0.15.5",
] ]
[[package]] [[package]]
@ -587,6 +768,23 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "json5"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
dependencies = [
"pest",
"pest_derive",
"serde",
]
[[package]] [[package]]
name = "khronos_api" name = "khronos_api"
version = "3.1.0" version = "3.1.0"
@ -617,9 +815,9 @@ checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.27" version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
[[package]] [[package]]
name = "memchr" name = "memchr"
@ -677,6 +875,16 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "ordered-multimap"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79"
dependencies = [
"dlv-list",
"hashbrown 0.14.5",
]
[[package]] [[package]]
name = "pango" name = "pango"
version = "0.21.1" version = "0.21.1"
@ -701,6 +909,56 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "pathdiff"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
[[package]]
name = "pest"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323"
dependencies = [
"memchr",
"thiserror",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc"
dependencies = [
"pest",
"pest_generator",
]
[[package]]
name = "pest_generator"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pest_meta"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5"
dependencies = [
"pest",
"sha2",
]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.16" version = "0.2.16"
@ -772,6 +1030,28 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "ron"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
dependencies = [
"base64",
"bitflags",
"serde",
"serde_derive",
]
[[package]]
name = "rust-ini"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7"
dependencies = [
"cfg-if",
"ordered-multimap",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.26" version = "0.1.26"
@ -800,6 +1080,12 @@ dependencies = [
"windows-sys 0.60.2", "windows-sys 0.60.2",
] ]
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]] [[package]]
name = "same-file" name = "same-file"
version = "1.0.6" version = "1.0.6"
@ -824,6 +1110,17 @@ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]]
name = "serde-untagged"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34836a629bcbc6f1afdf0907a744870039b1e14c0561cb26094fa683b158eff3"
dependencies = [
"erased-serde",
"serde",
"typeid",
]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.219" version = "1.0.219"
@ -835,6 +1132,18 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "serde_json"
version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]] [[package]]
name = "serde_spanned" name = "serde_spanned"
version = "0.6.9" version = "0.6.9"
@ -844,6 +1153,32 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_spanned"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
dependencies = [
"serde",
]
[[package]]
name = "serde_toml"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e68184169792863bfb6d8b5de8e15456ebf4302f28236f0ff1136591eb66541"
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.11" version = "0.4.11"
@ -876,7 +1211,7 @@ dependencies = [
"cfg-expr", "cfg-expr",
"heck", "heck",
"pkg-config", "pkg-config",
"toml", "toml 0.8.23",
"version-compare", "version-compare",
] ]
@ -919,6 +1254,15 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.47.1" version = "1.47.1"
@ -952,11 +1296,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
dependencies = [ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned 0.6.9",
"toml_datetime", "toml_datetime 0.6.11",
"toml_edit", "toml_edit",
] ]
[[package]]
name = "toml"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8"
dependencies = [
"indexmap",
"serde",
"serde_spanned 1.0.0",
"toml_datetime 0.7.0",
"toml_parser",
"toml_writer",
"winnow",
]
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.11" version = "0.6.11"
@ -966,6 +1325,15 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "toml_datetime"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.22.27" version = "0.22.27"
@ -974,17 +1342,56 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"serde", "serde",
"serde_spanned", "serde_spanned 0.6.9",
"toml_datetime", "toml_datetime 0.6.11",
"winnow", "winnow",
] ]
[[package]]
name = "toml_parser"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10"
dependencies = [
"winnow",
]
[[package]]
name = "toml_writer"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
[[package]]
name = "typeid"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
[[package]]
name = "typenum"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "ucd-trie"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.18" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "unicode-segmentation"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]] [[package]]
name = "unty" name = "unty"
version = "0.0.4" version = "0.0.4"
@ -997,6 +1404,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]] [[package]]
name = "virtue" name = "virtue"
version = "0.0.18" version = "0.0.18"
@ -1028,6 +1441,17 @@ dependencies = [
"wit-bindgen", "wit-bindgen",
] ]
[[package]]
name = "waycast-config"
version = "0.1.0"
dependencies = [
"config",
"directories",
"serde",
"serde_toml",
"toml 0.9.5",
]
[[package]] [[package]]
name = "waycast-core" name = "waycast-core"
version = "0.1.0" version = "0.1.0"
@ -1071,6 +1495,7 @@ dependencies = [
"glib", "glib",
"tokio", "tokio",
"walkdir", "walkdir",
"waycast-config",
"waycast-core", "waycast-core",
"waycast-macros", "waycast-macros",
] ]
@ -1090,6 +1515,12 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-link"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.59.0" version = "0.59.0"
@ -1108,6 +1539,15 @@ dependencies = [
"windows-targets 0.53.3", "windows-targets 0.53.3",
] ]
[[package]]
name = "windows-sys"
version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
dependencies = [
"windows-link 0.2.0",
]
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.52.6" version = "0.52.6"
@ -1130,7 +1570,7 @@ version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
dependencies = [ dependencies = [
"windows-link", "windows-link 0.1.3",
"windows_aarch64_gnullvm 0.53.0", "windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0", "windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0", "windows_i686_gnu 0.53.0",
@ -1257,3 +1697,14 @@ name = "xml-rs"
version = "0.8.27" version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7"
[[package]]
name = "yaml-rust2"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ce2a4ff45552406d02501cea6c18d8a7e50228e7736a872951fe2fe75c91be7"
dependencies = [
"arraydeque",
"encoding_rs",
"hashlink",
]

View File

@ -2,7 +2,8 @@
members = [ members = [
"waycast-core", "waycast-core",
"waycast-macros", "waycast-macros",
"waycast-plugins", "waycast-plugins",
"waycast-gtk" "waycast-gtk",
"waycast-config",
] ]
resolver = "2" resolver = "2"

11
waycast-config/Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "waycast-config"
version = "0.1.0"
edition = "2024"
[dependencies]
config = { version = "0.15.15", features = ["toml"] }
directories = "6.0.0"
serde = { version = "1.0.219", features = ["derive"] }
serde_toml = "0.0.1"
toml = "0.9.5"

31
waycast-config/src/lib.rs Normal file
View File

@ -0,0 +1,31 @@
use config::Config;
use directories::ProjectDirs;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use std::path::Path;
use std::sync::OnceLock;
use std::{fs::File, path::PathBuf};
#[derive(Debug, Deserialize, Serialize)]
pub struct WaycastConfig {}
static CONFIG_SINGLETON: OnceLock<Config> = OnceLock::new();
pub fn project_dirs() -> Option<ProjectDirs> {
ProjectDirs::from("dev.thegrind", "The Grind", "waycast")
}
pub fn config_file() -> &'static Config {
CONFIG_SINGLETON.get_or_init(|| init())
}
pub fn get<T: DeserializeOwned>(key: &str) -> Result<T, config::ConfigError> {
config_file().get::<T>(key)
}
fn init() -> Config {
Config::builder()
.add_source(config::File::with_name("waycast.toml"))
.add_source(config::Environment::with_prefix("WAYCAST"))
.build()
.unwrap()
}

View File

@ -0,0 +1,42 @@
use std::collections::HashMap;
use config::Config;
use directories::ProjectDirs;
pub fn main() {
// if let Some(dirs) = ProjectDirs::from("dev.thegrind", "The Grind", "waycast") {
// let config_dir = dirs.config_dir();
// let cache_dir = dirs.cache_dir();
// let data_dir = dirs.data_dir();
// println!("Config: {}", config_dir.display());
// println!("Cache: {}", cache_dir.display());
// println!("Data: {}", data_dir.display());
// }
// let settings = Config::builder()
// .add_source(config::File::with_name("waycast.toml"))
// .add_source(config::Environment::with_prefix("WAYCAST"))
// .build()
// .unwrap();
println!(
"{:?}",
waycast_config::config_file()
.get::<String>("plugins.projects.open_command")
.expect("Could not deserialize")
);
// // Start with defaults
// let mut config = WaycastConfig::default();
// config.plugins.file_search.ignore_dirs =
// vec!["vendor".into(), "pycache".into(), "node_modules".into()];
// // Serialize to TOML
// let toml_str = toml::to_string_pretty(&config).expect("Failed");
// println!("Serialized TOML:\n{}", toml_str);
// // Deserialize back
// let parsed: WaycastConfig = toml::from_str(&toml_str).expect("Fuck");
// println!("Deserialized struct:\n{:#?}", parsed);
}

View File

@ -12,22 +12,11 @@ fn main() {
.build(); .build();
app.connect_activate(|app| { app.connect_activate(|app| {
let mut file_search_plugin = waycast_plugins::file_search::new();
if let Err(e) = file_search_plugin.add_search_path("/home/javi/working-files/DJ Music/") {
eprintln!("{}", e)
}
let mut project_plugin = waycast_plugins::projects::new();
if let Err(e) = project_plugin.add_search_path("/home/javi/projects") {
eprintln!("{}", e)
}
// Create the core launcher // Create the core launcher
let launcher = WaycastLauncher::new() let launcher = WaycastLauncher::new()
.add_plugin(Box::new(waycast_plugins::drun::new())) .add_plugin(Box::new(waycast_plugins::drun::new()))
.add_plugin(Box::new(file_search_plugin)) .add_plugin(Box::new(waycast_plugins::file_search::new()))
.add_plugin(Box::new(project_plugin)) .add_plugin(Box::new(waycast_plugins::projects::new()))
.init(); .init();
// Create and show the GTK UI // Create and show the GTK UI

View File

@ -6,11 +6,18 @@ edition = "2021"
[dependencies] [dependencies]
waycast-core = { path = "../waycast-core" } waycast-core = { path = "../waycast-core" }
waycast-macros = { path = "../waycast-macros" } waycast-macros = { path = "../waycast-macros" }
waycast-config = { path = "../waycast-config" }
directories = "6.0.0" directories = "6.0.0"
gio = "0.21.1" gio = "0.21.1"
glib = "0.21.1" glib = "0.21.1"
tokio = { version = "1.0", features = ["rt", "rt-multi-thread", "time", "macros", "sync"] } tokio = { version = "1.0", features = [
"rt",
"rt-multi-thread",
"time",
"macros",
"sync",
] }
walkdir = "2.5.0" walkdir = "2.5.0"
[lints.rust] [lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(rust_analyzer)'] } unexpected_cfgs = { level = "warn", check-cfg = ['cfg(rust_analyzer)'] }

View File

@ -1,13 +1,14 @@
use directories::UserDirs; use directories::UserDirs;
use gio::prelude::FileExt; use gio::prelude::FileExt;
use glib::object::Cast; use glib::object::Cast;
use std::collections::HashSet;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use tokio::sync::Mutex; use tokio::sync::Mutex;
use walkdir::{DirEntry, WalkDir}; use walkdir::{DirEntry, WalkDir};
use waycast_macros::{plugin, launcher_entry}; use waycast_macros::{launcher_entry, plugin};
use waycast_core::{LaunchError, LauncherListItem, LauncherPlugin}; use waycast_core::{LaunchError, LauncherListItem, LauncherPlugin};
@ -72,9 +73,9 @@ impl LauncherListItem for FileEntry {
} }
} }
pub fn default_search_list() -> Vec<PathBuf> { pub fn default_search_list() -> HashSet<PathBuf> {
if let Some(ud) = UserDirs::new() { if let Some(ud) = UserDirs::new() {
let mut paths: Vec<PathBuf> = Vec::new(); let mut paths: HashSet<PathBuf> = HashSet::new();
let user_dirs = [ let user_dirs = [
ud.document_dir(), ud.document_dir(),
ud.picture_dir(), ud.picture_dir(),
@ -83,18 +84,27 @@ pub fn default_search_list() -> Vec<PathBuf> {
]; ];
for path in user_dirs.into_iter().flatten() { for path in user_dirs.into_iter().flatten() {
paths.push(path.to_path_buf()); paths.insert(path.to_path_buf());
} }
return paths; return paths;
} }
Vec::new() HashSet::new()
}
pub fn default_skip_list() -> HashSet<String> {
HashSet::from([
String::from("vendor"),
String::from("node_modules"),
String::from("cache"),
String::from("zig-cache"),
])
} }
pub struct FileSearchPlugin { pub struct FileSearchPlugin {
search_paths: Vec<PathBuf>, search_paths: HashSet<PathBuf>,
skip_dirs: Vec<String>, skip_dirs: HashSet<String>,
// Running list of files in memory // Running list of files in memory
files: Arc<Mutex<Vec<FileEntry>>>, files: Arc<Mutex<Vec<FileEntry>>>,
} }
@ -107,14 +117,24 @@ impl Default for FileSearchPlugin {
impl FileSearchPlugin { impl FileSearchPlugin {
pub fn new() -> Self { pub fn new() -> Self {
let mut search_paths = default_search_list();
let mut skip_dirs = default_skip_list();
if let Ok(paths) =
waycast_config::config_file().get::<Vec<PathBuf>>("plugins.file_search.search_paths")
{
search_paths.extend(paths);
}
if let Ok(paths) =
waycast_config::config_file().get::<Vec<String>>("plugins.file_search.ignore_dirs")
{
skip_dirs.extend(paths);
}
FileSearchPlugin { FileSearchPlugin {
search_paths: default_search_list(), search_paths,
skip_dirs: vec![ skip_dirs,
String::from("vendor"),
String::from("node_modules"),
String::from("cache"),
String::from("zig-cache"),
],
files: Arc::new(Mutex::new(Vec::new())), files: Arc::new(Mutex::new(Vec::new())),
} }
} }
@ -130,12 +150,12 @@ impl FileSearchPlugin {
return Err(format!("Path is not a directory: {}", p.display())); return Err(format!("Path is not a directory: {}", p.display()));
} }
self.search_paths.push(p.to_path_buf()); self.search_paths.insert(p.to_path_buf());
Ok(()) Ok(())
} }
pub fn add_skip_dir(&mut self, directory_name: String) -> Result<(), String> { pub fn add_skip_dir(&mut self, directory_name: String) -> Result<(), String> {
self.skip_dirs.push(directory_name); self.skip_dirs.insert(directory_name);
Ok(()) Ok(())
} }
@ -143,13 +163,27 @@ impl FileSearchPlugin {
let files_clone = Arc::clone(&self.files); let files_clone = Arc::clone(&self.files);
let skip_dirs_clone = self.skip_dirs.clone(); let skip_dirs_clone = self.skip_dirs.clone();
println!("File search");
println!("---Scanning directories---");
for p in &self.search_paths {
println!("{}", p.display());
}
println!("---Skipping directories---");
for p in &self.skip_dirs {
println!("{}", p);
}
let scan_task = async move { let scan_task = async move {
let mut local_files = Vec::new(); let mut local_files = Vec::new();
for path in &self.search_paths { for path in &self.search_paths {
let walker = WalkDir::new(path).into_iter(); let walker = WalkDir::new(path).into_iter();
for entry in walker for entry in walker
.filter_entry(|e| !skip_hidden(e) && !skip_dir(e, &skip_dirs_clone)) .filter_entry(|e| {
!skip_hidden(e)
&& skip_dirs_clone.contains(e.file_name().to_string_lossy().as_ref())
})
.filter_map(|e| e.ok()) .filter_map(|e| e.ok())
{ {
if entry.path().is_file() { if entry.path().is_file() {
@ -183,14 +217,6 @@ fn skip_hidden(entry: &DirEntry) -> bool {
.unwrap_or(false) .unwrap_or(false)
} }
fn skip_dir(entry: &DirEntry, dirs: &Vec<String>) -> bool {
entry
.file_name()
.to_str()
.map(|n| dirs.contains(&String::from(n)))
.unwrap_or(false)
}
impl LauncherPlugin for FileSearchPlugin { impl LauncherPlugin for FileSearchPlugin {
plugin! { plugin! {
name: "Files", name: "Files",
@ -198,7 +224,7 @@ impl LauncherPlugin for FileSearchPlugin {
description: "Search and open files", description: "Search and open files",
prefix: "f" prefix: "f"
} }
fn init(&self) { fn init(&self) {
// Start async file scanning with 2000ms timeout // Start async file scanning with 2000ms timeout
let self_clone = FileSearchPlugin { let self_clone = FileSearchPlugin {
@ -240,9 +266,6 @@ impl LauncherPlugin for FileSearchPlugin {
} }
} }
pub fn new() -> FileSearchPlugin { pub fn new() -> FileSearchPlugin {
FileSearchPlugin::new() FileSearchPlugin::new()
} }

View File

@ -7,6 +7,7 @@
// and I'll just regex in the path. // and I'll just regex in the path.
// TODO: Project type detection and icon // TODO: Project type detection and icon
use std::{ use std::{
collections::HashSet,
fs, fs,
path::{Path, PathBuf}, path::{Path, PathBuf},
process::Command, process::Command,
@ -20,6 +21,7 @@ use waycast_macros::{launcher_entry, plugin};
#[derive(Clone)] #[derive(Clone)]
pub struct ProjectEntry { pub struct ProjectEntry {
path: PathBuf, path: PathBuf,
exec_command: String,
} }
impl LauncherListItem for ProjectEntry { impl LauncherListItem for ProjectEntry {
@ -44,8 +46,9 @@ impl LauncherListItem for ProjectEntry {
} }
pub struct ProjectsPlugin { pub struct ProjectsPlugin {
search_paths: Vec<PathBuf>, search_paths: HashSet<PathBuf>,
skip_dirs: Vec<String>, skip_dirs: HashSet<String>,
open_command: String,
// Running list of files in memory // Running list of files in memory
files: Arc<Mutex<Vec<ProjectEntry>>>, files: Arc<Mutex<Vec<ProjectEntry>>>,
} }
@ -62,20 +65,16 @@ impl ProjectsPlugin {
return Err(format!("Path is not a directory: {}", p.display())); return Err(format!("Path is not a directory: {}", p.display()));
} }
self.search_paths.push(p.to_path_buf()); self.search_paths.insert(p.to_path_buf());
Ok(()) Ok(())
} }
pub fn add_skip_dir(&mut self, directory_name: String) -> Result<(), String> { pub fn add_skip_dir(&mut self, directory_name: String) -> Result<(), String> {
self.skip_dirs.push(directory_name); self.skip_dirs.insert(directory_name);
Ok(()) Ok(())
} }
} }
fn should_skip_dir(dir_name: &str, skip_dirs: &[String]) -> bool {
skip_dirs.iter().any(|skip| skip == dir_name)
}
impl LauncherPlugin for ProjectsPlugin { impl LauncherPlugin for ProjectsPlugin {
plugin! { plugin! {
name: "Projects", name: "Projects",
@ -88,6 +87,7 @@ impl LauncherPlugin for ProjectsPlugin {
let files_clone = Arc::clone(&self.files); let files_clone = Arc::clone(&self.files);
let search_paths = self.search_paths.clone(); let search_paths = self.search_paths.clone();
let skip_dirs = self.skip_dirs.clone(); let skip_dirs = self.skip_dirs.clone();
let exec_command = self.open_command.clone();
std::thread::spawn(move || { std::thread::spawn(move || {
let rt = tokio::runtime::Runtime::new().unwrap(); let rt = tokio::runtime::Runtime::new().unwrap();
@ -110,11 +110,14 @@ impl LauncherPlugin for ProjectsPlugin {
} }
// Skip directories in skip list // Skip directories in skip list
if should_skip_dir(name_str, &skip_dirs) { if skip_dirs.contains(name_str) {
continue; continue;
} }
project_entries.push(ProjectEntry { path }); project_entries.push(ProjectEntry {
path,
exec_command: exec_command.clone(),
});
} }
} }
} }
@ -155,17 +158,31 @@ impl LauncherPlugin for ProjectsPlugin {
} }
} }
// fn get_config_value<T>(key: &str) -> Result<T> {
// waycast_config::config_file().get::<T>(format!("plugins.projects.{}", key))
// }
pub fn new() -> ProjectsPlugin { pub fn new() -> ProjectsPlugin {
let search_paths =
match waycast_config::get::<HashSet<PathBuf>>("plugins.projects.search_paths") {
Ok(paths) => paths,
Err(_) => HashSet::new(),
};
let skip_dirs = match waycast_config::get::<HashSet<String>>("plugins.projects.skip_dirs") {
Ok(paths) => paths,
Err(_) => HashSet::new(),
};
let open_command = match waycast_config::get::<String>("plugins.projects.open_command") {
Ok(cmd) => cmd,
Err(_) => String::from("code -n {path}"),
};
ProjectsPlugin { ProjectsPlugin {
search_paths: Vec::new(), search_paths,
skip_dirs: vec![ skip_dirs,
String::from("vendor"), open_command,
String::from("node_modules"),
String::from("cache"),
String::from("zig-cache"),
String::from(".git"),
String::from(".svn"),
],
files: Arc::new(Mutex::new(Vec::new())), files: Arc::new(Mutex::new(Vec::new())),
} }
} }