Attempt 5...

This commit is contained in:
Stephen Hellings 2026-03-09 15:54:29 -04:00
parent e245af128c
commit d4c8d1c465
11 changed files with 1351 additions and 168 deletions

378
Cargo.lock generated
View file

@ -323,9 +323,9 @@ dependencies = [
[[package]] [[package]]
name = "cfg-expr" name = "cfg-expr"
version = "0.20.6" version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78cef5b5a1a6827c7322ae2a636368a573006b27cfa76c7ebd53e834daeaab6a" checksum = "3c6b04e07d8080154ed4ac03546d9a2b303cc2fe1901ba0b35b301516e289368"
dependencies = [ dependencies = [
"smallvec", "smallvec",
"target-lexicon", "target-lexicon",
@ -682,6 +682,12 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]] [[package]]
name = "foreign-types" name = "foreign-types"
version = "0.5.0" version = "0.5.0"
@ -815,10 +821,23 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"r-efi", "r-efi 5.3.0",
"wasip2", "wasip2",
] ]
[[package]]
name = "getrandom"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
dependencies = [
"cfg-if",
"libc",
"r-efi 6.0.0",
"wasip2",
"wasip3",
]
[[package]] [[package]]
name = "gl" name = "gl"
version = "0.14.0" version = "0.14.0"
@ -845,6 +864,15 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]]
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"foldhash",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.16.1" version = "0.16.1"
@ -875,6 +903,12 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "id-arena"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.13.0" version = "2.13.0"
@ -882,7 +916,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown 0.16.1",
"serde",
"serde_core",
] ]
[[package]] [[package]]
@ -985,10 +1021,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "leb128fmt"
version = "0.2.182" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "libc"
version = "0.2.183"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]] [[package]]
name = "libloading" name = "libloading"
@ -1658,6 +1700,16 @@ dependencies = [
"zerocopy", "zerocopy",
] ]
[[package]]
name = "prettyplease"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
"syn",
]
[[package]] [[package]]
name = "proc-macro-crate" name = "proc-macro-crate"
version = "3.5.0" version = "3.5.0"
@ -1697,9 +1749,9 @@ dependencies = [
[[package]] [[package]]
name = "quick-xml" name = "quick-xml"
version = "0.38.4" version = "0.39.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -1719,6 +1771,12 @@ version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "r-efi"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.9.2" version = "0.9.2"
@ -1880,6 +1938,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.228" version = "1.0.228"
@ -2087,12 +2151,12 @@ dependencies = [
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.6.2" version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.60.2", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -2132,7 +2196,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0" checksum = "82a72c767771b47409d2345987fda8628641887d5466101319899796367354a0"
dependencies = [ dependencies = [
"fastrand", "fastrand",
"getrandom 0.3.4", "getrandom 0.4.2",
"once_cell", "once_cell",
"rustix 1.1.4", "rustix 1.1.4",
"windows-sys 0.61.2", "windows-sys 0.61.2",
@ -2233,9 +2297,9 @@ dependencies = [
[[package]] [[package]]
name = "toml" name = "toml"
version = "1.0.3+spec-1.1.0" version = "1.0.6+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7614eaf19ad818347db24addfa201729cf2a9b6fdfd9eb0ab870fcacc606c0c" checksum = "399b1124a3c9e16766831c6bba21e50192572cdd98706ea114f9502509686ffc"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"serde_core", "serde_core",
@ -2266,9 +2330,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.25.3+spec-1.1.0" version = "0.25.4+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0a07913e63758bc95142d9863a5a45173b71515e68b690cad70cf99c3255ce1" checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"toml_datetime 1.0.0+spec-1.1.0", "toml_datetime 1.0.0+spec-1.1.0",
@ -2401,10 +2465,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
[[package]] [[package]]
name = "uuid" name = "unicode-xid"
version = "1.21.0" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "uuid"
version = "1.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"serde_core", "serde_core",
@ -2454,6 +2524,15 @@ dependencies = [
"wit-bindgen", "wit-bindgen",
] ]
[[package]]
name = "wasip3"
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
dependencies = [
"wit-bindgen",
]
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.114" version = "0.2.114"
@ -2514,10 +2593,44 @@ dependencies = [
] ]
[[package]] [[package]]
name = "wayland-backend" name = "wasm-encoder"
version = "0.3.12" version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fee64194ccd96bf648f42a65a7e589547096dfa702f7cadef84347b66ad164f9" checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
dependencies = [
"leb128fmt",
"wasmparser",
]
[[package]]
name = "wasm-metadata"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
dependencies = [
"anyhow",
"indexmap",
"wasm-encoder",
"wasmparser",
]
[[package]]
name = "wasmparser"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
dependencies = [
"bitflags 2.11.0",
"hashbrown 0.15.5",
"indexmap",
"semver",
]
[[package]]
name = "wayland-backend"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa75f400b7f719bcd68b3f47cd939ba654cedeef690f486db71331eec4c6a406"
dependencies = [ dependencies = [
"cc", "cc",
"downcast-rs", "downcast-rs",
@ -2529,9 +2642,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-client" name = "wayland-client"
version = "0.31.12" version = "0.31.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e6faa537fbb6c186cb9f1d41f2f811a4120d1b57ec61f50da451a0c5122bec" checksum = "ab51d9f7c071abeee76007e2b742499e535148035bb835f97aaed1338cf516c3"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"rustix 1.1.4", "rustix 1.1.4",
@ -2552,9 +2665,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-cursor" name = "wayland-cursor"
version = "0.31.12" version = "0.31.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5864c4b5b6064b06b1e8b74ead4a98a6c45a285fe7a0e784d24735f011fdb078" checksum = "4b3298683470fbdc6ca40151dfc48c8f2fd4c41a26e13042f801f85002384091"
dependencies = [ dependencies = [
"rustix 1.1.4", "rustix 1.1.4",
"wayland-client", "wayland-client",
@ -2563,9 +2676,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-egl" name = "wayland-egl"
version = "0.32.9" version = "0.32.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a2c9ef35f3b2e11d5709d8e75dc1e7e064fd8eec5d705d56073fafca85de854" checksum = "429e5852d67d4be674b0e413962186b5115f77012e765617ee97b6480d5d6ea7"
dependencies = [ dependencies = [
"wayland-backend", "wayland-backend",
"wayland-sys", "wayland-sys",
@ -2573,9 +2686,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-protocols" name = "wayland-protocols"
version = "0.32.10" version = "0.32.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baeda9ffbcfc8cd6ddaade385eaf2393bd2115a69523c735f12242353c3df4f3" checksum = "b23b5df31ceff1328f06ac607591d5ba360cf58f90c8fad4ac8d3a55a3c4aec7"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"wayland-backend", "wayland-backend",
@ -2586,9 +2699,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-protocols-misc" name = "wayland-protocols-misc"
version = "0.3.10" version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "791c58fdeec5406aa37169dd815327d1e47f334219b523444bc26d70ceb4c34e" checksum = "429b99200febaf95d4f4e46deff6fe4382bcff3280ee16a41cf887b3c3364984"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"wayland-backend", "wayland-backend",
@ -2599,9 +2712,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-protocols-plasma" name = "wayland-protocols-plasma"
version = "0.3.10" version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa98634619300a535a9a97f338aed9a5ff1e01a461943e8346ff4ae26007306b" checksum = "d392fc283a87774afc9beefcd6f931582bb97fe0e6ced0b306a62cb1d026527c"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"wayland-backend", "wayland-backend",
@ -2612,9 +2725,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-protocols-wlr" name = "wayland-protocols-wlr"
version = "0.3.10" version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9597cdf02cf0c34cd5823786dce6b5ae8598f05c2daf5621b6e178d4f7345f3" checksum = "78248e4cc0eff8163370ba5c158630dcae1f3497a586b826eca2ef5f348d6235"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"wayland-backend", "wayland-backend",
@ -2626,9 +2739,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-scanner" name = "wayland-scanner"
version = "0.31.8" version = "0.31.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5423e94b6a63e68e439803a3e153a9252d5ead12fd853334e2ad33997e3889e3" checksum = "c86287151a309799b821ca709b7345a048a2956af05957c89cb824ab919fa4e3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quick-xml", "quick-xml",
@ -2637,9 +2750,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-server" name = "wayland-server"
version = "0.31.11" version = "0.31.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9297ab90f8d1f597711d36455c5b1b2290eca59b8134485e377a296b80b118c9" checksum = "63736a4a73e781cf6a736aa32c5d6773c3eb5389197562742a8c611b49b5e359"
dependencies = [ dependencies = [
"bitflags 2.11.0", "bitflags 2.11.0",
"downcast-rs", "downcast-rs",
@ -2650,9 +2763,9 @@ dependencies = [
[[package]] [[package]]
name = "wayland-sys" name = "wayland-sys"
version = "0.31.8" version = "0.31.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e6dbfc3ac5ef974c92a2235805cc0114033018ae1290a72e474aa8b28cbbdfd" checksum = "374f6b70e8e0d6bf9461a32988fd553b59ff630964924dad6e4a4eb6bd538d17"
dependencies = [ dependencies = [
"dlib", "dlib",
"libc", "libc",
@ -2688,7 +2801,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -2733,15 +2846,6 @@ dependencies = [
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets 0.53.5",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.61.2" version = "0.61.2"
@ -2790,30 +2894,13 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6", "windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6", "windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6", "windows_i686_gnu 0.52.6",
"windows_i686_gnullvm 0.52.6", "windows_i686_gnullvm",
"windows_i686_msvc 0.52.6", "windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6", "windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6", "windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6", "windows_x86_64_msvc 0.52.6",
] ]
[[package]]
name = "windows-targets"
version = "0.53.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
dependencies = [
"windows-link",
"windows_aarch64_gnullvm 0.53.1",
"windows_aarch64_msvc 0.53.1",
"windows_i686_gnu 0.53.1",
"windows_i686_gnullvm 0.53.1",
"windows_i686_msvc 0.53.1",
"windows_x86_64_gnu 0.53.1",
"windows_x86_64_gnullvm 0.53.1",
"windows_x86_64_msvc 0.53.1",
]
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.42.2" version = "0.42.2"
@ -2832,12 +2919,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.42.2" version = "0.42.2"
@ -2856,12 +2937,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.42.2" version = "0.42.2"
@ -2880,24 +2955,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
[[package]] [[package]]
name = "windows_i686_gnullvm" name = "windows_i686_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.42.2" version = "0.42.2"
@ -2916,12 +2979,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_i686_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.42.2" version = "0.42.2"
@ -2940,12 +2997,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.42.2" version = "0.42.2"
@ -2964,12 +3015,6 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.42.2" version = "0.42.2"
@ -2988,17 +3033,11 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
[[package]] [[package]]
name = "winit" name = "winit"
version = "0.30.12" version = "0.30.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66d4b9ed69c4009f6321f762d6e61ad8a2389cd431b97cb1e146812e9e6c732" checksum = "a6755fa58a9f8350bd1e472d4c3fcc25f824ec358933bba33306d0b63df5978d"
dependencies = [ dependencies = [
"ahash", "ahash",
"android-activity", "android-activity",
@ -3047,9 +3086,9 @@ dependencies = [
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.7.14" version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -3059,6 +3098,88 @@ name = "wit-bindgen"
version = "0.51.0" version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
dependencies = [
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
dependencies = [
"anyhow",
"heck",
"wit-parser",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
dependencies = [
"anyhow",
"heck",
"indexmap",
"prettyplease",
"syn",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
]
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
dependencies = [
"anyhow",
"prettyplease",
"proc-macro2",
"quote",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
]
[[package]]
name = "wit-component"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
dependencies = [
"anyhow",
"bitflags 2.11.0",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"wasm-encoder",
"wasm-metadata",
"wasmparser",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"semver",
"serde",
"serde_derive",
"serde_json",
"unicode-xid",
"wasmparser",
]
[[package]] [[package]]
name = "wo" name = "wo"
@ -3082,13 +3203,14 @@ dependencies = [
"shellexpand", "shellexpand",
"smithay", "smithay",
"tokio", "tokio",
"toml 1.0.3+spec-1.1.0", "toml 1.0.6+spec-1.1.0",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
"udev", "udev",
"wayland-backend", "wayland-backend",
"wayland-protocols", "wayland-protocols",
"wayland-server", "wayland-server",
"xcursor",
"xkbcommon 0.9.0", "xkbcommon 0.9.0",
"zbus", "zbus",
] ]
@ -3236,18 +3358,18 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.8.40" version = "0.8.42"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a789c6e490b576db9f7e6b6d661bcc9799f7c0ac8352f56ea20193b2681532e5" checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3"
dependencies = [ dependencies = [
"zerocopy-derive", "zerocopy-derive",
] ]
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.8.40" version = "0.8.42"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f65c489a7071a749c849713807783f70672b28094011623e200cb86dcb835953" checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View file

@ -60,6 +60,9 @@ input = "0.9"
udev = "0.9" udev = "0.9"
xkbcommon = "0.9" xkbcommon = "0.9"
# Cursor themes
xcursor = "0.3"
# Rendering # Rendering
pixman = "0.2" pixman = "0.2"
drm-fourcc = "2.2.0" drm-fourcc = "2.2.0"

1
nohup.out Normal file
View file

@ -0,0 +1 @@
error: Script not found "dev"

View file

@ -81,6 +81,14 @@ pub struct CompositorConfig {
/// Pinned applications for the launcher dock /// Pinned applications for the launcher dock
#[serde(default)] #[serde(default)]
pub applications: Vec<ApplicationConfig>, pub applications: Vec<ApplicationConfig>,
/// XCursor theme name (default: "breeze_cursors")
#[serde(default = "default_cursor_theme")]
pub cursor_theme: String,
/// Cursor size in pixels (default: 24)
#[serde(default = "default_cursor_size")]
pub cursor_size: u32,
} }
impl Default for CompositorConfig { impl Default for CompositorConfig {
@ -100,6 +108,8 @@ impl Default for CompositorConfig {
enable_syscalls: false, enable_syscalls: false,
focus_notify: false, focus_notify: false,
applications: vec![], applications: vec![],
cursor_theme: default_cursor_theme(),
cursor_size: default_cursor_size(),
} }
} }
} }
@ -265,6 +275,8 @@ fn default_fps() -> u32 { 60 }
fn default_format() -> String { "ARGB8888".into() } fn default_format() -> String { "ARGB8888".into() }
fn default_asset_prefix() -> String { "file".into() } fn default_asset_prefix() -> String { "file".into() }
fn default_true() -> bool { true } fn default_true() -> bool { true }
fn default_cursor_theme() -> String { "breeze_cursors".into() }
fn default_cursor_size() -> u32 { 24 }
fn expand_path(s: &str) -> String { fn expand_path(s: &str) -> String {
shellexpand::full(s) shellexpand::full(s)

155
src/cursor.rs Normal file
View file

@ -0,0 +1,155 @@
//! XCursor theme loading and per-shape texture caching.
//!
//! Loads cursor images from an installed XCursor theme and converts them to
//! GLES textures on first use, caching the result for subsequent frames.
use smithay::backend::allocator::Fourcc;
use smithay::backend::renderer::gles::GlesRenderer;
use smithay::backend::renderer::gles::GlesTexture;
use smithay::backend::renderer::ImportMem;
use smithay::utils::{Buffer as BufferCoord, Size};
use std::collections::HashMap;
use tracing::{info, warn};
/// Cached cursor texture with its hotspot offset.
#[derive(Clone)]
pub struct CursorImage {
pub texture: GlesTexture,
pub width: u32,
pub height: u32,
pub xhot: u32,
pub yhot: u32,
}
/// Manages cursor theme loading and GL texture caching.
pub struct CursorThemeManager {
theme: xcursor::CursorTheme,
size: u32,
cache: HashMap<String, Option<CursorImage>>,
}
impl CursorThemeManager {
/// Load an XCursor theme by name with the given nominal cursor size.
pub fn new(theme_name: &str, size: u32) -> Self {
info!(
"Loading cursor theme '{}' (size {})",
theme_name, size
);
let theme = xcursor::CursorTheme::load(theme_name);
Self {
theme,
size,
cache: HashMap::new(),
}
}
/// Get (or lazily load) the GL texture for the given cursor icon name.
///
/// Returns `None` if the icon cannot be found in the theme or the texture
/// import fails.
pub fn get_cursor(
&mut self,
name: &str,
renderer: &mut GlesRenderer,
) -> Option<&CursorImage> {
if !self.cache.contains_key(name) {
let img = self.load_cursor(name, renderer);
self.cache.insert(name.to_string(), img);
}
self.cache.get(name).and_then(|opt| opt.as_ref())
}
fn load_cursor(
&self,
name: &str,
renderer: &mut GlesRenderer,
) -> Option<CursorImage> {
let icon_path = self.theme.load_icon(name).or_else(|| {
// Try common XCursor aliases
let fallback = match name {
"default" => Some("left_ptr"),
"pointer" => Some("hand2"),
"text" => Some("xterm"),
"wait" => Some("watch"),
"progress" => Some("left_ptr_watch"),
"help" => Some("question_arrow"),
"crosshair" => Some("cross"),
"move" => Some("fleur"),
"not-allowed" => Some("crossed_circle"),
"no-drop" => Some("crossed_circle"),
"grab" => Some("openhand"),
"grabbing" => Some("closedhand"),
"e-resize" => Some("right_side"),
"w-resize" => Some("left_side"),
"n-resize" => Some("top_side"),
"s-resize" => Some("bottom_side"),
"ne-resize" => Some("top_right_corner"),
"nw-resize" => Some("top_left_corner"),
"se-resize" => Some("bottom_right_corner"),
"sw-resize" => Some("bottom_left_corner"),
"ew-resize" => Some("sb_h_double_arrow"),
"ns-resize" => Some("sb_v_double_arrow"),
"nesw-resize" => Some("fd_double_arrow"),
"nwse-resize" => Some("bd_double_arrow"),
"col-resize" => Some("sb_h_double_arrow"),
"row-resize" => Some("sb_v_double_arrow"),
"all-resize" | "all-scroll" => Some("fleur"),
"context-menu" => Some("left_ptr"),
"vertical-text" => Some("xterm"),
"alias" => Some("link"),
"copy" => Some("copy"),
"cell" => Some("plus"),
"zoom-in" => Some("zoom_in"),
"zoom-out" => Some("zoom_out"),
_ => None,
};
fallback.and_then(|fb| self.theme.load_icon(fb))
})?;
let data = std::fs::read(&icon_path).ok()?;
let images = xcursor::parser::parse_xcursor(&data)?;
// Pick the image closest to our target size.
let best = images
.iter()
.min_by_key(|img| (img.size as i32 - self.size as i32).unsigned_abs())?;
// XCursor pixels are ARGB (native byte order). Convert to RGBA for
// GL import with Fourcc::Abgr8888 (which is RGBA in memory on little-endian).
let pixel_count = (best.width * best.height) as usize;
let mut rgba = Vec::with_capacity(pixel_count * 4);
for pixel_argb in best.pixels_argb.chunks_exact(4) {
// ARGB → RGBA
rgba.push(pixel_argb[1]); // R
rgba.push(pixel_argb[2]); // G
rgba.push(pixel_argb[3]); // B
rgba.push(pixel_argb[0]); // A
}
let size = Size::from((best.width as i32, best.height as i32));
match renderer.import_memory(&rgba, Fourcc::Abgr8888, size, false) {
Ok(texture) => {
info!(
"Loaded cursor '{}' ({}x{}, hotspot {},{}) from {}",
name,
best.width,
best.height,
best.xhot,
best.yhot,
icon_path.display()
);
Some(CursorImage {
texture,
width: best.width,
height: best.height,
xhot: best.xhot,
yhot: best.yhot,
})
}
Err(e) => {
warn!("Failed to import cursor texture for '{}': {e}", name);
None
}
}
}
}

View file

@ -85,6 +85,13 @@ impl WoState {
// the XKB offset before forwarding. // the XKB offset before forwarding.
let evdev_key = u32::from(key_code).saturating_sub(8); let evdev_key = u32::from(key_code).saturating_sub(8);
// Check if a client is inhibiting compositor keyboard shortcuts
// (e.g. fullscreen games requesting all key events).
let shortcuts_inhibited = {
use smithay::wayland::keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitorSeat;
self.seat.keyboard_shortcuts_inhibited()
};
// Use non-blocking send to avoid input stalls. // Use non-blocking send to avoid input stalls.
let wayland_has_focus = self let wayland_has_focus = self
.seat .seat
@ -116,6 +123,12 @@ impl WoState {
serial, serial,
time, time,
|state, modifiers, _handle| { |state, modifiers, _handle| {
// When keyboard shortcuts are inhibited, forward all keys to the
// focused client without intercepting compositor shortcuts.
if shortcuts_inhibited {
return FilterResult::Forward;
}
if press && state.can_switch_vt { if press && state.can_switch_vt {
if let Some(vt) = evdev_function_key_to_vt(evdev_key) { if let Some(vt) = evdev_function_key_to_vt(evdev_key) {
// Accept Ctrl+Alt+Fn and Meta+Alt+Fn. // Accept Ctrl+Alt+Fn and Meta+Alt+Fn.

View file

@ -1,6 +1,7 @@
//! Wo Wayland compositor library //! Wo Wayland compositor library
pub mod config; pub mod config;
pub mod cursor;
pub mod dmabuf; pub mod dmabuf;
pub mod electron; pub mod electron;
pub mod handlers; pub mod handlers;

View file

@ -2,6 +2,7 @@
mod backend; mod backend;
mod config; mod config;
mod cursor;
mod dmabuf; mod dmabuf;
mod electron; mod electron;
mod handlers; mod handlers;
@ -24,7 +25,7 @@ use smithay::{
Swapchain, Swapchain,
}, },
drm::{ drm::{
gbm::framebuffer_from_bo, DrmDevice, DrmDeviceFd, DrmNode, PlaneConfig, gbm::{framebuffer_from_bo, GbmFramebuffer}, DrmDevice, DrmDeviceFd, DrmNode, PlaneConfig,
PlaneState, PlaneState,
}, },
egl::{EGLContext, EGLDisplay}, egl::{EGLContext, EGLDisplay},
@ -42,7 +43,9 @@ use smithay::{
utils::{Buffer, DeviceFd, Physical, Rectangle, Transform}, utils::{Buffer, DeviceFd, Physical, Rectangle, Transform},
wayland::{ wayland::{
xdg_activation::XdgActivationHandler, xdg_activation::XdgActivationHandler,
xwayland_shell::XWaylandShellState,
}, },
xwayland::{xwm::X11Wm, XWayland, XWaylandEvent},
}; };
use std::path::Path; use std::path::Path;
use std::{ use std::{
@ -102,6 +105,99 @@ struct EventLoopData {
pending_slot: Option<Slot<smithay::backend::allocator::gbm::GbmBuffer>>, pending_slot: Option<Slot<smithay::backend::allocator::gbm::GbmBuffer>>,
} }
/// Newtype wrapper around `Option<EventLoopData>` for the DRM calloop event
/// loop. The `Option` is needed because the event loop is created before the
/// DRM resources are fully initialized (`None` during pre-init, `Some` after).
/// The newtype allows implementing XWayland traits (orphan rules forbid impls
/// on `Option<T>` directly).
struct DrmLoopData(Option<EventLoopData>);
impl std::ops::Deref for DrmLoopData {
type Target = Option<EventLoopData>;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl std::ops::DerefMut for DrmLoopData {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
// XwmHandler delegation so X11Wm calloop sources work on the DRM event loop.
impl smithay::xwayland::xwm::XwmHandler for DrmLoopData {
fn xwm_state(&mut self, xwm: smithay::xwayland::xwm::XwmId) -> &mut X11Wm {
self.0.as_mut().expect("EventLoopData initialized").state.xwm_state(xwm)
}
fn new_window(&mut self, xwm: smithay::xwayland::xwm::XwmId, window: smithay::xwayland::xwm::X11Surface) {
self.0.as_mut().expect("EventLoopData initialized").state.new_window(xwm, window)
}
fn new_override_redirect_window(&mut self, xwm: smithay::xwayland::xwm::XwmId, window: smithay::xwayland::xwm::X11Surface) {
self.0.as_mut().expect("EventLoopData initialized").state.new_override_redirect_window(xwm, window)
}
fn map_window_request(&mut self, xwm: smithay::xwayland::xwm::XwmId, window: smithay::xwayland::xwm::X11Surface) {
self.0.as_mut().expect("EventLoopData initialized").state.map_window_request(xwm, window)
}
fn mapped_override_redirect_window(&mut self, xwm: smithay::xwayland::xwm::XwmId, window: smithay::xwayland::xwm::X11Surface) {
self.0.as_mut().expect("EventLoopData initialized").state.mapped_override_redirect_window(xwm, window)
}
fn unmapped_window(&mut self, xwm: smithay::xwayland::xwm::XwmId, window: smithay::xwayland::xwm::X11Surface) {
self.0.as_mut().expect("EventLoopData initialized").state.unmapped_window(xwm, window)
}
fn destroyed_window(&mut self, xwm: smithay::xwayland::xwm::XwmId, window: smithay::xwayland::xwm::X11Surface) {
self.0.as_mut().expect("EventLoopData initialized").state.destroyed_window(xwm, window)
}
fn configure_request(
&mut self,
xwm: smithay::xwayland::xwm::XwmId,
window: smithay::xwayland::xwm::X11Surface,
x: Option<i32>,
y: Option<i32>,
w: Option<u32>,
h: Option<u32>,
reorder: Option<smithay::xwayland::xwm::Reorder>,
) {
self.0.as_mut().expect("EventLoopData initialized").state.configure_request(xwm, window, x, y, w, h, reorder)
}
fn configure_notify(
&mut self,
xwm: smithay::xwayland::xwm::XwmId,
window: smithay::xwayland::xwm::X11Surface,
geometry: smithay::utils::Rectangle<i32, smithay::utils::Logical>,
above: Option<smithay::xwayland::xwm::X11Window>,
) {
self.0.as_mut().expect("EventLoopData initialized").state.configure_notify(xwm, window, geometry, above)
}
fn resize_request(
&mut self,
xwm: smithay::xwayland::xwm::XwmId,
window: smithay::xwayland::xwm::X11Surface,
button: u32,
resize_edge: smithay::xwayland::xwm::ResizeEdge,
) {
self.0.as_mut().expect("EventLoopData initialized").state.resize_request(xwm, window, button, resize_edge)
}
fn move_request(&mut self, xwm: smithay::xwayland::xwm::XwmId, window: smithay::xwayland::xwm::X11Surface, button: u32) {
self.0.as_mut().expect("EventLoopData initialized").state.move_request(xwm, window, button)
}
fn fullscreen_request(&mut self, xwm: smithay::xwayland::xwm::XwmId, window: smithay::xwayland::xwm::X11Surface) {
self.0.as_mut().expect("EventLoopData initialized").state.fullscreen_request(xwm, window)
}
fn unfullscreen_request(&mut self, xwm: smithay::xwayland::xwm::XwmId, window: smithay::xwayland::xwm::X11Surface) {
self.0.as_mut().expect("EventLoopData initialized").state.unfullscreen_request(xwm, window)
}
}
impl smithay::wayland::xwayland_shell::XWaylandShellHandler for DrmLoopData {
fn xwayland_shell_state(&mut self) -> &mut smithay::wayland::xwayland_shell::XWaylandShellState {
self.0.as_mut().expect("EventLoopData initialized").state.xwayland_shell_state()
}
fn surface_associated(
&mut self,
xwm: smithay::xwayland::xwm::XwmId,
wl_surface: smithay::reexports::wayland_server::protocol::wl_surface::WlSurface,
window: smithay::xwayland::xwm::X11Surface,
) {
self.0.as_mut().expect("EventLoopData initialized").state.surface_associated(xwm, wl_surface, window)
}
}
const MAX_CONSECUTIVE_FLIP_FAILURES: u32 = 5; const MAX_CONSECUTIVE_FLIP_FAILURES: u32 = 5;
fn write_flip_failure_report(report: &str) { fn write_flip_failure_report(report: &str) {
@ -448,6 +544,35 @@ fn render_frame(data: &mut EventLoopData) {
} }
} }
// Prepare cursor elements from the cursor surface (set by Wayland clients)
let cursor_elements: Vec<WaylandSurfaceRenderElement<GlesRenderer>> =
if let smithay::input::pointer::CursorImageStatus::Surface(ref cursor_surface) = data.state.cursor_status {
render_elements_from_surface_tree(
renderer,
cursor_surface,
(data.state.pointer_location.x as i32, data.state.pointer_location.y as i32),
scale,
1.0,
Kind::Cursor,
)
} else {
Vec::new()
};
// Load themed cursor texture for Named cursor status
let themed_cursor = if let smithay::input::pointer::CursorImageStatus::Named(ref icon) = data.state.cursor_status {
data.state.cursor_theme_manager.get_cursor(icon.name(), renderer).cloned()
} else if cursor_elements.is_empty() {
// No client surface and not Hidden — use default theme cursor as fallback
if !matches!(data.state.cursor_status, smithay::input::pointer::CursorImageStatus::Hidden) {
data.state.cursor_theme_manager.get_cursor("default", renderer).cloned()
} else {
None
}
} else {
None
};
let mut target = match renderer.bind(&mut target_dmabuf) { let mut target = match renderer.bind(&mut target_dmabuf) {
Ok(t) => t, Ok(t) => t,
Err(e) => { Err(e) => {
@ -477,6 +602,7 @@ fn render_frame(data: &mut EventLoopData) {
let mut sorted_windows: Vec<_> = data.state.config.windows.iter().collect(); let mut sorted_windows: Vec<_> = data.state.config.windows.iter().collect();
sorted_windows.sort_by_key(|w| w.z_order); sorted_windows.sort_by_key(|w| w.z_order);
let mut rendered_tex_count = 0u32;
for win_cfg in sorted_windows { for win_cfg in sorted_windows {
if let Some(texture) = data.gles_tex_cache.get(&win_cfg.name) { if let Some(texture) = data.gles_tex_cache.get(&win_cfg.name) {
let (x, y, _w, _h) = data.state let (x, y, _w, _h) = data.state
@ -506,10 +632,22 @@ fn render_frame(data: &mut EventLoopData) {
return false; return false;
} }
warn!("Electron texture rendering failed for {}: {e}", win_cfg.name); warn!("Electron texture rendering failed for {}: {e}", win_cfg.name);
} else {
rendered_tex_count += 1;
} }
} }
} }
// Log every frame for first 60 frames to diagnose flickering
if data.total_flips < 60 {
info!(
"render_frame #{}: textures_rendered={}, gles_cache={}, windows={}",
data.total_flips, rendered_tex_count,
data.gles_tex_cache.len(),
data.state.config.windows.len(),
);
}
for element in wayland_elements { for element in wayland_elements {
let src = element.src(); let src = element.src();
let dst = element.geometry(scale); let dst = element.geometry(scale);
@ -523,6 +661,32 @@ fn render_frame(data: &mut EventLoopData) {
} }
} }
// Render cursor on top of everything
if !cursor_elements.is_empty() {
for element in &cursor_elements {
let src = element.src();
let dst = element.geometry(scale);
if let Err(e) = element.draw(&mut frame, src, dst, &[data.output_rect], &[]) {
trace!("Failed to render cursor element: {e}");
}
}
} else if let Some(ref cur) = themed_cursor {
let cx = data.state.pointer_location.x as i32 - cur.xhot as i32;
let cy = data.state.pointer_location.y as i32 - cur.yhot as i32;
if let Err(e) = frame.render_texture_at(
&cur.texture,
(cx, cy).into(),
1,
1.0,
Transform::Normal,
&[data.output_rect],
&[],
1.0,
) {
trace!("Failed to render themed cursor: {e}");
}
}
// Send frame callbacks // Send frame callbacks
let presented_at = std::time::SystemTime::now() let presented_at = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH) .duration_since(std::time::UNIX_EPOCH)
@ -548,6 +712,18 @@ fn render_frame(data: &mut EventLoopData) {
); );
} }
// Send frame callbacks for the cursor surface so the client keeps
// animating it (e.g. spinning/loading cursors).
if let smithay::input::pointer::CursorImageStatus::Surface(ref cursor_surface) = data.state.cursor_status {
smithay::desktop::utils::send_frames_surface_tree(
cursor_surface,
&data.state.backend.output,
presented_at,
Some(data.frame_time),
|_, _| Some(data.state.backend.output.clone()),
);
}
// Finalize the GL frame — flushes all rendering commands to the // Finalize the GL frame — flushes all rendering commands to the
// framebuffer. Without this, the GBM BO may contain stale or // framebuffer. Without this, the GBM BO may contain stale or
// incomplete pixel data, causing flicker. // incomplete pixel data, causing flicker.
@ -563,6 +739,15 @@ fn render_frame(data: &mut EventLoopData) {
} }
} }
// Ensure all GPU work targeting this BO completes before the DRM
// subsystem starts scanning it out. glFlush (done by finish())
// only queues commands; glFinish blocks until they're done.
renderer.with_context(|gl| unsafe { gl.Finish() })
.unwrap_or_else(|e| warn!("glFinish failed: {e}"));
// Unbind the render target so the BO is no longer GL-locked.
drop(target);
true true
})(); })();
@ -581,14 +766,28 @@ fn render_frame(data: &mut EventLoopData) {
data.state.damaged_windows.clear(); data.state.damaged_windows.clear();
data.state.dirty_surfaces.clear(); data.state.dirty_surfaces.clear();
// Create framebuffer and schedule page flip // Get or create the DRM framebuffer for this slot.
let fb = match framebuffer_from_bo(&data.drm_device_fd, &slot, false) { // Caching in the slot's userdata avoids a create/destroy cycle every
Ok(fb) => fb, // frame and — critically — keeps the GbmFramebuffer alive through
Err(e) => { // the page flip. Previously the FB was dropped at the end of
warn!("Error creating framebuffer: {e}"); // render_frame, calling drmModeRmFB while the flip was still pending.
data.swapchain.submitted(&slot); // While the kernel holds an internal reference, some DRM drivers
return; // misbehave when the userspace handle is removed before the flip
} // completes, causing every-other-frame flicker.
let fb_handle = if let Some(cached_fb) = slot.userdata().get::<GbmFramebuffer>() {
*cached_fb.as_ref()
} else {
let fb = match framebuffer_from_bo(&data.drm_device_fd, &slot, false) {
Ok(fb) => fb,
Err(e) => {
warn!("Error creating framebuffer: {e}");
data.swapchain.submitted(&slot);
return;
}
};
let handle = *fb.as_ref();
slot.userdata().insert_if_missing(move || fb);
handle
}; };
let plane_state = PlaneState { let plane_state = PlaneState {
@ -599,7 +798,7 @@ fn render_frame(data: &mut EventLoopData) {
transform: Transform::Normal, transform: Transform::Normal,
alpha: 1.0, alpha: 1.0,
damage_clips: None, damage_clips: None,
fb: *fb.as_ref(), fb: fb_handle,
fence: None, fence: None,
}), }),
}; };
@ -716,15 +915,15 @@ fn run_drm(mut config: Config) -> Result<(), anyhow::Error> {
// polls the libseat fd, seat.dispatch() is never called, the EnableSeat // polls the libseat fd, seat.dispatch() is never called, the EnableSeat
// message from seatd/logind stays unread, and libseat_open_device() // message from seatd/logind stays unread, and libseat_open_device()
// returns EAGAIN for every attempt. // returns EAGAIN for every attempt.
let mut event_loop: EventLoop<Option<EventLoopData>> = let mut event_loop: EventLoop<DrmLoopData> =
EventLoop::try_new().context("creating event loop")?; EventLoop::try_new().context("creating event loop")?;
let loop_handle = event_loop.handle(); let loop_handle = event_loop.handle();
let loop_signal = event_loop.get_signal(); let loop_signal = event_loop.get_signal();
loop_handle loop_handle
.insert_source(session_notifier, |event, _, data: &mut Option<EventLoopData>| { .insert_source(session_notifier, |event, _, data: &mut DrmLoopData| {
use smithay::backend::session::Event; use smithay::backend::session::Event;
let Some(data) = data.as_mut() else { let Some(data) = data.0.as_mut() else {
// Pre-init phase: ActivateSession received before DRM setup is // Pre-init phase: ActivateSession received before DRM setup is
// complete. The session is now active; device opening can proceed. // complete. The session is now active; device opening can proceed.
return; return;
@ -768,7 +967,7 @@ fn run_drm(mut config: Config) -> Result<(), anyhow::Error> {
if !session.is_active() { if !session.is_active() {
info!("Waiting for seat activation (EnableSeat from seat manager)..."); info!("Waiting for seat activation (EnableSeat from seat manager)...");
} }
let mut pre_init: Option<EventLoopData> = None; let mut pre_init = DrmLoopData(None);
let deadline = Instant::now() + Duration::from_secs(5); let deadline = Instant::now() + Duration::from_secs(5);
loop { loop {
let remaining = deadline.saturating_duration_since(Instant::now()); let remaining = deadline.saturating_duration_since(Instant::now());
@ -1080,6 +1279,59 @@ fn run_drm(mut config: Config) -> Result<(), anyhow::Error> {
state.electron_ipc = Some(ipc); state.electron_ipc = Some(ipc);
// Spawn XWayland for X11 client support (mirrors nested.rs)
state.xwayland_shell_state = Some(XWaylandShellState::new::<WoState>(&dh));
match XWayland::spawn(
&dh,
None,
std::iter::empty::<(String, String)>(),
true,
std::process::Stdio::null(),
std::process::Stdio::null(),
|_| {},
) {
Ok((xwayland, xw_client)) => {
let wm_handle = loop_handle.clone();
let xw_client = std::rc::Rc::new(std::cell::RefCell::new(Some(xw_client)));
let xw_client_cb = xw_client.clone();
if let Err(e) =
loop_handle.insert_source(xwayland, move |event, _, drm_data: &mut DrmLoopData| {
let data = drm_data.0.as_mut().expect("EventLoopData initialized");
match event {
XWaylandEvent::Ready {
x11_socket,
display_number,
} => {
info!("XWayland ready on DISPLAY :{display_number}");
std::env::set_var("DISPLAY", format!(":{display_number}"));
if let Some(client) = xw_client_cb.borrow_mut().take() {
match X11Wm::start_wm(wm_handle.clone(), x11_socket, client) {
Ok(wm) => {
data.state.xwm = Some(wm);
info!("X11 window manager attached");
}
Err(e) => error!("X11Wm::start_wm failed: {e:#}"),
}
}
}
XWaylandEvent::Error => {
warn!("XWayland server encountered an error during startup");
}
}
})
{
error!("Failed to register XWayland event source: {e:#}");
} else {
info!("XWayland server starting");
}
}
Err(e) => {
warn!("XWayland spawn failed (X11 support disabled): {e:#}");
}
}
std::env::set_var("WAYLAND_DISPLAY", &config.compositor.socket_name); std::env::set_var("WAYLAND_DISPLAY", &config.compositor.socket_name);
let app_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("electron"); let app_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("electron");
@ -1218,8 +1470,8 @@ fn run_drm(mut config: Config) -> Result<(), anyhow::Error> {
.expect("Error setting Ctrl-C handler"); .expect("Error setting Ctrl-C handler");
loop_handle loop_handle
.insert_source(_drm_notifier, |event, _, data: &mut Option<EventLoopData>| { .insert_source(_drm_notifier, |event, _, drm_data: &mut DrmLoopData| {
let data = data.as_mut().expect("EventLoopData initialized"); let data = drm_data.0.as_mut().expect("EventLoopData initialized");
use smithay::backend::drm::DrmEvent; use smithay::backend::drm::DrmEvent;
if !data.active { if !data.active {
if let DrmEvent::VBlank(_) = event { if let DrmEvent::VBlank(_) = event {
@ -1245,8 +1497,8 @@ fn run_drm(mut config: Config) -> Result<(), anyhow::Error> {
loop_handle loop_handle
.insert_source( .insert_source(
libinput_backend, libinput_backend,
move |event, _, data: &mut Option<EventLoopData>| { move |event, _, drm_data: &mut DrmLoopData| {
let data = data.as_mut().expect("EventLoopData initialized"); let data = drm_data.0.as_mut().expect("EventLoopData initialized");
data.state.process_input_event(event); data.state.process_input_event(event);
data.input_events_pending = true; data.input_events_pending = true;
}, },
@ -1258,10 +1510,10 @@ fn run_drm(mut config: Config) -> Result<(), anyhow::Error> {
render_frame(&mut loop_data); render_frame(&mut loop_data);
// Main event loop - purely event-driven (blocking) // Main event loop - purely event-driven (blocking)
let mut main_data: Option<EventLoopData> = Some(loop_data); let mut main_data = DrmLoopData(Some(loop_data));
event_loop event_loop
.run(None, &mut main_data, |opt_data| { .run(None, &mut main_data, |drm_data| {
let data = opt_data.as_mut().expect("EventLoopData initialized"); let data = drm_data.0.as_mut().expect("EventLoopData initialized");
if !data.state.running { if !data.state.running {
loop_signal.stop(); loop_signal.stop();
return; return;

View file

@ -612,6 +612,19 @@ pub fn run_nested(config: Config) -> Result<()> {
Vec::new() Vec::new()
}; };
// Load themed cursor texture for Named cursor status
let themed_cursor = if let smithay::input::pointer::CursorImageStatus::Named(ref icon) = state.cursor_status {
state.cursor_theme_manager.get_cursor(icon.name(), renderer).cloned()
} else if cursor_elements.is_empty() {
if !matches!(state.cursor_status, smithay::input::pointer::CursorImageStatus::Hidden) {
state.cursor_theme_manager.get_cursor("default", renderer).cloned()
} else {
None
}
} else {
None
};
// Wayland windows are exclusively rendered by comraw via off-screen buffers. // Wayland windows are exclusively rendered by comraw via off-screen buffers.
// The native space.elements() rendering pass has been removed here. // The native space.elements() rendering pass has been removed here.
@ -675,13 +688,31 @@ pub fn run_nested(config: Config) -> Result<()> {
// allowing the client to fully control window compositing and layout. // allowing the client to fully control window compositing and layout.
// Render cursor on top of everything // Render cursor on top of everything
for element in &cursor_elements { if !cursor_elements.is_empty() {
use smithay::utils::Scale as ScaleF; for element in &cursor_elements {
let scale = ScaleF::from(1.0); use smithay::utils::Scale as ScaleF;
let src = element.src(); let scale = ScaleF::from(1.0);
let dst = element.geometry(scale); let src = element.src();
if let Err(e) = element.draw(&mut frame, src, dst, &[output_rect], &[]) { let dst = element.geometry(scale);
trace!("Failed to render cursor element: {}", e); if let Err(e) = element.draw(&mut frame, src, dst, &[output_rect], &[]) {
trace!("Failed to render cursor element: {}", e);
}
}
} else if let Some(ref cur) = themed_cursor {
use smithay::backend::renderer::Frame as _;
let cx = state.pointer_location.x as i32 - cur.xhot as i32;
let cy = state.pointer_location.y as i32 - cur.yhot as i32;
if let Err(e) = frame.render_texture_at(
&cur.texture,
(cx, cy).into(),
1,
1.0,
Transform::Normal,
&[output_rect],
&[],
1.0,
) {
trace!("Failed to render themed cursor: {}", e);
} }
} }

View file

@ -18,6 +18,7 @@ use smithay::{
}, },
relative_pointer::RelativePointerManagerState, relative_pointer::RelativePointerManagerState,
pointer_constraints::{self, PointerConstraintsHandler, PointerConstraintsState}, pointer_constraints::{self, PointerConstraintsHandler, PointerConstraintsState},
keyboard_shortcuts_inhibit::{KeyboardShortcutsInhibitHandler, KeyboardShortcutsInhibitState, KeyboardShortcutsInhibitor},
shell::xdg::{XdgShellState, decoration::XdgDecorationState}, shm::ShmState, single_pixel_buffer::SinglePixelBufferState, tablet_manager::TabletSeatHandler, viewporter::ViewporterState, xdg_activation::{XdgActivationHandler, XdgActivationState, XdgActivationToken, XdgActivationTokenData}, xwayland_shell::XWaylandShellState shell::xdg::{XdgShellState, decoration::XdgDecorationState}, shm::ShmState, single_pixel_buffer::SinglePixelBufferState, tablet_manager::TabletSeatHandler, viewporter::ViewporterState, xdg_activation::{XdgActivationHandler, XdgActivationState, XdgActivationToken, XdgActivationTokenData}, xwayland_shell::XWaylandShellState
}, },
xwayland::{XWayland, xwm::X11Wm}, xwayland::{XWayland, xwm::X11Wm},
@ -27,6 +28,7 @@ use smithay::reexports::wayland_protocols::wp::linux_dmabuf::zv1::server::zwp_li
pub mod portal; pub mod portal;
use crate::{ use crate::{
config::Config, config::Config,
cursor::CursorThemeManager,
dmabuf::TextureCache, dmabuf::TextureCache,
electron::{ElectronIpc, ElectronProcess}, electron::{ElectronIpc, ElectronProcess},
syscall::SyscallHandler, syscall::SyscallHandler,
@ -77,6 +79,7 @@ pub struct WoState {
pub cursor_shape_manager_state: CursorShapeManagerState, pub cursor_shape_manager_state: CursorShapeManagerState,
pub relative_pointer_manager_state: RelativePointerManagerState, pub relative_pointer_manager_state: RelativePointerManagerState,
pub pointer_constraints_state: PointerConstraintsState, pub pointer_constraints_state: PointerConstraintsState,
pub keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState,
pub output_manager: OutputManagerState, pub output_manager: OutputManagerState,
pub seat: Seat<Self>, pub seat: Seat<Self>,
@ -109,6 +112,7 @@ pub struct WoState {
/// Buffered pixel exports from offscreen rendering, written to SHM after render block. /// Buffered pixel exports from offscreen rendering, written to SHM after render block.
pub pending_shm_exports: Vec<(String, u32, u32, u32, Vec<u8>)>, pub pending_shm_exports: Vec<(String, u32, u32, u32, Vec<u8>)>,
pub grab_state: Option<crate::handlers::xdg_shell::GrabState>, pub grab_state: Option<crate::handlers::xdg_shell::GrabState>,
pub cursor_theme_manager: CursorThemeManager,
/// Set to true inside new_toplevel to enable checkpoint logging on the /// Set to true inside new_toplevel to enable checkpoint logging on the
/// same main-loop tick where the window appears. /// same main-loop tick where the window appears.
@ -156,6 +160,7 @@ impl WoState {
let xdg_decoration_state = XdgDecorationState::new::<Self>(&dh); let xdg_decoration_state = XdgDecorationState::new::<Self>(&dh);
let relative_pointer_manager_state = RelativePointerManagerState::new::<Self>(&dh); let relative_pointer_manager_state = RelativePointerManagerState::new::<Self>(&dh);
let pointer_constraints_state = PointerConstraintsState::new::<Self>(&dh); let pointer_constraints_state = PointerConstraintsState::new::<Self>(&dh);
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(&dh);
let shm_state = ShmState::new::<Self>(&dh, vec![]); let shm_state = ShmState::new::<Self>(&dh, vec![]);
let viewporter_state = ViewporterState::new::<Self>(&dh); let viewporter_state = ViewporterState::new::<Self>(&dh);
let xdg_activation_state = XdgActivationState::new::<Self>(&dh); let xdg_activation_state = XdgActivationState::new::<Self>(&dh);
@ -249,6 +254,11 @@ impl WoState {
let popup_manager = PopupManager::default(); let popup_manager = PopupManager::default();
let space = Space::default(); let space = Space::default();
let cursor_theme_manager = CursorThemeManager::new(
&config.compositor.cursor_theme,
config.compositor.cursor_size,
);
let mut state = Self { let mut state = Self {
display_handle: dh, display_handle: dh,
compositor_state, compositor_state,
@ -269,6 +279,7 @@ impl WoState {
cursor_shape_manager_state, cursor_shape_manager_state,
relative_pointer_manager_state, relative_pointer_manager_state,
pointer_constraints_state, pointer_constraints_state,
keyboard_shortcuts_inhibit_state,
output_manager, output_manager,
seat, seat,
pointer_location: (0.0, 0.0).into(), pointer_location: (0.0, 0.0).into(),
@ -298,6 +309,7 @@ impl WoState {
window_shm_buffers: std::collections::HashMap::new(), window_shm_buffers: std::collections::HashMap::new(),
pending_shm_exports: Vec::new(), pending_shm_exports: Vec::new(),
grab_state: None, grab_state: None,
cursor_theme_manager,
debug_new_toplevel: false, debug_new_toplevel: false,
wayland_window_names: std::collections::HashMap::new(), wayland_window_names: std::collections::HashMap::new(),
wayland_name_to_id: std::collections::HashMap::new(), wayland_name_to_id: std::collections::HashMap::new(),
@ -624,3 +636,17 @@ impl PointerConstraintsHandler for WoState {
smithay::delegate_pointer_constraints!(WoState); smithay::delegate_pointer_constraints!(WoState);
smithay::delegate_relative_pointer!(WoState); smithay::delegate_relative_pointer!(WoState);
impl KeyboardShortcutsInhibitHandler for WoState {
fn keyboard_shortcuts_inhibit_state(&mut self) -> &mut KeyboardShortcutsInhibitState {
&mut self.keyboard_shortcuts_inhibit_state
}
fn new_inhibitor(&mut self, inhibitor: KeyboardShortcutsInhibitor) {
// Automatically activate: games/fullscreen apps that request inhibition
// should receive all key events without compositor interception.
inhibitor.activate();
}
}
smithay::delegate_keyboard_shortcuts_inhibit!(WoState);

View file

@ -1,11 +1,578 @@
2026-03-09T13:10:06.828981Z  INFO wo: wo compositor starting 2026-03-09T19:05:04.695426Z  INFO wo: wo compositor starting
2026-03-09T13:10:06.829194Z  INFO wo::config: Loading config from "/home/hellings/.config/wo/config.toml" 2026-03-09T19:05:04.696005Z  INFO wo::config: Loading config from "/home/hellings/.config/wo/config.toml"
2026-03-09T13:10:06.829640Z  INFO wo: Running in DRM/KMS mode 2026-03-09T19:05:04.696508Z  INFO wo: Running in DRM/KMS mode
2026-03-09T13:10:06.831907Z  INFO wo: LibSeat session created successfully 2026-03-09T19:05:04.698340Z  INFO wo: LibSeat session created successfully
2026-03-09T13:10:06.832112Z  INFO wo: Session notifier registered for VT switching 2026-03-09T19:05:04.698373Z  INFO wo: libseat environment seat=seat0 libseat_backend=logind
2026-03-09T13:10:06.832217Z  INFO wo: Session is active, ready to open devices 2026-03-09T19:05:04.698483Z  INFO wo: Session notifier registered for VT switching
2026-03-09T13:10:06.832243Z  INFO wo: Using seat: seat0 2026-03-09T19:05:04.698605Z  INFO wo: Session is active, ready to open devices
2026-03-09T13:10:06.834656Z  INFO wo: trying DRM devices in priority order candidates=["/dev/dri/card1"] 2026-03-09T19:05:04.698634Z  INFO wo: Using seat: seat0
2026-03-09T13:10:06.834715Z  INFO wo: Opening DRM device: "/dev/dri/card1" 2026-03-09T19:05:04.701686Z  INFO wo: trying DRM devices in priority order candidates=["/dev/dri/card1", "/dev/dri/card2"]
2026-03-09T13:10:06.835267Z  INFO wo: libseat returned EAGAIN; pumping event loop and retrying device open... gpu=/dev/dri/card1 2026-03-09T19:05:04.701715Z  INFO wo: Opening DRM device: "/dev/dri/card1"
2026-03-09T13:10:07.351716Z  WARN wo: Failed to open DRM device: Failed to open device: Resource temporarily unavailable (os error 11) gpu=/dev/dri/card1 permission_related=false attempt=10 2026-03-09T19:05:04.702165Z  INFO wo: using GPU gpu=/dev/dri/card1
2026-03-09T19:05:04.702199Z  WARN smithay::backend::drm::device::fd: Unable to become drm master, assuming unprivileged mode
2026-03-09T19:05:04.702984Z  INFO wo: DRM device created atomic=true
2026-03-09T19:05:05.166132Z  INFO wo::electron: IPC socket listening socket="/run/user/1000/wo-ipc.sock"
2026-03-09T19:05:05.166366Z  INFO wo: resolved render node card=/dev/dri/card1 render_node=/dev/dri/renderD128
2026-03-09T19:05:05.166392Z  INFO wo::electron: Spawning Electron for window 'main' with config: WindowConfig { name: "main", url: Some("http://localhost:5173"), html: None, css: None, js: None, width: 2560, height: 1600, x: 0, y: 0, z_order: -1073741824, fps: 60, format: "ARGB8888", focusable: false, interactive: false, floating: false }
2026-03-09T19:05:05.166450Z  INFO wo::electron: Serialized config: {"name":"main","url":"http://localhost:5173","html":null,"css":null,"js":null,"width":2560,"height":1600,"x":0,"y":0,"z_order":-1073741824,"fps":60,"format":"ARGB8888","focusable":false,"interactive":false,"floating":false}
2026-03-09T19:05:05.166833Z  INFO wo::electron: spawned Electron process window=main pid=3988 render_node="/dev/dri/renderD128"
2026-03-09T19:05:05.166880Z  INFO wo: using swapchain format/modifiers from renderer swapchain_format=DrmFourcc(XR24) modifiers=14
2026-03-09T19:05:05.229616Z  INFO wo: Wayland socket bound socket=wo-0
2026-03-09T19:05:05.229850Z  INFO wo: Kickstarting VBlank-driven rendering
2026-03-09T19:05:05.229867Z  INFO wo: First render: output=2560x1600, windows=1, bg=Color32F([0.0, 0.0, 0.0, 1.0])
2026-03-09T19:05:05.232882Z  INFO wo: render_frame #0: textures_rendered=0, gles_cache=0, windows=1
2026-03-09T19:05:05.233523Z  INFO wo: Performing modeset commit (commit_pending=false, first_frame=true, textures=0)
2026-03-09T19:05:05.234462Z  INFO wo: First successful page flip (commit_pending=false)
[Wo] Electron starting, NODE_VERSION= v22.22.0
[Wo] WO_WINDOW_CONFIG env = {"name":"main","url":"http://localhost:5173","html":null,"css":null,"js":null,"width":2560,"height":1600,"x":0,"y":0,"z_order":-1073741824,"fps":60,"format":"ARGB8888","focusable":false,"interactive":false,"floating":false}
[Wo] WINDOW_CONFIG parsed = {"name":"main","url":"http://localhost:5173","html":null,"css":null,"js":null,"width":2560,"height":1600,"x":0,"y":0,"z_order":-1073741824,"fps":60,"format":"ARGB8888","focusable":false,"interactive":false,"floating":false}
[Wo] App ready, CLIENT_MODE= false WO_STANDALONE= undefined
[Wo] Will connect to compositor
[Wo] Connecting to compositor IPC: /run/user/1000/wo-ipc.sock
[Wo] Portal UI bridge listening at /tmp/wo-portal-ui.sock
[Wo] IPC connected, sent HELLO message
2026-03-09T19:05:05.740058Z  INFO wo::electron: Electron window connected window=main
[Wo] DMABUF sender initialized
[Wo] Creating window
[Wo] createWindow starting
[Wo] preloadPath=/home/hellings/Documents/wo/electron/dist/preload.js
[Wo] BrowserWindow created, CLIENT_MODE=false offscreen=true
[Wo] setupIpcHandlers completed
[Wo] Loading content URL: http://localhost:5173
VITE v8.0.0-beta.16 ready in 368 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
[Wo] Content loaded from: http://localhost:5173
[Wo] Page initialized, setting up rendering
[Wo] Setting up OSR rendering, FPS=60
[Wo] createWindow completed successfully
[Wo] Window created successfully
[Wo] ERROR sending frame: Error: gbm_bo_create failed: all buffer creation methods exhausted
2026-03-09T19:05:06.078535Z  INFO wo::electron: received FRAME, sending ACK window=main seq=1
2026-03-09T19:05:06.091525Z  INFO wo::electron: received FRAME, sending ACK window=main seq=2
2026-03-09T19:05:06.115813Z  INFO wo::electron: received FRAME, sending ACK window=main seq=3
2026-03-09T19:05:06.135055Z  INFO wo::electron: received FRAME, sending ACK window=main seq=4
2026-03-09T19:05:06.158107Z  INFO wo::electron: received FRAME, sending ACK window=main seq=5
2026-03-09T19:05:06.167813Z  INFO wo::electron: received FRAME, sending ACK window=main seq=6
2026-03-09T19:05:06.185891Z  INFO wo::electron: received FRAME, sending ACK window=main seq=7
2026-03-09T19:05:06.215319Z  INFO wo::electron: received FRAME, sending ACK window=main seq=8
2026-03-09T19:05:06.229324Z  INFO wo::electron: received FRAME, sending ACK window=main seq=9
[Wo] SKIPPED paint due to frame backpressure inFlight=2
2026-03-09T19:05:06.253232Z  INFO wo::electron: received FRAME, sending ACK window=main seq=10
2026-03-09T19:05:06.267600Z  INFO wo::electron: received FRAME, sending ACK window=main seq=11
2026-03-09T19:05:06.291503Z  INFO wo::electron: received FRAME, sending ACK window=main seq=12
2026-03-09T19:05:06.306499Z  INFO wo::electron: received FRAME, sending ACK window=main seq=13
2026-03-09T19:05:06.326881Z  INFO wo::electron: received FRAME, sending ACK window=main seq=14
2026-03-09T19:05:06.344775Z  INFO wo::electron: received FRAME, sending ACK window=main seq=15
2026-03-09T19:05:06.359875Z  INFO wo::electron: received FRAME, sending ACK window=main seq=16
2026-03-09T19:05:06.379902Z  INFO wo::electron: received FRAME, sending ACK window=main seq=17
2026-03-09T19:05:06.396090Z  INFO wo::electron: received FRAME, sending ACK window=main seq=18
2026-03-09T19:05:06.418605Z  INFO wo::electron: received FRAME, sending ACK window=main seq=19
2026-03-09T19:05:06.433523Z  INFO wo::electron: received FRAME, sending ACK window=main seq=20
2026-03-09T19:05:06.451557Z  INFO wo::electron: received FRAME, sending ACK window=main seq=21
2026-03-09T19:05:06.468400Z  INFO wo::electron: received FRAME, sending ACK window=main seq=22
2026-03-09T19:05:06.487784Z  INFO wo::electron: received FRAME, sending ACK window=main seq=23
2026-03-09T19:05:06.508063Z  INFO wo::electron: received FRAME, sending ACK window=main seq=24
2026-03-09T19:05:06.524830Z  INFO wo::electron: received FRAME, sending ACK window=main seq=25
2026-03-09T19:05:06.540826Z  INFO wo::electron: received FRAME, sending ACK window=main seq=26
2026-03-09T19:05:06.560716Z  INFO wo::electron: received FRAME, sending ACK window=main seq=27
2026-03-09T19:05:06.577925Z  INFO wo::electron: received FRAME, sending ACK window=main seq=28
2026-03-09T19:05:06.594433Z  INFO wo::electron: received FRAME, sending ACK window=main seq=29
2026-03-09T19:05:06.613620Z  INFO wo::electron: received FRAME, sending ACK window=main seq=30
2026-03-09T19:05:06.630279Z  INFO wo::electron: received FRAME, sending ACK window=main seq=31
2026-03-09T19:05:06.646498Z  INFO wo::electron: received FRAME, sending ACK window=main seq=32
2026-03-09T19:05:06.665370Z  INFO wo::electron: received FRAME, sending ACK window=main seq=33
2026-03-09T19:05:06.681783Z  INFO wo::electron: received FRAME, sending ACK window=main seq=34
2026-03-09T19:05:06.698679Z  INFO wo::electron: received FRAME, sending ACK window=main seq=35
2026-03-09T19:05:06.717124Z  INFO wo::electron: received FRAME, sending ACK window=main seq=36
2026-03-09T19:05:06.733661Z  INFO wo::electron: received FRAME, sending ACK window=main seq=37
2026-03-09T19:05:06.750732Z  INFO wo::electron: received FRAME, sending ACK window=main seq=38
2026-03-09T19:05:06.768398Z  INFO wo::electron: received FRAME, sending ACK window=main seq=39
2026-03-09T19:05:06.786759Z  INFO wo::electron: received FRAME, sending ACK window=main seq=40
2026-03-09T19:05:06.805011Z  INFO wo::electron: received FRAME, sending ACK window=main seq=41
2026-03-09T19:05:06.820089Z  INFO wo::electron: received FRAME, sending ACK window=main seq=42
2026-03-09T19:05:06.841008Z  INFO wo::electron: received FRAME, sending ACK window=main seq=43
2026-03-09T19:05:06.858484Z  INFO wo::electron: received FRAME, sending ACK window=main seq=44
2026-03-09T19:05:06.873345Z  INFO wo::electron: received FRAME, sending ACK window=main seq=45
2026-03-09T19:05:06.895251Z  INFO wo::electron: received FRAME, sending ACK window=main seq=46
2026-03-09T19:05:06.913572Z  INFO wo::electron: received FRAME, sending ACK window=main seq=47
2026-03-09T19:05:06.928565Z  INFO wo::electron: received FRAME, sending ACK window=main seq=48
2026-03-09T19:05:06.946778Z  INFO wo::electron: received FRAME, sending ACK window=main seq=49
2026-03-09T19:05:06.963032Z  INFO wo::electron: received FRAME, sending ACK window=main seq=50
2026-03-09T19:05:06.981865Z  INFO wo::electron: received FRAME, sending ACK window=main seq=51
2026-03-09T19:05:07.003166Z  INFO wo::electron: received FRAME, sending ACK window=main seq=52
2026-03-09T19:05:07.019432Z  INFO wo::electron: received FRAME, sending ACK window=main seq=53
2026-03-09T19:05:07.036505Z  INFO wo::electron: received FRAME, sending ACK window=main seq=54
2026-03-09T19:05:07.055273Z  INFO wo::electron: received FRAME, sending ACK window=main seq=55
2026-03-09T19:05:07.071839Z  INFO wo::electron: received FRAME, sending ACK window=main seq=56
2026-03-09T19:05:07.089251Z  INFO wo::electron: received FRAME, sending ACK window=main seq=57
2026-03-09T19:05:07.107110Z  INFO wo::electron: received FRAME, sending ACK window=main seq=58
2026-03-09T19:05:07.125533Z  INFO wo::electron: received FRAME, sending ACK window=main seq=59
2026-03-09T19:05:07.143999Z  INFO wo::electron: received FRAME, sending ACK window=main seq=60
2026-03-09T19:05:07.158213Z  INFO wo::electron: received FRAME, sending ACK window=main seq=61
2026-03-09T19:05:07.180784Z  INFO wo::electron: received FRAME, sending ACK window=main seq=62
2026-03-09T19:05:07.198923Z  INFO wo::electron: received FRAME, sending ACK window=main seq=63
2026-03-09T19:05:07.214403Z  INFO wo::electron: received FRAME, sending ACK window=main seq=64
2026-03-09T19:05:07.235149Z  INFO wo::electron: received FRAME, sending ACK window=main seq=65
2026-03-09T19:05:07.253179Z  INFO wo::electron: received FRAME, sending ACK window=main seq=66
2026-03-09T19:05:07.270568Z  INFO wo::electron: received FRAME, sending ACK window=main seq=67
2026-03-09T19:05:07.285814Z  INFO wo::electron: received FRAME, sending ACK window=main seq=68
2026-03-09T19:05:07.304510Z  INFO wo::electron: received FRAME, sending ACK window=main seq=69
2026-03-09T19:05:07.319567Z  INFO wo::electron: received FRAME, sending ACK window=main seq=70
2026-03-09T19:05:07.342323Z  INFO wo::electron: received FRAME, sending ACK window=main seq=71
2026-03-09T19:05:07.361423Z  INFO wo::electron: received FRAME, sending ACK window=main seq=72
2026-03-09T19:05:07.371420Z  INFO wo: First DMABUF imported for 'main' (2560x1600, total_textures=1)
2026-03-09T19:05:07.371855Z  INFO wo: Spawned portal service: "/home/hellings/Documents/wo/target/debug/wo-portal"
2026-03-09T19:05:07.373260Z  INFO wo: render_frame #1: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.374775Z  INFO wo_portal: xdg-desktop-portal-wo starting
2026-03-09T19:05:07.374902Z  INFO wo::config: Loading config from "/home/hellings/.config/wo/config.toml"
2026-03-09T19:05:07.376323Z  INFO wo::electron: received FRAME, sending ACK window=main seq=73
2026-03-09T19:05:07.378710Z  INFO wo_portal: Portal service registered as org.freedesktop.impl.portal.desktop.wo
2026-03-09T19:05:07.378751Z  INFO wo_portal: Compositor IPC socket: /run/user/1000/wo-ipc.sock
2026-03-09T19:05:07.378764Z  INFO wo_portal: Listening for screen capture requests...
2026-03-09T19:05:07.385634Z  INFO wo: render_frame #2: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.398533Z  INFO wo: render_frame #3: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.398557Z  INFO wo::electron: received FRAME, sending ACK window=main seq=74
2026-03-09T19:05:07.408768Z  INFO wo: render_frame #4: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.414881Z  INFO wo::electron: received FRAME, sending ACK window=main seq=75
2026-03-09T19:05:07.424981Z  INFO wo: render_frame #5: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.429527Z  INFO wo::electron: received FRAME, sending ACK window=main seq=76
2026-03-09T19:05:07.441735Z  INFO wo: render_frame #6: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.449042Z  INFO wo::electron: received FRAME, sending ACK window=main seq=77
2026-03-09T19:05:07.458571Z  INFO wo: render_frame #7: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.467037Z  INFO wo::electron: received FRAME, sending ACK window=main seq=78
2026-03-09T19:05:07.475323Z  INFO wo: render_frame #8: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.482430Z  INFO wo::electron: received FRAME, sending ACK window=main seq=79
2026-03-09T19:05:07.492752Z  INFO wo: render_frame #9: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.506061Z  INFO wo::electron: received FRAME, sending ACK window=main seq=80
2026-03-09T19:05:07.510418Z  INFO wo: render_frame #10: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.519103Z  INFO wo::electron: received FRAME, sending ACK window=main seq=81
2026-03-09T19:05:07.527895Z  INFO wo: render_frame #11: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.541595Z  INFO wo: render_frame #12: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.543444Z  INFO wo::electron: received FRAME, sending ACK window=main seq=82
2026-03-09T19:05:07.558040Z  INFO wo::electron: received FRAME, sending ACK window=main seq=83
2026-03-09T19:05:07.558618Z  INFO wo: render_frame #13: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.575042Z  INFO wo: render_frame #14: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.580487Z  INFO wo::electron: received FRAME, sending ACK window=main seq=84
2026-03-09T19:05:07.592113Z  INFO wo: render_frame #15: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.598258Z  INFO wo::electron: received FRAME, sending ACK window=main seq=85
2026-03-09T19:05:07.608849Z  INFO wo: render_frame #16: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.615962Z  INFO wo::electron: received FRAME, sending ACK window=main seq=86
2026-03-09T19:05:07.626569Z  INFO wo: render_frame #17: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.636117Z  INFO wo::electron: received FRAME, sending ACK window=main seq=87
2026-03-09T19:05:07.642524Z  INFO wo: render_frame #18: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.655159Z  INFO wo::electron: received FRAME, sending ACK window=main seq=88
2026-03-09T19:05:07.659312Z  INFO wo: render_frame #19: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.671247Z  INFO wo::electron: received FRAME, sending ACK window=main seq=89
2026-03-09T19:05:07.675380Z  INFO wo: render_frame #20: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.691736Z  INFO wo: render_frame #21: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.695107Z  INFO wo::electron: received FRAME, sending ACK window=main seq=90
2026-03-09T19:05:07.708598Z  INFO wo: render_frame #22: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.710449Z  INFO wo::electron: received FRAME, sending ACK window=main seq=91
2026-03-09T19:05:07.725305Z  INFO wo: render_frame #23: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.729455Z  INFO wo::electron: received FRAME, sending ACK window=main seq=92
2026-03-09T19:05:07.741999Z  INFO wo: render_frame #24: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.742543Z  INFO wo::electron: received FRAME, sending ACK window=main seq=93
2026-03-09T19:05:07.759094Z  INFO wo: render_frame #25: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.767284Z  INFO wo::electron: received FRAME, sending ACK window=main seq=94
2026-03-09T19:05:07.775382Z  INFO wo: render_frame #26: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.781747Z  INFO wo::electron: received FRAME, sending ACK window=main seq=95
2026-03-09T19:05:07.792691Z  INFO wo: render_frame #27: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.804420Z  INFO wo::electron: received FRAME, sending ACK window=main seq=96
2026-03-09T19:05:07.808976Z  INFO wo: render_frame #28: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.819069Z  INFO wo::electron: received FRAME, sending ACK window=main seq=97
2026-03-09T19:05:07.826573Z  INFO wo: render_frame #29: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.839607Z  INFO wo::electron: received FRAME, sending ACK window=main seq=98
2026-03-09T19:05:07.842139Z  INFO wo: render_frame #30: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.852177Z  INFO wo::electron: received FRAME, sending ACK window=main seq=99
2026-03-09T19:05:07.859664Z  INFO wo: render_frame #31: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.873405Z  INFO wo::electron: received FRAME, sending ACK window=main seq=100
2026-03-09T19:05:07.875306Z  INFO wo: render_frame #32: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.889434Z  INFO wo::electron: received FRAME, sending ACK window=main seq=101
2026-03-09T19:05:07.892493Z  INFO wo: render_frame #33: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.910140Z  INFO wo::electron: received FRAME, sending ACK window=main seq=102
2026-03-09T19:05:07.911559Z  INFO wo: render_frame #34: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.925015Z  INFO wo::electron: received FRAME, sending ACK window=main seq=103
2026-03-09T19:05:07.933414Z  INFO wo: render_frame #35: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.945412Z  INFO wo::electron: received FRAME, sending ACK window=main seq=104
2026-03-09T19:05:07.955034Z  INFO wo: render_frame #36: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.964758Z  INFO wo::electron: received FRAME, sending ACK window=main seq=105
2026-03-09T19:05:07.967527Z  INFO wo: render_frame #37: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.975407Z  INFO wo: render_frame #38: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.977139Z  INFO wo::electron: received FRAME, sending ACK window=main seq=106
2026-03-09T19:05:07.992236Z  INFO wo: render_frame #39: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:07.994447Z  INFO wo::electron: received FRAME, sending ACK window=main seq=107
2026-03-09T19:05:08.009142Z  INFO wo: render_frame #40: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.012236Z  INFO wo::electron: received FRAME, sending ACK window=main seq=108
2026-03-09T19:05:08.025700Z  INFO wo: render_frame #41: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.031393Z  INFO wo::electron: received FRAME, sending ACK window=main seq=109
2026-03-09T19:05:08.042188Z  INFO wo: render_frame #42: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.043748Z  INFO wo::electron: received FRAME, sending ACK window=main seq=110
2026-03-09T19:05:08.060693Z  INFO wo: render_frame #43: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.072965Z  INFO wo::electron: received FRAME, sending ACK window=main seq=111
2026-03-09T19:05:08.075576Z  INFO wo: render_frame #44: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.085621Z  INFO wo::electron: received FRAME, sending ACK window=main seq=112
2026-03-09T19:05:08.092495Z  INFO wo: render_frame #45: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.102376Z  INFO wo::electron: received FRAME, sending ACK window=main seq=113
2026-03-09T19:05:08.110177Z  INFO wo: render_frame #46: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.119066Z  INFO wo::electron: received FRAME, sending ACK window=main seq=114
2026-03-09T19:05:08.126233Z  INFO wo: render_frame #47: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.135287Z  INFO wo::electron: received FRAME, sending ACK window=main seq=115
2026-03-09T19:05:08.142536Z  INFO wo: render_frame #48: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.150631Z  INFO wo::electron: received FRAME, sending ACK window=main seq=116
2026-03-09T19:05:08.159303Z  INFO wo: render_frame #49: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.171184Z  INFO wo::electron: received FRAME, sending ACK window=main seq=117
2026-03-09T19:05:08.175739Z  INFO wo: render_frame #50: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.190803Z  INFO wo::electron: received FRAME, sending ACK window=main seq=118
2026-03-09T19:05:08.192719Z  INFO wo: render_frame #51: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.209300Z  INFO wo: render_frame #52: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.211910Z  INFO wo::electron: received FRAME, sending ACK window=main seq=119
2026-03-09T19:05:08.226057Z  INFO wo: render_frame #53: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.226385Z  INFO wo::electron: received FRAME, sending ACK window=main seq=120
2026-03-09T19:05:08.241468Z  INFO wo::electron: received FRAME, sending ACK window=main seq=121
2026-03-09T19:05:08.242524Z  INFO wo: render_frame #54: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.259309Z  INFO wo: render_frame #55: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.259672Z  INFO wo::electron: received FRAME, sending ACK window=main seq=122
2026-03-09T19:05:08.275543Z  INFO wo::electron: received FRAME, sending ACK window=main seq=123
2026-03-09T19:05:08.275965Z  INFO wo: render_frame #56: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.290724Z  INFO wo::electron: received FRAME, sending ACK window=main seq=124
2026-03-09T19:05:08.293454Z  INFO wo: render_frame #57: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.308995Z  INFO wo: render_frame #58: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.311290Z  INFO wo::electron: received FRAME, sending ACK window=main seq=125
2026-03-09T19:05:08.326174Z  INFO wo: render_frame #59: textures_rendered=1, gles_cache=1, windows=1
2026-03-09T19:05:08.332259Z  INFO wo::electron: received FRAME, sending ACK window=main seq=126
2026-03-09T19:05:08.347320Z  INFO wo::electron: received FRAME, sending ACK window=main seq=127
2026-03-09T19:05:08.367845Z  INFO wo::electron: received FRAME, sending ACK window=main seq=128
2026-03-09T19:05:08.386642Z  INFO wo::electron: received FRAME, sending ACK window=main seq=129
2026-03-09T19:05:08.408885Z  INFO wo::electron: received FRAME, sending ACK window=main seq=130
2026-03-09T19:05:08.428166Z  INFO wo::electron: received FRAME, sending ACK window=main seq=131
2026-03-09T19:05:08.446778Z  INFO wo::electron: received FRAME, sending ACK window=main seq=132
2026-03-09T19:05:08.461172Z  INFO wo::electron: received FRAME, sending ACK window=main seq=133
2026-03-09T19:05:08.484331Z  INFO wo::electron: received FRAME, sending ACK window=main seq=134
2026-03-09T19:05:08.506797Z  INFO wo::electron: received FRAME, sending ACK window=main seq=135
2026-03-09T19:05:08.527019Z  INFO wo::electron: received FRAME, sending ACK window=main seq=136
2026-03-09T19:05:08.544423Z  INFO wo::electron: received FRAME, sending ACK window=main seq=137
2026-03-09T19:05:08.565329Z  INFO wo::electron: received FRAME, sending ACK window=main seq=138
2026-03-09T19:05:08.583494Z  INFO wo::electron: received FRAME, sending ACK window=main seq=139
2026-03-09T19:05:08.605203Z  INFO wo::electron: received FRAME, sending ACK window=main seq=140
2026-03-09T19:05:08.757098Z  INFO wo::electron: received FRAME, sending ACK window=main seq=141
2026-03-09T19:05:08.776883Z  INFO wo::electron: received FRAME, sending ACK window=main seq=142
2026-03-09T19:05:08.797115Z  INFO wo::electron: received FRAME, sending ACK window=main seq=143
2026-03-09T19:05:08.817753Z  INFO wo::electron: received FRAME, sending ACK window=main seq=144
2026-03-09T19:05:08.837605Z  INFO wo::electron: received FRAME, sending ACK window=main seq=145
[Wo] Load timeout, continuing
2026-03-09T19:05:08.858544Z  INFO wo::electron: received FRAME, sending ACK window=main seq=146
2026-03-09T19:05:08.879656Z  INFO wo::electron: received FRAME, sending ACK window=main seq=147
2026-03-09T19:05:08.896826Z  INFO wo::electron: received FRAME, sending ACK window=main seq=148
2026-03-09T19:05:08.917898Z  INFO wo::electron: received FRAME, sending ACK window=main seq=149
2026-03-09T19:05:08.937260Z  INFO wo::electron: received FRAME, sending ACK window=main seq=150
2026-03-09T19:05:08.958668Z  INFO wo::electron: received FRAME, sending ACK window=main seq=151
2026-03-09T19:05:08.974782Z  INFO wo::electron: received FRAME, sending ACK window=main seq=152
2026-03-09T19:05:09.000150Z  INFO wo::electron: received FRAME, sending ACK window=main seq=153
2026-03-09T19:05:09.016152Z  INFO wo::electron: received FRAME, sending ACK window=main seq=154
2026-03-09T19:05:09.035956Z  INFO wo::electron: received FRAME, sending ACK window=main seq=155
2026-03-09T19:05:09.055953Z  INFO wo::electron: received FRAME, sending ACK window=main seq=156
2026-03-09T19:05:09.070892Z  INFO wo::electron: received FRAME, sending ACK window=main seq=157
2026-03-09T19:05:09.087604Z  INFO wo::electron: received FRAME, sending ACK window=main seq=158
2026-03-09T19:05:09.112960Z  INFO wo::electron: received FRAME, sending ACK window=main seq=159
2026-03-09T19:05:09.143908Z  INFO wo::electron: received FRAME, sending ACK window=main seq=160
2026-03-09T19:05:09.158543Z  INFO wo::electron: received FRAME, sending ACK window=main seq=161
2026-03-09T19:05:09.181403Z  INFO wo::electron: received FRAME, sending ACK window=main seq=162
2026-03-09T19:05:09.199534Z  INFO wo::electron: received FRAME, sending ACK window=main seq=163
2026-03-09T19:05:09.215902Z  INFO wo::electron: received FRAME, sending ACK window=main seq=164
2026-03-09T19:05:09.231086Z  INFO wo::electron: received FRAME, sending ACK window=main seq=165
2026-03-09T19:05:09.247916Z  INFO wo::electron: received FRAME, sending ACK window=main seq=166
2026-03-09T19:05:09.263202Z  INFO wo::electron: received FRAME, sending ACK window=main seq=167
2026-03-09T19:05:09.279943Z  INFO wo::electron: received FRAME, sending ACK window=main seq=168
2026-03-09T19:05:09.302232Z  INFO wo::electron: received FRAME, sending ACK window=main seq=169
2026-03-09T19:05:09.322814Z  INFO wo::electron: received FRAME, sending ACK window=main seq=170
2026-03-09T19:05:09.335478Z  INFO wo::electron: received FRAME, sending ACK window=main seq=171
2026-03-09T19:05:09.358890Z  INFO wo::electron: received FRAME, sending ACK window=main seq=172
2026-03-09T19:05:09.381262Z  INFO wo::electron: received FRAME, sending ACK window=main seq=173
2026-03-09T19:05:09.395508Z  INFO wo::electron: received FRAME, sending ACK window=main seq=174
2026-03-09T19:05:09.417419Z  INFO wo::electron: received FRAME, sending ACK window=main seq=175
2026-03-09T19:05:09.433241Z  INFO wo::electron: received FRAME, sending ACK window=main seq=176
2026-03-09T19:05:09.449443Z  INFO wo::electron: received FRAME, sending ACK window=main seq=177
2026-03-09T19:05:09.464904Z  INFO wo::electron: received FRAME, sending ACK window=main seq=178
2026-03-09T19:05:09.481937Z  INFO wo::electron: received FRAME, sending ACK window=main seq=179
2026-03-09T19:05:09.497275Z  INFO wo::electron: received FRAME, sending ACK window=main seq=180
2026-03-09T19:05:09.514493Z  INFO wo::electron: received FRAME, sending ACK window=main seq=181
2026-03-09T19:05:09.537129Z  INFO wo::electron: received FRAME, sending ACK window=main seq=182
2026-03-09T19:05:09.551380Z  INFO wo::electron: received FRAME, sending ACK window=main seq=183
2026-03-09T19:05:09.574504Z  INFO wo::electron: received FRAME, sending ACK window=main seq=184
2026-03-09T19:05:09.588673Z  INFO wo::electron: received FRAME, sending ACK window=main seq=185
2026-03-09T19:05:09.610532Z  INFO wo::electron: received FRAME, sending ACK window=main seq=186
2026-03-09T19:05:09.626399Z  INFO wo::electron: received FRAME, sending ACK window=main seq=187
2026-03-09T19:05:09.643221Z  INFO wo::electron: received FRAME, sending ACK window=main seq=188
2026-03-09T19:05:09.656890Z  INFO wo::electron: received FRAME, sending ACK window=main seq=189
2026-03-09T19:05:09.676851Z  INFO wo::electron: received FRAME, sending ACK window=main seq=190
2026-03-09T19:05:09.689396Z  INFO wo::electron: received FRAME, sending ACK window=main seq=191
2026-03-09T19:05:09.705067Z  INFO wo::electron: received FRAME, sending ACK window=main seq=192
2026-03-09T19:05:09.727534Z  INFO wo::electron: received FRAME, sending ACK window=main seq=193
2026-03-09T19:05:09.749999Z  INFO wo::electron: received FRAME, sending ACK window=main seq=194
2026-03-09T19:05:09.765554Z  INFO wo::electron: received FRAME, sending ACK window=main seq=195
2026-03-09T19:05:09.784934Z  INFO wo::electron: received FRAME, sending ACK window=main seq=196
2026-03-09T19:05:09.802931Z  INFO wo::electron: received FRAME, sending ACK window=main seq=197
2026-03-09T19:05:09.818907Z  INFO wo::electron: received FRAME, sending ACK window=main seq=198
2026-03-09T19:05:09.835515Z  INFO wo::electron: received FRAME, sending ACK window=main seq=199
2026-03-09T19:05:09.858681Z  INFO wo::electron: received FRAME, sending ACK window=main seq=200
2026-03-09T19:05:09.875952Z  INFO wo::electron: received FRAME, sending ACK window=main seq=201
2026-03-09T19:05:09.894321Z  INFO wo::electron: received FRAME, sending ACK window=main seq=202
2026-03-09T19:05:09.916169Z  INFO wo::electron: received FRAME, sending ACK window=main seq=203
2026-03-09T19:05:09.928981Z  INFO wo::electron: received FRAME, sending ACK window=main seq=204
2026-03-09T19:05:09.952677Z  INFO wo::electron: received FRAME, sending ACK window=main seq=205
2026-03-09T19:05:09.967260Z  INFO wo::electron: received FRAME, sending ACK window=main seq=206
2026-03-09T19:05:09.990725Z  INFO wo::electron: received FRAME, sending ACK window=main seq=207
2026-03-09T19:05:10.006487Z  INFO wo::electron: received FRAME, sending ACK window=main seq=208
2026-03-09T19:05:10.021208Z  INFO wo::electron: received FRAME, sending ACK window=main seq=209
2026-03-09T19:05:10.035614Z  INFO wo::electron: received FRAME, sending ACK window=main seq=210
2026-03-09T19:05:10.059276Z  INFO wo::electron: received FRAME, sending ACK window=main seq=211
2026-03-09T19:05:10.077026Z  INFO wo::electron: received FRAME, sending ACK window=main seq=212
2026-03-09T19:05:10.095038Z  INFO wo::electron: received FRAME, sending ACK window=main seq=213
2026-03-09T19:05:10.107985Z  INFO wo::electron: received FRAME, sending ACK window=main seq=214
2026-03-09T19:05:10.133539Z  INFO wo::electron: received FRAME, sending ACK window=main seq=215
2026-03-09T19:05:10.149316Z  INFO wo::electron: received FRAME, sending ACK window=main seq=216
2026-03-09T19:05:10.168667Z  INFO wo::electron: received FRAME, sending ACK window=main seq=217
2026-03-09T19:05:10.185506Z  INFO wo::electron: received FRAME, sending ACK window=main seq=218
2026-03-09T19:05:10.201283Z  INFO wo::electron: received FRAME, sending ACK window=main seq=219
2026-03-09T19:05:10.220526Z  INFO wo::electron: received FRAME, sending ACK window=main seq=220
2026-03-09T19:05:10.239132Z  INFO wo::electron: received FRAME, sending ACK window=main seq=221
2026-03-09T19:05:10.254284Z  INFO wo::electron: received FRAME, sending ACK window=main seq=222
2026-03-09T19:05:10.277162Z  INFO wo::electron: received FRAME, sending ACK window=main seq=223
2026-03-09T19:05:10.291921Z  INFO wo::electron: received FRAME, sending ACK window=main seq=224
2026-03-09T19:05:10.314433Z  INFO wo::electron: received FRAME, sending ACK window=main seq=225
2026-03-09T19:05:10.328169Z  INFO wo::electron: received FRAME, sending ACK window=main seq=226
2026-03-09T19:05:10.347406Z  INFO wo::electron: received FRAME, sending ACK window=main seq=227
2026-03-09T19:05:10.360267Z  INFO wo::electron: received FRAME, sending ACK window=main seq=228
2026-03-09T19:05:10.388525Z  INFO wo::electron: received FRAME, sending ACK window=main seq=229
2026-03-09T19:05:10.402887Z  INFO wo::electron: received FRAME, sending ACK window=main seq=230
2026-03-09T19:05:10.425009Z  INFO wo::electron: received FRAME, sending ACK window=main seq=231
2026-03-09T19:05:10.446980Z  INFO wo::electron: received FRAME, sending ACK window=main seq=232
2026-03-09T19:05:10.462289Z  INFO wo::electron: received FRAME, sending ACK window=main seq=233
2026-03-09T19:05:10.482716Z  INFO wo::electron: received FRAME, sending ACK window=main seq=234
2026-03-09T19:05:10.499518Z  INFO wo::electron: received FRAME, sending ACK window=main seq=235
2026-03-09T19:05:10.519049Z  INFO wo::electron: received FRAME, sending ACK window=main seq=236
2026-03-09T19:05:10.531616Z  INFO wo::electron: received FRAME, sending ACK window=main seq=237
2026-03-09T19:05:10.554883Z  INFO wo::electron: received FRAME, sending ACK window=main seq=238
2026-03-09T19:05:10.568809Z  INFO wo::electron: received FRAME, sending ACK window=main seq=239
2026-03-09T19:05:10.588641Z  INFO wo::electron: received FRAME, sending ACK window=main seq=240
2026-03-09T19:05:10.607131Z  INFO wo::electron: received FRAME, sending ACK window=main seq=241
2026-03-09T19:05:10.625324Z  INFO wo::electron: received FRAME, sending ACK window=main seq=242
2026-03-09T19:05:10.642669Z  INFO wo::electron: received FRAME, sending ACK window=main seq=243
2026-03-09T19:05:10.660453Z  INFO wo::electron: received FRAME, sending ACK window=main seq=244
2026-03-09T19:05:10.674928Z  INFO wo::electron: received FRAME, sending ACK window=main seq=245
2026-03-09T19:05:10.696541Z  INFO wo::electron: received FRAME, sending ACK window=main seq=246
2026-03-09T19:05:10.715069Z  INFO wo::electron: received FRAME, sending ACK window=main seq=247
2026-03-09T19:05:10.729069Z  INFO wo::electron: received FRAME, sending ACK window=main seq=248
2026-03-09T19:05:10.749994Z  INFO wo::electron: received FRAME, sending ACK window=main seq=249
2026-03-09T19:05:10.768351Z  INFO wo::electron: received FRAME, sending ACK window=main seq=250
2026-03-09T19:05:10.785358Z  INFO wo::electron: received FRAME, sending ACK window=main seq=251
2026-03-09T19:05:10.805945Z  INFO wo::electron: received FRAME, sending ACK window=main seq=252
2026-03-09T19:05:10.824142Z  INFO wo::electron: received FRAME, sending ACK window=main seq=253
2026-03-09T19:05:10.840256Z  INFO wo::electron: received FRAME, sending ACK window=main seq=254
2026-03-09T19:05:10.860929Z  INFO wo::electron: received FRAME, sending ACK window=main seq=255
2026-03-09T19:05:10.879418Z  INFO wo::electron: received FRAME, sending ACK window=main seq=256
2026-03-09T19:05:10.893761Z  INFO wo::electron: received FRAME, sending ACK window=main seq=257
2026-03-09T19:05:10.915569Z  INFO wo::electron: received FRAME, sending ACK window=main seq=258
2026-03-09T19:05:10.933922Z  INFO wo::electron: received FRAME, sending ACK window=main seq=259
2026-03-09T19:05:10.948233Z  INFO wo::electron: received FRAME, sending ACK window=main seq=260
2026-03-09T19:05:10.969982Z  INFO wo::electron: received FRAME, sending ACK window=main seq=261
2026-03-09T19:05:10.988772Z  INFO wo::electron: received FRAME, sending ACK window=main seq=262
2026-03-09T19:05:11.003425Z  INFO wo::electron: received FRAME, sending ACK window=main seq=263
2026-03-09T19:05:11.024974Z  INFO wo::electron: received FRAME, sending ACK window=main seq=264
2026-03-09T19:05:11.043851Z  INFO wo::electron: received FRAME, sending ACK window=main seq=265
2026-03-09T19:05:11.057928Z  INFO wo::electron: received FRAME, sending ACK window=main seq=266
2026-03-09T19:05:11.079831Z  INFO wo::electron: received FRAME, sending ACK window=main seq=267
2026-03-09T19:05:11.098666Z  INFO wo::electron: received FRAME, sending ACK window=main seq=268
2026-03-09T19:05:11.113216Z  INFO wo::electron: received FRAME, sending ACK window=main seq=269
2026-03-09T19:05:11.134778Z  INFO wo::electron: received FRAME, sending ACK window=main seq=270
2026-03-09T19:05:11.153050Z  INFO wo::electron: received FRAME, sending ACK window=main seq=271
2026-03-09T19:05:11.167202Z  INFO wo::electron: received FRAME, sending ACK window=main seq=272
2026-03-09T19:05:11.188755Z  INFO wo::electron: received FRAME, sending ACK window=main seq=273
2026-03-09T19:05:11.207161Z  INFO wo::electron: received FRAME, sending ACK window=main seq=274
2026-03-09T19:05:11.221273Z  INFO wo::electron: received FRAME, sending ACK window=main seq=275
2026-03-09T19:05:11.242745Z  INFO wo::electron: received FRAME, sending ACK window=main seq=276
2026-03-09T19:05:11.261659Z  INFO wo::electron: received FRAME, sending ACK window=main seq=277
2026-03-09T19:05:11.275941Z  INFO wo::electron: received FRAME, sending ACK window=main seq=278
2026-03-09T19:05:11.297677Z  INFO wo::electron: received FRAME, sending ACK window=main seq=279
2026-03-09T19:05:11.316634Z  INFO wo::electron: received FRAME, sending ACK window=main seq=280
2026-03-09T19:05:11.331408Z  INFO wo::electron: received FRAME, sending ACK window=main seq=281
2026-03-09T19:05:11.351880Z  INFO wo::electron: received FRAME, sending ACK window=main seq=282
2026-03-09T19:05:11.370290Z  INFO wo::electron: received FRAME, sending ACK window=main seq=283
2026-03-09T19:05:11.384324Z  INFO wo::electron: received FRAME, sending ACK window=main seq=284
2026-03-09T19:05:11.405958Z  INFO wo::electron: received FRAME, sending ACK window=main seq=285
2026-03-09T19:05:11.424713Z  INFO wo::electron: received FRAME, sending ACK window=main seq=286
2026-03-09T19:05:11.439068Z  INFO wo::electron: received FRAME, sending ACK window=main seq=287
2026-03-09T19:05:11.460789Z  INFO wo::electron: received FRAME, sending ACK window=main seq=288
2026-03-09T19:05:11.479149Z  INFO wo::electron: received FRAME, sending ACK window=main seq=289
2026-03-09T19:05:11.493560Z  INFO wo::electron: received FRAME, sending ACK window=main seq=290
2026-03-09T19:05:11.514261Z  INFO wo::electron: received FRAME, sending ACK window=main seq=291
2026-03-09T19:05:11.532751Z  INFO wo::electron: received FRAME, sending ACK window=main seq=292
2026-03-09T19:05:11.546625Z  INFO wo::electron: received FRAME, sending ACK window=main seq=293
2026-03-09T19:05:11.568310Z  INFO wo::electron: received FRAME, sending ACK window=main seq=294
2026-03-09T19:05:11.587304Z  INFO wo::electron: received FRAME, sending ACK window=main seq=295
2026-03-09T19:05:11.602688Z  INFO wo::electron: received FRAME, sending ACK window=main seq=296
2026-03-09T19:05:11.622009Z  INFO wo::electron: received FRAME, sending ACK window=main seq=297
2026-03-09T19:05:11.640316Z  INFO wo::electron: received FRAME, sending ACK window=main seq=298
2026-03-09T19:05:11.656712Z  INFO wo::electron: received FRAME, sending ACK window=main seq=299
2026-03-09T19:05:11.677363Z  INFO wo::electron: received FRAME, sending ACK window=main seq=300
2026-03-09T19:05:11.696314Z  INFO wo::electron: received FRAME, sending ACK window=main seq=301
2026-03-09T19:05:11.710829Z  INFO wo::electron: received FRAME, sending ACK window=main seq=302
2026-03-09T19:05:11.731520Z  INFO wo::electron: received FRAME, sending ACK window=main seq=303
2026-03-09T19:05:11.749776Z  INFO wo::electron: received FRAME, sending ACK window=main seq=304
2026-03-09T19:05:11.764112Z  INFO wo::electron: received FRAME, sending ACK window=main seq=305
2026-03-09T19:05:11.785723Z  INFO wo::electron: received FRAME, sending ACK window=main seq=306
2026-03-09T19:05:11.804143Z  INFO wo::electron: received FRAME, sending ACK window=main seq=307
2026-03-09T19:05:11.818835Z  INFO wo::electron: received FRAME, sending ACK window=main seq=308
2026-03-09T19:05:11.839330Z  INFO wo::electron: received FRAME, sending ACK window=main seq=309
2026-03-09T19:05:11.857515Z  INFO wo::electron: received FRAME, sending ACK window=main seq=310
2026-03-09T19:05:11.871818Z  INFO wo::electron: received FRAME, sending ACK window=main seq=311
2026-03-09T19:05:11.893550Z  INFO wo::electron: received FRAME, sending ACK window=main seq=312
2026-03-09T19:05:11.911740Z  INFO wo::electron: received FRAME, sending ACK window=main seq=313
2026-03-09T19:05:11.926315Z  INFO wo::electron: received FRAME, sending ACK window=main seq=314
2026-03-09T19:05:11.947679Z  INFO wo::electron: received FRAME, sending ACK window=main seq=315
2026-03-09T19:05:11.966154Z  INFO wo::electron: received FRAME, sending ACK window=main seq=316
2026-03-09T19:05:11.981056Z  INFO wo::electron: received FRAME, sending ACK window=main seq=317
2026-03-09T19:05:12.001704Z  INFO wo::electron: received FRAME, sending ACK window=main seq=318
2026-03-09T19:05:12.019779Z  INFO wo::electron: received FRAME, sending ACK window=main seq=319
2026-03-09T19:05:12.034249Z  INFO wo::electron: received FRAME, sending ACK window=main seq=320
2026-03-09T19:05:12.055935Z  INFO wo::electron: received FRAME, sending ACK window=main seq=321
2026-03-09T19:05:12.074940Z  INFO wo::electron: received FRAME, sending ACK window=main seq=322
2026-03-09T19:05:12.089564Z  INFO wo::electron: received FRAME, sending ACK window=main seq=323
2026-03-09T19:05:12.110190Z  INFO wo::electron: received FRAME, sending ACK window=main seq=324
2026-03-09T19:05:12.140751Z  INFO wo::electron: received FRAME, sending ACK window=main seq=325
2026-03-09T19:05:12.164765Z  INFO wo::electron: received FRAME, sending ACK window=main seq=326
2026-03-09T19:05:12.177277Z  INFO wo::electron: received FRAME, sending ACK window=main seq=327
2026-03-09T19:05:12.202364Z  INFO wo::electron: received FRAME, sending ACK window=main seq=328
2026-03-09T19:05:12.218435Z  INFO wo::electron: received FRAME, sending ACK window=main seq=329
2026-03-09T19:05:12.239689Z  INFO wo::electron: received FRAME, sending ACK window=main seq=330
2026-03-09T19:05:12.255865Z  INFO wo::electron: received FRAME, sending ACK window=main seq=331
2026-03-09T19:05:12.271073Z  INFO wo::electron: received FRAME, sending ACK window=main seq=332
2026-03-09T19:05:12.286363Z  INFO wo::electron: received FRAME, sending ACK window=main seq=333
2026-03-09T19:05:12.312331Z  INFO wo::electron: received FRAME, sending ACK window=main seq=334
2026-03-09T19:05:12.328733Z  INFO wo::electron: received FRAME, sending ACK window=main seq=335
2026-03-09T19:05:12.346479Z  INFO wo::electron: received FRAME, sending ACK window=main seq=336
2026-03-09T19:05:12.373025Z  INFO wo::electron: received FRAME, sending ACK window=main seq=337
2026-03-09T19:05:12.390977Z  INFO wo::electron: received FRAME, sending ACK window=main seq=338
2026-03-09T19:05:12.407722Z  INFO wo::electron: received FRAME, sending ACK window=main seq=339
2026-03-09T19:05:12.424472Z  INFO wo::electron: received FRAME, sending ACK window=main seq=340
2026-03-09T19:05:12.441822Z  INFO wo::electron: received FRAME, sending ACK window=main seq=341
2026-03-09T19:05:12.460188Z  INFO wo::electron: received FRAME, sending ACK window=main seq=342
2026-03-09T19:05:12.477883Z  INFO wo::electron: received FRAME, sending ACK window=main seq=343
2026-03-09T19:05:12.492498Z  INFO wo::electron: received FRAME, sending ACK window=main seq=344
2026-03-09T19:05:12.513175Z  INFO wo::electron: received FRAME, sending ACK window=main seq=345
2026-03-09T19:05:12.531739Z  INFO wo::electron: received FRAME, sending ACK window=main seq=346
2026-03-09T19:05:12.545860Z  INFO wo::electron: received FRAME, sending ACK window=main seq=347
2026-03-09T19:05:12.567429Z  INFO wo::electron: received FRAME, sending ACK window=main seq=348
2026-03-09T19:05:12.586376Z  INFO wo::electron: received FRAME, sending ACK window=main seq=349
2026-03-09T19:05:12.601073Z  INFO wo::electron: received FRAME, sending ACK window=main seq=350
2026-03-09T19:05:12.621546Z  INFO wo::electron: received FRAME, sending ACK window=main seq=351
2026-03-09T19:05:12.640222Z  INFO wo::electron: received FRAME, sending ACK window=main seq=352
2026-03-09T19:05:12.654652Z  INFO wo::electron: received FRAME, sending ACK window=main seq=353
2026-03-09T19:05:12.675364Z  INFO wo::electron: received FRAME, sending ACK window=main seq=354
2026-03-09T19:05:12.693906Z  INFO wo::electron: received FRAME, sending ACK window=main seq=355
2026-03-09T19:05:12.708264Z  INFO wo::electron: received FRAME, sending ACK window=main seq=356
2026-03-09T19:05:12.729829Z  INFO wo::electron: received FRAME, sending ACK window=main seq=357
2026-03-09T19:05:12.748635Z  INFO wo::electron: received FRAME, sending ACK window=main seq=358
2026-03-09T19:05:12.762763Z  INFO wo::electron: received FRAME, sending ACK window=main seq=359
2026-03-09T19:05:12.787127Z  INFO wo::electron: received FRAME, sending ACK window=main seq=360
2026-03-09T19:05:12.803766Z  INFO wo::electron: received FRAME, sending ACK window=main seq=361
2026-03-09T19:05:12.818997Z  INFO wo::electron: received FRAME, sending ACK window=main seq=362
2026-03-09T19:05:12.837389Z  INFO wo::electron: received FRAME, sending ACK window=main seq=363
2026-03-09T19:05:12.852794Z  INFO wo::electron: received FRAME, sending ACK window=main seq=364
2026-03-09T19:05:12.873555Z  INFO wo::electron: received FRAME, sending ACK window=main seq=365
2026-03-09T19:05:12.891577Z  INFO wo::electron: received FRAME, sending ACK window=main seq=366
2026-03-09T19:05:12.905672Z  INFO wo::electron: received FRAME, sending ACK window=main seq=367
2026-03-09T19:05:12.927162Z  INFO wo::electron: received FRAME, sending ACK window=main seq=368
2026-03-09T19:05:12.947907Z  INFO wo::electron: received FRAME, sending ACK window=main seq=369
2026-03-09T19:05:12.963667Z  INFO wo::electron: received FRAME, sending ACK window=main seq=370
2026-03-09T19:05:12.982352Z  INFO wo::electron: received FRAME, sending ACK window=main seq=371
2026-03-09T19:05:13.000854Z  INFO wo::electron: received FRAME, sending ACK window=main seq=372
2026-03-09T19:05:13.015132Z  INFO wo::electron: received FRAME, sending ACK window=main seq=373
2026-03-09T19:05:13.036803Z  INFO wo::electron: received FRAME, sending ACK window=main seq=374
2026-03-09T19:05:13.056234Z  INFO wo::electron: received FRAME, sending ACK window=main seq=375
2026-03-09T19:05:13.071863Z  INFO wo::electron: received FRAME, sending ACK window=main seq=376
2026-03-09T19:05:13.091266Z  INFO wo::electron: received FRAME, sending ACK window=main seq=377
2026-03-09T19:05:13.109715Z  INFO wo::electron: received FRAME, sending ACK window=main seq=378
2026-03-09T19:05:13.123733Z  INFO wo::electron: received FRAME, sending ACK window=main seq=379
2026-03-09T19:05:13.145413Z  INFO wo::electron: received FRAME, sending ACK window=main seq=380
2026-03-09T19:05:13.163979Z  INFO wo::electron: received FRAME, sending ACK window=main seq=381
2026-03-09T19:05:13.178681Z  INFO wo::electron: received FRAME, sending ACK window=main seq=382
2026-03-09T19:05:13.199512Z  INFO wo::electron: received FRAME, sending ACK window=main seq=383
2026-03-09T19:05:13.218213Z  INFO wo::electron: received FRAME, sending ACK window=main seq=384
2026-03-09T19:05:13.232930Z  INFO wo::electron: received FRAME, sending ACK window=main seq=385
2026-03-09T19:05:13.253482Z  INFO wo::electron: received FRAME, sending ACK window=main seq=386
2026-03-09T19:05:13.272062Z  INFO wo::electron: received FRAME, sending ACK window=main seq=387
2026-03-09T19:05:13.287568Z  INFO wo::electron: received FRAME, sending ACK window=main seq=388
2026-03-09T19:05:13.306257Z  INFO wo::electron: received FRAME, sending ACK window=main seq=389
2026-03-09T19:05:13.324128Z  INFO wo::electron: received FRAME, sending ACK window=main seq=390
2026-03-09T19:05:13.340022Z  INFO wo::electron: received FRAME, sending ACK window=main seq=391
2026-03-09T19:05:13.360564Z  INFO wo::electron: received FRAME, sending ACK window=main seq=392
2026-03-09T19:05:13.379982Z  INFO wo::electron: received FRAME, sending ACK window=main seq=393
2026-03-09T19:05:13.394802Z  INFO wo::electron: received FRAME, sending ACK window=main seq=394
2026-03-09T19:05:13.415633Z  INFO wo::electron: received FRAME, sending ACK window=main seq=395
2026-03-09T19:05:13.439081Z  INFO wo::electron: received FRAME, sending ACK window=main seq=396
2026-03-09T19:05:13.457838Z  INFO wo::electron: received FRAME, sending ACK window=main seq=397
2026-03-09T19:05:13.473913Z  INFO wo::electron: received FRAME, sending ACK window=main seq=398
2026-03-09T19:05:13.494966Z  INFO wo::electron: received FRAME, sending ACK window=main seq=399
2026-03-09T19:05:13.508544Z  INFO wo::electron: received FRAME, sending ACK window=main seq=400
2026-03-09T19:05:13.523620Z  INFO wo::electron: received FRAME, sending ACK window=main seq=401
2026-03-09T19:05:13.539501Z  INFO wo::electron: received FRAME, sending ACK window=main seq=402
2026-03-09T19:05:13.563298Z  INFO wo::electron: received FRAME, sending ACK window=main seq=403
2026-03-09T19:05:13.579611Z  INFO wo::electron: received FRAME, sending ACK window=main seq=404
2026-03-09T19:05:13.596487Z  INFO wo::electron: received FRAME, sending ACK window=main seq=405
2026-03-09T19:05:13.616174Z  INFO wo::electron: received FRAME, sending ACK window=main seq=406
2026-03-09T19:05:13.631073Z  INFO wo::electron: received FRAME, sending ACK window=main seq=407
2026-03-09T19:05:13.646849Z  INFO wo::electron: received FRAME, sending ACK window=main seq=408
2026-03-09T19:05:13.664197Z  INFO wo::electron: received FRAME, sending ACK window=main seq=409
2026-03-09T19:05:13.690689Z  INFO wo::electron: received FRAME, sending ACK window=main seq=410
2026-03-09T19:05:13.708523Z  INFO wo::electron: received FRAME, sending ACK window=main seq=411
2026-03-09T19:05:13.722851Z  INFO wo::electron: received FRAME, sending ACK window=main seq=412
2026-03-09T19:05:13.743455Z  INFO wo::electron: received FRAME, sending ACK window=main seq=413
2026-03-09T19:05:13.763570Z  INFO wo::electron: received FRAME, sending ACK window=main seq=414
2026-03-09T19:05:13.782992Z  INFO wo::electron: received FRAME, sending ACK window=main seq=415
2026-03-09T19:05:13.801121Z  INFO wo::electron: received FRAME, sending ACK window=main seq=416
2026-03-09T19:05:13.825578Z  INFO wo::electron: received FRAME, sending ACK window=main seq=417
2026-03-09T19:05:13.838722Z  INFO wo::electron: received FRAME, sending ACK window=main seq=418
2026-03-09T19:05:13.855922Z  INFO wo::electron: received FRAME, sending ACK window=main seq=419
2026-03-09T19:05:13.876609Z  INFO wo::electron: received FRAME, sending ACK window=main seq=420
2026-03-09T19:05:13.900907Z  INFO wo::electron: received FRAME, sending ACK window=main seq=421
2026-03-09T19:05:13.916321Z  INFO wo::electron: received FRAME, sending ACK window=main seq=422
2026-03-09T19:05:13.935874Z  INFO wo::electron: received FRAME, sending ACK window=main seq=423
2026-03-09T19:05:13.955127Z  INFO wo::electron: received FRAME, sending ACK window=main seq=424
2026-03-09T19:05:13.978076Z  INFO wo::electron: received FRAME, sending ACK window=main seq=425
2026-03-09T19:05:14.000845Z  INFO wo::electron: received FRAME, sending ACK window=main seq=426
2026-03-09T19:05:14.017284Z  INFO wo::electron: received FRAME, sending ACK window=main seq=427
2026-03-09T19:05:14.038754Z  INFO wo::electron: received FRAME, sending ACK window=main seq=428
2026-03-09T19:05:14.056086Z  INFO wo::electron: received FRAME, sending ACK window=main seq=429
2026-03-09T19:05:14.073033Z  INFO wo::electron: received FRAME, sending ACK window=main seq=430
2026-03-09T19:05:14.093819Z  INFO wo::electron: received FRAME, sending ACK window=main seq=431
2026-03-09T19:05:14.110765Z  INFO wo::electron: received FRAME, sending ACK window=main seq=432
2026-03-09T19:05:14.131288Z  INFO wo::electron: received FRAME, sending ACK window=main seq=433
2026-03-09T19:05:14.147637Z  INFO wo::electron: received FRAME, sending ACK window=main seq=434
2026-03-09T19:05:14.162861Z  INFO wo::electron: received FRAME, sending ACK window=main seq=435
2026-03-09T19:05:14.180438Z  INFO wo::electron: received FRAME, sending ACK window=main seq=436
2026-03-09T19:05:14.194591Z  INFO wo::electron: received FRAME, sending ACK window=main seq=437
2026-03-09T19:05:14.220352Z  INFO wo::electron: received FRAME, sending ACK window=main seq=438
2026-03-09T19:05:14.237740Z  INFO wo::electron: received FRAME, sending ACK window=main seq=439
2026-03-09T19:05:14.253159Z  INFO wo::electron: received FRAME, sending ACK window=main seq=440
2026-03-09T19:05:14.276561Z  INFO wo::electron: received FRAME, sending ACK window=main seq=441
2026-03-09T19:05:14.291959Z  INFO wo::electron: received FRAME, sending ACK window=main seq=442
2026-03-09T19:05:14.312479Z  INFO wo::electron: received FRAME, sending ACK window=main seq=443
2026-03-09T19:05:14.325942Z  INFO wo::electron: received FRAME, sending ACK window=main seq=444
2026-03-09T19:05:14.344599Z  INFO wo::electron: received FRAME, sending ACK window=main seq=445
2026-03-09T19:05:14.360100Z  INFO wo::electron: received FRAME, sending ACK window=main seq=446
2026-03-09T19:05:14.379636Z  INFO wo::electron: received FRAME, sending ACK window=main seq=447
2026-03-09T19:05:14.393127Z  INFO wo::electron: received FRAME, sending ACK window=main seq=448
2026-03-09T19:05:14.410253Z  INFO wo::electron: received FRAME, sending ACK window=main seq=449
2026-03-09T19:05:14.433364Z  INFO wo::electron: received FRAME, sending ACK window=main seq=450
2026-03-09T19:05:14.452105Z  INFO wo::electron: received FRAME, sending ACK window=main seq=451
2026-03-09T19:05:14.470881Z  INFO wo::electron: received FRAME, sending ACK window=main seq=452
2026-03-09T19:05:14.492229Z  INFO wo::electron: received FRAME, sending ACK window=main seq=453
2026-03-09T19:05:14.512036Z  INFO wo::electron: received FRAME, sending ACK window=main seq=454
[Wo] ERROR sending frame: Error: EPIPE: broken pipe, write
[Wo] ERROR sending frame: Error: EPIPE: broken pipe, write
[Wo] IPC connection closed
[Wo] SKIPPED paint (dmabufSender=false ipcConnected=false)