├── .envrc ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── demo.gif ├── flake.lock ├── flake.nix ├── shaders └── spotlight.fs └── src └── main.rs /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .direnv 3 | result 4 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "lldb", 9 | "request": "launch", 10 | "name": "Debug executable 'woomer'", 11 | "cargo": { 12 | "args": [ 13 | "build", 14 | "--bin=woomer", 15 | "--package=woomer" 16 | ], 17 | "filter": { 18 | "name": "woomer", 19 | "kind": "bin" 20 | } 21 | }, 22 | "args": [], 23 | "cwd": "${workspaceFolder}" 24 | }, 25 | { 26 | "type": "lldb", 27 | "request": "launch", 28 | "name": "Debug unit tests in executable 'woomer'", 29 | "cargo": { 30 | "args": [ 31 | "test", 32 | "--no-run", 33 | "--bin=woomer", 34 | "--package=woomer" 35 | ], 36 | "filter": { 37 | "name": "woomer", 38 | "kind": "bin" 39 | } 40 | }, 41 | "args": [], 42 | "cwd": "${workspaceFolder}" 43 | } 44 | ] 45 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.server.path": "rust-analyzer" 3 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | I don't have strict rules or formats when creating pull requests or issues on my projects. 2 | You can send pull requests however you like as long as it: 3 | 4 | - is well structured 5 | - is not a troll 6 | - has a good description of what was added 7 | - has decent commit messages, don't put garbage on them please 8 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "adler2" 7 | version = "2.0.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 10 | 11 | [[package]] 12 | name = "aho-corasick" 13 | version = "1.1.3" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 16 | dependencies = [ 17 | "memchr", 18 | ] 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.4.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 25 | 26 | [[package]] 27 | name = "bindgen" 28 | version = "0.70.1" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" 31 | dependencies = [ 32 | "bitflags 2.9.1", 33 | "cexpr", 34 | "clang-sys", 35 | "itertools", 36 | "log", 37 | "prettyplease", 38 | "proc-macro2", 39 | "quote", 40 | "regex", 41 | "rustc-hash", 42 | "shlex", 43 | "syn", 44 | ] 45 | 46 | [[package]] 47 | name = "bit_field" 48 | version = "0.10.2" 49 | source = "registry+https://github.com/rust-lang/crates.io-index" 50 | checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" 51 | 52 | [[package]] 53 | name = "bitflags" 54 | version = "1.3.2" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 57 | 58 | [[package]] 59 | name = "bitflags" 60 | version = "2.9.1" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" 63 | 64 | [[package]] 65 | name = "bytemuck" 66 | version = "1.23.0" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" 69 | dependencies = [ 70 | "bytemuck_derive", 71 | ] 72 | 73 | [[package]] 74 | name = "bytemuck_derive" 75 | version = "1.9.3" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" 78 | dependencies = [ 79 | "proc-macro2", 80 | "quote", 81 | "syn", 82 | ] 83 | 84 | [[package]] 85 | name = "byteorder" 86 | version = "1.5.0" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 89 | 90 | [[package]] 91 | name = "cc" 92 | version = "1.2.23" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" 95 | dependencies = [ 96 | "shlex", 97 | ] 98 | 99 | [[package]] 100 | name = "cexpr" 101 | version = "0.6.0" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 104 | dependencies = [ 105 | "nom", 106 | ] 107 | 108 | [[package]] 109 | name = "cfg-if" 110 | version = "1.0.0" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 113 | 114 | [[package]] 115 | name = "clang-sys" 116 | version = "1.8.1" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" 119 | dependencies = [ 120 | "glob", 121 | "libc", 122 | "libloading", 123 | ] 124 | 125 | [[package]] 126 | name = "cmake" 127 | version = "0.1.54" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" 130 | dependencies = [ 131 | "cc", 132 | ] 133 | 134 | [[package]] 135 | name = "color_quant" 136 | version = "1.1.0" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" 139 | 140 | [[package]] 141 | name = "crc32fast" 142 | version = "1.4.2" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 145 | dependencies = [ 146 | "cfg-if", 147 | ] 148 | 149 | [[package]] 150 | name = "crossbeam-deque" 151 | version = "0.8.6" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" 154 | dependencies = [ 155 | "crossbeam-epoch", 156 | "crossbeam-utils", 157 | ] 158 | 159 | [[package]] 160 | name = "crossbeam-epoch" 161 | version = "0.9.18" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 164 | dependencies = [ 165 | "crossbeam-utils", 166 | ] 167 | 168 | [[package]] 169 | name = "crossbeam-utils" 170 | version = "0.8.21" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 173 | 174 | [[package]] 175 | name = "crunchy" 176 | version = "0.2.3" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" 179 | 180 | [[package]] 181 | name = "dlib" 182 | version = "0.5.2" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" 185 | dependencies = [ 186 | "libloading", 187 | ] 188 | 189 | [[package]] 190 | name = "downcast-rs" 191 | version = "1.2.1" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" 194 | 195 | [[package]] 196 | name = "drm" 197 | version = "0.12.0" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "98888c4bbd601524c11a7ed63f814b8825f420514f78e96f752c437ae9cbb5d1" 200 | dependencies = [ 201 | "bitflags 2.9.1", 202 | "bytemuck", 203 | "drm-ffi", 204 | "drm-fourcc", 205 | "rustix", 206 | ] 207 | 208 | [[package]] 209 | name = "drm-ffi" 210 | version = "0.8.0" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "97c98727e48b7ccb4f4aea8cfe881e5b07f702d17b7875991881b41af7278d53" 213 | dependencies = [ 214 | "drm-sys", 215 | "rustix", 216 | ] 217 | 218 | [[package]] 219 | name = "drm-fourcc" 220 | version = "2.2.0" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" 223 | 224 | [[package]] 225 | name = "drm-sys" 226 | version = "0.7.0" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | checksum = "fd39dde40b6e196c2e8763f23d119ddb1a8714534bf7d77fa97a65b0feda3986" 229 | dependencies = [ 230 | "libc", 231 | "linux-raw-sys 0.6.5", 232 | ] 233 | 234 | [[package]] 235 | name = "either" 236 | version = "1.15.0" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 239 | 240 | [[package]] 241 | name = "errno" 242 | version = "0.3.12" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" 245 | dependencies = [ 246 | "libc", 247 | "windows-sys", 248 | ] 249 | 250 | [[package]] 251 | name = "exr" 252 | version = "1.73.0" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" 255 | dependencies = [ 256 | "bit_field", 257 | "half", 258 | "lebe", 259 | "miniz_oxide", 260 | "rayon-core", 261 | "smallvec", 262 | "zune-inflate", 263 | ] 264 | 265 | [[package]] 266 | name = "fdeflate" 267 | version = "0.3.7" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" 270 | dependencies = [ 271 | "simd-adler32", 272 | ] 273 | 274 | [[package]] 275 | name = "flate2" 276 | version = "1.1.1" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" 279 | dependencies = [ 280 | "crc32fast", 281 | "miniz_oxide", 282 | ] 283 | 284 | [[package]] 285 | name = "gbm" 286 | version = "0.15.0" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "45bf55ba6dd53ad0ac115046ff999c5324c283444ee6e0be82454c4e8eb2f36a" 289 | dependencies = [ 290 | "bitflags 2.9.1", 291 | "drm", 292 | "drm-fourcc", 293 | "gbm-sys", 294 | "libc", 295 | "wayland-backend", 296 | "wayland-server", 297 | ] 298 | 299 | [[package]] 300 | name = "gbm-sys" 301 | version = "0.3.1" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "a9cc2f64de9fa707b5c6b2d2f10d7a7e49e845018a9f5685891eb40d3bab2538" 304 | dependencies = [ 305 | "libc", 306 | ] 307 | 308 | [[package]] 309 | name = "gif" 310 | version = "0.13.1" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" 313 | dependencies = [ 314 | "color_quant", 315 | "weezl", 316 | ] 317 | 318 | [[package]] 319 | name = "gl" 320 | version = "0.14.0" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "a94edab108827d67608095e269cf862e60d920f144a5026d3dbcfd8b877fb404" 323 | dependencies = [ 324 | "gl_generator", 325 | ] 326 | 327 | [[package]] 328 | name = "gl_generator" 329 | version = "0.14.0" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" 332 | dependencies = [ 333 | "khronos_api", 334 | "log", 335 | "xml-rs", 336 | ] 337 | 338 | [[package]] 339 | name = "glob" 340 | version = "0.3.2" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" 343 | 344 | [[package]] 345 | name = "half" 346 | version = "2.6.0" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" 349 | dependencies = [ 350 | "cfg-if", 351 | "crunchy", 352 | ] 353 | 354 | [[package]] 355 | name = "image" 356 | version = "0.24.9" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" 359 | dependencies = [ 360 | "bytemuck", 361 | "byteorder", 362 | "color_quant", 363 | "exr", 364 | "gif", 365 | "jpeg-decoder", 366 | "num-traits", 367 | "png", 368 | "qoi", 369 | "tiff", 370 | ] 371 | 372 | [[package]] 373 | name = "itertools" 374 | version = "0.13.0" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" 377 | dependencies = [ 378 | "either", 379 | ] 380 | 381 | [[package]] 382 | name = "jpeg-decoder" 383 | version = "0.3.1" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" 386 | dependencies = [ 387 | "rayon", 388 | ] 389 | 390 | [[package]] 391 | name = "khronos-egl" 392 | version = "6.0.0" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" 395 | dependencies = [ 396 | "libc", 397 | "pkg-config", 398 | ] 399 | 400 | [[package]] 401 | name = "khronos_api" 402 | version = "3.1.0" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" 405 | 406 | [[package]] 407 | name = "lebe" 408 | version = "0.5.2" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" 411 | 412 | [[package]] 413 | name = "libc" 414 | version = "0.2.172" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 417 | 418 | [[package]] 419 | name = "libloading" 420 | version = "0.8.7" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c" 423 | dependencies = [ 424 | "cfg-if", 425 | "windows-targets 0.53.0", 426 | ] 427 | 428 | [[package]] 429 | name = "libwayshot" 430 | version = "0.3.2-dev" 431 | source = "git+https://github.com/waycrate/wayshot?branch=freeze-feat-andreas#0088b11b1880444f7a045c60559e156cf3f39eb8" 432 | dependencies = [ 433 | "drm", 434 | "gbm", 435 | "gl", 436 | "image", 437 | "khronos-egl", 438 | "memmap2", 439 | "rustix", 440 | "thiserror", 441 | "tracing", 442 | "wayland-backend", 443 | "wayland-client", 444 | "wayland-protocols", 445 | "wayland-protocols-wlr", 446 | ] 447 | 448 | [[package]] 449 | name = "linux-raw-sys" 450 | version = "0.4.15" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 453 | 454 | [[package]] 455 | name = "linux-raw-sys" 456 | version = "0.6.5" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" 459 | 460 | [[package]] 461 | name = "log" 462 | version = "0.4.27" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 465 | 466 | [[package]] 467 | name = "memchr" 468 | version = "2.7.4" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 471 | 472 | [[package]] 473 | name = "memmap2" 474 | version = "0.9.5" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" 477 | dependencies = [ 478 | "libc", 479 | ] 480 | 481 | [[package]] 482 | name = "memoffset" 483 | version = "0.9.1" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" 486 | dependencies = [ 487 | "autocfg", 488 | ] 489 | 490 | [[package]] 491 | name = "minimal-lexical" 492 | version = "0.2.1" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 495 | 496 | [[package]] 497 | name = "miniz_oxide" 498 | version = "0.8.8" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" 501 | dependencies = [ 502 | "adler2", 503 | "simd-adler32", 504 | ] 505 | 506 | [[package]] 507 | name = "nom" 508 | version = "7.1.3" 509 | source = "registry+https://github.com/rust-lang/crates.io-index" 510 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 511 | dependencies = [ 512 | "memchr", 513 | "minimal-lexical", 514 | ] 515 | 516 | [[package]] 517 | name = "num-traits" 518 | version = "0.2.19" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 521 | dependencies = [ 522 | "autocfg", 523 | ] 524 | 525 | [[package]] 526 | name = "once_cell" 527 | version = "1.21.3" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 530 | 531 | [[package]] 532 | name = "paste" 533 | version = "1.0.15" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 536 | 537 | [[package]] 538 | name = "pin-project-lite" 539 | version = "0.2.16" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 542 | 543 | [[package]] 544 | name = "pkg-config" 545 | version = "0.3.32" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 548 | 549 | [[package]] 550 | name = "png" 551 | version = "0.17.16" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" 554 | dependencies = [ 555 | "bitflags 1.3.2", 556 | "crc32fast", 557 | "fdeflate", 558 | "flate2", 559 | "miniz_oxide", 560 | ] 561 | 562 | [[package]] 563 | name = "prettyplease" 564 | version = "0.2.32" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6" 567 | dependencies = [ 568 | "proc-macro2", 569 | "syn", 570 | ] 571 | 572 | [[package]] 573 | name = "proc-macro2" 574 | version = "1.0.95" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 577 | dependencies = [ 578 | "unicode-ident", 579 | ] 580 | 581 | [[package]] 582 | name = "qoi" 583 | version = "0.4.1" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" 586 | dependencies = [ 587 | "bytemuck", 588 | ] 589 | 590 | [[package]] 591 | name = "quick-xml" 592 | version = "0.37.5" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" 595 | dependencies = [ 596 | "memchr", 597 | ] 598 | 599 | [[package]] 600 | name = "quote" 601 | version = "1.0.40" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 604 | dependencies = [ 605 | "proc-macro2", 606 | ] 607 | 608 | [[package]] 609 | name = "raylib" 610 | version = "5.5.1" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "e5c54335590d1b6e6fbdbccee09dafdfd76a1111fc3c709eca949e71e81f7a8a" 613 | dependencies = [ 614 | "cfg-if", 615 | "paste", 616 | "raylib-sys", 617 | "seq-macro", 618 | "thiserror", 619 | ] 620 | 621 | [[package]] 622 | name = "raylib-sys" 623 | version = "5.5.1" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | checksum = "3ce5adc950b042db67f1f78f24f7e76563652ce24db032afe9ca9e534d8b7a13" 626 | dependencies = [ 627 | "bindgen", 628 | "cc", 629 | "cmake", 630 | ] 631 | 632 | [[package]] 633 | name = "rayon" 634 | version = "1.10.0" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 637 | dependencies = [ 638 | "either", 639 | "rayon-core", 640 | ] 641 | 642 | [[package]] 643 | name = "rayon-core" 644 | version = "1.12.1" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 647 | dependencies = [ 648 | "crossbeam-deque", 649 | "crossbeam-utils", 650 | ] 651 | 652 | [[package]] 653 | name = "regex" 654 | version = "1.11.1" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 657 | dependencies = [ 658 | "aho-corasick", 659 | "memchr", 660 | "regex-automata", 661 | "regex-syntax", 662 | ] 663 | 664 | [[package]] 665 | name = "regex-automata" 666 | version = "0.4.9" 667 | source = "registry+https://github.com/rust-lang/crates.io-index" 668 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 669 | dependencies = [ 670 | "aho-corasick", 671 | "memchr", 672 | "regex-syntax", 673 | ] 674 | 675 | [[package]] 676 | name = "regex-syntax" 677 | version = "0.8.5" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 680 | 681 | [[package]] 682 | name = "rustc-hash" 683 | version = "1.1.0" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 686 | 687 | [[package]] 688 | name = "rustix" 689 | version = "0.38.44" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" 692 | dependencies = [ 693 | "bitflags 2.9.1", 694 | "errno", 695 | "libc", 696 | "linux-raw-sys 0.4.15", 697 | "windows-sys", 698 | ] 699 | 700 | [[package]] 701 | name = "scoped-tls" 702 | version = "1.0.1" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 705 | 706 | [[package]] 707 | name = "seq-macro" 708 | version = "0.3.6" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" 711 | 712 | [[package]] 713 | name = "shlex" 714 | version = "1.3.0" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 717 | 718 | [[package]] 719 | name = "simd-adler32" 720 | version = "0.3.7" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 723 | 724 | [[package]] 725 | name = "smallvec" 726 | version = "1.15.0" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" 729 | 730 | [[package]] 731 | name = "syn" 732 | version = "2.0.101" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" 735 | dependencies = [ 736 | "proc-macro2", 737 | "quote", 738 | "unicode-ident", 739 | ] 740 | 741 | [[package]] 742 | name = "thiserror" 743 | version = "1.0.69" 744 | source = "registry+https://github.com/rust-lang/crates.io-index" 745 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 746 | dependencies = [ 747 | "thiserror-impl", 748 | ] 749 | 750 | [[package]] 751 | name = "thiserror-impl" 752 | version = "1.0.69" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 755 | dependencies = [ 756 | "proc-macro2", 757 | "quote", 758 | "syn", 759 | ] 760 | 761 | [[package]] 762 | name = "tiff" 763 | version = "0.9.1" 764 | source = "registry+https://github.com/rust-lang/crates.io-index" 765 | checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" 766 | dependencies = [ 767 | "flate2", 768 | "jpeg-decoder", 769 | "weezl", 770 | ] 771 | 772 | [[package]] 773 | name = "tracing" 774 | version = "0.1.41" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 777 | dependencies = [ 778 | "pin-project-lite", 779 | "tracing-attributes", 780 | "tracing-core", 781 | ] 782 | 783 | [[package]] 784 | name = "tracing-attributes" 785 | version = "0.1.28" 786 | source = "registry+https://github.com/rust-lang/crates.io-index" 787 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 788 | dependencies = [ 789 | "proc-macro2", 790 | "quote", 791 | "syn", 792 | ] 793 | 794 | [[package]] 795 | name = "tracing-core" 796 | version = "0.1.33" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 799 | dependencies = [ 800 | "once_cell", 801 | ] 802 | 803 | [[package]] 804 | name = "unicode-ident" 805 | version = "1.0.18" 806 | source = "registry+https://github.com/rust-lang/crates.io-index" 807 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 808 | 809 | [[package]] 810 | name = "wayland-backend" 811 | version = "0.3.10" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" 814 | dependencies = [ 815 | "cc", 816 | "downcast-rs", 817 | "rustix", 818 | "scoped-tls", 819 | "smallvec", 820 | "wayland-sys", 821 | ] 822 | 823 | [[package]] 824 | name = "wayland-client" 825 | version = "0.31.10" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" 828 | dependencies = [ 829 | "bitflags 2.9.1", 830 | "rustix", 831 | "wayland-backend", 832 | "wayland-scanner", 833 | ] 834 | 835 | [[package]] 836 | name = "wayland-protocols" 837 | version = "0.31.2" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" 840 | dependencies = [ 841 | "bitflags 2.9.1", 842 | "wayland-backend", 843 | "wayland-client", 844 | "wayland-scanner", 845 | ] 846 | 847 | [[package]] 848 | name = "wayland-protocols-wlr" 849 | version = "0.2.0" 850 | source = "registry+https://github.com/rust-lang/crates.io-index" 851 | checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" 852 | dependencies = [ 853 | "bitflags 2.9.1", 854 | "wayland-backend", 855 | "wayland-client", 856 | "wayland-protocols", 857 | "wayland-scanner", 858 | ] 859 | 860 | [[package]] 861 | name = "wayland-scanner" 862 | version = "0.31.6" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484" 865 | dependencies = [ 866 | "proc-macro2", 867 | "quick-xml", 868 | "quote", 869 | ] 870 | 871 | [[package]] 872 | name = "wayland-server" 873 | version = "0.31.9" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "485dfb8ccf0daa0d34625d34e6ac15f99e550a7999b6fd88a0835ccd37655785" 876 | dependencies = [ 877 | "bitflags 2.9.1", 878 | "downcast-rs", 879 | "rustix", 880 | "wayland-backend", 881 | "wayland-scanner", 882 | ] 883 | 884 | [[package]] 885 | name = "wayland-sys" 886 | version = "0.31.6" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615" 889 | dependencies = [ 890 | "dlib", 891 | "libc", 892 | "log", 893 | "memoffset", 894 | "pkg-config", 895 | ] 896 | 897 | [[package]] 898 | name = "weezl" 899 | version = "0.1.8" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" 902 | 903 | [[package]] 904 | name = "windows-sys" 905 | version = "0.59.0" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 908 | dependencies = [ 909 | "windows-targets 0.52.6", 910 | ] 911 | 912 | [[package]] 913 | name = "windows-targets" 914 | version = "0.52.6" 915 | source = "registry+https://github.com/rust-lang/crates.io-index" 916 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 917 | dependencies = [ 918 | "windows_aarch64_gnullvm 0.52.6", 919 | "windows_aarch64_msvc 0.52.6", 920 | "windows_i686_gnu 0.52.6", 921 | "windows_i686_gnullvm 0.52.6", 922 | "windows_i686_msvc 0.52.6", 923 | "windows_x86_64_gnu 0.52.6", 924 | "windows_x86_64_gnullvm 0.52.6", 925 | "windows_x86_64_msvc 0.52.6", 926 | ] 927 | 928 | [[package]] 929 | name = "windows-targets" 930 | version = "0.53.0" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" 933 | dependencies = [ 934 | "windows_aarch64_gnullvm 0.53.0", 935 | "windows_aarch64_msvc 0.53.0", 936 | "windows_i686_gnu 0.53.0", 937 | "windows_i686_gnullvm 0.53.0", 938 | "windows_i686_msvc 0.53.0", 939 | "windows_x86_64_gnu 0.53.0", 940 | "windows_x86_64_gnullvm 0.53.0", 941 | "windows_x86_64_msvc 0.53.0", 942 | ] 943 | 944 | [[package]] 945 | name = "windows_aarch64_gnullvm" 946 | version = "0.52.6" 947 | source = "registry+https://github.com/rust-lang/crates.io-index" 948 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 949 | 950 | [[package]] 951 | name = "windows_aarch64_gnullvm" 952 | version = "0.53.0" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" 955 | 956 | [[package]] 957 | name = "windows_aarch64_msvc" 958 | version = "0.52.6" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 961 | 962 | [[package]] 963 | name = "windows_aarch64_msvc" 964 | version = "0.53.0" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" 967 | 968 | [[package]] 969 | name = "windows_i686_gnu" 970 | version = "0.52.6" 971 | source = "registry+https://github.com/rust-lang/crates.io-index" 972 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 973 | 974 | [[package]] 975 | name = "windows_i686_gnu" 976 | version = "0.53.0" 977 | source = "registry+https://github.com/rust-lang/crates.io-index" 978 | checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" 979 | 980 | [[package]] 981 | name = "windows_i686_gnullvm" 982 | version = "0.52.6" 983 | source = "registry+https://github.com/rust-lang/crates.io-index" 984 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 985 | 986 | [[package]] 987 | name = "windows_i686_gnullvm" 988 | version = "0.53.0" 989 | source = "registry+https://github.com/rust-lang/crates.io-index" 990 | checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" 991 | 992 | [[package]] 993 | name = "windows_i686_msvc" 994 | version = "0.52.6" 995 | source = "registry+https://github.com/rust-lang/crates.io-index" 996 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 997 | 998 | [[package]] 999 | name = "windows_i686_msvc" 1000 | version = "0.53.0" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" 1003 | 1004 | [[package]] 1005 | name = "windows_x86_64_gnu" 1006 | version = "0.52.6" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1009 | 1010 | [[package]] 1011 | name = "windows_x86_64_gnu" 1012 | version = "0.53.0" 1013 | source = "registry+https://github.com/rust-lang/crates.io-index" 1014 | checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" 1015 | 1016 | [[package]] 1017 | name = "windows_x86_64_gnullvm" 1018 | version = "0.52.6" 1019 | source = "registry+https://github.com/rust-lang/crates.io-index" 1020 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1021 | 1022 | [[package]] 1023 | name = "windows_x86_64_gnullvm" 1024 | version = "0.53.0" 1025 | source = "registry+https://github.com/rust-lang/crates.io-index" 1026 | checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" 1027 | 1028 | [[package]] 1029 | name = "windows_x86_64_msvc" 1030 | version = "0.52.6" 1031 | source = "registry+https://github.com/rust-lang/crates.io-index" 1032 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1033 | 1034 | [[package]] 1035 | name = "windows_x86_64_msvc" 1036 | version = "0.53.0" 1037 | source = "registry+https://github.com/rust-lang/crates.io-index" 1038 | checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" 1039 | 1040 | [[package]] 1041 | name = "woomer" 1042 | version = "0.1.0" 1043 | dependencies = [ 1044 | "image", 1045 | "libwayshot", 1046 | "raylib", 1047 | ] 1048 | 1049 | [[package]] 1050 | name = "xml-rs" 1051 | version = "0.8.26" 1052 | source = "registry+https://github.com/rust-lang/crates.io-index" 1053 | checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda" 1054 | 1055 | [[package]] 1056 | name = "zune-inflate" 1057 | version = "0.2.54" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" 1060 | dependencies = [ 1061 | "simd-adler32", 1062 | ] 1063 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "woomer" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | image = "0.24.9" 10 | libwayshot = { git = "https://github.com/waycrate/wayshot", branch = "freeze-feat-andreas" } 11 | raylib = { version = "5.0.1", features = ["wayland", "opengl_33"] } 12 | [features] 13 | dev = [] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024 Tiago Dinis Ribeiro dos Santos 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Woomer - Boomer but for wayland 2 | 3 | Zoomer application for wayland (linux) inspired by [tsoding's boomer](https://github.com/tsoding/boomer) written in rust 4 | 5 | ![demo of woomer](./demo.gif) 6 | 7 | ## Controls 8 | 9 | | Control | Description | 10 | |---------------------------------------------------|---------------------------------------------------------------| 11 | | Right Click or ESC | Quit the application. | 12 | | R | Reload the shaders (only for Developer mode) | 13 | | Hold CTRL | Enable flashlight effect. | 14 | | Drag with left mouse button | Move the image around. | 15 | | Scroll wheel | Zoom in/out. | 16 | | Ctrl + SHIFT + Scroll wheel | Change the radius of the flashlight. | 17 | 18 | ## HiDPI Displays 19 | ### Hyprland 20 | If you set your scaling different to 1.0 in your .config/hypr/hyprland.conf, you also need the following variables to be set: 21 | ```sh 22 | $scale = 2 23 | monitor = , highres, auto, $scale 24 | 25 | xwayland { 26 | force_zero_scaling = true 27 | } 28 | env = GDK_SCALE,$scale 29 | ``` 30 | 31 | Please also refer to: [Hyprland Wiki](https://wiki.hyprland.org/Configuring/XWayland/) 32 | 33 | ## Building 34 | 35 | Dependencies: 36 | 37 | - wayland-client 38 | - cmake 39 | - rust 40 | - pkg-config 41 | - clang (for compiling raylib) 42 | - libclang (for bindgen) 43 | 44 | Like with any other rust program you can run: 45 | 46 | ```sh 47 | cargo b 48 | ``` 49 | 50 | However if you want hot reloading of the spotlight shader you can add the `dev` feature: 51 | 52 | ```sh 53 | cargo b -F dev 54 | ``` 55 | 56 | ## Installing using the Nix flake 57 | 58 | You can also install woomer using the nix flake: 59 | 60 | ```nix 61 | # flake.nix 62 | { 63 | inputs = { 64 | woomer.url = "github:coffeeispower/woomer"; 65 | # ..... 66 | } 67 | # .... 68 | } 69 | ``` 70 | 71 | After that, you can just install it 72 | 73 | ```nix 74 | {inputs, system, ...}: 75 | { 76 | home.packages = [ 77 | inputs.woomer.packages.${system}.default 78 | # .... 79 | ]; 80 | # .... 81 | } 82 | ``` 83 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coffeeispower/woomer/3c92d2bee37a2b1fc78877f4712607fb852fd750/demo.gif -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "crane": { 4 | "locked": { 5 | "lastModified": 1747587869, 6 | "narHash": "sha256-Zay3WJdSvC2VQmNqWSVLBOg/1iS/0/Q0c9JOBsB+3qw=", 7 | "owner": "ipetkov", 8 | "repo": "crane", 9 | "rev": "76603d32f18e0e378d9f6335c8fc286413493655", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "owner": "ipetkov", 14 | "repo": "crane", 15 | "type": "github" 16 | } 17 | }, 18 | "flake-utils": { 19 | "inputs": { 20 | "systems": "systems" 21 | }, 22 | "locked": { 23 | "lastModified": 1731533236, 24 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 25 | "owner": "numtide", 26 | "repo": "flake-utils", 27 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "numtide", 32 | "repo": "flake-utils", 33 | "type": "github" 34 | } 35 | }, 36 | "nixpkgs": { 37 | "locked": { 38 | "lastModified": 1747852984, 39 | "narHash": "sha256-q2PmaOxyR3zqOF54a3E1Cj1gh0sDu8APX9b+OkX4J5s=", 40 | "owner": "NixOS", 41 | "repo": "nixpkgs", 42 | "rev": "8c441601c43232976179eac52dde704c8bdf81ed", 43 | "type": "github" 44 | }, 45 | "original": { 46 | "owner": "NixOS", 47 | "ref": "nixpkgs-unstable", 48 | "repo": "nixpkgs", 49 | "type": "github" 50 | } 51 | }, 52 | "root": { 53 | "inputs": { 54 | "crane": "crane", 55 | "flake-utils": "flake-utils", 56 | "nixpkgs": "nixpkgs" 57 | } 58 | }, 59 | "systems": { 60 | "locked": { 61 | "lastModified": 1681028828, 62 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 63 | "owner": "nix-systems", 64 | "repo": "default", 65 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 66 | "type": "github" 67 | }, 68 | "original": { 69 | "owner": "nix-systems", 70 | "repo": "default", 71 | "type": "github" 72 | } 73 | } 74 | }, 75 | "root": "root", 76 | "version": 7 77 | } 78 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | 2 | { 3 | description = "Zoomer application for wayland inspired by tsoding's boomer"; 4 | 5 | inputs = { 6 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 7 | 8 | crane = { 9 | url = "github:ipetkov/crane"; 10 | inputs.nixpkgs.follows = "nixpkgs"; 11 | }; 12 | 13 | flake-utils.url = "github:numtide/flake-utils"; 14 | }; 15 | 16 | outputs = { self, nixpkgs, crane, flake-utils, ... }: 17 | flake-utils.lib.eachDefaultSystem (system: 18 | let 19 | pkgs = nixpkgs.legacyPackages.${system}; 20 | 21 | craneLib = crane.mkLib pkgs; 22 | 23 | # Common arguments can be set here to avoid repeating them later 24 | # Note: changes here will rebuild all dependency crates 25 | commonArgs = rec { 26 | src = let 27 | shaderFilter = path: _type: builtins.match ".*fs$" path != null; 28 | shaderOrCargo = path: type: 29 | (shaderFilter path type) || (craneLib.filterCargoSources path type); 30 | in 31 | pkgs.lib.cleanSourceWith { 32 | src = craneLib.path ./.; 33 | filter = shaderOrCargo; 34 | }; 35 | strictDeps = true; 36 | nativeBuildInputs = (with pkgs; [ 37 | cmake 38 | pkg-config 39 | clang 40 | wayland 41 | ]); 42 | buildInputs = (with pkgs; [ 43 | wayland 44 | glfw 45 | libgbm 46 | ]) ++ ( 47 | with pkgs.xorg; [ 48 | libX11.dev 49 | libXrandr.dev 50 | libXinerama.dev 51 | libXcursor.dev 52 | libXi.dev 53 | ]); 54 | LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; 55 | LIBCLANG_PATH = pkgs.libclang.lib + "/lib/"; 56 | }; 57 | 58 | woomer = craneLib.buildPackage (commonArgs // { 59 | cargoArtifacts = craneLib.buildDepsOnly commonArgs; 60 | 61 | postFixup = '' 62 | patchelf $out/bin/woomer \ 63 | --add-needed libwayland-client.so \ 64 | --add-needed libwayland-cursor.so \ 65 | --add-needed libwayland-egl.so \ 66 | --add-rpath ${pkgs.lib.makeLibraryPath [ pkgs.wayland ]} 67 | ''; 68 | 69 | meta = with nixpkgs.lib; { 70 | description = "Zoomer application for Wayland inspired by tsoding's boomer"; 71 | license = licenses.mit; 72 | mainProgram = "woomer"; 73 | }; 74 | }); 75 | in 76 | { 77 | checks = { 78 | inherit woomer; 79 | }; 80 | 81 | packages.default = woomer; 82 | 83 | apps.default = flake-utils.lib.mkApp { 84 | drv = woomer; 85 | }; 86 | 87 | devShells.default = craneLib.devShell { 88 | inherit (commonArgs) nativeBuildInputs buildInputs LIBCLANG_PATH LD_LIBRARY_PATH; 89 | # Inherit inputs from checks. 90 | checks = self.checks.${system}; 91 | packages = with pkgs; [ 92 | rust-analyzer 93 | ]; 94 | 95 | }; 96 | }); 97 | } 98 | -------------------------------------------------------------------------------- /shaders/spotlight.fs: -------------------------------------------------------------------------------- 1 | #version 330 2 | 3 | // Input vertex attributes (from vertex shader) 4 | in vec2 fragTexCoord; 5 | in vec4 fragColor; 6 | 7 | // Input uniform values 8 | uniform sampler2D texture0; 9 | uniform vec4 colDiffuse; 10 | 11 | uniform vec4 spotlightTint; 12 | uniform vec2 cursorPosition; 13 | uniform float spotlightRadiusMultiplier; 14 | 15 | // This is multiplied by spotlightRadiusMultiplier to obtain the radius in pixels 16 | const int UNIT_RADIUS = 60; 17 | 18 | // Output fragment color 19 | out vec4 finalColor; 20 | 21 | void main() 22 | { 23 | // Texel color fetching from texture sampler 24 | vec4 texelColor = texture(texture0, fragTexCoord); 25 | 26 | // Calculate distance from the current fragment to the cursor position 27 | float distanceToCursor = distance(gl_FragCoord.xy, vec2(cursorPosition.x, cursorPosition.y)); 28 | 29 | // Calculate spotlight radius in pixels 30 | float spotlightRadius = float(UNIT_RADIUS) * spotlightRadiusMultiplier; 31 | if (distanceToCursor > spotlightRadius) { 32 | finalColor = (mix(texelColor, vec4(spotlightTint.rgb, 1.0), spotlightTint.a) * colDiffuse); 33 | } else { 34 | finalColor = (texelColor * colDiffuse); 35 | } 36 | } -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use libwayshot::WayshotConnection; 2 | use raylib::{ffi::Image as FfiImage, prelude::*}; 3 | const SPOTLIGHT_TINT: Color = Color::new(0x00, 0x00, 0x00, 190); 4 | 5 | fn main() { 6 | let wayshot_connection = 7 | WayshotConnection::new().expect("failed to connect to the wayland display server"); 8 | let screenshot_image = wayshot_connection 9 | .screenshot_all(false) 10 | .expect("failed to take a screenshot") 11 | .to_rgba8(); 12 | let (width, height) = screenshot_image.dimensions(); 13 | let (mut rl, thread) = raylib::init() 14 | .title(env!("CARGO_BIN_NAME")) 15 | .fullscreen() 16 | .size(0, 0) 17 | .transparent() 18 | .vsync() 19 | .build(); 20 | 21 | // let monitor_id = unsafe { raylib::ffi::GetCurrentMonitor() }; 22 | // let monitor_position = unsafe { raylib::ffi::GetMonitorPosition(monitor_id) }; 23 | // dbg!(monitor_position); 24 | // let monitor_width = unsafe { raylib::ffi::GetMonitorWidth(monitor_id) }; 25 | // let monitor_height = unsafe { raylib::ffi::GetMonitorHeight(monitor_id) }; 26 | let screenshot_image = unsafe { 27 | Image::from_raw(FfiImage { 28 | // We can leak memory here because raylib will free the memory for us 29 | data: Box::new(screenshot_image.into_vec()) 30 | .leak() 31 | .as_mut_ptr() 32 | .cast(), 33 | format: PixelFormat::PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 as i32, 34 | mipmaps: 1, 35 | width: width as i32, 36 | height: height as i32, 37 | }) 38 | }; 39 | let screenshot_texture = rl 40 | .load_texture_from_image(&thread, &screenshot_image) 41 | .expect("failed to load screenshot into a texture"); 42 | #[cfg(feature = "dev")] 43 | let mut spotlight_shader = rl 44 | .load_shader(&thread, None, Some("shaders/spotlight.fs")) 45 | .expect("Failed to load spotlight shader"); 46 | 47 | #[cfg(not(feature = "dev"))] 48 | let mut spotlight_shader = 49 | rl.load_shader_from_memory(&thread, None, Some(include_str!("../shaders/spotlight.fs"))); 50 | let mut rl_camera = Camera2D::default(); 51 | rl_camera.zoom = 1.0; 52 | // TODO: Get the current monitor position in virtual space and put the camera there 53 | let mut delta_scale = 0f64; 54 | let mut scale_pivot = rl.get_mouse_position(); 55 | let mut velocity = Vector2::default(); 56 | let mut spotlight_radius_multiplier = 1.0; 57 | let mut spotlight_radius_multiplier_delta = 0.0; 58 | 59 | #[cfg(feature = "dev")] 60 | let mut spotlight_tint_uniform_location; 61 | #[cfg(feature = "dev")] 62 | let mut cursor_position_uniform_location; 63 | #[cfg(feature = "dev")] 64 | let mut spotlight_radius_multiplier_uniform_location; 65 | #[cfg(not(feature = "dev"))] 66 | let spotlight_tint_uniform_location; 67 | #[cfg(not(feature = "dev"))] 68 | let cursor_position_uniform_location; 69 | #[cfg(not(feature = "dev"))] 70 | let spotlight_radius_multiplier_uniform_location; 71 | 72 | spotlight_tint_uniform_location = spotlight_shader.get_shader_location("spotlightTint"); 73 | cursor_position_uniform_location = spotlight_shader.get_shader_location("cursorPosition"); 74 | spotlight_radius_multiplier_uniform_location = 75 | spotlight_shader.get_shader_location("spotlightRadiusMultiplier"); 76 | while !rl.window_should_close() { 77 | if rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_RIGHT) { 78 | break; 79 | } 80 | #[cfg(feature = "dev")] 81 | if rl.is_key_pressed(KeyboardKey::KEY_R) { 82 | spotlight_shader = rl 83 | .load_shader(&thread, None, Some("shaders/spotlight.fs")) 84 | .expect("Failed to load spotlight shader"); 85 | spotlight_tint_uniform_location = spotlight_shader.get_shader_location("spotlightTint"); 86 | cursor_position_uniform_location = 87 | spotlight_shader.get_shader_location("cursorPosition"); 88 | spotlight_radius_multiplier_uniform_location = 89 | spotlight_shader.get_shader_location("spotlightRadiusMultiplier"); 90 | } 91 | let enable_spotlight = 92 | rl.is_key_down(KeyboardKey::KEY_LEFT_CONTROL) || rl.is_key_down(KeyboardKey::KEY_RIGHT_CONTROL); 93 | let scrolled_amount = rl.get_mouse_wheel_move_v().y; 94 | if rl.is_key_pressed(KeyboardKey::KEY_LEFT_CONTROL) 95 | || rl.is_key_pressed(KeyboardKey::KEY_RIGHT_CONTROL) 96 | { 97 | spotlight_radius_multiplier = 5.0; 98 | spotlight_radius_multiplier_delta = -15.0; 99 | } 100 | if scrolled_amount != 0.0 { 101 | match ( 102 | enable_spotlight, 103 | rl.is_key_down(KeyboardKey::KEY_LEFT_SHIFT) || rl.is_key_down(KeyboardKey::KEY_RIGHT_SHIFT), 104 | ) { 105 | (_, false) => { 106 | delta_scale += scrolled_amount as f64; 107 | } 108 | (true, true) => { 109 | spotlight_radius_multiplier_delta -= scrolled_amount as f64; 110 | } 111 | _ => {} 112 | } 113 | scale_pivot = rl.get_mouse_position(); 114 | } 115 | if delta_scale.abs() > 0.5 { 116 | let p0 = scale_pivot / rl_camera.zoom; 117 | rl_camera.zoom = (rl_camera.zoom as f64 + delta_scale * rl.get_frame_time() as f64) 118 | .clamp(1.0, 10.) as f32; 119 | let p1 = scale_pivot / rl_camera.zoom; 120 | rl_camera.target += p0 - p1; 121 | delta_scale -= delta_scale * rl.get_frame_time() as f64 * 4.0 122 | } 123 | spotlight_radius_multiplier = (spotlight_radius_multiplier as f64 124 | + spotlight_radius_multiplier_delta * rl.get_frame_time() as f64) 125 | .clamp(0.3, 10.) as f32; 126 | spotlight_radius_multiplier_delta -= 127 | spotlight_radius_multiplier_delta * rl.get_frame_time() as f64 * 4.0; 128 | const VELOCITY_THRESHOLD: f32 = 15.0; 129 | if rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) { 130 | let delta = rl 131 | .get_screen_to_world2D(rl.get_mouse_position() - rl.get_mouse_delta(), rl_camera) 132 | - rl.get_screen_to_world2D(rl.get_mouse_position(), rl_camera); 133 | rl_camera.target += delta; 134 | velocity = delta * rl.get_fps().as_f32(); 135 | } else if velocity.length_sqr() > VELOCITY_THRESHOLD * VELOCITY_THRESHOLD { 136 | rl_camera.target += velocity * rl.get_frame_time(); 137 | velocity -= velocity * rl.get_frame_time() * 6.0; 138 | } 139 | 140 | let mut d = rl.begin_drawing(&thread); 141 | let mut mode2d = d.begin_mode2D(rl_camera); 142 | if enable_spotlight { 143 | mode2d.clear_background(SPOTLIGHT_TINT); 144 | let mouse_position = mode2d.get_mouse_position(); 145 | spotlight_shader.set_shader_value( 146 | spotlight_tint_uniform_location, 147 | SPOTLIGHT_TINT.color_normalize(), 148 | ); 149 | let screen_height = mode2d.get_screen_height().as_f32(); 150 | spotlight_shader.set_shader_value( 151 | cursor_position_uniform_location, 152 | Vector2::new(mouse_position.x, screen_height - mouse_position.y), 153 | ); 154 | spotlight_shader.set_shader_value( 155 | spotlight_radius_multiplier_uniform_location, 156 | spotlight_radius_multiplier, 157 | ); 158 | 159 | let mut shader_mode = mode2d.begin_shader_mode(&mut spotlight_shader); 160 | shader_mode.draw_texture(&screenshot_texture, 0, 0, Color::WHITE); 161 | } else { 162 | mode2d.clear_background(Color::get_color(0)); 163 | mode2d.draw_texture(&screenshot_texture, 0, 0, Color::WHITE); 164 | } 165 | } 166 | } 167 | --------------------------------------------------------------------------------