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

View file

@ -10,8 +10,10 @@ log = "0.4"
env_logger = "0.9.0"
rayon = "1.5.1"
winit = "0.25"
winit = {git="https://github.com/rust-windowing/winit"}
cairo-rs = {version = "0.14.0", features = ["xcb"]}
cairo-sys-rs = {version = "0.14.0", features = ["xcb"]}
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 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 ui;
mod sources;
mod matcher;
fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();
debug!{"Set up roftl"};
let roftl = roftl::Roftl::default()
let mut roftl = roftl::Roftl::new()
.add_source(sources::TestSource::new("ts1"))
.add_source(sources::Window::new());
.add_source(sources::Window::new())
.with_matcher(SkimMatcher::new());
debug!{"Source roftl sources"}
roftl.source();
let mut input_buffer = String::new();
debug!{"Build window"}
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.with_decorations(false)
.with_transparent(true)
.build(&event_loop)
.expect("Could not create window");
debug!{"Window id: {:?}", window.id()}
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"}
event_loop.run(move |evt, _win, flow| {
*flow = ControlFlow::Wait;
if let Event::WindowEvent{window_id, ..} = evt {
if window_id != window.id() {
debug!{"Received event for foreign window"}
return;
}
}
match evt {
Event::WindowEvent{event: CloseRequested, ..} => *flow = ControlFlow::Exit,
Event::WindowEvent{event: ReceivedCharacter(character), ..} => {
*flow = process_input(character, &mut input_buffer, &window)
Event::WindowEvent{event: CloseRequested, window_id}
if window_id == window.id() =>
{
*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}
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 {
'q' | 'Q' => ControlFlow::Exit,
// Escape
c if c == char::from(0x1b) => ControlFlow::Exit,
c if c == char::from(0x1b) => ControlFlow::Exit,
// Backspace
c if c == char::from(0x08) => {
@ -73,8 +114,20 @@ fn process_input(character: char, input_buffer: &mut String, window: &Window) ->
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() => {
debug!{"Got unknown control character"}
debug!{"Got unknown control character {:#x}", u32::from(c)}
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 super::matcher::PrefixMatcher;
pub type SourceRef = Box<dyn Source>;
pub type MatcherRef = Box<dyn Matcher>;
#[derive(Clone, Debug)]
pub struct Entry {
pub source: &'static str,
@ -21,45 +26,61 @@ pub trait Source: Send + Sync {
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 {
sources: Vec<Box<dyn Source>>,
sources: Vec<SourceRef>,
matcher: MatcherRef,
entries: Vec<Entry>,
narrow_map: Mutex<HashMap<usize, usize>>
}
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())) {
panic! {"Source with name '{}' already exists", source.name()}
panic! {"Source with name '{}' already exists", source.name()}
}
self.sources.push(source);
self
}
pub fn source(mut self) -> Self {
self.entries = self
.sources
.par_iter_mut()
.flat_map_iter(|s| s.entries())
.collect();
println!("Entries {:?}", self.entries);
pub fn with_matcher(mut self, matcher: MatcherRef) -> Self {
self.matcher = matcher;
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> {
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.entries
.par_iter()
.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)| {
self.narrow_map.lock().unwrap().insert(count.load(std::sync::atomic::Ordering::Acquire), idx);
count.fetch_add(1, std::sync::atomic::Ordering::Acquire);
self.narrow_map.lock().unwrap().insert(count.fetch_add(1, Ordering::Relaxed), idx);
e
})
.collect()

View file

@ -3,4 +3,3 @@ pub use test::TestSource;
mod windows;
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 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>
{
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 mut roots = setup.roots();
let screen = roots.next().unwrap();
let depth = screen.allowed_depths().next().unwrap();
let visualtype = depth.visuals().next().unwrap();
let window_visualid = xcb::get_window_attributes(&xcb_conn, window_id)
.get_reply()
.expect("Could not fetch attributes for window")
.visual();
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
// when dropped. We cannot let this happen since the xcb_connection_t
// 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);
visualtype
}
fn make_context(window: &Window) -> cairo::Context {
fn make_context(window: &Window) -> cairo::Context
{
let winit_xcb_conn = window
.xcb_connection()
.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 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(
&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")
}
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 radius = corner_radius / aspect;
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();
}
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.set_font_size (0.25);
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);
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.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_text(&cr, input);
for i in 1..10 {
draw_rectangle(&cr, 0.0, 0.3*(i as f64), 4.0, 0.3, 2.0);
}
result.iter().enumerate()
.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_source_rgb(255.0, 255.0, 255.0);