Unstable winit, matcher, xcb fix

- Move to unstable winit since 0.25.0 does not handle transparency correctly on
X11

- Matcher trait to enable different matching algorithms

- Find correct visualtype for cairo xcb surface: Visualtype was more or less
taken randomly which only worked by chance. Now find visualtype that corresponds
to visualid of the winit window which should be the correct one.
This commit is contained in:
Armin Friedl 2021-10-14 21:29:16 +02:00
parent 2fdfc5b749
commit 35f01cafe3
9 changed files with 345 additions and 311 deletions

377
Cargo.lock generated
View file

@ -2,12 +2,6 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "ab_glyph_rasterizer"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9fe5e32de01730eb1f6b7f5b51c17e03e2325bf40a74f754f04f130043affff"
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.18" version = "0.7.18"
@ -17,37 +11,12 @@ dependencies = [
"memchr", "memchr",
] ]
[[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]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.44" version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@ -65,35 +34,24 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "blake2b_simd"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[package]] [[package]]
name = "block" name = "block"
version = "0.1.6" version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
[[package]]
name = "bumpalo"
version = "3.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538"
[[package]] [[package]]
name = "cairo-rs" name = "cairo-rs"
version = "0.14.7" version = "0.14.7"
@ -120,12 +78,12 @@ dependencies = [
[[package]] [[package]]
name = "calloop" name = "calloop"
version = "0.6.5" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b036167e76041694579972c28cf4877b4f92da222560ddb49008937b6a6727c" checksum = "42dcfbd723aa6eff9f024cfd5ad08b11144d79b2d8d37b4a31a006ceab255c77"
dependencies = [ dependencies = [
"log", "log",
"nix 0.18.0", "nix",
] ]
[[package]] [[package]]
@ -186,12 +144,6 @@ dependencies = [
"objc", "objc",
] ]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.7.0" version = "0.7.0"
@ -274,20 +226,6 @@ dependencies = [
"objc", "objc",
] ]
[[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]] [[package]]
name = "crossbeam-channel" name = "crossbeam-channel"
version = "0.5.1" version = "0.5.1"
@ -322,16 +260,6 @@ dependencies = [
"scopeguard", "scopeguard",
] ]
[[package]]
name = "crossbeam-queue"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils",
]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.5" version = "0.8.5"
@ -388,39 +316,19 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "dirs"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]] [[package]]
name = "dispatch" name = "dispatch"
version = "0.2.0" 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 = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" 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]] [[package]]
name = "dlib" name = "dlib"
version = "0.5.0" 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 = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794"
dependencies = [ dependencies = [
"libloading 0.7.1", "libloading",
] ]
[[package]] [[package]]
@ -516,14 +424,12 @@ dependencies = [
] ]
[[package]] [[package]]
name = "getrandom" name = "fuzzy-matcher"
version = "0.1.16" version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "thread_local",
"libc",
"wasi",
] ]
[[package]] [[package]]
@ -618,6 +524,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"js-sys",
"wasm-bindgen",
"web-sys",
] ]
[[package]] [[package]]
@ -635,6 +544,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "js-sys"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
dependencies = [
"wasm-bindgen",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -647,16 +565,6 @@ version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
[[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",
]
[[package]] [[package]]
name = "libloading" name = "libloading"
version = "0.7.1" version = "0.7.1"
@ -702,9 +610,9 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]] [[package]]
name = "memmap2" name = "memmap2"
version = "0.1.0" version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b70ca2a6103ac8b665dc150b142ef0e4e89df640c9e6cf295d189c3caebe5a" checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -737,18 +645,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "mio-misc"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ddf05411bb159cdb5801bb10002afb66cb4572be656044315e363460ce69dc2"
dependencies = [
"crossbeam",
"crossbeam-queue",
"log",
"mio",
]
[[package]] [[package]]
name = "miow" name = "miow"
version = "0.3.7" version = "0.3.7"
@ -805,26 +701,15 @@ checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d"
[[package]] [[package]]
name = "nix" name = "nix"
version = "0.18.0" version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83450fe6a6142ddd95fb064b746083fc4ef1705fe81f64a64e1d4b39f54a1055" checksum = "cf1e25ee6b412c2a1e3fcb6a4499a5c1bfe7f43e014bdce9a6b6666e5aa2d187"
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 = [ dependencies = [
"bitflags", "bitflags",
"cc", "cc",
"cfg-if 1.0.0", "cfg-if 1.0.0",
"libc", "libc",
"memoffset",
] ]
[[package]] [[package]]
@ -894,15 +779,6 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "owned_ttf_parser"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3"
dependencies = [
"ttf-parser",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.11.2" version = "0.11.2"
@ -923,7 +799,7 @@ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"instant", "instant",
"libc", "libc",
"redox_syscall 0.2.10", "redox_syscall",
"smallvec", "smallvec",
"winapi", "winapi",
] ]
@ -1047,12 +923,6 @@ dependencies = [
"num_cpus", "num_cpus",
] ]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.10" version = "0.2.10"
@ -1062,17 +932,6 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "redox_users"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [
"getrandom",
"redox_syscall 0.1.57",
"rust-argon2",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.5.4" version = "1.5.4"
@ -1097,6 +956,7 @@ dependencies = [
"cairo-rs", "cairo-rs",
"cairo-sys-rs", "cairo-sys-rs",
"env_logger", "env_logger",
"fuzzy-matcher",
"log", "log",
"rayon", "rayon",
"winit", "winit",
@ -1104,37 +964,6 @@ dependencies = [
"xcb-util", "xcb-util",
] ]
[[package]]
name = "rust-argon2"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[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 = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "scoped-tls" name = "scoped-tls"
version = "1.0.0" version = "1.0.0"
@ -1167,18 +996,18 @@ checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
[[package]] [[package]]
name = "smithay-client-toolkit" name = "smithay-client-toolkit"
version = "0.12.3" version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4750c76fd5d3ac95fa3ed80fe667d6a3d8590a960e5b575b98eea93339a80b80" checksum = "8f41633cd89f7d598d5d933fe36ce614fe9eb54d8b5bc2340556d8b0b7f2c144"
dependencies = [ dependencies = [
"andrew",
"bitflags", "bitflags",
"calloop", "calloop",
"dlib 0.4.2", "dlib",
"lazy_static", "lazy_static",
"log", "log",
"memmap2", "memmap2",
"nix 0.18.0", "nix",
"pkg-config",
"wayland-client", "wayland-client",
"wayland-cursor", "wayland-cursor",
"wayland-protocols", "wayland-protocols",
@ -1266,6 +1095,15 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "thread_local"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
dependencies = [
"once_cell",
]
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.5.8" version = "0.5.8"
@ -1275,12 +1113,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "ttf-parser"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc"
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.8.0" version = "1.8.0"
@ -1306,32 +1138,69 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]] [[package]]
name = "walkdir" name = "wasm-bindgen"
version = "2.3.2" version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
dependencies = [ dependencies = [
"same-file", "cfg-if 1.0.0",
"winapi", "wasm-bindgen-macro",
"winapi-util",
] ]
[[package]] [[package]]
name = "wasi" name = "wasm-bindgen-backend"
version = "0.9.0+wasi-snapshot-preview1" version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
[[package]] [[package]]
name = "wayland-client" name = "wayland-client"
version = "0.28.6" version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ab332350e502f159382201394a78e3cc12d0f04db863429260164ea40e0355" checksum = "6deeba72b1fd9e9fc6641603bd5f72fa465857e3577b9a823fc316ffd45e69b4"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"downcast-rs", "downcast-rs",
"libc", "libc",
"nix 0.20.0", "nix",
"scoped-tls", "scoped-tls",
"wayland-commons", "wayland-commons",
"wayland-scanner", "wayland-scanner",
@ -1340,11 +1209,11 @@ dependencies = [
[[package]] [[package]]
name = "wayland-commons" name = "wayland-commons"
version = "0.28.6" version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21817947c7011bbd0a27e11b17b337bfd022e8544b071a2641232047966fbda" checksum = "93d6377fc0efc620da05cb78c5dc846420940e7b2c471aa2faf59c58e063c2b7"
dependencies = [ dependencies = [
"nix 0.20.0", "nix",
"once_cell", "once_cell",
"smallvec", "smallvec",
"wayland-sys", "wayland-sys",
@ -1352,20 +1221,20 @@ dependencies = [
[[package]] [[package]]
name = "wayland-cursor" name = "wayland-cursor"
version = "0.28.6" version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be610084edd1586d45e7bdd275fe345c7c1873598caa464c4fb835dee70fa65a" checksum = "bf9197a26e00b5e282b57ea9b620e4305ea5682f55f0b1ad862e388abf2d2bb5"
dependencies = [ dependencies = [
"nix 0.20.0", "nix",
"wayland-client", "wayland-client",
"xcursor", "xcursor",
] ]
[[package]] [[package]]
name = "wayland-protocols" name = "wayland-protocols"
version = "0.28.6" version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "286620ea4d803bacf61fa087a4242ee316693099ee5a140796aaba02b29f861f" checksum = "503643f261c0f18124a4666b8c1e66258cf68b51f675d6e64469fbc72ddf0cd6"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"wayland-client", "wayland-client",
@ -1375,9 +1244,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-scanner" name = "wayland-scanner"
version = "0.28.6" version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce923eb2deb61de332d1f356ec7b6bf37094dc5573952e1c8936db03b54c03f1" checksum = "7d3d043a8926b2836749018bfb393e2328cac86bd414b9c3d3f8c523d0dee2dd"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1386,15 +1255,25 @@ dependencies = [
[[package]] [[package]]
name = "wayland-sys" name = "wayland-sys"
version = "0.28.6" version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d841fca9aed7febf9bed2e9796c49bf58d4152ceda8ac949ebe00868d8f0feb8" checksum = "fef2a7d20f93be1379a2dfd9457c291e840b942fa38fe0b95ad6b0425a22d43a"
dependencies = [ dependencies = [
"dlib 0.5.0", "dlib",
"lazy_static", "lazy_static",
"pkg-config", "pkg-config",
] ]
[[package]]
name = "web-sys"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"
@ -1429,10 +1308,10 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "winit" name = "winit"
version = "0.25.0" version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/rust-windowing/winit#1b3b82a3c1369c5248a2e6a251230ba6c615e918"
checksum = "79610794594d5e86be473ef7763f604f2159cbac8c94debd00df8fb41e86c2f8"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"block",
"cocoa", "cocoa",
"core-foundation 0.9.1", "core-foundation 0.9.1",
"core-graphics 0.22.2", "core-graphics 0.22.2",
@ -1443,7 +1322,6 @@ dependencies = [
"libc", "libc",
"log", "log",
"mio", "mio",
"mio-misc",
"ndk", "ndk",
"ndk-glue", "ndk-glue",
"ndk-sys", "ndk-sys",
@ -1451,9 +1329,11 @@ dependencies = [
"parking_lot", "parking_lot",
"percent-encoding", "percent-encoding",
"raw-window-handle", "raw-window-handle",
"scopeguard",
"smithay-client-toolkit", "smithay-client-toolkit",
"wasm-bindgen",
"wayland-client", "wayland-client",
"wayland-protocols",
"web-sys",
"winapi", "winapi",
"x11-dl", "x11-dl",
] ]
@ -1498,15 +1378,6 @@ dependencies = [
"nom", "nom",
] ]
[[package]]
name = "xdg"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de4cfc7dc9727713f386aadce9496f1ed64ea368d9f1f813a54d0f98f8741286"
dependencies = [
"dirs",
]
[[package]] [[package]]
name = "xml-rs" name = "xml-rs"
version = "0.8.4" version = "0.8.4"

View file

@ -10,8 +10,10 @@ log = "0.4"
env_logger = "0.9.0" env_logger = "0.9.0"
rayon = "1.5.1" rayon = "1.5.1"
winit = "0.25" winit = {git="https://github.com/rust-windowing/winit"}
cairo-rs = {version = "0.14.0", features = ["xcb"]} cairo-rs = {version = "0.14.0", features = ["xcb"]}
cairo-sys-rs = {version = "0.14.0", features = ["xcb"]} cairo-sys-rs = {version = "0.14.0", features = ["xcb"]}
xcb = "0.9.0" xcb = "0.9.0"
xcb-util = {version = "0.3.0", features = ["ewmh", "icccm"]} xcb-util = {version = "0.3.0", features = ["ewmh", "icccm"]}
fuzzy-matcher = "0.3.7"

View file

@ -1,56 +1,77 @@
use log::{debug, trace}; use log::{debug, trace};
use std::error::Error; use std::error::Error;
use winit::{event::{Event, WindowEvent::{CloseRequested, ReceivedCharacter}}, event_loop::{ControlFlow, EventLoop}, window::{Window, WindowBuilder}}; use winit::window::{Window, WindowBuilder};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode,
WindowEvent::{CloseRequested, ReceivedCharacter}};
use crate::matcher::SkimMatcher;
mod roftl; mod roftl;
mod ui; mod ui;
mod sources; mod sources;
mod matcher;
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
env_logger::init(); env_logger::init();
debug!{"Set up roftl"}; debug!{"Set up roftl"};
let roftl = roftl::Roftl::default() let mut roftl = roftl::Roftl::new()
.add_source(sources::TestSource::new("ts1")) .add_source(sources::TestSource::new("ts1"))
.add_source(sources::Window::new()); .add_source(sources::Window::new())
.with_matcher(SkimMatcher::new());
debug!{"Source roftl sources"} debug!{"Source roftl sources"}
roftl.source(); roftl.source();
let mut input_buffer = String::new();
debug!{"Build window"} debug!{"Build window"}
let event_loop = EventLoop::new(); let event_loop = EventLoop::new();
let window = WindowBuilder::new() let window = WindowBuilder::new()
.with_decorations(false)
.with_transparent(true) .with_transparent(true)
.build(&event_loop) .build(&event_loop)
.expect("Could not create window"); .expect("Could not create window");
debug!{"Window id: {:?}", window.id()}
debug!{"Draw empty state to window"} debug!{"Draw empty state to window"}
ui::draw_on_window(&window, ""); ui::draw_on_window(&window, "", vec![]);
let mut input_buffer = String::new();
debug!{"Start event loop"} debug!{"Start event loop"}
event_loop.run(move |evt, _win, flow| { event_loop.run(move |evt, _win, flow| {
*flow = ControlFlow::Wait; *flow = ControlFlow::Wait;
if let Event::WindowEvent{window_id, ..} = evt {
if window_id != window.id() {
debug!{"Received event for foreign window"}
return;
}
}
match evt { match evt {
Event::WindowEvent{event: CloseRequested, ..} => *flow = ControlFlow::Exit, Event::WindowEvent{event: CloseRequested, window_id}
if window_id == window.id() =>
Event::WindowEvent{event: ReceivedCharacter(character), ..} => { {
*flow = process_input(character, &mut input_buffer, &window) *flow = ControlFlow::Exit;
} }
Event::RedrawRequested(window_id) if window_id == window.id() => { Event::WindowEvent{event: ReceivedCharacter(character), window_id}
if window_id == window.id() =>
{
*flow = process_character(character, &mut input_buffer, &window);
}
Event::WindowEvent{event: winit::event::WindowEvent::KeyboardInput{input, ..}, window_id}
if window_id == window.id() =>
{
process_input(input, &mut input_buffer, &window);
}
Event::RedrawRequested(window_id)
if window_id == window.id() =>
{
trace!{"Redrawing with input {}", input_buffer} trace!{"Redrawing with input {}", input_buffer}
ui::draw_on_window(&window, &input_buffer);
let result = roftl.narrow(&input_buffer);
trace!{"Narrow result {:?}", result}
ui::draw_on_window(&window, &input_buffer, result);
} }
_ => () _ => ()
@ -58,12 +79,32 @@ fn main() -> Result<(), Box<dyn Error>> {
}); });
} }
fn process_input(character: char, input_buffer: &mut String, window: &Window) -> ControlFlow { fn process_input(input: KeyboardInput, input_buffer: &mut String, window: &Window) -> ControlFlow {
if let KeyboardInput { virtual_keycode: Some(code), state, .. } = input {
return match (code, state) {
(VirtualKeyCode::Down, ElementState::Released) => {
debug!("Received down");
ControlFlow::Wait
},
(VirtualKeyCode::Up, ElementState::Released) => {
debug!("Received up");
ControlFlow::Wait
},
_ => ControlFlow::Wait,
}
}
ControlFlow::Wait
}
fn process_character(character: char, input_buffer: &mut String, window: &Window) -> ControlFlow {
match character { match character {
'q' | 'Q' => ControlFlow::Exit, 'q' | 'Q' => ControlFlow::Exit,
// Escape // Escape
c if c == char::from(0x1b) => ControlFlow::Exit, c if c == char::from(0x1b) => ControlFlow::Exit,
// Backspace // Backspace
c if c == char::from(0x08) => { c if c == char::from(0x08) => {
@ -73,8 +114,20 @@ fn process_input(character: char, input_buffer: &mut String, window: &Window) ->
ControlFlow::Wait ControlFlow::Wait
} }
// Ctrl+n
c if c == char::from(0x0e) => {
debug!{"Received Ctrl+next"}
ControlFlow::Wait
}
// Ctrl+p
c if c == char::from(0x10) => {
debug!{"Received Ctrl+previous"}
ControlFlow::Wait
}
c if c.is_control() => { c if c.is_control() => {
debug!{"Got unknown control character"} debug!{"Got unknown control character {:#x}", u32::from(c)}
ControlFlow::Wait ControlFlow::Wait
} }

5
src/matcher/mod.rs Normal file
View file

@ -0,0 +1,5 @@
mod prefix;
pub use prefix::PrefixMatcher;
mod skim;
pub use skim::SkimMatcher;

22
src/matcher/prefix.rs Normal file
View file

@ -0,0 +1,22 @@
use crate::roftl::Matcher;
pub struct PrefixMatcher;
impl PrefixMatcher {
pub fn new() -> Box<Self> {
Box::new(PrefixMatcher{})
}
}
impl Matcher for PrefixMatcher {
fn try_match(&self, haystack: &str, needle: &str) -> Option<(f64, Vec<usize>)> {
let mut indices = vec![];
if haystack.starts_with(needle) {
(0..needle.len()).for_each(|i| indices.push(i));
return Option::Some((1.0, indices));
}
Option::None
}
}

24
src/matcher/skim.rs Normal file
View file

@ -0,0 +1,24 @@
use fuzzy_matcher::{FuzzyMatcher, skim::SkimMatcherV2};
use crate::roftl::Matcher;
pub struct SkimMatcher {
matcher: SkimMatcherV2
}
impl SkimMatcher {
pub fn new() -> Box<Self> {
Box::new(SkimMatcher{
matcher: SkimMatcherV2::default()
})
}
}
impl Matcher for SkimMatcher {
fn try_match(&self, haystack: &str, needle: &str) -> Option<(f64, Vec<usize>)> {
match self.matcher.fuzzy_indices(haystack, needle) {
Some((score, indices)) => Some(((i64::MAX as f64/score as f64), indices)),
None => None
}
}
}

View file

@ -1,7 +1,12 @@
use std::{collections::HashMap, sync::Mutex}; use std::{collections::HashMap, sync::{Arc, Mutex, atomic::{AtomicUsize, Ordering}}};
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator}; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator};
use super::matcher::PrefixMatcher;
pub type SourceRef = Box<dyn Source>;
pub type MatcherRef = Box<dyn Matcher>;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Entry { pub struct Entry {
pub source: &'static str, pub source: &'static str,
@ -21,45 +26,61 @@ pub trait Source: Send + Sync {
fn action(&self, entry: &Entry, action: Action); fn action(&self, entry: &Entry, action: Action);
} }
#[derive(Default)] pub trait Matcher: Send + Sync {
fn try_match(&self, haystack: &str, needle: &str) -> Option<(f64, Vec<usize>)>;
}
pub struct Roftl { pub struct Roftl {
sources: Vec<Box<dyn Source>>, sources: Vec<SourceRef>,
matcher: MatcherRef,
entries: Vec<Entry>, entries: Vec<Entry>,
narrow_map: Mutex<HashMap<usize, usize>> narrow_map: Mutex<HashMap<usize, usize>>
} }
impl Roftl { impl Roftl {
pub fn add_source(mut self, source: Box<dyn Source>) -> Self { pub fn new() -> Self {
Roftl {
sources: vec![],
matcher: PrefixMatcher::new(),
entries: vec![],
narrow_map: Mutex::default()
}
}
pub fn add_source(mut self, source: SourceRef) -> Self {
if self.sources.par_iter().any(|s| s.name().eq(source.name())) { if self.sources.par_iter().any(|s| s.name().eq(source.name())) {
panic! {"Source with name '{}' already exists", source.name()} panic! {"Source with name '{}' already exists", source.name()}
} }
self.sources.push(source); self.sources.push(source);
self self
} }
pub fn source(mut self) -> Self { pub fn with_matcher(mut self, matcher: MatcherRef) -> Self {
self.entries = self self.matcher = matcher;
.sources
.par_iter_mut()
.flat_map_iter(|s| s.entries())
.collect();
println!("Entries {:?}", self.entries);
self self
} }
pub fn source(&mut self) {
self.entries = self
.sources
.par_iter_mut()
.flat_map(|s| s.entries())
.collect();
println!("Entries {:?}", self.entries);
}
pub fn narrow(&self, input: &str) -> Vec<&Entry> { pub fn narrow(&self, input: &str) -> Vec<&Entry> {
let count = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0)); let count = Arc::new(AtomicUsize::new(0));
self.narrow_map.lock().unwrap().clear(); self.narrow_map.lock().unwrap().clear();
self.entries self.entries
.par_iter() .par_iter()
.enumerate() .enumerate()
.filter(|(_idx, e)| e.name.starts_with(input)) .filter(|(_idx, e)| self.matcher.try_match(&e.name, input).is_some())
.map(move |(idx, e)| { .map(move |(idx, e)| {
self.narrow_map.lock().unwrap().insert(count.load(std::sync::atomic::Ordering::Acquire), idx); self.narrow_map.lock().unwrap().insert(count.fetch_add(1, Ordering::Relaxed), idx);
count.fetch_add(1, std::sync::atomic::Ordering::Acquire);
e e
}) })
.collect() .collect()

View file

@ -3,4 +3,3 @@ pub use test::TestSource;
mod windows; mod windows;
pub use windows::Window; pub use windows::Window;

View file

@ -1,34 +1,52 @@
use std::{borrow::BorrowMut, ffi::c_void}; use std::borrow::BorrowMut;
use std::ffi::c_void;
use log::debug;
use winit::{platform::unix::WindowExtUnix, window::Window}; use winit::{platform::unix::WindowExtUnix, window::Window};
use super::roftl::Entry;
fn get_visual_type<T>(mut connection: T) -> xcb::Visualtype fn get_visual_type<T>(mut connection: T, window_id: u32) -> xcb::Visualtype
where T: BorrowMut<*mut c_void> where T: BorrowMut<*mut c_void>
{ {
let xcb_conn = unsafe { xcb::Connection::from_raw_conn(*connection.borrow_mut() as *mut xcb::ffi::xcb_connection_t) }; let xcb_conn = unsafe { xcb::Connection::from_raw_conn(*connection.borrow_mut() as *mut xcb::ffi::xcb_connection_t) };
let setup = xcb_conn.get_setup(); let window_visualid = xcb::get_window_attributes(&xcb_conn, window_id)
let mut roots = setup.roots(); .get_reply()
let screen = roots.next().unwrap(); .expect("Could not fetch attributes for window")
let depth = screen.allowed_depths().next().unwrap(); .visual();
let visualtype = depth.visuals().next().unwrap();
debug!{"Found visualid {} for window", window_visualid}
debug!{"Trying to map visualid to visualtype {}", window_visualid}
let visualtype = xcb_conn.get_setup().roots()
.flat_map(|screen| screen.allowed_depths())
.flat_map(|depth| depth.visuals())
.find(|visualtype| {visualtype.visual_id() == window_visualid})
.expect("Could not match visualid to visualtype");
// xcb::Connection calls disconnect on the underlying xcb_connection_t // xcb::Connection calls disconnect on the underlying xcb_connection_t
// when dropped. We cannot let this happen since the xcb_connection_t // when dropped. We cannot let this happen since the xcb_connection_t
// is actually owned by the winit::Window // is actually owned by the winit::Window
// We try to signify this with `where T: BorrowMut<*mut c_void>` but
// this is unfortunately not enforced down to the raw pointer
std::mem::forget(xcb_conn); std::mem::forget(xcb_conn);
visualtype visualtype
} }
fn make_context(window: &Window) -> cairo::Context { fn make_context(window: &Window) -> cairo::Context
{
let winit_xcb_conn = window let winit_xcb_conn = window
.xcb_connection() .xcb_connection()
.expect("Could not get connection from window"); .expect("Could not get connection from window");
let xlib_window_id = window
.xlib_window()
.expect("Could not get xlib window");
let visual_type = unsafe { let visual_type = unsafe {
let mut visual_type = get_visual_type(winit_xcb_conn).base; let mut visual_type = get_visual_type(winit_xcb_conn, xlib_window_id as u32).base;
cairo::XCBVisualType::from_raw_none( cairo::XCBVisualType::from_raw_none(
&mut visual_type as *mut xcb::ffi::xcb_visualtype_t as *mut cairo::ffi::xcb_visualtype_t &mut visual_type as *mut xcb::ffi::xcb_visualtype_t as *mut cairo::ffi::xcb_visualtype_t
) )
@ -51,7 +69,8 @@ fn make_context(window: &Window) -> cairo::Context {
cairo::Context::new(&surface).expect("Could not create drawing context") cairo::Context::new(&surface).expect("Could not create drawing context")
} }
fn draw_rectangle(cr: &cairo::Context, x: f64, y: f64, width: f64, height: f64, aspect: f64) { fn draw_rectangle(cr: &cairo::Context, x: f64, y: f64, width: f64, height: f64, aspect: f64)
{
let corner_radius = height / 10.0; /* and corner curvature radius */ let corner_radius = height / 10.0; /* and corner curvature radius */
let radius = corner_radius / aspect; let radius = corner_radius / aspect;
let degrees = std::f64::consts::PI / 180.0; let degrees = std::f64::consts::PI / 180.0;
@ -71,7 +90,8 @@ fn draw_rectangle(cr: &cairo::Context, x: f64, y: f64, width: f64, height: f64,
cr.stroke ().unwrap(); cr.stroke ().unwrap();
} }
fn draw_text(cr: &cairo::Context, input: &str) { fn draw_text(cr: &cairo::Context, input: &str)
{
cr.select_font_face ("serif", cairo::FontSlant::Normal, cairo::FontWeight::Normal); cr.select_font_face ("serif", cairo::FontSlant::Normal, cairo::FontWeight::Normal);
cr.set_font_size (0.25); cr.set_font_size (0.25);
cr.set_source_rgb (0.0, 0.0, 1.0); cr.set_source_rgb (0.0, 0.0, 1.0);
@ -87,9 +107,25 @@ fn draw_text(cr: &cairo::Context, input: &str) {
} }
} }
pub fn draw_on_window(window: &Window, input: &str) { fn draw_result(cr: &cairo::Context, input: &str, x: f64, y: f64)
{
cr.select_font_face ("serif", cairo::FontSlant::Normal, cairo::FontWeight::Normal);
cr.set_font_size (0.25);
cr.set_source_rgb (0.0, 0.0, 1.0);
cr.move_to (x, y);
cr.show_text(input).unwrap();
}
pub fn draw_on_window(window: &Window, input: &str, result: Vec<&Entry>)
{
let cr = make_context(&window); let cr = make_context(&window);
cr.save().unwrap();
cr.set_source_rgba(0.0, 0.0, 0.0, 0.5);
cr.set_operator(cairo::Operator::Source);
cr.paint().unwrap();
cr.restore().unwrap();
cr.translate(300.0, 300.0); cr.translate(300.0, 300.0);
cr.scale(100.0, 100.0); cr.scale(100.0, 100.0);
@ -97,10 +133,11 @@ pub fn draw_on_window(window: &Window, input: &str) {
draw_rectangle(&cr, 0.0, 0.0, 4.0, 0.3, 2.0); draw_rectangle(&cr, 0.0, 0.0, 4.0, 0.3, 2.0);
draw_text(&cr, input); draw_text(&cr, input);
for i in 1..10 { result.iter().enumerate()
draw_rectangle(&cr, 0.0, 0.3*(i as f64), 4.0, 0.3, 2.0); .for_each(|(i, e)| {
} draw_rectangle(&cr, 0.0, 0.3*((1+i) as f64), 4.0, 0.3, 2.0);
draw_result(&cr, &e.name, 0.05, 0.3*((i+1) as f64)+0.23);
});
// cr.set_line_width(0.5); // cr.set_line_width(0.5);
// cr.set_source_rgb(255.0, 255.0, 255.0); // cr.set_source_rgb(255.0, 255.0, 255.0);