From 331b884f1e1d50c067e99d22a41cefc78a12b79b Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 12 May 2023 20:01:37 +0200 Subject: [PATCH 001/264] tiling: Animate tree changes --- Cargo.lock | 957 ++++++++++++++++++---- Cargo.toml | 8 +- src/backend/kms/mod.rs | 4 +- src/backend/render/cursor.rs | 2 + src/backend/render/element.rs | 10 + src/backend/render/mod.rs | 15 +- src/backend/winit.rs | 2 +- src/main.rs | 4 + src/shell/element/mod.rs | 62 +- src/shell/element/stack.rs | 4 +- src/shell/element/surface.rs | 48 +- src/shell/element/window.rs | 16 +- src/shell/layout/floating/grabs/moving.rs | 9 +- src/shell/layout/floating/mod.rs | 2 + src/shell/layout/tiling/blocker.rs | 65 ++ src/shell/layout/tiling/grabs.rs | 3 +- src/shell/layout/tiling/mod.rs | 712 +++++++++++----- src/shell/mod.rs | 13 + src/shell/workspace.rs | 27 +- src/state.rs | 6 +- src/utils/iced.rs | 3 +- src/wayland/handlers/compositor.rs | 63 +- src/wayland/handlers/screencopy.rs | 1 + 23 files changed, 1641 insertions(+), 395 deletions(-) create mode 100644 src/shell/layout/tiling/blocker.rs diff --git a/Cargo.lock b/Cargo.lock index 542f3cfa..8082ce9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" [[package]] name = "ab_glyph" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe21446ad43aa56417a767f3e2f3d7c4ca522904de1dd640529a76e9c5c3b33c" +checksum = "5110f1c78cf582855d895ecd0746b653db010cec6d9f5575293f27934d980a39" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -87,9 +87,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" dependencies = [ "backtrace", ] @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "atomic_refcell" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "857253367827bd9d0fd973f0ef15506a96e79e41b0ad7aa691203a4e3214f6c8" +checksum = "79d6dc922a2792b006573f60b2648076355daeae5ce9cb59507e5908c9625d31" [[package]] name = "autocfg" @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" [[package]] name = "bytemuck" @@ -312,6 +312,56 @@ dependencies = [ "num-traits", ] +[[package]] +name = "clipboard-win" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" +dependencies = [ + "error-code", + "str-buf", + "winapi", +] + +[[package]] +name = "clipboard_macos" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145a7f9e9b89453bc0a5e32d166456405d389cea5b578f57f1274b1397588a95" +dependencies = [ + "objc", + "objc-foundation", + "objc_id", +] + +[[package]] +name = "clipboard_wayland" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f6364a9f7a66f2ac1a1a098aa1c7f6b686f2496c6ac5e5c0d773445df912747" +dependencies = [ + "smithay-clipboard", +] + +[[package]] +name = "clipboard_x11" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "983a7010836ecd04dde2c6d27a0cb56ec5d21572177e782bdcb24a600124e921" +dependencies = [ + "thiserror", + "x11rb 0.9.0", +] + +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + [[package]] name = "cocoa" version = "0.24.1" @@ -323,7 +373,7 @@ dependencies = [ "cocoa-foundation", "core-foundation", "core-graphics", - "foreign-types", + "foreign-types 0.3.2", "libc", "objc", ] @@ -338,7 +388,7 @@ dependencies = [ "block", "core-foundation", "core-graphics-types", - "foreign-types", + "foreign-types 0.3.2", "libc", "objc", ] @@ -359,11 +409,17 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "com-rs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf43edc576402991846b093a7ca18a3477e0ef9c588cde84964b5d3e43016642" + [[package]] name = "const_panic" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58baae561b85ca19b3122a9ddd35c8ec40c3bcd14fe89921824eae73f7baffbf" +checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" [[package]] name = "core-foundation" @@ -390,7 +446,7 @@ dependencies = [ "bitflags", "core-foundation", "core-graphics-types", - "foreign-types", + "foreign-types 0.3.2", "libc", ] @@ -402,7 +458,19 @@ checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ "bitflags", "core-foundation", - "foreign-types", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "core-text" +version = "19.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" +dependencies = [ + "core-foundation", + "core-graphics", + "foreign-types 0.3.2", "libc", ] @@ -415,6 +483,7 @@ dependencies = [ "bytemuck", "calloop", "cosmic-protocols", + "cosmic-time", "edid-rs", "egui", "glow 0.11.2", @@ -465,7 +534,7 @@ name = "cosmic-text" version = "0.7.0" source = "git+https://github.com/pop-os/cosmic-text?rev=e788c175#e788c175ec31094b04dcacbc0537dba4433afcfc" dependencies = [ - "fontdb 0.13.0", + "fontdb 0.13.1", "libm", "log", "ouroboros 0.15.6", @@ -493,11 +562,24 @@ dependencies = [ "serde", ] +[[package]] +name = "cosmic-time" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "269b94889f152389ed39fde8a69a6083ff4ca73993360d2850d5c281e3488c11" +dependencies = [ + "iced 0.9.0", + "iced_core 0.9.0", + "iced_futures 0.6.0", + "iced_native 0.10.3", + "iced_style 0.8.0", +] + [[package]] name = "cpufeatures" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -554,6 +636,29 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossfont" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21fd3add36ea31aba1520aa5288714dd63be506106753226d0eb387a93bc9c45" +dependencies = [ + "cocoa", + "core-foundation", + "core-foundation-sys", + "core-graphics", + "core-text", + "dwrote", + "foreign-types 0.5.0", + "freetype-rs", + "libc", + "log", + "objc", + "once_cell", + "pkg-config", + "servo-fontconfig", + "winapi", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -597,6 +702,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "d3d12" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8f0de2f5a8e7bd4a9eec0e3c781992a4ce1724f68aec7d7a3715344de8b39da" +dependencies = [ + "bitflags", + "libloading", + "winapi", +] + [[package]] name = "darling" version = "0.10.2" @@ -799,6 +915,20 @@ dependencies = [ "libc", ] +[[package]] +name = "dwrote" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" +dependencies = [ + "lazy_static", + "libc", + "serde", + "serde_derive", + "winapi", + "wio", +] + [[package]] name = "ecolor" version = "0.21.0" @@ -1012,6 +1142,16 @@ dependencies = [ "libc", ] +[[package]] +name = "error-code" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" +dependencies = [ + "libc", + "str-buf", +] + [[package]] name = "euclid" version = "0.22.9" @@ -1021,6 +1161,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "expat-sys" +version = "2.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" +dependencies = [ + "cmake", + "pkg-config", +] + [[package]] name = "exr" version = "1.6.3" @@ -1066,12 +1216,12 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", - "miniz_oxide 0.6.2", + "miniz_oxide 0.7.1", ] [[package]] @@ -1121,9 +1271,9 @@ dependencies = [ [[package]] name = "fontdb" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfec8f19f9b89b2901219cc62604810d2bfef15dc1182e95320f57e7cbbe041a" +checksum = "237ff9f0813bbfc9de836016472e0c9ae7802f174a51594607e5f4ff334cb2f5" dependencies = [ "log", "memmap2 0.5.10", @@ -1137,7 +1287,28 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared", + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", ] [[package]] @@ -1146,6 +1317,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "fraction" version = "0.13.1" @@ -1169,6 +1346,28 @@ dependencies = [ "xdg", ] +[[package]] +name = "freetype-rs" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb" +dependencies = [ + "bitflags", + "freetype-sys", + "libc", +] + +[[package]] +name = "freetype-sys" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" +dependencies = [ + "cmake", + "libc", + "pkg-config", +] + [[package]] name = "futures" version = "0.3.28" @@ -1434,9 +1633,9 @@ dependencies = [ [[package]] name = "gpu-alloc" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc59e5f710e310e76e6707f86c561dd646f69a8876da9131703b2f717de818d" +checksum = "22beaafc29b38204457ea030f6fb7a84c9e4dd1b86e311ba0542533453d87f62" dependencies = [ "bitflags", "gpu-alloc-types", @@ -1451,6 +1650,19 @@ dependencies = [ "bitflags", ] +[[package]] +name = "gpu-allocator" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce95f9e2e11c2c6fadfce42b5af60005db06576f231f5c92550fdded43c423e8" +dependencies = [ + "backtrace", + "log", + "thiserror", + "winapi", + "windows", +] + [[package]] name = "gpu-descriptor" version = "0.2.3" @@ -1499,6 +1711,21 @@ dependencies = [ "ahash 0.7.6", ] +[[package]] +name = "hassle-rs" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90601c6189668c7345fc53842cb3f3a3d872203d523be1b3cb44a36a3e62fb85" +dependencies = [ + "bitflags", + "com-rs", + "libc", + "libloading", + "thiserror", + "widestring", + "winapi", +] + [[package]] name = "hermit-abi" version = "0.2.6" @@ -1529,23 +1756,47 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "iced" version = "0.6.0" source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" dependencies = [ - "iced_core", + "iced_core 0.6.2", "iced_dyrend", - "iced_futures", + "iced_futures 0.5.1", "iced_glow", - "iced_graphics", - "iced_native", + "iced_graphics 0.5.0", + "iced_native 0.7.0", "iced_softbuffer", - "iced_wgpu", + "iced_wgpu 0.7.0", "image", "thiserror", ] +[[package]] +name = "iced" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbddf356d01e9d41cd394a9d04d62bfd89650a30f12fda5839cabb8c4591c88" +dependencies = [ + "iced_core 0.9.0", + "iced_futures 0.6.0", + "iced_graphics 0.8.0", + "iced_native 0.10.3", + "iced_wgpu 0.10.0", + "iced_winit", + "thiserror", +] + [[package]] name = "iced_core" version = "0.6.2" @@ -1556,16 +1807,27 @@ dependencies = [ "wasm-timer", ] +[[package]] +name = "iced_core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11e1942e28dedee756cc27e67e7a838cdc1e59fb6bf9627ec9f709ab3b135782" +dependencies = [ + "bitflags", + "instant", + "palette", +] + [[package]] name = "iced_dyrend" version = "0.1.0" source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" dependencies = [ "iced_glow", - "iced_graphics", - "iced_native", + "iced_graphics 0.5.0", + "iced_native 0.7.0", "iced_softbuffer", - "iced_wgpu", + "iced_wgpu 0.7.0", "log", "raw-window-handle 0.5.2", ] @@ -1581,6 +1843,19 @@ dependencies = [ "wasm-timer", ] +[[package]] +name = "iced_futures" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "215d51fa4f70dbb63775d7141243c4d98d4d525d8949695601f8fbac7dcbc04e" +dependencies = [ + "futures", + "log", + "tokio", + "wasm-bindgen-futures", + "wasm-timer", +] + [[package]] name = "iced_glow" version = "0.5.1" @@ -1591,8 +1866,8 @@ dependencies = [ "glow 0.11.2", "glow_glyph", "glyph_brush", - "iced_graphics", - "iced_native", + "iced_graphics 0.5.0", + "iced_native 0.7.0", "log", ] @@ -1604,8 +1879,8 @@ dependencies = [ "bitflags", "bytemuck", "glam", - "iced_native", - "iced_style", + "iced_native 0.7.0", + "iced_style 0.5.1", "image", "kamadak-exif", "log", @@ -1616,12 +1891,28 @@ dependencies = [ "usvg 0.18.0", ] +[[package]] +name = "iced_graphics" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338a6aff7db906537074ad0fe8b720cfdb9512cdfea43c628c76bd1cf50fdcc0" +dependencies = [ + "bitflags", + "bytemuck", + "glam", + "iced_native 0.10.3", + "iced_style 0.8.0", + "log", + "raw-window-handle 0.5.2", + "thiserror", +] + [[package]] name = "iced_lazy" version = "0.3.0" source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" dependencies = [ - "iced_native", + "iced_native 0.7.0", "ouroboros 0.13.0", ] @@ -1630,10 +1921,25 @@ name = "iced_native" version = "0.7.0" source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" dependencies = [ - "iced_core", - "iced_futures", - "iced_style", + "iced_core 0.6.2", + "iced_futures 0.5.1", + "iced_style 0.5.1", + "num-traits", + "twox-hash", + "unicode-segmentation", +] + +[[package]] +name = "iced_native" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d012eb06da490fe46a695b39721c20da9643f35cf2ecb9d30618fdeb96170616" +dependencies = [ + "iced_core 0.9.0", + "iced_futures 0.6.0", + "iced_style 0.8.0", "num-traits", + "thiserror", "twox-hash", "unicode-segmentation", ] @@ -1644,8 +1950,8 @@ version = "0.1.0" source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" dependencies = [ "cosmic-text", - "iced_graphics", - "iced_native", + "iced_graphics 0.5.0", + "iced_native 0.7.0", "lazy_static", "log", "raqote", @@ -1658,7 +1964,18 @@ name = "iced_style" version = "0.5.1" source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" dependencies = [ - "iced_core", + "iced_core 0.6.2", + "once_cell", + "palette", +] + +[[package]] +name = "iced_style" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e37333dc2991201140302cd0d4cea051bd37ca3671d5008ec85df86d232ff30" +dependencies = [ + "iced_core 0.9.0", "once_cell", "palette", ] @@ -1675,19 +1992,56 @@ dependencies = [ "glam", "glyph_brush", "guillotiere", - "iced_graphics", - "iced_native", + "iced_graphics 0.5.0", + "iced_native 0.7.0", + "log", + "raw-window-handle 0.5.2", + "wgpu 0.14.2", + "wgpu_glyph 0.18.0", +] + +[[package]] +name = "iced_wgpu" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478803c56061f567ce5ddf223b20d11d3c118cc46bb0d0552370dc65cdc4cb9c" +dependencies = [ + "bitflags", + "bytemuck", + "encase", + "futures", + "glam", + "glyph_brush", + "guillotiere", + "iced_graphics 0.8.0", + "iced_native 0.10.3", "log", "raw-window-handle 0.5.2", - "wgpu", - "wgpu_glyph", + "wgpu 0.15.1", + "wgpu_glyph 0.19.0", +] + +[[package]] +name = "iced_winit" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a59ea3a85149a6a1f9e92b6c740ce90f04e5c7d848cfd05742336863fceb955" +dependencies = [ + "iced_futures 0.6.0", + "iced_graphics 0.8.0", + "iced_native 0.10.3", + "log", + "thiserror", + "web-sys", + "winapi", + "window_clipboard", + "winit", ] [[package]] name = "id_tree" version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd9db8dd5be8bde5a2624ed4b2dfb74368fe7999eb9c4940fd3ca344b61071a" +source = "git+https://github.com/Drakulix/id-tree.git?branch=feature/copy_clone#c9a2b8c325566d223cf06362c902636b0405e28c" dependencies = [ "snowflake", ] @@ -1817,9 +2171,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5" dependencies = [ "wasm-bindgen", ] @@ -1873,9 +2227,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.141" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libcosmic" @@ -1887,12 +2241,12 @@ dependencies = [ "derive_setters", "fraction", "freedesktop-icons", - "iced", - "iced_core", + "iced 0.6.0", + "iced_core 0.6.2", "iced_lazy", - "iced_native", + "iced_native 0.7.0", "iced_softbuffer", - "iced_style", + "iced_style 0.5.1", "lazy_static", "palette", "slotmap", @@ -1970,9 +2324,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "lock_api" @@ -2098,7 +2452,7 @@ dependencies = [ "bitflags", "block", "core-graphics-types", - "foreign-types", + "foreign-types 0.3.2", "log", "objc", ] @@ -2150,7 +2504,27 @@ checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" name = "naga" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "262d2840e72dbe250e8cf2f522d080988dfca624c4112c096238a4845f591707" +checksum = "262d2840e72dbe250e8cf2f522d080988dfca624c4112c096238a4845f591707" +dependencies = [ + "bit-set", + "bitflags", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "rustc-hash", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "naga" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eafe22a23b797c9bc227c6c896419b26b5bb88fa903417a3adaed08778850d5" dependencies = [ "bit-set", "bitflags", @@ -2239,6 +2613,19 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "nix" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" +dependencies = [ + "bitflags", + "cc", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + [[package]] name = "nix" version = "0.23.2" @@ -2434,6 +2821,17 @@ dependencies = [ "objc_exception", ] +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + [[package]] name = "objc_exception" version = "0.1.2" @@ -2443,6 +2841,15 @@ dependencies = [ "cc", ] +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + [[package]] name = "object" version = "0.30.3" @@ -2460,9 +2867,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "ordered-float" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13a384337e997e6860ffbaa83708b2ef329fd8c54cb67a5f64d421e0f943254f" +checksum = "2fc2dbde8f8a79f2102cc474ceb0ad68e3b80b85289ea62389b60e66777e4213" dependencies = [ "num-traits", ] @@ -2532,11 +2939,11 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owned_ttf_parser" -version = "0.18.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25e9fb15717794fae58ab55c26e044103aad13186fbb625893f9a3bbcc24228" +checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4" dependencies = [ - "ttf-parser 0.18.1", + "ttf-parser 0.19.0", ] [[package]] @@ -2706,9 +3113,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "png" @@ -2842,9 +3249,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -2903,6 +3310,16 @@ dependencies = [ "typed-arena", ] +[[package]] +name = "raw-window-handle" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28f55143d0548dad60bb4fbdc835a3d7ac6acc3324506450c5fdd6e42903a76" +dependencies = [ + "libc", + "raw-window-handle 0.4.3", +] + [[package]] name = "raw-window-handle" version = "0.4.3" @@ -2983,13 +3400,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.1", ] [[package]] @@ -2998,7 +3415,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.29", ] [[package]] @@ -3007,6 +3424,12 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +[[package]] +name = "regex-syntax" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" + [[package]] name = "renderdoc" version = "0.10.1" @@ -3131,9 +3554,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.37.11" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags", "errno 0.3.1", @@ -3220,6 +3643,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sctk-adwaita" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61270629cc6b4d77ec1907db1033d5c2e1a404c412743621981a871dc9c12339" +dependencies = [ + "crossfont", + "log", + "smithay-client-toolkit", + "tiny-skia 0.7.0", +] + [[package]] name = "sendfd" version = "0.4.3" @@ -3231,18 +3666,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.160" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", @@ -3260,6 +3695,27 @@ dependencies = [ "serde", ] +[[package]] +name = "servo-fontconfig" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c" +dependencies = [ + "libc", + "servo-fontconfig-sys", +] + +[[package]] +name = "servo-fontconfig-sys" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388" +dependencies = [ + "expat-sys", + "freetype-sys", + "pkg-config", +] + [[package]] name = "sha2" version = "0.10.6" @@ -3334,7 +3790,7 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "smithay" version = "0.3.0" -source = "git+https://github.com/smithay//smithay?rev=25d1176484#25d1176484e1c846c4b510f6a4bf5cc5a6d2e4e9" +source = "git+https://github.com/pop-os/smithay?branch=tiling_rework#920556dd8f5b16609fee20a44191add364740e61" dependencies = [ "appendlist", "ash", @@ -3374,7 +3830,7 @@ dependencies = [ "wayland-server", "wayland-sys 0.30.1", "winit", - "x11rb", + "x11rb 0.11.1", "xkbcommon 0.5.0", ] @@ -3397,6 +3853,16 @@ dependencies = [ "wayland-protocols 0.29.5", ] +[[package]] +name = "smithay-clipboard" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" +dependencies = [ + "smithay-client-toolkit", + "wayland-client 0.29.5", +] + [[package]] name = "smithay-egui" version = "0.1.0" @@ -3429,7 +3895,7 @@ dependencies = [ "cocoa", "core-graphics", "fastrand", - "foreign-types", + "foreign-types 0.3.2", "log", "nix 0.26.2", "objc", @@ -3443,7 +3909,7 @@ dependencies = [ "web-sys", "windows-sys 0.42.0", "x11-dl", - "x11rb", + "x11rb 0.11.1", ] [[package]] @@ -3477,6 +3943,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "str-buf" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" + [[package]] name = "strict-num" version = "0.1.0" @@ -3537,9 +4009,9 @@ checksum = "9ac8fb7895b4afa060ad731a32860db8755da3449a47e796d5ecf758db2671d4" [[package]] name = "swash" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba6e16b35fe4f8b2020640610575827892b4e2db5d289b3b76ff4e1cfd38752" +checksum = "3b7c73c813353c347272919aa1af2885068b05e625e5532b43049e4f641ae77f" dependencies = [ "yazi", "zeno", @@ -3645,9 +4117,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" dependencies = [ "itoa", "serde", @@ -3657,15 +4129,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" dependencies = [ "time-core", ] @@ -3684,6 +4156,21 @@ dependencies = [ "safe_arch", ] +[[package]] +name = "tiny-skia" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642680569bb895b16e4b9d181c60be1ed136fa0c9c7f11d004daf053ba89bf82" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "bytemuck", + "cfg-if", + "png", + "safe_arch", + "tiny-skia-path 0.7.0", +] + [[package]] name = "tiny-skia" version = "0.8.4" @@ -3695,7 +4182,17 @@ dependencies = [ "bytemuck", "cfg-if", "png", - "tiny-skia-path", + "tiny-skia-path 0.8.4", +] + +[[package]] +name = "tiny-skia-path" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c114d32f0c2ee43d585367cb013dfaba967ab9f62b90d9af0d696e955e70fa6c" +dependencies = [ + "arrayref", + "bytemuck", ] [[package]] @@ -3709,6 +4206,18 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tokio" +version = "1.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" +dependencies = [ + "autocfg", + "num_cpus", + "pin-project-lite", + "windows-sys 0.48.0", +] + [[package]] name = "toml" version = "0.5.11" @@ -3749,20 +4258,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", "valuable", @@ -3792,9 +4301,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "nu-ansi-term", @@ -3820,6 +4329,12 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0609f771ad9c6155384897e1df4d948e692667cc0588548b68eb44d052b27633" +[[package]] +name = "ttf-parser" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44dcf002ae3b32cd25400d6df128c5babec3927cd1eb7ce813cfff20eb6c3746" + [[package]] name = "twox-hash" version = "1.6.3" @@ -4018,9 +4533,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4028,24 +4543,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "083abe15c5d88556b77bdf7aef403625be9e327ad37c62c4e4129af740168163" dependencies = [ "cfg-if", "js-sys", @@ -4055,9 +4570,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4065,22 +4580,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" [[package]] name = "wasm-timer" @@ -4099,9 +4614,9 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ebd48bfc1178c9190c7ff80cc822b3335ffc83141e9aa723168f377257623e" +checksum = "41b48e27457e8da3b2260ac60d0a94512f5cba36448679f3747c0865b7893ed8" dependencies = [ "cc", "downcast-rs", @@ -4286,9 +4801,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721" dependencies = [ "js-sys", "wasm-bindgen", @@ -4309,17 +4824,41 @@ dependencies = [ "arrayvec 0.7.2", "js-sys", "log", - "naga", + "naga 0.10.0", + "parking_lot 0.12.1", + "raw-window-handle 0.5.2", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core 0.14.2", + "wgpu-hal 0.14.1", + "wgpu-types 0.14.1", +] + +[[package]] +name = "wgpu" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d745a1b6d91d85c33defbb29f0eee0450e1d2614d987e14bf6baf26009d132d7" +dependencies = [ + "arrayvec 0.7.2", + "cfg-if", + "js-sys", + "log", + "naga 0.11.0", "parking_lot 0.12.1", + "profiling", "raw-window-handle 0.5.2", "smallvec", "static_assertions", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "wgpu-core", - "wgpu-hal", - "wgpu-types", + "wgpu-core 0.15.1", + "wgpu-hal 0.15.4", + "wgpu-types 0.15.2", ] [[package]] @@ -4335,15 +4874,38 @@ dependencies = [ "codespan-reporting", "fxhash", "log", - "naga", + "naga 0.10.0", + "parking_lot 0.12.1", + "profiling", + "raw-window-handle 0.5.2", + "smallvec", + "thiserror", + "web-sys", + "wgpu-hal 0.14.1", + "wgpu-types 0.14.1", +] + +[[package]] +name = "wgpu-core" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7131408d940e335792645a98f03639573b0480e9e2e7cddbbab74f7c6d9f3fff" +dependencies = [ + "arrayvec 0.7.2", + "bit-vec", + "bitflags", + "codespan-reporting", + "fxhash", + "log", + "naga 0.11.0", "parking_lot 0.12.1", "profiling", "raw-window-handle 0.5.2", "smallvec", "thiserror", "web-sys", - "wgpu-hal", - "wgpu-types", + "wgpu-hal 0.15.4", + "wgpu-types 0.15.2", ] [[package]] @@ -4359,8 +4921,8 @@ dependencies = [ "bitflags", "block", "core-graphics-types", - "d3d12", - "foreign-types", + "d3d12 0.5.0", + "foreign-types 0.3.2", "fxhash", "glow 0.11.2", "gpu-alloc", @@ -4370,7 +4932,49 @@ dependencies = [ "libloading", "log", "metal", - "naga", + "naga 0.10.0", + "objc", + "parking_lot 0.12.1", + "profiling", + "range-alloc", + "raw-window-handle 0.5.2", + "renderdoc-sys", + "smallvec", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types 0.14.1", + "winapi", +] + +[[package]] +name = "wgpu-hal" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdcf61a283adc744bb5453dd88ea91f3f86d5ca6b027661c6c73c7734ae0288b" +dependencies = [ + "android_system_properties", + "arrayvec 0.7.2", + "ash", + "bit-set", + "bitflags", + "block", + "core-graphics-types", + "d3d12 0.6.0", + "foreign-types 0.3.2", + "fxhash", + "glow 0.12.1", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "hassle-rs", + "js-sys", + "khronos-egl", + "libc", + "libloading", + "log", + "metal", + "naga 0.11.0", "objc", "parking_lot 0.12.1", "profiling", @@ -4381,7 +4985,7 @@ dependencies = [ "thiserror", "wasm-bindgen", "web-sys", - "wgpu-types", + "wgpu-types 0.15.2", "winapi", ] @@ -4394,6 +4998,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "wgpu-types" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32444e121b0bd00cb02c0de32fde457a9491bd44e03e7a5db6df9b1da2f6f110" +dependencies = [ + "bitflags", + "js-sys", + "web-sys", +] + [[package]] name = "wgpu_glyph" version = "0.18.0" @@ -4403,9 +5018,27 @@ dependencies = [ "bytemuck", "glyph_brush", "log", - "wgpu", + "wgpu 0.14.2", +] + +[[package]] +name = "wgpu_glyph" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e25440d5f32ec39de49c57c15c2d3f9133a7939b069b5ad07e5afd8b78fb8adc" +dependencies = [ + "bytemuck", + "glyph_brush", + "log", + "wgpu 0.15.1", ] +[[package]] +name = "widestring" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" + [[package]] name = "winapi" version = "0.3.9" @@ -4446,6 +5079,29 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "window_clipboard" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "015dd4474dc6aa96fe19aae3a24587a088bd90331dba5a5cc60fb3a180234c4d" +dependencies = [ + "clipboard-win", + "clipboard_macos", + "clipboard_wayland", + "clipboard_x11", + "raw-window-handle 0.3.4", + "thiserror", +] + +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.36.1" @@ -4659,6 +5315,7 @@ dependencies = [ "percent-encoding", "raw-window-handle 0.4.3", "raw-window-handle 0.5.2", + "sctk-adwaita", "smithay-client-toolkit", "wasm-bindgen", "wayland-client 0.29.5", @@ -4670,9 +5327,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.4.1" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" dependencies = [ "memchr", ] @@ -4697,6 +5354,18 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "x11rb" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e99be55648b3ae2a52342f9a870c0e138709a3493261ce9b469afe6e4df6d8a" +dependencies = [ + "gethostname", + "nix 0.22.3", + "winapi", + "winapi-wsapoll", +] + [[package]] name = "x11rb" version = "0.11.1" @@ -4733,11 +5402,11 @@ dependencies = [ [[package]] name = "xdg" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4583db5cbd4c4c0303df2d15af80f0539db703fa1c68802d4cbbd2dd0f88f6" +checksum = "688597db5a750e9cad4511cb94729a078e274308099a0382b5b8203bbc767fee" dependencies = [ - "dirs", + "home", ] [[package]] @@ -4767,9 +5436,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.4" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" +checksum = "dc95a04ea24f543cd9be5aab44f963fa35589c99e18415c38fb2b17e133bf8d2" [[package]] name = "xmlparser" @@ -4785,9 +5454,9 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" [[package]] name = "yazi" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec4882895da007f1fb0524971b07f60fc742f457996d970443affd44a48ce954" +checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1" [[package]] name = "zeno" @@ -4827,9 +5496,9 @@ dependencies = [ [[package]] name = "zune-inflate" -version = "0.2.53" +version = "0.2.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440a08fd59c6442e4b846ea9b10386c38307eae728b216e1ab2c305d1c9daaf8" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" dependencies = [ "simd-adler32", ] diff --git a/Cargo.toml b/Cargo.toml index 967dd2bb..38d8b160 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,6 @@ log-panics = { version = "2", features = ["with-backtrace"] } thiserror = "1.0.26" regex = "1" xcursor = "0.3.3" -id_tree = "1.8.0" xkbcommon = "0.4" indexmap = "1.8.0" xdg = "^2.1" @@ -40,6 +39,11 @@ tracing-journald = "0.3.0" tracing = { version = "0.1.37", features = ["max_level_debug", "release_max_level_info"] } puffin = { version = "0.14.3", optional = true } puffin_egui = { version = "0.21.0", optional = true } +cosmic-time = "0.2.0" + +[dependencies.id_tree] +git = "https://github.com/Drakulix/id-tree.git" +branch = "feature/copy_clone" [dependencies.smithay] version = "0.3" @@ -70,4 +74,4 @@ debug = true lto = "fat" [patch."https://github.com/Smithay/smithay.git"] -smithay = { git = "https://github.com/smithay//smithay", rev = "25d1176484" } +smithay = { git = "https://github.com/pop-os/smithay", branch = "tiling_rework" } diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index 18bee99d..e3e3fc4b 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -485,7 +485,9 @@ impl State { } surface.pending = false; - surface.dirty.then(|| { + (surface.dirty + || data.state.common.shell.animations_going()) + .then(|| { (surface.output.clone(), surface.fps.avg_rendertime(5)) }) } diff --git a/src/backend/render/cursor.rs b/src/backend/render/cursor.rs index 14765568..c6f0db74 100644 --- a/src/backend/render/cursor.rs +++ b/src/backend/render/cursor.rs @@ -162,6 +162,7 @@ where surface, position.to_physical_precise_round(scale), scale, + 1.0, ) } @@ -190,6 +191,7 @@ where surface, location.into().to_physical_precise_round(scale), scale, + 1.0, ) } diff --git a/src/backend/render/element.rs b/src/backend/render/element.rs index 526bfafb..d3bcbae8 100644 --- a/src/backend/render/element.rs +++ b/src/backend/render/element.rs @@ -118,6 +118,16 @@ where CosmicElement::Egui(elem) => elem.opaque_regions(scale), } } + + fn alpha(&self) -> f32 { + match self { + CosmicElement::Workspace(elem) => elem.alpha(), + CosmicElement::Cursor(elem) => elem.alpha(), + CosmicElement::MoveGrab(elem) => elem.alpha(), + #[cfg(feature = "debug")] + CosmicElement::Egui(elem) => elem.alpha(), + } + } } impl RenderElement for CosmicElement { diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index e48e86c4..f820a113 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -66,7 +66,7 @@ pub type GlMultiFrame<'a, 'b, 'frame> = MultiFrame<'a, 'a, 'b, 'frame, GbmGlesBackend, GbmGlesBackend>; pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0]; -pub static FOCUS_INDICATOR_COLOR: [f32; 4] = [0.580, 0.921, 0.921, 1.0]; +pub static FOCUS_INDICATOR_COLOR: [f32; 3] = [0.580, 0.921, 0.921]; pub static FOCUS_INDICATOR_SHADER: &str = include_str!("./shaders/focus_indicator.frag"); pub struct IndicatorShader(pub GlesPixelProgram); @@ -87,6 +87,7 @@ impl IndicatorShader { renderer: &R, geo: Rectangle, thickness: u8, + alpha: f32, ) -> PixelShaderElement { let thickness: f32 = thickness as f32; let thickness_loc = (thickness as i32, thickness as i32); @@ -110,15 +111,14 @@ impl IndicatorShader { } None => { let shader = Self::get(renderer); - let color = FOCUS_INDICATOR_COLOR; let elem = PixelShaderElement::new( shader, - dbg!(geo), + geo, None, //TODO - color[3], + alpha, vec![ - Uniform::new("color", [color[0], color[1], color[2]]), + Uniform::new("color", FOCUS_INDICATOR_COLOR), Uniform::new("thickness", thickness), Uniform::new("radius", thickness * 2.0), ], @@ -283,6 +283,11 @@ where } } + state + .shell + .space_for_handle_mut(&handle) + .ok_or(OutputNoMode)? + .update_animations(&state.event_loop_handle); let workspace = state.shell.space_for_handle(&handle).ok_or(OutputNoMode)?; let last_active_seat = state.last_active_seat().clone(); let move_active = last_active_seat diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 3bec32f6..d9ad3bb7 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -95,7 +95,7 @@ impl WinitState { .unwrap_or_default(), 0, wp_presentation_feedback::Kind::Vsync, - ) + ); } } Err(err) => { diff --git a/src/main.rs b/src/main.rs index 5e61523a..7810ebab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -66,6 +66,10 @@ fn main() -> Result<()> { } // trigger routines + data.state + .common + .shell + .update_animations(&data.state.common.event_loop_handle); data.state.common.shell.refresh(); state::Common::refresh_focus(&mut data.state); diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 7bd840a0..9aa7fc29 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -11,7 +11,10 @@ use smithay::{ backend::{ input::KeyState, renderer::{ - element::{AsRenderElements, Element, RenderElement, UnderlyingStorage}, + element::{ + utils::CropRenderElement, AsRenderElements, Element, RenderElement, + UnderlyingStorage, + }, gles::element::PixelShaderElement, glow::GlowRenderer, multigpu::Error as MultiError, @@ -418,15 +421,17 @@ impl CosmicMapped { } } - pub fn configure(&self) { - for window in match &self.element { + pub fn configure(&self) -> Option { + match &self.element { CosmicMappedInternal::Stack(s) => { - Box::new(s.surfaces()) as Box> + let active = s.active(); + for surface in s.surfaces().filter(|s| s != &active) { + surface.send_configure(); + } + active.send_configure() } - CosmicMappedInternal::Window(w) => Box::new(std::iter::once(w.surface())), + CosmicMappedInternal::Window(w) => w.surface().send_configure(), _ => unreachable!(), - } { - window.send_configure(); } } @@ -676,6 +681,8 @@ where { Stack(self::stack::CosmicStackRenderElement), Window(self::window::CosmicWindowRenderElement), + CroppedStack(CropRenderElement>), + CroppedWindow(CropRenderElement>), Indicator(PixelShaderElement), #[cfg(feature = "debug")] Egui(TextureRenderElement), @@ -690,6 +697,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.id(), CosmicMappedRenderElement::Window(elem) => elem.id(), + CosmicMappedRenderElement::CroppedStack(elem) => elem.id(), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.id(), CosmicMappedRenderElement::Indicator(elem) => elem.id(), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.id(), @@ -700,6 +709,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.current_commit(), CosmicMappedRenderElement::Window(elem) => elem.current_commit(), + CosmicMappedRenderElement::CroppedStack(elem) => elem.current_commit(), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.current_commit(), CosmicMappedRenderElement::Indicator(elem) => elem.current_commit(), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.current_commit(), @@ -710,6 +721,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.src(), CosmicMappedRenderElement::Window(elem) => elem.src(), + CosmicMappedRenderElement::CroppedStack(elem) => elem.src(), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.src(), CosmicMappedRenderElement::Indicator(elem) => elem.src(), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.src(), @@ -720,6 +733,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.geometry(scale), CosmicMappedRenderElement::Window(elem) => elem.geometry(scale), + CosmicMappedRenderElement::CroppedStack(elem) => elem.geometry(scale), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.geometry(scale), CosmicMappedRenderElement::Indicator(elem) => elem.geometry(scale), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.geometry(scale), @@ -730,6 +745,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.location(scale), CosmicMappedRenderElement::Window(elem) => elem.location(scale), + CosmicMappedRenderElement::CroppedStack(elem) => elem.location(scale), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.location(scale), CosmicMappedRenderElement::Indicator(elem) => elem.location(scale), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.location(scale), @@ -740,6 +757,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.transform(), CosmicMappedRenderElement::Window(elem) => elem.transform(), + CosmicMappedRenderElement::CroppedStack(elem) => elem.transform(), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.transform(), CosmicMappedRenderElement::Indicator(elem) => elem.transform(), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.transform(), @@ -754,6 +773,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::Window(elem) => elem.damage_since(scale, commit), + CosmicMappedRenderElement::CroppedStack(elem) => elem.damage_since(scale, commit), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::Indicator(elem) => elem.damage_since(scale, commit), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.damage_since(scale, commit), @@ -764,11 +785,25 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::Window(elem) => elem.opaque_regions(scale), + CosmicMappedRenderElement::CroppedStack(elem) => elem.opaque_regions(scale), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::Indicator(elem) => elem.opaque_regions(scale), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.opaque_regions(scale), } } + + fn alpha(&self) -> f32 { + match self { + CosmicMappedRenderElement::Stack(elem) => elem.alpha(), + CosmicMappedRenderElement::Window(elem) => elem.alpha(), + CosmicMappedRenderElement::CroppedStack(elem) => elem.alpha(), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.alpha(), + CosmicMappedRenderElement::Indicator(elem) => elem.alpha(), + #[cfg(feature = "debug")] + CosmicMappedRenderElement::Egui(elem) => elem.alpha(), + } + } } impl RenderElement for CosmicMappedRenderElement { @@ -782,6 +817,8 @@ impl RenderElement for CosmicMappedRenderElement { match self { CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), + CosmicMappedRenderElement::CroppedStack(elem) => elem.draw(frame, src, dst, damage), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Indicator(elem) => { RenderElement::::draw(elem, frame, src, dst, damage) } @@ -796,6 +833,8 @@ impl RenderElement for CosmicMappedRenderElement { match self { CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer), + CosmicMappedRenderElement::CroppedStack(elem) => elem.underlying_storage(renderer), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Indicator(elem) => elem.underlying_storage(renderer), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.underlying_storage(renderer), @@ -816,6 +855,8 @@ impl<'a, 'b> RenderElement> match self { CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), + CosmicMappedRenderElement::CroppedStack(elem) => elem.draw(frame, src, dst, damage), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Indicator(elem) => { RenderElement::::draw(elem, frame.glow_frame_mut(), src, dst, damage) .map_err(|err| MultiError::Render(err)) @@ -836,6 +877,8 @@ impl<'a, 'b> RenderElement> match self { CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer), + CosmicMappedRenderElement::CroppedStack(elem) => elem.underlying_storage(renderer), + CosmicMappedRenderElement::CroppedWindow(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Indicator(elem) => { elem.underlying_storage(renderer.glow_renderer_mut()) } @@ -910,6 +953,7 @@ where renderer: &mut R, location: Point, scale: Scale, + alpha: f32, ) -> Vec { #[cfg(feature = "debug")] let mut elements = if let Some(debug) = self.debug.lock().unwrap().as_mut() { @@ -1080,12 +1124,12 @@ where CosmicMappedInternal::Stack(s) => { elements.extend(AsRenderElements::::render_elements::< CosmicMappedRenderElement, - >(s, renderer, location, scale)) + >(s, renderer, location, scale, alpha)) } CosmicMappedInternal::Window(w) => { elements.extend(AsRenderElements::::render_elements::< CosmicMappedRenderElement, - >(w, renderer, location, scale)) + >(w, renderer, location, scale, alpha)) } _ => {} }; diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 1d7ecb5e..9ecd1b34 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -604,9 +604,10 @@ where renderer: &mut R, mut location: Point, scale: Scale, + alpha: f32, ) -> Vec { let mut elements = AsRenderElements::::render_elements::>( - &self.0, renderer, location, scale, + &self.0, renderer, location, scale, alpha, ); location.y += TAB_HEIGHT; @@ -616,6 +617,7 @@ where renderer, location, scale, + alpha, ); elements })); diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index ac15a12e..d02c4083 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -29,7 +29,7 @@ use smithay::{ wayland_server::protocol::wl_surface::WlSurface, }, space_elements, - utils::{user_data::UserDataMap, Logical, Rectangle, Size}, + utils::{user_data::UserDataMap, Logical, Rectangle, Serial, Size}, wayland::{ compositor::{with_states, SurfaceData}, seat::WaylandFocus, @@ -345,11 +345,44 @@ impl CosmicSurface { }) } - pub fn send_configure(&self) { + pub fn serial_acked(&self, serial: &Serial) -> bool { match self { - CosmicSurface::Wayland(window) => window.toplevel().send_configure(), + CosmicSurface::Wayland(window) => { + with_states(window.toplevel().wl_surface(), |states| { + let attrs = states + .data_map + .get::() + .unwrap() + .lock() + .unwrap(); + attrs + .configure_serial + .as_ref() + .map(|s| s >= serial) + .unwrap_or(false) + }) + } + _ => true, + } + } + + pub fn force_configure(&self) -> Option { + match self { + CosmicSurface::Wayland(window) => Some(window.toplevel().send_configure()), CosmicSurface::X11(surface) => { let _ = surface.configure(None); + None + } + _ => unreachable!(), + } + } + + pub fn send_configure(&self) -> Option { + match self { + CosmicSurface::Wayland(window) => window.toplevel().send_pending_configure(), + CosmicSurface::X11(surface) => { + let _ = surface.configure(None); + None } _ => unreachable!(), } @@ -675,10 +708,15 @@ where renderer: &mut R, location: smithay::utils::Point, scale: smithay::utils::Scale, + alpha: f32, ) -> Vec { match self { - CosmicSurface::Wayland(window) => window.render_elements(renderer, location, scale), - CosmicSurface::X11(surface) => surface.render_elements(renderer, location, scale), + CosmicSurface::Wayland(window) => { + window.render_elements(renderer, location, scale, alpha) + } + CosmicSurface::X11(surface) => { + surface.render_elements(renderer, location, scale, alpha) + } _ => unreachable!(), } } diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 3aca2632..35416758 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -640,6 +640,13 @@ where CosmicWindowRenderElement::Window(w) => w.opaque_regions(scale), } } + + fn alpha(&self) -> f32 { + match self { + CosmicWindowRenderElement::Header(h) => h.alpha(), + CosmicWindowRenderElement::Window(w) => w.alpha(), + } + } } impl RenderElement for CosmicWindowRenderElement { @@ -710,6 +717,7 @@ where renderer: &mut R, location: Point, scale: Scale, + alpha: f32, ) -> Vec { let has_ssd = self.0.with_program(|p| p.has_ssd()); @@ -721,14 +729,18 @@ where let mut elements = self.0.with_program(|p| { AsRenderElements::::render_elements::>( - &p.window, renderer, window_loc, scale, + &p.window, renderer, window_loc, scale, alpha, ) }); if has_ssd { elements.extend(AsRenderElements::::render_elements::< CosmicWindowRenderElement, >( - &self.0, renderer.glow_renderer_mut(), location, scale + &self.0, + renderer.glow_renderer_mut(), + location, + scale, + alpha, )) } diff --git a/src/shell/layout/floating/grabs/moving.rs b/src/shell/layout/floating/grabs/moving.rs index 4623ffd0..24b9ea59 100644 --- a/src/shell/layout/floating/grabs/moving.rs +++ b/src/shell/layout/floating/grabs/moving.rs @@ -68,6 +68,7 @@ impl MoveGrabState { renderer, Rectangle::from_loc_and_size(render_location, self.window.geometry().size), self.indicator_thickness, + 1.0, )) .into(), ); @@ -77,6 +78,7 @@ impl MoveGrabState { renderer, (render_location - self.window.geometry().loc).to_physical_precise_round(scale), scale, + 1.0, )); elements } @@ -266,7 +268,7 @@ impl MoveSurfaceGrab { .active_space_mut(&output) .floating_layer .map_internal(grab_state.window, &output, Some(window_location + offset)); - + let pointer_pos = handle.current_location(); let relative_pos = state.common.shell.map_global_to_space(pointer_pos, &output); Some(window_location + offset + (pointer_pos - relative_pos).to_i32_round()) @@ -282,7 +284,10 @@ impl MoveSurfaceGrab { if let Some(position) = position { handle.motion( state, - Some((PointerFocusTarget::from(self.window.clone()), position - self.window.geometry().loc)), + Some(( + PointerFocusTarget::from(self.window.clone()), + position - self.window.geometry().loc, + )), &MotionEvent { location: handle.current_location(), serial: serial, diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index e878bda0..b5a0ce04 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -374,6 +374,7 @@ impl FloatingLayout { renderer, render_location.to_physical_precise_round(output_scale), output_scale.into(), + 1.0, ); if focused == Some(elem) { if indicator_thickness > 0 { @@ -384,6 +385,7 @@ impl FloatingLayout { elem.geometry().size, ), indicator_thickness, + 1.0, ); elements.insert(0, element.into()); } diff --git a/src/shell/layout/tiling/blocker.rs b/src/shell/layout/tiling/blocker.rs new file mode 100644 index 00000000..73768ced --- /dev/null +++ b/src/shell/layout/tiling/blocker.rs @@ -0,0 +1,65 @@ +use crate::{ + shell::element::CosmicSurface, state::Data, + wayland::handlers::compositor::client_compositor_state, +}; +use calloop::LoopHandle; +use smithay::{ + reexports::wayland_server::{backend::ClientId, Client, Resource}, + utils::Serial, + wayland::{ + compositor::{Blocker, BlockerState}, + seat::WaylandFocus, + }, +}; +use std::{ + collections::HashMap, + time::{Duration, Instant}, +}; + +#[derive(Debug, Clone)] +pub struct TilingBlocker { + pub necessary_acks: Vec<(CosmicSurface, Serial)>, + start: Instant, +} + +impl Blocker for TilingBlocker { + fn state(&self) -> BlockerState { + if self.is_ready() { + BlockerState::Released + } else { + BlockerState::Pending + } + } +} + +impl TilingBlocker { + pub fn new(configures: impl IntoIterator) -> Self { + TilingBlocker { + necessary_acks: configures.into_iter().collect(), + start: Instant::now(), + } + } + + pub fn is_ready(&self) -> bool { + Instant::now().duration_since(self.start) >= Duration::from_millis(200) + || self + .necessary_acks + .iter() + .all(|(surf, serial)| surf.serial_acked(serial)) + } + + pub fn signal_ready(&self, handle: &LoopHandle<'static, Data>) { + let clients = self + .necessary_acks + .iter() + .flat_map(|(surface, _)| surface.wl_surface().and_then(|s| s.client())) + .map(|client| (client.id(), client)) + .collect::>(); + handle.insert_idle(move |data| { + let dh = data.display.handle(); + for client in clients.values() { + client_compositor_state(&client).blocker_cleared(&mut data.state, &dh); + } + }); + } +} diff --git a/src/shell/layout/tiling/grabs.rs b/src/shell/layout/tiling/grabs.rs index d12c0450..46e9cc70 100644 --- a/src/shell/layout/tiling/grabs.rs +++ b/src/shell/layout/tiling/grabs.rs @@ -64,7 +64,8 @@ impl PointerGrab for ResizeForkGrab { if let Some(output) = self.output.upgrade() { let tiling_layer = &mut data.common.shell.active_space_mut(&output).tiling_layer; - if let Some(tree) = tiling_layer.trees.get_mut(&output) { + if let Some(queue) = tiling_layer.queues.get_mut(&output) { + let tree = &mut queue.trees.back_mut().unwrap().0; if tree.get(&self.node).is_ok() { let orientation = tree.get(&self.node).unwrap().data().orientation(); let delta = match orientation { diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 0723078c..a1e3d34d 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -18,24 +18,36 @@ use crate::{ }, }; +use calloop::LoopHandle; +use cosmic_time::{Cubic, Ease, Tween}; use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree}; use smithay::{ backend::renderer::{ - element::{AsRenderElements, RenderElement}, + element::{utils::CropRenderElement, AsRenderElements, RenderElement}, ImportAll, ImportMem, Renderer, }, desktop::{layer_map_for_output, space::SpaceElement, PopupKind}, input::{pointer::GrabStartData as PointerGrabStartData, Seat}, output::Output, utils::{IsAlive, Logical, Point, Rectangle, Scale}, - wayland::seat::WaylandFocus, + wayland::{compositor::add_blocker, seat::WaylandFocus}, +}; +use std::{ + borrow::Borrow, + collections::{HashMap, VecDeque}, + hash::Hash, + sync::Arc, + time::{Duration, Instant}, }; -use std::{borrow::Borrow, collections::HashMap, hash::Hash, sync::Arc}; use tracing::trace; +mod blocker; mod grabs; +pub use self::blocker::*; pub use self::grabs::*; +const ANIMATION_DURATION: Duration = Duration::from_millis(200); + #[derive(Debug, Clone)] struct OutputData { output: Output, @@ -83,10 +95,24 @@ pub enum FocusResult { Some(KeyboardFocusTarget), } +#[derive(Debug, Clone, Default)] +struct TreeQueue { + trees: VecDeque<(Tree, Option)>, + animation_start: Option, +} + +impl TreeQueue { + pub fn push_tree(&mut self, tree: Tree, blocker: Option) { + self.trees.push_back((tree, blocker)) + } +} + #[derive(Debug, Clone)] pub struct TilingLayout { gaps: (i32, i32), - trees: HashMap>, + queues: HashMap, + standby_tree: Option>, + pending_blockers: Vec, } #[derive(Debug, Clone)] @@ -251,24 +277,33 @@ impl TilingLayout { pub fn new(gaps: (u8, u8)) -> TilingLayout { TilingLayout { gaps: (gaps.0 as i32, gaps.1 as i32), - trees: HashMap::new(), + queues: HashMap::new(), + standby_tree: None, + pending_blockers: Vec::new(), } } } impl TilingLayout { pub fn map_output(&mut self, output: &Output, location: Point) { - if !self.trees.contains_key(output) { - self.trees.insert( + if !self.queues.contains_key(output) { + self.queues.insert( OutputData { output: output.clone(), location, }, - Tree::new(), + TreeQueue { + trees: { + let mut queue = VecDeque::new(); + queue.push_back((self.standby_tree.take().unwrap_or_else(Tree::new), None)); + queue + }, + animation_start: None, + }, ); } else { - let tree = self.trees.remove(output).unwrap(); - self.trees.insert( + let tree = self.queues.remove(output).unwrap(); + self.queues.insert( OutputData { output: output.clone(), location, @@ -283,9 +318,19 @@ impl TilingLayout { output: &Output, toplevel_info: &mut ToplevelInfoState, ) { - if let Some(src) = self.trees.remove(output) { - // TODO: expects last remaining output - let Some((new_output, dst)) = self.trees.iter_mut().next() else { return; }; + if let Some(mut src) = self.queues.remove(output) { + // Operate on last pending tree & unblock queue + for blocker in src.trees.iter_mut().flat_map(|(_, blocker)| blocker.take()) { + self.pending_blockers.push(blocker); + } + let (src, _) = src.trees.pop_back().expect("No tree in queue"); + + let Some((new_output, dst_queue)) = self.queues.iter_mut().next() else { + self.standby_tree = Some(src); + return; + }; + + let mut dst = dst_queue.trees.back().unwrap().0.copy_clone(); let orientation = match new_output.output.geometry().size { x if x.w >= x.h => Orientation::Vertical, _ => Orientation::Horizontal, @@ -309,8 +354,10 @@ impl TilingLayout { mapped.output_enter(&new_output.output, mapped.bbox()); } } - TilingLayout::merge_trees(src, dst, orientation); - self.refresh() + TilingLayout::merge_trees(src, &mut dst, orientation); + + let blocker = TilingLayout::update_positions(output, &mut dst, self.gaps); + dst_queue.push_tree(dst, blocker); } } @@ -324,7 +371,6 @@ impl TilingLayout { window.output_enter(&output, window.bbox()); window.set_bounds(output.geometry().size); self.map_internal(window, &output, Some(focus_stack)); - self.refresh(); } fn map_internal<'a>( @@ -333,15 +379,17 @@ impl TilingLayout { output: &Output, focus_stack: Option + 'a>, ) { - let tree = self.trees.get_mut(output).expect("Output not mapped?"); + let queue = self.queues.get_mut(output).expect("Output not mapped?"); + let mut tree = queue.trees.back().unwrap().0.copy_clone(); + let window = window.into(); let new_window = Node::new(Data::Mapped { mapped: window.clone(), last_geometry: Rectangle::from_loc_and_size((0, 0), (100, 100)), }); - let last_active = - focus_stack.and_then(|focus_stack| TilingLayout::last_active_window(tree, focus_stack)); + let last_active = focus_stack + .and_then(|focus_stack| TilingLayout::last_active_window(&mut tree, focus_stack)); let window_id = if let Some((_last_active_window, ref node_id)) = last_active { let orientation = { @@ -353,7 +401,7 @@ impl TilingLayout { } }; let new_id = tree.insert(new_window, InsertBehavior::AsRoot).unwrap(); - TilingLayout::new_group(tree, &node_id, &new_id, orientation).unwrap(); + TilingLayout::new_group(&mut tree, &node_id, &new_id, orientation).unwrap(); new_id } else { // nothing? then we add to the root @@ -367,7 +415,7 @@ impl TilingLayout { } }; let new_id = tree.insert(new_window, InsertBehavior::AsRoot).unwrap(); - TilingLayout::new_group(tree, &root_id, &new_id, orientation).unwrap(); + TilingLayout::new_group(&mut tree, &root_id, &new_id, orientation).unwrap(); new_id } else { tree.insert(new_window, InsertBehavior::AsRoot).unwrap() @@ -375,15 +423,23 @@ impl TilingLayout { }; *window.tiling_node_id.lock().unwrap() = Some(window_id); + + let blocker = TilingLayout::update_positions(output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); } pub fn unmap(&mut self, window: &CosmicMapped) -> Option { let output = { let node_id = window.tiling_node_id.lock().unwrap().clone()?; - self.trees + self.queues .iter() - .find(|(_, tree)| { - tree.get(&node_id) + .find(|(_, queue)| { + queue + .trees + .back() + .unwrap() + .0 + .get(&node_id) .map(|node| node.data().is_mapped(Some(window))) .unwrap_or(false) }) @@ -391,19 +447,23 @@ impl TilingLayout { }; self.unmap_window_internal(window); + window.output_leave(&output); window.set_tiled(false); - self.refresh(); Some(output) } fn unmap_window_internal(&mut self, mapped: &CosmicMapped) { - if let Some(node_id) = mapped.tiling_node_id.lock().unwrap().as_ref() { - if let Some(tree) = self.trees.values_mut().find(|tree| { - tree.get(node_id) + let tiling_node_id = mapped.tiling_node_id.lock().unwrap().as_ref().cloned(); + if let Some(node_id) = tiling_node_id { + if let Some((output, queue)) = self.queues.iter_mut().find(|(_, queue)| { + let tree = &queue.trees.back().unwrap().0; + tree.get(&node_id) .map(|node| node.data().is_mapped(Some(mapped))) .unwrap_or(false) }) { + let mut tree = queue.trees.back().unwrap().0.copy_clone(); + let parent_id = tree .get(&node_id) .ok() @@ -412,7 +472,7 @@ impl TilingLayout { let position = parent_id.as_ref().and_then(|parent_id| { tree.children_ids(&parent_id) .unwrap() - .position(|id| id == node_id) + .position(|id| id == &node_id) }); let parent_parent_id = parent_id.as_ref().and_then(|parent_id| { tree.get(parent_id) @@ -423,7 +483,7 @@ impl TilingLayout { // remove self trace!(?mapped, "Remove window."); - let _ = tree.remove_node(node_id.clone(), RemoveBehavior::DropChildren); + let _ = tree.remove_node(node_id, RemoveBehavior::DropChildren); // fixup parent node match parent_id { @@ -457,6 +517,9 @@ impl TilingLayout { } None => {} // root } + + let blocker = TilingLayout::update_positions(&output.output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); } } } @@ -465,11 +528,12 @@ impl TilingLayout { self.mapped().find_map(|(o, m, _)| (m == elem).then_some(o)) } + // TODO: Move would needs this to be accurate during animations pub fn element_geometry(&self, elem: &CosmicMapped) -> Option> { if let Some(id) = elem.tiling_node_id.lock().unwrap().as_ref() { if let Some(output) = self.output_for_element(elem) { - let (output_data, tree) = self.trees.get_key_value(output).unwrap(); - let node = tree.get(id).ok()?; + let (output_data, queue) = self.queues.get_key_value(output).unwrap(); + let node = queue.trees.back().unwrap().0.get(id).ok()?; let data = node.data(); assert!(data.is_mapped(Some(elem))); let mut geo = *data.geometry(); @@ -486,9 +550,10 @@ impl TilingLayout { seat: &Seat, ) -> Option { let output = seat.active_output(); - let tree = self.trees.get_mut(&output).unwrap(); + let queue = self.queues.get_mut(&output).unwrap(); + let mut tree = queue.trees.back().unwrap().0.copy_clone(); - let node_id = match TilingLayout::currently_focused_node(tree, seat) { + let node_id = match TilingLayout::currently_focused_node(&mut tree, seat) { Some(node_id) => node_id, None => { return None; @@ -533,7 +598,7 @@ impl TilingLayout { | (Orientation::Vertical, Direction::Down) ) { TilingLayout::new_group( - tree, + &mut tree, &parent, &node_id, match direction { @@ -556,7 +621,9 @@ impl TilingLayout { .unwrap() .data_mut() .remove_window(og_idx); - self.refresh(); + + let blocker = TilingLayout::update_positions(&output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); return None; } @@ -580,7 +647,9 @@ impl TilingLayout { .unwrap() .data_mut() .remove_window(og_idx); - self.refresh(); + + let blocker = TilingLayout::update_positions(&output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); return None; } @@ -646,7 +715,7 @@ impl TilingLayout { .unwrap() .clone(); TilingLayout::new_group( - tree, + &mut tree, &old_id, &node_id, !group_orientation, @@ -678,7 +747,8 @@ impl TilingLayout { .swap_windows(idx, next_idx); } else { // else we make a new fork - TilingLayout::new_group(tree, &next_child_id, &node_id, orientation).unwrap(); + TilingLayout::new_group(&mut tree, &next_child_id, &node_id, orientation) + .unwrap(); tree.make_nth_sibling( &node_id, if direction == Direction::Left || direction == Direction::Up { @@ -693,7 +763,9 @@ impl TilingLayout { .data_mut() .remove_window(og_idx); } - self.refresh(); + + let blocker = TilingLayout::update_positions(&output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); return None; } @@ -715,7 +787,7 @@ impl TilingLayout { focus_stack: impl Iterator + 'a, ) -> FocusResult { let output = seat.active_output(); - let tree = self.trees.get_mut(&output).unwrap(); + let tree = &self.queues.get(&output).unwrap().trees.back().unwrap().0; // TODO: Rather use something like seat.current_keyboard_focus // TODO https://github.com/Smithay/smithay/pull/777 @@ -860,8 +932,10 @@ impl TilingLayout { focus_stack: impl Iterator + 'a, ) { let output = seat.active_output(); - let tree = self.trees.get_mut(&output).unwrap(); - if let Some((_, last_active)) = TilingLayout::last_active_window(tree, focus_stack) { + let Some(queue) = self.queues.get_mut(&output) else { return }; + let mut tree = queue.trees.back().unwrap().0.copy_clone(); + + if let Some((_, last_active)) = TilingLayout::last_active_window(&tree, focus_stack) { if let Some(group) = tree.get(&last_active).unwrap().parent().cloned() { if let &mut Data::Group { ref mut orientation, @@ -890,13 +964,15 @@ impl TilingLayout { } *orientation = new_orientation; + + let blocker = TilingLayout::update_positions(&output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); } } } - self.refresh(); } - pub fn refresh<'a>(&mut self) { + pub fn refresh(&mut self) { #[cfg(feature = "debug")] puffin::profile_function!(); @@ -908,53 +984,47 @@ impl TilingLayout { for dead_window in dead_windows.iter() { self.unmap_window_internal(&dead_window); } - // flatten trees - for tree in self.trees.values_mut() { - let root_id = match tree.root_node_id() { - Some(root) => root, - None => { + + for (_, mapped, _) in self.mapped() { + mapped.refresh(); + } + } + + pub fn animations_going(&self) -> bool { + self.queues + .values() + .any(|queue| queue.animation_start.is_some()) + } + + pub fn update_animation_state(&mut self, handle: &LoopHandle<'static, crate::state::Data>) { + for blocker in self.pending_blockers.drain(..) { + blocker.signal_ready(handle); + } + for queue in self.queues.values_mut() { + if let Some(start) = queue.animation_start { + let duration_since_start = Instant::now().duration_since(start); + if duration_since_start > ANIMATION_DURATION { + assert!(queue.trees.len() >= 2); + let _ = queue.animation_start.take(); + let _ = queue.trees.pop_front(); + let _ = queue.trees.front_mut().unwrap().1.take(); + } else { continue; } - }; - for node_id in tree - .traverse_pre_order_ids(root_id) - .unwrap() - .collect::>() - .into_iter() - { - let node = tree.get(&node_id).unwrap(); - let data = node.data(); - if data.is_group() && data.len() == 1 { - // RemoveBehavior::LiftChildren sadly does not what we want: lifting them into the same place. - // So we need to fix that manually.. - let child_id = tree - .children_ids(&node_id) - .unwrap() - .cloned() - .next() - .unwrap(); - let idx = node.parent().map(|parent_id| { - tree.children_ids(&parent_id) - .unwrap() - .position(|id| id == &node_id) - .unwrap() - }); - tree.remove_node(node_id, RemoveBehavior::LiftChildren) - .unwrap(); - if let Some(idx) = idx { - tree.make_nth_sibling(&child_id, idx).unwrap(); - } else { - // additionally `RemoveBehavior::LiftChildren` doesn't work, when removing the root-node, - // even with just one child. *sigh* - tree.move_node(&child_id, MoveBehavior::ToRoot).unwrap(); + } + if let Some((_, blocker)) = queue.trees.get(1) { + if blocker + .as_ref() + .map(TilingBlocker::is_ready) + .unwrap_or(true) + { + queue.animation_start = Some(Instant::now()); + if let Some(blocker) = blocker.as_ref() { + blocker.signal_ready(handle) } } } } - for (_, mapped, _) in self.mapped() { - mapped.refresh(); - } - TilingLayout::update_space_positions(&mut self.trees, self.gaps); } pub fn resize_request( @@ -964,7 +1034,8 @@ impl TilingLayout { start_data: PointerGrabStartData, edges: ResizeEdge, ) -> Option { - let (output, mut node_id) = self.trees.iter().find_map(|(output, tree)| { + let (output, mut node_id) = self.queues.iter().find_map(|(output, queue)| { + let tree = &queue.trees.back().unwrap().0; let root_id = tree.root_node_id()?; tree.traverse_pre_order_ids(root_id) .unwrap() @@ -972,7 +1043,8 @@ impl TilingLayout { .map(|id| (&output.output, id)) })?; - let tree = self.trees.get(output).unwrap(); + let queue = self.queues.get(output).unwrap(); + let tree = &queue.trees.back().unwrap().0; while let Some(group_id) = tree.get(&node_id).unwrap().parent() { let orientation = tree.get(group_id).unwrap().data().orientation(); if !((orientation == Orientation::Vertical @@ -1010,7 +1082,7 @@ impl TilingLayout { } fn last_active_window<'a>( - tree: &mut Tree, + tree: &Tree, mut focus_stack: impl Iterator, ) -> Option<(CosmicMapped, NodeId)> { focus_stack @@ -1110,87 +1182,135 @@ impl TilingLayout { Ok(group_id) } - fn update_space_positions(trees: &mut HashMap>, gaps: (i32, i32)) { + fn update_positions( + output: &Output, + tree: &mut Tree, + gaps: (i32, i32), + ) -> Option { #[cfg(feature = "debug")] puffin::profile_function!(); - let (outer, inner) = gaps; - for (output, tree) in trees - .iter_mut() - .map(|(output_data, tree)| (&output_data.output, tree)) - { - if let Some(root) = tree.root_node_id() { - let mut geo = layer_map_for_output(&output).non_exclusive_zone(); - geo.loc.x += outer; - geo.loc.y += outer; - geo.size.w -= outer * 2; - geo.size.h -= outer * 2; - let mut stack = vec![geo]; - - for node_id in tree - .traverse_pre_order_ids(root) - .unwrap() - .collect::>() - .into_iter() - { + if let Some(root_id) = tree.root_node_id() { + let mut configures = Vec::new(); + + let (outer, inner) = gaps; + let mut geo = layer_map_for_output(&output).non_exclusive_zone(); + geo.loc.x += outer; + geo.loc.y += outer; + geo.size.w -= outer * 2; + geo.size.h -= outer * 2; + let mut stack = vec![geo]; + + for node_id in tree + .traverse_pre_order_ids(root_id) + .unwrap() + .collect::>() + .into_iter() + { + let node = tree.get_mut(&node_id).unwrap(); + let data = node.data_mut(); + + // flatten tree + if data.is_group() && data.len() == 1 { + // RemoveBehavior::LiftChildren sadly does not what we want: lifting them into the same place. + // So we need to fix that manually.. + let idx = node.parent().cloned().map(|parent_id| { + tree.children_ids(&parent_id) + .unwrap() + .position(|id| id == &node_id) + .unwrap() + }); + let child_id = tree + .children_ids(&node_id) + .unwrap() + .cloned() + .next() + .unwrap(); + tree.remove_node(node_id, RemoveBehavior::LiftChildren) + .unwrap(); + if let Some(idx) = idx { + tree.make_nth_sibling(&child_id, idx).unwrap(); + } else { + // additionally `RemoveBehavior::LiftChildren` doesn't work, when removing the root-node, + // even with just one child. *sigh* + tree.move_node(&child_id, MoveBehavior::ToRoot).unwrap(); + } + + continue; + } + + if let Some(mut geo) = stack.pop() { let node = tree.get_mut(&node_id).unwrap(); - if let Some(mut geo) = stack.pop() { - let data = node.data_mut(); - match data { - Data::Group { - orientation, sizes, .. - } => { - match orientation { - Orientation::Horizontal => { - let mut previous: i32 = sizes.iter().sum(); - for size in sizes.iter().rev() { - previous -= *size; - stack.push(Rectangle::from_loc_and_size( - (geo.loc.x, geo.loc.y + previous), - (geo.size.w, *size), - )); - } - } - Orientation::Vertical => { - let mut previous: i32 = sizes.iter().sum(); - for size in sizes.iter().rev() { - previous -= *size; - stack.push(Rectangle::from_loc_and_size( - (geo.loc.x + previous, geo.loc.y), - (*size, geo.size.h), - )); - } - } + let data = node.data_mut(); + if data.is_mapped(None) { + geo.loc += (inner, inner).into(); + geo.size -= (inner * 2, inner * 2).into(); + } + data.update_geometry(geo); + + match data { + Data::Group { + orientation, sizes, .. + } => match orientation { + Orientation::Horizontal => { + let mut previous: i32 = sizes.iter().sum(); + for size in sizes.iter().rev() { + previous -= *size; + stack.push(Rectangle::from_loc_and_size( + (geo.loc.x, geo.loc.y + previous), + (geo.size.w, *size), + )); } - data.update_geometry(geo); } - Data::Mapped { mapped, .. } => { - geo.loc += (inner, inner).into(); - if !(mapped.is_fullscreen() || mapped.is_maximized()) { - mapped.set_tiled(true); - let size = (geo.size.w - inner * 2, geo.size.h - inner * 2); - let internal_geometry = Rectangle::from_loc_and_size( - geo.loc + output.geometry().loc, - size, - ); - if mapped.geometry() != internal_geometry { - mapped.set_geometry(internal_geometry); - mapped.configure(); + Orientation::Vertical => { + let mut previous: i32 = sizes.iter().sum(); + for size in sizes.iter().rev() { + previous -= *size; + stack.push(Rectangle::from_loc_and_size( + (geo.loc.x + previous, geo.loc.y), + (*size, geo.size.h), + )); + } + } + }, + Data::Mapped { mapped, .. } => { + if !(mapped.is_fullscreen() || mapped.is_maximized()) { + mapped.set_tiled(true); + let internal_geometry = Rectangle::from_loc_and_size( + geo.loc + output.geometry().loc, + geo.size, + ); + if mapped.geometry() != internal_geometry { + mapped.set_geometry(internal_geometry); + if let Some(serial) = mapped.configure() { + configures.push((mapped.active_window(), serial)); } } - data.update_geometry(geo); } } } } } + + if !configures.is_empty() { + let blocker = TilingBlocker::new(configures); + for (surface, _) in &blocker.necessary_acks { + if let Some(surface) = surface.wl_surface() { + add_blocker(&surface, blocker.clone()); + } + } + return Some(blocker); + } } + + None } pub fn mapped(&self) -> impl Iterator)> { - self.trees + self.queues .iter() - .flat_map(|(output_data, tree)| { + .flat_map(|(output_data, queue)| { + let tree = &queue.trees.back().unwrap().0; if let Some(root) = tree.root_node_id() { Some( tree.traverse_pre_order(root) @@ -1252,15 +1372,20 @@ impl TilingLayout { } pub fn merge(&mut self, other: TilingLayout) { - for (output_data, src) in other.trees { - let mut dst = self.trees.entry(output_data.clone()).or_default(); + for (output_data, mut src_queue) in other.queues { + let src = src_queue.trees.pop_back().unwrap().0; + let dst_queue = self.queues.entry(output_data.clone()).or_default(); + let mut dst = dst_queue.trees.back().unwrap().0.copy_clone(); + let orientation = match output_data.output.geometry().size { x if x.w >= x.h => Orientation::Vertical, _ => Orientation::Horizontal, }; TilingLayout::merge_trees(src, &mut dst, orientation); + + let blocker = TilingLayout::update_positions(&output_data.output, &mut dst, self.gaps); + dst_queue.push_tree(dst, blocker); } - self.refresh(); } fn merge_trees(src: Tree, dst: &mut Tree, orientation: Orientation) { @@ -1320,25 +1445,124 @@ impl TilingLayout { let output_scale = output.current_scale().fractional_scale(); - if !self.trees.contains_key(output) { + if !self.queues.contains_key(output) { return Err(OutputNotMapped); } - Ok(self - .trees - .iter() - .flat_map(|(output_data, tree)| { - if &output_data.output != output { - return None; - } + let queue = self.queues.get(output).unwrap(); + let (target_tree, _) = if queue.animation_start.is_some() { + queue + .trees + .get(1) + .expect("Animation ongoing, should have two trees") + } else { + queue.trees.front().unwrap() + }; + let reference_tree = queue + .animation_start + .is_some() + .then(|| &queue.trees.front().unwrap().0); + + let percentage = if let Some(animation_start) = queue.animation_start { + let percentage = Instant::now().duration_since(animation_start).as_millis() as f32 + / ANIMATION_DURATION.as_millis() as f32; + Ease::Cubic(Cubic::Out).tween(percentage) + } else { + 1.0 + }; - if let Some(root) = tree.root_node_id() { - Some( - tree.traverse_pre_order(root) + let mut elements = Vec::new(); + + // all old windows and fade them out + if let Some(reference_tree) = reference_tree.as_ref() { + if let Some(root) = reference_tree.root_node_id() { + elements.extend( + reference_tree + .traverse_pre_order(root) + .unwrap() + .filter(|node| node.data().is_mapped(None)) + .map(|node| match node.data() { + Data::Mapped { + mapped, + last_geometry, + .. + } => (mapped, last_geometry), + _ => unreachable!(), + }) + .filter(|(mapped, _)| { + if let Some(root) = target_tree.root_node_id() { + !target_tree + .traverse_pre_order(root) + .unwrap() + .any(|node| node.data().is_mapped(Some(mapped))) + } else { + true + } + }) + .flat_map(|(mapped, geo)| { + let crop_rect = geo.clone(); + AsRenderElements::::render_elements::>( + mapped, + renderer, + geo.loc.to_physical_precise_round(output_scale) + - mapped + .geometry() + .loc + .to_physical_precise_round(output_scale), + Scale::from(output_scale), + 1.0 - percentage, + ) + .into_iter() + .flat_map(|element| match element { + CosmicMappedRenderElement::Stack(elem) => { + CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + ) + .map(CosmicMappedRenderElement::CroppedStack) + } + CosmicMappedRenderElement::Window(elem) => { + CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + ) + .map(CosmicMappedRenderElement::CroppedWindow) + } + x => Some(x), + }) + .collect::>() + }), + ) + } + } + + if let Some(root) = target_tree.root_node_id() { + elements.extend( + target_tree + .traverse_pre_order(root) + .unwrap() + .filter(|node| node.data().is_mapped(None)) + .filter(|node| match node.data() { + Data::Mapped { mapped, .. } => mapped.is_activated(), + _ => unreachable!(), + }) + .map(|node| match node.data() { + Data::Mapped { + mapped, + last_geometry, + .. + } => (mapped, last_geometry), + _ => unreachable!(), + }) + .chain( + target_tree + .traverse_pre_order(root) .unwrap() .filter(|node| node.data().is_mapped(None)) .filter(|node| match node.data() { - Data::Mapped { mapped, .. } => mapped.is_activated(), + Data::Mapped { mapped, .. } => !mapped.is_activated(), _ => unreachable!(), }) .map(|node| match node.data() { @@ -1346,56 +1570,116 @@ impl TilingLayout { mapped, last_geometry, .. - } => (mapped, last_geometry.loc), + } => (mapped, last_geometry), _ => unreachable!(), - }) - .chain( - tree.traverse_pre_order(root) + }), + ) + .flat_map(|(mapped, new_geo)| { + let old_geo = if let Some(reference_tree) = reference_tree.as_ref() { + if let Some(root) = reference_tree.root_node_id() { + reference_tree + .traverse_pre_order(root) .unwrap() - .filter(|node| node.data().is_mapped(None)) - .filter(|node| match node.data() { - Data::Mapped { mapped, .. } => !mapped.is_activated(), - _ => unreachable!(), - }) + .find(|node| node.data().is_mapped(Some(mapped))) .map(|node| match node.data() { - Data::Mapped { - mapped, - last_geometry, - .. - } => (mapped, last_geometry.loc), + Data::Mapped { last_geometry, .. } => last_geometry, _ => unreachable!(), - }), - ), - ) - } else { - None - } - }) - .flatten() - .flat_map(|(mapped, loc)| { - let mut elements = - AsRenderElements::::render_elements::>( - mapped, - renderer, - loc.to_physical_precise_round(output_scale) - - mapped - .geometry() - .loc - .to_physical_precise_round(output_scale), - Scale::from(output_scale), - ); - if focused == Some(mapped) { - if indicator_thickness > 0 { - let element = IndicatorShader::element( - renderer, - Rectangle::from_loc_and_size(loc, mapped.geometry().size), - indicator_thickness, - ); - elements.insert(0, element.into()); - } - } - elements - }) - .collect::>()) + }) + } else { + None + } + } else { + None + }; + + let (geo, alpha) = if let Some(old_geo) = old_geo { + ( + Rectangle::from_loc_and_size( + ( + old_geo.loc.x + + ((new_geo.loc.x - old_geo.loc.x) as f32 * percentage) + .round() + as i32, + old_geo.loc.y + + ((new_geo.loc.y - old_geo.loc.y) as f32 * percentage) + .round() + as i32, + ), + ( + old_geo.size.w + + ((new_geo.size.w - old_geo.size.w) as f32 + * percentage) + .round() + as i32, + old_geo.size.h + + ((new_geo.size.h - old_geo.size.h) as f32 + * percentage) + .round() + as i32, + ), + ), + 1.0, + ) + } else { + // TODO: If old_geo.is_none() animate alpha - fade in + (*new_geo, percentage) + }; + + if alpha < 1.0 { + dbg!(alpha); + } + + let crop_rect = geo.clone(); + let mut elements = + AsRenderElements::::render_elements::>( + mapped, + renderer, + geo.loc.to_physical_precise_round(output_scale) + - mapped + .geometry() + .loc + .to_physical_precise_round(output_scale), + Scale::from(output_scale), + alpha, + ) + .into_iter() + .flat_map(|element| match element { + CosmicMappedRenderElement::Stack(elem) => { + CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + ) + .map(CosmicMappedRenderElement::CroppedStack) + } + CosmicMappedRenderElement::Window(elem) => { + CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + ) + .map(CosmicMappedRenderElement::CroppedWindow) + } + x => Some(x), + }) + .collect::>(); + + if focused == Some(mapped) { + if indicator_thickness > 0 { + let element = IndicatorShader::element( + renderer, + geo, + indicator_thickness, + 1.0, + ); + elements.insert(0, element.into()); + } + } + elements + }), + ) + } + + Ok(elements) } } diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 0ff4b8e6..47f11785 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1,3 +1,4 @@ +use calloop::LoopHandle; use serde::{Deserialize, Serialize}; use std::{cell::RefCell, collections::HashMap}; use tracing::warn; @@ -1036,6 +1037,18 @@ impl Shell { } } + pub fn animations_going(&self) -> bool { + self.workspaces + .spaces() + .any(|workspace| workspace.animations_going()) + } + + pub fn update_animations(&mut self, handle: &LoopHandle<'static, crate::state::Data>) { + for workspace in self.workspaces.spaces_mut() { + workspace.update_animations(handle) + } + } + pub fn refresh(&mut self) { #[cfg(feature = "debug")] puffin::profile_function!(); diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index d48d38ec..1ae1239f 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -17,6 +17,7 @@ use crate::{ xwayland::XWaylandState, }; +use calloop::LoopHandle; use indexmap::IndexSet; use smithay::{ backend::renderer::{ @@ -85,6 +86,14 @@ impl Workspace { self.tiling_layer.refresh(); } + pub fn animations_going(&self) -> bool { + self.tiling_layer.animations_going() + } + + pub fn update_animations(&mut self, handle: &LoopHandle<'static, crate::state::Data>) { + self.tiling_layer.update_animation_state(handle) + } + pub fn commit(&mut self, surface: &WlSurface) { if let Some(mapped) = self.element_for_wl_surface(surface) { mapped @@ -484,6 +493,7 @@ impl Workspace { renderer, loc.to_physical_precise_round(output_scale), Scale::from(output_scale), + 1.0, ) }), ); @@ -499,6 +509,7 @@ impl Workspace { (or.geometry().loc - output.geometry().loc) .to_physical_precise_round(output_scale), Scale::from(output_scale), + 1.0, ) }), ); @@ -507,7 +518,11 @@ impl Workspace { render_elements.extend(AsRenderElements::::render_elements::< WorkspaceRenderElement, >( - fullscreen, renderer, (0, 0).into(), output_scale.into() + fullscreen, + renderer, + (0, 0).into(), + output_scale.into(), + 1.0, )); if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) { @@ -551,6 +566,7 @@ impl Workspace { renderer, loc.to_physical_precise_round(output_scale), Scale::from(output_scale), + 1.0, ) }), ); @@ -570,6 +586,7 @@ impl Workspace { (or.geometry().loc - output.geometry().loc) .to_physical_precise_round(output_scale), Scale::from(output_scale), + 1.0, ) }), ); @@ -620,6 +637,7 @@ impl Workspace { renderer, loc.to_physical_precise_round(output_scale), Scale::from(output_scale), + 1.0, ) }), ); @@ -715,6 +733,13 @@ where WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale), } } + + fn alpha(&self) -> f32 { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.alpha(), + WorkspaceRenderElement::Window(elem) => elem.alpha(), + } + } } impl RenderElement for WorkspaceRenderElement diff --git a/src/state.rs b/src/state.rs index 3597e341..39772323 100644 --- a/src/state.rs +++ b/src/state.rs @@ -50,7 +50,7 @@ use smithay::{ }, utils::{Clock, IsAlive, Monotonic}, wayland::{ - compositor::CompositorState, + compositor::{CompositorClientState, CompositorState}, data_device::DataDeviceState, dmabuf::{DmabufFeedback, DmabufState}, keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitState, @@ -69,6 +69,7 @@ use std::{cell::RefCell, ffi::OsString, time::Duration}; use std::{collections::VecDeque, time::Instant}; pub struct ClientState { + pub compositor_client_state: CompositorClientState, pub workspace_client_state: WorkspaceClientState, pub drm_node: Option, pub privileged: bool, @@ -312,6 +313,7 @@ impl State { pub fn new_client_state(&self) -> ClientState { ClientState { + compositor_client_state: CompositorClientState::default(), workspace_client_state: WorkspaceClientState::default(), drm_node: match &self.backend { BackendData::Kms(kms_state) => { @@ -334,6 +336,7 @@ impl State { pub fn new_client_state_with_node(&self, drm_node: DrmNode) -> ClientState { ClientState { + compositor_client_state: CompositorClientState::default(), workspace_client_state: WorkspaceClientState::default(), drm_node: Some(drm_node), privileged: false, @@ -342,6 +345,7 @@ impl State { pub fn new_privileged_client_state(&self) -> ClientState { ClientState { + compositor_client_state: CompositorClientState::default(), workspace_client_state: WorkspaceClientState::default(), drm_node: match &self.backend { BackendData::Kms(kms_state) => Some(kms_state.primary), diff --git a/src/utils/iced.rs b/src/utils/iced.rs index 901448fc..b23dc201 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -567,6 +567,7 @@ where renderer: &mut R, location: Point, scale: Scale, + alpha: f32, ) -> Vec { let mut internal = self.0.lock().unwrap(); @@ -633,7 +634,7 @@ where renderer, location.to_f64(), &buffer, - None, + Some(alpha), Some(Rectangle::from_loc_and_size( (0., 0.), size.to_f64().to_logical(1.0, Transform::Normal), diff --git a/src/wayland/handlers/compositor.rs b/src/wayland/handlers/compositor.rs index f5e447fd..37b87b5e 100644 --- a/src/wayland/handlers/compositor.rs +++ b/src/wayland/handlers/compositor.rs @@ -2,17 +2,22 @@ use crate::{ shell::CosmicSurface, - state::{BackendData, Data}, + state::{BackendData, ClientState, Data}, utils::prelude::*, wayland::protocols::screencopy::SessionType, }; +use calloop::Interest; use smithay::{ backend::renderer::utils::{on_commit_buffer_handler, with_renderer_surface_state}, delegate_compositor, desktop::{layer_map_for_output, LayerSurface, PopupKind, WindowSurfaceType}, - reexports::wayland_server::protocol::wl_surface::WlSurface, + reexports::wayland_server::{protocol::wl_surface::WlSurface, Client, Resource}, wayland::{ - compositor::{with_states, CompositorHandler, CompositorState}, + compositor::{ + add_blocker, add_pre_commit_hook, with_states, BufferAssignment, CompositorClientState, + CompositorHandler, CompositorState, SurfaceAttributes, + }, + dmabuf::get_dmabuf, seat::WaylandFocus, shell::{ wlr_layer::LayerSurfaceAttributes, @@ -21,7 +26,7 @@ use smithay::{ }, }, }, - xwayland::X11Wm, + xwayland::{X11Wm, XWaylandClientData}, }; use std::sync::Mutex; @@ -105,15 +110,63 @@ impl State { } } +pub fn client_compositor_state<'a>(client: &'a Client) -> &'a CompositorClientState { + if let Some(state) = client.get_data::() { + return &state.compositor_state; + } + if let Some(state) = client.get_data::() { + return &state.compositor_client_state; + } + panic!("Unknown client data type") +} + impl CompositorHandler for State { fn compositor_state(&mut self) -> &mut CompositorState { &mut self.common.compositor_state } + fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { + client_compositor_state(client) + } + + fn new_surface(&mut self, surface: &WlSurface) { + add_pre_commit_hook::(surface, move |state, _dh, surface| { + let maybe_dmabuf = with_states(surface, |surface_data| { + surface_data + .cached_state + .pending::() + .buffer + .as_ref() + .and_then(|assignment| match assignment { + BufferAssignment::NewBuffer(buffer) => get_dmabuf(buffer).ok(), + _ => None, + }) + }); + if let Some(dmabuf) = maybe_dmabuf { + if let Ok((blocker, source)) = dmabuf.generate_blocker(Interest::READ) { + let client = surface.client().unwrap(); + let res = + state + .common + .event_loop_handle + .insert_source(source, move |_, _, data| { + data.state + .client_compositor_state(&client) + .blocker_cleared(&mut data.state, &data.display.handle()); + Ok(()) + }); + if res.is_ok() { + add_blocker(surface, blocker); + } + } + } + }) + } + fn commit(&mut self, surface: &WlSurface) { X11Wm::commit_hook::(surface); // first load the buffer for various smithay helper functions - on_commit_buffer_handler(surface); + on_commit_buffer_handler::(surface); // then handle initial configure events and map windows if necessary if let Some((window, seat)) = self diff --git a/src/wayland/handlers/screencopy.rs b/src/wayland/handlers/screencopy.rs index 8fffcfea..aebef716 100644 --- a/src/wayland/handlers/screencopy.rs +++ b/src/wayland/handlers/screencopy.rs @@ -947,6 +947,7 @@ pub fn render_window_to_buffer( renderer, (-geometry.loc.x, -geometry.loc.y).into(), Scale::from(1.0), + 1.0, ); for seat in common.seats() { From 02919122a7d36c1df80e7f2bb32847f4814e9b1c Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 15 May 2023 08:06:25 -0600 Subject: [PATCH 002/264] Add cmake to debian/control Build-Depends to fix package compilation --- debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/control b/debian/control index 728f7a24..b8f45584 100644 --- a/debian/control +++ b/debian/control @@ -4,6 +4,7 @@ Priority: optional Maintainer: Victoria Brekenfeld Build-Depends: cargo, + cmake, debhelper-compat (=10), rustc (>=1.57), libudev-dev, From 84b3213146964992e49f74fe27c2be8de396da08 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 15 May 2023 10:53:14 -0600 Subject: [PATCH 003/264] Add libfontconfig-dev to build depends, sort them alphabetically --- debian/control | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/debian/control b/debian/control index b8f45584..4ac55e22 100644 --- a/debian/control +++ b/debian/control @@ -6,16 +6,17 @@ Build-Depends: cargo, cmake, debhelper-compat (=10), - rustc (>=1.57), - libudev-dev, libegl1-mesa-dev, + libfontconfig-dev, libgbm-dev, libinput-dev, + libseat-dev, + libsystemd-dev, + libudev-dev, libwayland-dev, libxcb1-dev, libxkbcommon-dev, - libsystemd-dev, - libseat-dev + rustc (>=1.57), Standards-Version: 4.1.1 Homepage: https://github.com/pop-os/cosmic-comp From 4ea0136a9bcfb8a39070521a759e3dbf0429eaea Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 17 May 2023 19:46:21 +0200 Subject: [PATCH 004/264] tiling: Add code to render group hints --- rust-toolchain.toml | 2 +- src/backend/render/mod.rs | 135 ++-- src/shell/element/mod.rs | 70 +- src/shell/focus/target.rs | 6 +- src/shell/layout/floating/grabs/moving.rs | 4 +- src/shell/layout/floating/mod.rs | 4 +- src/shell/layout/tiling/mod.rs | 754 ++++++++++++++++------ src/shell/workspace.rs | 10 +- 8 files changed, 724 insertions(+), 261 deletions(-) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 70772a38..5937e385 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.65" \ No newline at end of file +channel = "1.66" \ No newline at end of file diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index f820a113..dab84e90 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -3,6 +3,8 @@ use std::{ borrow::{Borrow, BorrowMut}, cell::RefCell, + collections::HashMap, + sync::Weak, }; #[cfg(feature = "debug")] @@ -12,8 +14,8 @@ use crate::{ }; use crate::{ shell::{ - element::window::CosmicWindowRenderElement, layout::floating::SeatMoveGrabState, - CosmicMappedRenderElement, + element::window::CosmicWindowRenderElement, focus::target::WindowGroup, + layout::floating::SeatMoveGrabState, CosmicMapped, CosmicMappedRenderElement, }, state::{Common, Fps}, utils::prelude::SeatExt, @@ -47,7 +49,7 @@ use smithay::{ }, }, output::Output, - utils::{Logical, Physical, Point, Rectangle, Size}, + utils::{IsAlive, Logical, Physical, Point, Rectangle, Size}, wayland::{ dmabuf::get_dmabuf, shm::{shm_format_to_fourcc, with_buffer_contents}, @@ -66,11 +68,54 @@ pub type GlMultiFrame<'a, 'b, 'frame> = MultiFrame<'a, 'a, 'b, 'frame, GbmGlesBackend, GbmGlesBackend>; pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0]; +pub static ACTIVE_GROUP_COLOR: [f32; 3] = [0.678, 0.635, 0.619]; +pub static GROUP_COLOR: [f32; 3] = [0.431, 0.404, 0.396]; pub static FOCUS_INDICATOR_COLOR: [f32; 3] = [0.580, 0.921, 0.921]; pub static FOCUS_INDICATOR_SHADER: &str = include_str!("./shaders/focus_indicator.frag"); pub struct IndicatorShader(pub GlesPixelProgram); -struct IndicatorElement(pub RefCell); + +#[derive(Clone)] +pub enum Key { + Group(Weak<()>), + Window(CosmicMapped), +} +impl std::hash::Hash for Key { + fn hash(&self, state: &mut H) { + match self { + Key::Group(arc) => (arc.as_ptr() as usize).hash(state), + Key::Window(window) => window.hash(state), + } + } +} +impl PartialEq for Key { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Key::Group(g1), Key::Group(g2)) => Weak::ptr_eq(g1, g2), + (Key::Window(w1), Key::Window(w2)) => w1 == w2, + _ => false, + } + } +} +impl Eq for Key {} +impl From for Key { + fn from(window: CosmicMapped) -> Self { + Key::Window(window) + } +} +impl From for Key { + fn from(group: WindowGroup) -> Self { + Key::Group(group.alive.clone()) + } +} + +#[derive(PartialEq)] +struct IndicatorSettings { + thickness: u8, + alpha: f32, + color: [f32; 3], +} +type IndicatorCache = RefCell>; impl IndicatorShader { pub fn get(renderer: &R) -> GlesPixelProgram { @@ -85,50 +130,63 @@ impl IndicatorShader { pub fn element( renderer: &R, + key: impl Into, geo: Rectangle, thickness: u8, alpha: f32, + color: [f32; 3], ) -> PixelShaderElement { - let thickness: f32 = thickness as f32; - let thickness_loc = (thickness as i32, thickness as i32); - let thickness_size = ((thickness * 2.0) as i32, (thickness * 2.0) as i32); - let geo = Rectangle::from_loc_and_size( - geo.loc - Point::from(thickness_loc), - geo.size + Size::from(thickness_size), - ); + let settings = IndicatorSettings { + thickness, + alpha, + color, + }; let user_data = Borrow::::borrow(renderer.glow_renderer()) .egl_context() .user_data(); - match user_data.get::() { - Some(elem) => { - let mut elem = elem.0.borrow_mut(); - if elem.geometry(1.0.into()).to_logical(1) != geo { - elem.resize(geo, None); - } - elem.clone() - } - None => { - let shader = Self::get(renderer); - - let elem = PixelShaderElement::new( - shader, - geo, - None, //TODO - alpha, - vec![ - Uniform::new("color", FOCUS_INDICATOR_COLOR), - Uniform::new("thickness", thickness), - Uniform::new("radius", thickness * 2.0), - ], - ); - if !user_data.insert_if_missing(|| IndicatorElement(RefCell::new(elem.clone()))) { - *user_data.get::().unwrap().0.borrow_mut() = elem.clone(); - } - elem - } + user_data.insert_if_missing(|| IndicatorCache::new(HashMap::new())); + let mut cache = user_data.get::().unwrap().borrow_mut(); + cache.retain(|k, _| match k { + Key::Group(w) => w.upgrade().is_some(), + Key::Window(w) => w.alive(), + }); + + let key = key.into(); + if cache + .get(&key) + .filter(|(old_settings, _)| &settings == old_settings) + .is_none() + { + let thickness: f32 = thickness as f32; + let thickness_loc = (thickness as i32, thickness as i32); + let thickness_size = ((thickness * 2.0) as i32, (thickness * 2.0) as i32); + let geo = Rectangle::from_loc_and_size( + geo.loc - Point::from(thickness_loc), + geo.size + Size::from(thickness_size), + ); + let shader = Self::get(renderer); + + let elem = PixelShaderElement::new( + shader, + geo, + None, //TODO + alpha, + vec![ + Uniform::new("color", color), + Uniform::new("thickness", thickness), + Uniform::new("radius", thickness * 2.0), + ], + ); + cache.insert(key.clone(), (settings, elem)); + } + + let elem = &mut cache.get_mut(&key).unwrap().1; + if elem.geometry(1.0.into()).to_logical(1) != geo { + elem.resize(geo, None); } + elem.clone() } } @@ -307,6 +365,7 @@ where &state.shell.override_redirect_windows, state.xwayland_state.as_mut(), (!move_active && is_active_space).then_some(&last_active_seat), + true, state.config.static_conf.active_hint, exclude_workspace_overview, ) diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 9aa7fc29..818d5a2a 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -12,8 +12,8 @@ use smithay::{ input::KeyState, renderer::{ element::{ - utils::CropRenderElement, AsRenderElements, Element, RenderElement, - UnderlyingStorage, + utils::{CropRenderElement, RelocateRenderElement, RescaleRenderElement}, + AsRenderElements, Element, RenderElement, UnderlyingStorage, }, gles::element::PixelShaderElement, glow::GlowRenderer, @@ -259,7 +259,7 @@ impl CosmicMapped { } pub fn set_tiled(&self, tiled: bool) { - for window in match &self.element { + if let Some(window) = match &self.element { // we use the tiled state of stack windows anyway to get rid of decorations CosmicMappedInternal::Stack(_) => None, CosmicMappedInternal::Window(w) => Some(w.surface()), @@ -681,8 +681,16 @@ where { Stack(self::stack::CosmicStackRenderElement), Window(self::window::CosmicWindowRenderElement), - CroppedStack(CropRenderElement>), - CroppedWindow(CropRenderElement>), + TiledStack( + RelocateRenderElement< + RescaleRenderElement>>, + >, + ), + TiledWindow( + RelocateRenderElement< + RescaleRenderElement>>, + >, + ), Indicator(PixelShaderElement), #[cfg(feature = "debug")] Egui(TextureRenderElement), @@ -697,8 +705,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.id(), CosmicMappedRenderElement::Window(elem) => elem.id(), - CosmicMappedRenderElement::CroppedStack(elem) => elem.id(), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.id(), + CosmicMappedRenderElement::TiledStack(elem) => elem.id(), + CosmicMappedRenderElement::TiledWindow(elem) => elem.id(), CosmicMappedRenderElement::Indicator(elem) => elem.id(), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.id(), @@ -709,8 +717,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.current_commit(), CosmicMappedRenderElement::Window(elem) => elem.current_commit(), - CosmicMappedRenderElement::CroppedStack(elem) => elem.current_commit(), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.current_commit(), + CosmicMappedRenderElement::TiledStack(elem) => elem.current_commit(), + CosmicMappedRenderElement::TiledWindow(elem) => elem.current_commit(), CosmicMappedRenderElement::Indicator(elem) => elem.current_commit(), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.current_commit(), @@ -721,8 +729,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.src(), CosmicMappedRenderElement::Window(elem) => elem.src(), - CosmicMappedRenderElement::CroppedStack(elem) => elem.src(), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.src(), + CosmicMappedRenderElement::TiledStack(elem) => elem.src(), + CosmicMappedRenderElement::TiledWindow(elem) => elem.src(), CosmicMappedRenderElement::Indicator(elem) => elem.src(), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.src(), @@ -733,8 +741,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.geometry(scale), CosmicMappedRenderElement::Window(elem) => elem.geometry(scale), - CosmicMappedRenderElement::CroppedStack(elem) => elem.geometry(scale), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.geometry(scale), + CosmicMappedRenderElement::TiledStack(elem) => elem.geometry(scale), + CosmicMappedRenderElement::TiledWindow(elem) => elem.geometry(scale), CosmicMappedRenderElement::Indicator(elem) => elem.geometry(scale), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.geometry(scale), @@ -745,8 +753,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.location(scale), CosmicMappedRenderElement::Window(elem) => elem.location(scale), - CosmicMappedRenderElement::CroppedStack(elem) => elem.location(scale), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.location(scale), + CosmicMappedRenderElement::TiledStack(elem) => elem.location(scale), + CosmicMappedRenderElement::TiledWindow(elem) => elem.location(scale), CosmicMappedRenderElement::Indicator(elem) => elem.location(scale), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.location(scale), @@ -757,8 +765,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.transform(), CosmicMappedRenderElement::Window(elem) => elem.transform(), - CosmicMappedRenderElement::CroppedStack(elem) => elem.transform(), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.transform(), + CosmicMappedRenderElement::TiledStack(elem) => elem.transform(), + CosmicMappedRenderElement::TiledWindow(elem) => elem.transform(), CosmicMappedRenderElement::Indicator(elem) => elem.transform(), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.transform(), @@ -773,8 +781,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::Window(elem) => elem.damage_since(scale, commit), - CosmicMappedRenderElement::CroppedStack(elem) => elem.damage_since(scale, commit), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.damage_since(scale, commit), + CosmicMappedRenderElement::TiledStack(elem) => elem.damage_since(scale, commit), + CosmicMappedRenderElement::TiledWindow(elem) => elem.damage_since(scale, commit), CosmicMappedRenderElement::Indicator(elem) => elem.damage_since(scale, commit), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.damage_since(scale, commit), @@ -785,8 +793,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::Window(elem) => elem.opaque_regions(scale), - CosmicMappedRenderElement::CroppedStack(elem) => elem.opaque_regions(scale), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.opaque_regions(scale), + CosmicMappedRenderElement::TiledStack(elem) => elem.opaque_regions(scale), + CosmicMappedRenderElement::TiledWindow(elem) => elem.opaque_regions(scale), CosmicMappedRenderElement::Indicator(elem) => elem.opaque_regions(scale), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.opaque_regions(scale), @@ -797,8 +805,8 @@ where match self { CosmicMappedRenderElement::Stack(elem) => elem.alpha(), CosmicMappedRenderElement::Window(elem) => elem.alpha(), - CosmicMappedRenderElement::CroppedStack(elem) => elem.alpha(), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.alpha(), + CosmicMappedRenderElement::TiledStack(elem) => elem.alpha(), + CosmicMappedRenderElement::TiledWindow(elem) => elem.alpha(), CosmicMappedRenderElement::Indicator(elem) => elem.alpha(), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.alpha(), @@ -817,8 +825,8 @@ impl RenderElement for CosmicMappedRenderElement { match self { CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), - CosmicMappedRenderElement::CroppedStack(elem) => elem.draw(frame, src, dst, damage), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.draw(frame, src, dst, damage), + CosmicMappedRenderElement::TiledStack(elem) => elem.draw(frame, src, dst, damage), + CosmicMappedRenderElement::TiledWindow(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Indicator(elem) => { RenderElement::::draw(elem, frame, src, dst, damage) } @@ -833,8 +841,8 @@ impl RenderElement for CosmicMappedRenderElement { match self { CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer), - CosmicMappedRenderElement::CroppedStack(elem) => elem.underlying_storage(renderer), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.underlying_storage(renderer), + CosmicMappedRenderElement::TiledStack(elem) => elem.underlying_storage(renderer), + CosmicMappedRenderElement::TiledWindow(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Indicator(elem) => elem.underlying_storage(renderer), #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => elem.underlying_storage(renderer), @@ -855,8 +863,8 @@ impl<'a, 'b> RenderElement> match self { CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), - CosmicMappedRenderElement::CroppedStack(elem) => elem.draw(frame, src, dst, damage), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.draw(frame, src, dst, damage), + CosmicMappedRenderElement::TiledStack(elem) => elem.draw(frame, src, dst, damage), + CosmicMappedRenderElement::TiledWindow(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Indicator(elem) => { RenderElement::::draw(elem, frame.glow_frame_mut(), src, dst, damage) .map_err(|err| MultiError::Render(err)) @@ -877,8 +885,8 @@ impl<'a, 'b> RenderElement> match self { CosmicMappedRenderElement::Stack(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Window(elem) => elem.underlying_storage(renderer), - CosmicMappedRenderElement::CroppedStack(elem) => elem.underlying_storage(renderer), - CosmicMappedRenderElement::CroppedWindow(elem) => elem.underlying_storage(renderer), + CosmicMappedRenderElement::TiledStack(elem) => elem.underlying_storage(renderer), + CosmicMappedRenderElement::TiledWindow(elem) => elem.underlying_storage(renderer), CosmicMappedRenderElement::Indicator(elem) => { elem.underlying_storage(renderer.glow_renderer_mut()) } diff --git a/src/shell/focus/target.rs b/src/shell/focus/target.rs index 39d6481b..673e9366 100644 --- a/src/shell/focus/target.rs +++ b/src/shell/focus/target.rs @@ -52,9 +52,9 @@ impl From for PointerFocusTarget { #[derive(Debug, Clone)] pub struct WindowGroup { - pub(in crate::shell) node: NodeId, - pub(in crate::shell) output: WeakOutput, - pub(in crate::shell) alive: Weak<()>, + pub node: NodeId, + pub output: WeakOutput, + pub alive: Weak<()>, } impl PartialEq for WindowGroup { diff --git a/src/shell/layout/floating/grabs/moving.rs b/src/shell/layout/floating/grabs/moving.rs index 24b9ea59..3f5587cf 100644 --- a/src/shell/layout/floating/grabs/moving.rs +++ b/src/shell/layout/floating/grabs/moving.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - backend::render::{element::AsGlowRenderer, IndicatorShader}, + backend::render::{element::AsGlowRenderer, IndicatorShader, FOCUS_INDICATOR_COLOR}, shell::{ element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, focus::target::{KeyboardFocusTarget, PointerFocusTarget}, @@ -66,9 +66,11 @@ impl MoveGrabState { elements.push( CosmicMappedRenderElement::from(IndicatorShader::element( renderer, + self.window.clone(), Rectangle::from_loc_and_size(render_location, self.window.geometry().size), self.indicator_thickness, 1.0, + FOCUS_INDICATOR_COLOR, )) .into(), ); diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index b5a0ce04..a82c2041 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -13,7 +13,7 @@ use smithay::{ use std::collections::HashMap; use crate::{ - backend::render::{element::AsGlowRenderer, IndicatorShader}, + backend::render::{element::AsGlowRenderer, IndicatorShader, FOCUS_INDICATOR_COLOR}, shell::{ element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, grabs::ResizeEdge, @@ -380,12 +380,14 @@ impl FloatingLayout { if indicator_thickness > 0 { let element = IndicatorShader::element( renderer, + elem.clone(), Rectangle::from_loc_and_size( self.space.element_location(elem).unwrap() - output_loc, elem.geometry().size, ), indicator_thickness, 1.0, + FOCUS_INDICATOR_COLOR, ); elements.insert(0, element.into()); } diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index a1e3d34d..d0d2d805 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1,7 +1,10 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - backend::render::{element::AsGlowRenderer, IndicatorShader}, + backend::render::{ + element::AsGlowRenderer, IndicatorShader, Key, ACTIVE_GROUP_COLOR, FOCUS_INDICATOR_COLOR, + GROUP_COLOR, + }, shell::{ element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, focus::{ @@ -23,7 +26,10 @@ use cosmic_time::{Cubic, Ease, Tween}; use id_tree::{InsertBehavior, MoveBehavior, Node, NodeId, NodeIdError, RemoveBehavior, Tree}; use smithay::{ backend::renderer::{ - element::{utils::CropRenderElement, AsRenderElements, RenderElement}, + element::{ + utils::{CropRenderElement, Relocate, RelocateRenderElement, RescaleRenderElement}, + AsRenderElements, RenderElement, + }, ImportAll, ImportMem, Renderer, }, desktop::{layer_map_for_output, space::SpaceElement, PopupKind}, @@ -1432,6 +1438,8 @@ impl TilingLayout { renderer: &mut R, output: &Output, focused: Option<&CosmicMapped>, + non_exclusive_zone: Rectangle, + draw_groups: bool, indicator_thickness: u8, ) -> Result>, OutputNotMapped> where @@ -1473,213 +1481,589 @@ impl TilingLayout { let mut elements = Vec::new(); - // all old windows and fade them out - if let Some(reference_tree) = reference_tree.as_ref() { - if let Some(root) = reference_tree.root_node_id() { - elements.extend( - reference_tree - .traverse_pre_order(root) - .unwrap() - .filter(|node| node.data().is_mapped(None)) - .map(|node| match node.data() { - Data::Mapped { - mapped, - last_geometry, - .. - } => (mapped, last_geometry), - _ => unreachable!(), - }) - .filter(|(mapped, _)| { - if let Some(root) = target_tree.root_node_id() { - !target_tree - .traverse_pre_order(root) - .unwrap() - .any(|node| node.data().is_mapped(Some(mapped))) - } else { - true - } - }) - .flat_map(|(mapped, geo)| { - let crop_rect = geo.clone(); - AsRenderElements::::render_elements::>( - mapped, - renderer, - geo.loc.to_physical_precise_round(output_scale) - - mapped - .geometry() - .loc - .to_physical_precise_round(output_scale), - Scale::from(output_scale), - 1.0 - percentage, - ) - .into_iter() - .flat_map(|element| match element { - CosmicMappedRenderElement::Stack(elem) => { - CropRenderElement::from_element( - elem, - output_scale, - crop_rect.to_physical_precise_round(output_scale), - ) - .map(CosmicMappedRenderElement::CroppedStack) - } - CosmicMappedRenderElement::Window(elem) => { - CropRenderElement::from_element( - elem, - output_scale, - crop_rect.to_physical_precise_round(output_scale), - ) - .map(CosmicMappedRenderElement::CroppedWindow) - } - x => Some(x), - }) - .collect::>() - }), + // all gone windows and fade them out + let old_geometries = if let Some(reference_tree) = reference_tree.as_ref() { + let (geometries, _) = if draw_groups { + geometries_for_groupview( + reference_tree, + renderer, + non_exclusive_zone, + focused, // TODO: Would be better to be an old focus, + // but for that we have to associate focus with a tree (and animate focus changes properly) + 1.0 - percentage, ) + } else { + None } + .unzip(); + + // all old windows we want to fade out + elements.extend(render_old_tree( + reference_tree, + target_tree, + renderer, + geometries.clone(), + output_scale, + percentage, + )); + + geometries + } else { + None + }; + + let (geometries, group_elements) = if draw_groups { + geometries_for_groupview( + target_tree, + renderer, + non_exclusive_zone, + focused, + percentage, + ) + } else { + None } + .unzip(); - if let Some(root) = target_tree.root_node_id() { - elements.extend( - target_tree - .traverse_pre_order(root) - .unwrap() - .filter(|node| node.data().is_mapped(None)) - .filter(|node| match node.data() { - Data::Mapped { mapped, .. } => mapped.is_activated(), - _ => unreachable!(), - }) - .map(|node| match node.data() { - Data::Mapped { - mapped, - last_geometry, - .. - } => (mapped, last_geometry), - _ => unreachable!(), - }) - .chain( - target_tree - .traverse_pre_order(root) + // tiling hints + if let Some(group_elements) = group_elements { + elements.extend(group_elements); + } + + // all alive windows + elements.extend(render_new_tree( + target_tree, + reference_tree, + renderer, + geometries, + old_geometries, + focused, + output_scale, + percentage, + if draw_groups { 3 } else { indicator_thickness }, + )); + + Ok(elements) + } +} + +fn geometries_for_groupview( + tree: &Tree, + renderer: &mut R, + non_exclusive_zone: Rectangle, + focused: Option<&CosmicMapped>, + alpha: f32, +) -> Option<( + HashMap>, + Vec>, +)> +where + R: Renderer + ImportAll + ImportMem + AsGlowRenderer, + ::TextureId: 'static, + CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, +{ + // we need to recalculate geometry for all elements, if we are drawing groups + if let Some(root) = tree.root_node_id() { + let mut stack = vec![non_exclusive_zone]; + let mut elements = Vec::new(); + let mut geometries = HashMap::new(); + + const GAP: i32 = 16; + for node_id in tree.traverse_pre_order_ids(root).unwrap() { + if let Some(mut geo) = stack.pop() { + // zoom in windows + geo.loc += (GAP, GAP).into(); + geo.size -= (GAP * 2, GAP * 2).into(); + + let node: &Node = tree.get(&node_id).unwrap(); + let data = node.data(); + + let is_potential_group = if let Some(focused) = focused { + // 1. focused can move into us directly + if let Some(parent) = node.parent() { + let parent_data = tree.get(parent).unwrap().data(); + + let idx = tree + .children_ids(parent) .unwrap() - .filter(|node| node.data().is_mapped(None)) - .filter(|node| match node.data() { - Data::Mapped { mapped, .. } => !mapped.is_activated(), - _ => unreachable!(), + .position(|id| id == &node_id) + .unwrap(); + if let Some((focused_idx, _focused_id)) = tree + .children_ids(parent) + .unwrap() + .enumerate() + .find(|(_, child_id)| { + tree.get(child_id).unwrap().data().is_mapped(Some(focused)) }) - .map(|node| match node.data() { - Data::Mapped { - mapped, - last_geometry, - .. - } => (mapped, last_geometry), - _ => unreachable!(), - }), - ) - .flat_map(|(mapped, new_geo)| { - let old_geo = if let Some(reference_tree) = reference_tree.as_ref() { - if let Some(root) = reference_tree.root_node_id() { - reference_tree - .traverse_pre_order(root) + { + // only direct neighbors + focused_idx.abs_diff(idx) == 1 + // skip neighbors, if this is a group of two windows + && !(parent_data.len() == 2 && data.is_mapped(None)) + // skip groups of two in opposite orientation to indicate move between + && !(parent_data.len() == 2 && if data.is_group() { parent_data.orientation() != data.orientation() } else { false } ) + } else { + false + } + } + // 2. focused can move out into us + else { + tree.children_ids(&node_id) + .unwrap() + .find(|child_id| { + tree.children(child_id) .unwrap() - .find(|node| node.data().is_mapped(Some(mapped))) - .map(|node| match node.data() { - Data::Mapped { last_geometry, .. } => last_geometry, - _ => unreachable!(), - }) - } else { - None - } + .any(|child| child.data().is_mapped(Some(focused))) + }) + .is_some() + } + } else { + false + }; + + match data { + Data::Group { + orientation, + last_geometry, + sizes, + alive, + } => { + let has_active_child = if let Some(focused) = focused { + tree.children(&node_id) + .unwrap() + .any(|child| child.data().is_mapped(Some(focused))) } else { - None + false }; - let (geo, alpha) = if let Some(old_geo) = old_geo { - ( - Rectangle::from_loc_and_size( - ( - old_geo.loc.x - + ((new_geo.loc.x - old_geo.loc.x) as f32 * percentage) - .round() - as i32, - old_geo.loc.y - + ((new_geo.loc.y - old_geo.loc.y) as f32 * percentage) - .round() - as i32, - ), - ( - old_geo.size.w - + ((new_geo.size.w - old_geo.size.w) as f32 - * percentage) - .round() - as i32, - old_geo.size.h - + ((new_geo.size.h - old_geo.size.h) as f32 - * percentage) - .round() - as i32, - ), - ), - 1.0, + if (is_potential_group || has_active_child) && &node_id != root { + elements.push( + IndicatorShader::element( + renderer, + Key::Group(Arc::downgrade(&alive)), + geo, + 3, + alpha, + if has_active_child { + ACTIVE_GROUP_COLOR + } else { + GROUP_COLOR + }, + ) + .into(), ) - } else { - // TODO: If old_geo.is_none() animate alpha - fade in - (*new_geo, percentage) + } + + geometries.insert(node_id.clone(), geo); + + let previous_length = match orientation { + Orientation::Horizontal => last_geometry.size.h, + Orientation::Vertical => last_geometry.size.w, + }; + let new_length = match orientation { + Orientation::Horizontal => geo.size.h, + Orientation::Vertical => geo.size.w, }; - if alpha < 1.0 { - dbg!(alpha); + let mut sizes = sizes + .iter() + .map(|len| { + (((*len as f64) / (previous_length as f64)) * (new_length as f64)) + .round() as i32 + }) + .collect::>(); + let sum: i32 = sizes.iter().sum(); + if sum < new_length { + *sizes.last_mut().unwrap() += new_length - sum; } - let crop_rect = geo.clone(); - let mut elements = - AsRenderElements::::render_elements::>( - mapped, - renderer, - geo.loc.to_physical_precise_round(output_scale) - - mapped - .geometry() - .loc - .to_physical_precise_round(output_scale), - Scale::from(output_scale), - alpha, - ) - .into_iter() - .flat_map(|element| match element { - CosmicMappedRenderElement::Stack(elem) => { + match orientation { + Orientation::Horizontal => { + let mut previous: i32 = sizes.iter().sum(); + for size in sizes.iter().rev() { + previous -= *size; + stack.push(Rectangle::from_loc_and_size( + (geo.loc.x, geo.loc.y + previous), + (geo.size.w, *size), + )); + } + } + Orientation::Vertical => { + let mut previous: i32 = sizes.iter().sum(); + for size in sizes.iter().rev() { + previous -= *size; + stack.push(Rectangle::from_loc_and_size( + (geo.loc.x + previous, geo.loc.y), + (*size, geo.size.h), + )); + } + } + } + } + Data::Mapped { mapped, .. } => { + if is_potential_group { + elements.push( + IndicatorShader::element( + renderer, + mapped.clone(), + geo, + 3, + alpha, + GROUP_COLOR, + ) + .into(), + ); + + geo.loc += (GAP, GAP).into(); + geo.size -= (GAP * 2, GAP * 2).into(); + } + + geometries.insert(node_id.clone(), geo); + } + } + } + } + + Some((geometries, elements)) + } else { + None + } +} + +fn render_old_tree( + reference_tree: &Tree, + target_tree: &Tree, + renderer: &mut R, + geometries: Option>>, + output_scale: f64, + percentage: f32, +) -> Vec> +where + R: Renderer + ImportAll + ImportMem + AsGlowRenderer, + ::TextureId: 'static, + CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, +{ + if let Some(root) = reference_tree.root_node_id() { + let geometries = geometries.unwrap_or_default(); + reference_tree + .traverse_pre_order_ids(root) + .unwrap() + .filter(|node_id| reference_tree.get(node_id).unwrap().data().is_mapped(None)) + .map( + |node_id| match reference_tree.get(&node_id).unwrap().data() { + Data::Mapped { + mapped, + last_geometry, + .. + } => (mapped, last_geometry, geometries.get(&node_id)), + _ => unreachable!(), + }, + ) + .filter(|(mapped, _, _)| { + if let Some(root) = target_tree.root_node_id() { + !target_tree + .traverse_pre_order(root) + .unwrap() + .any(|node| node.data().is_mapped(Some(mapped))) + } else { + true + } + }) + .flat_map(|(mapped, original_geo, scaled_geo)| { + let (scale, offset) = scaled_geo + .map(|adapted_geo| scale_to_center(&original_geo, adapted_geo)) + .unwrap_or_else(|| (1.0.into(), (0, 0).into())); + let geo = scaled_geo + .map(|adapted_geo| { + Rectangle::from_loc_and_size( + adapted_geo.loc + offset, + ( + (original_geo.size.w as f64 * scale).round() as i32, + (original_geo.size.h as f64 * scale).round() as i32, + ), + ) + }) + .unwrap_or(*original_geo); + + let crop_rect = geo.clone(); + let original_location = original_geo.loc.to_physical_precise_round(output_scale) + - mapped + .geometry() + .loc + .to_physical_precise_round(output_scale); + AsRenderElements::::render_elements::>( + mapped, + renderer, + original_location, + Scale::from(output_scale), + 1.0 - percentage, + ) + .into_iter() + .flat_map(|element| match element { + CosmicMappedRenderElement::Stack(elem) => Some( + CosmicMappedRenderElement::TiledStack(RelocateRenderElement::from_element( + RescaleRenderElement::from_element( + CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + )?, + original_location, + scale, + ), + geo.loc.to_physical_precise_round(output_scale), + Relocate::Absolute, + )), + ), + CosmicMappedRenderElement::Window(elem) => { + Some(CosmicMappedRenderElement::TiledWindow( + RelocateRenderElement::from_element( + RescaleRenderElement::from_element( CropRenderElement::from_element( elem, output_scale, crop_rect.to_physical_precise_round(output_scale), - ) - .map(CosmicMappedRenderElement::CroppedStack) - } - CosmicMappedRenderElement::Window(elem) => { + )?, + (0, 0).into(), + scale, + ), + geo.loc.to_physical_precise_round(output_scale), + Relocate::Absolute, + ), + )) + } + x => Some(x), + }) + .collect::>() + }) + .collect() + } else { + Vec::new() + } +} + +fn render_new_tree( + target_tree: &Tree, + reference_tree: Option<&Tree>, + renderer: &mut R, + geometries: Option>>, + old_geometries: Option>>, + focused: Option<&CosmicMapped>, + output_scale: f64, + percentage: f32, + indicator_thickness: u8, +) -> Vec> +where + R: Renderer + ImportAll + ImportMem + AsGlowRenderer, + ::TextureId: 'static, + CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, +{ + if let Some(root) = target_tree.root_node_id() { + let old_geometries = old_geometries.unwrap_or_default(); + let geometries = geometries.unwrap_or_default(); + target_tree + .traverse_pre_order_ids(root) + .unwrap() + .filter(|node_id| target_tree.get(node_id).unwrap().data().is_mapped(None)) + .map(|node_id| match target_tree.get(&node_id).unwrap().data() { + Data::Mapped { + mapped, + last_geometry, + .. + } => (mapped, last_geometry, geometries.get(&node_id)), + _ => unreachable!(), + }) + .flat_map(|(mapped, original_geo, scaled_geo)| { + let (old_original_geo, old_scaled_geo) = + if let Some(reference_tree) = reference_tree.as_ref() { + if let Some(root) = reference_tree.root_node_id() { + reference_tree + .traverse_pre_order_ids(root) + .unwrap() + .find(|node_id| { + reference_tree + .get(node_id) + .unwrap() + .data() + .is_mapped(Some(mapped)) + }) + .map( + |node_id| match reference_tree.get(&node_id).unwrap().data() { + Data::Mapped { last_geometry, .. } => { + (last_geometry, old_geometries.get(&node_id)) + } + _ => unreachable!(), + }, + ) + } else { + None + } + } else { + None + } + .unzip(); + let old_geo = old_original_geo.map(|original_geo| { + let (scale, offset) = old_scaled_geo + .unwrap() + .map(|adapted_geo| scale_to_center(original_geo, adapted_geo)) + .unwrap_or_else(|| (1.0.into(), (0, 0).into())); + old_scaled_geo + .unwrap() + .map(|adapted_geo| { + Rectangle::from_loc_and_size( + adapted_geo.loc + offset, + ( + (original_geo.size.w as f64 * scale).round() as i32, + (original_geo.size.h as f64 * scale).round() as i32, + ), + ) + }) + .unwrap_or(*original_geo) + }); + + let crop_rect = original_geo; + let (scale, offset) = scaled_geo + .map(|adapted_geo| scale_to_center(original_geo, adapted_geo)) + .unwrap_or_else(|| (1.0.into(), (0, 0).into())); + let new_geo = scaled_geo + .map(|adapted_geo| { + Rectangle::from_loc_and_size( + adapted_geo.loc + offset, + ( + (original_geo.size.w as f64 * scale).round() as i32, + (original_geo.size.h as f64 * scale).round() as i32, + ), + ) + }) + .unwrap_or(*original_geo); + + let (geo, alpha) = if let Some(old_geo) = old_geo { + ( + Rectangle::from_loc_and_size( + ( + old_geo.loc.x + + ((new_geo.loc.x - old_geo.loc.x) as f32 * percentage).round() + as i32, + old_geo.loc.y + + ((new_geo.loc.y - old_geo.loc.y) as f32 * percentage).round() + as i32, + ), + ( + old_geo.size.w + + ((new_geo.size.w - old_geo.size.w) as f32 * percentage) + .round() as i32, + old_geo.size.h + + ((new_geo.size.h - old_geo.size.h) as f32 * percentage) + .round() as i32, + ), + ), + 1.0, + ) + } else { + (new_geo, percentage) + }; + + let original_location = original_geo.loc.to_physical_precise_round(output_scale) + - mapped + .geometry() + .loc + .to_physical_precise_round(output_scale); + let mut elements = AsRenderElements::::render_elements::< + CosmicMappedRenderElement, + >( + mapped, + renderer, + original_location, + Scale::from(output_scale), + alpha, + ) + .into_iter() + .flat_map(|element| match element { + CosmicMappedRenderElement::Stack(elem) => Some( + CosmicMappedRenderElement::TiledStack(RelocateRenderElement::from_element( + RescaleRenderElement::from_element( + CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + )?, + original_location, + scale, + ), + geo.loc.to_physical_precise_round(output_scale), + Relocate::Absolute, + )), + ), + CosmicMappedRenderElement::Window(elem) => { + Some(CosmicMappedRenderElement::TiledWindow( + RelocateRenderElement::from_element( + RescaleRenderElement::from_element( CropRenderElement::from_element( elem, output_scale, crop_rect.to_physical_precise_round(output_scale), - ) - .map(CosmicMappedRenderElement::CroppedWindow) - } - x => Some(x), - }) - .collect::>(); + )?, + (0, 0).into(), + scale, + ), + geo.loc.to_physical_precise_round(output_scale), + Relocate::Absolute, + ), + )) + } + x => Some(x), + }) + .collect::>(); + + if focused == Some(mapped) { + if indicator_thickness > 0 { + let element = IndicatorShader::element( + renderer, + mapped.clone(), + geo, + indicator_thickness, + 1.0, + FOCUS_INDICATOR_COLOR, + ); + elements.insert(0, element.into()); + } + } - if focused == Some(mapped) { - if indicator_thickness > 0 { - let element = IndicatorShader::element( - renderer, - geo, - indicator_thickness, - 1.0, - ); - elements.insert(0, element.into()); - } - } - elements - }), - ) - } + elements + }) + .collect() + } else { + Vec::new() + } +} - Ok(elements) +fn scale_to_center( + old_geo: &Rectangle, + new_geo: &Rectangle, +) -> (f64, Point) { + let scale_w = new_geo.size.w as f64 / old_geo.size.w as f64; + let scale_h = new_geo.size.h as f64 / old_geo.size.h as f64; + + if scale_w > scale_h { + ( + scale_h, + ( + ((new_geo.size.w as f64 - old_geo.size.w as f64 * scale_h) / 2.0).round() as i32, + 0, + ) + .into(), + ) + } else { + ( + scale_w, + ( + 0, + ((new_geo.size.h as f64 - old_geo.size.h as f64 * scale_w) / 2.0).round() as i32, + ) + .into(), + ) } } diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 1ae1239f..b5383f5b 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -454,6 +454,7 @@ impl Workspace { override_redirect_windows: &[X11Surface], xwm_state: Option<&'a mut XWaylandState>, draw_focus_indicator: Option<&Seat>, + draw_groups: bool, indicator_thickness: u8, exclude_workspace_overview: bool, ) -> Result>, OutputNotMapped> @@ -604,7 +605,14 @@ impl Workspace { //tiling surfaces render_elements.extend( self.tiling_layer - .render_output::(renderer, output, focused.as_ref(), indicator_thickness)? + .render_output::( + renderer, + output, + focused.as_ref(), + layer_map.non_exclusive_zone(), + draw_groups, + indicator_thickness, + )? .into_iter() .map(WorkspaceRenderElement::from), ); From adc28eeb93552c086e25e28bbb3c59b34f51e0bd Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 19 May 2023 19:44:57 +0200 Subject: [PATCH 005/264] tiling: Animate and enable/disable hints --- src/backend/render/element.rs | 8 +- src/backend/render/mod.rs | 14 ++- src/config/mod.rs | 12 +- src/input/mod.rs | 89 +++++++++---- src/shell/element/mod.rs | 9 +- src/shell/element/window.rs | 7 +- src/shell/layout/floating/mod.rs | 5 +- src/shell/layout/tiling/mod.rs | 55 ++++++-- src/shell/mod.rs | 50 ++++++-- src/shell/workspace.rs | 194 +++++++++++++++++++++++++---- src/wayland/handlers/screencopy.rs | 7 +- 11 files changed, 362 insertions(+), 88 deletions(-) diff --git a/src/backend/render/element.rs b/src/backend/render/element.rs index d3bcbae8..07f5ad11 100644 --- a/src/backend/render/element.rs +++ b/src/backend/render/element.rs @@ -10,11 +10,9 @@ use smithay::{ }; #[cfg(feature = "debug")] -use smithay::backend::renderer::{ - element::texture::TextureRenderElement, gles::GlesTexture, multigpu::Error as MultiError, -}; +use smithay::backend::renderer::{element::texture::TextureRenderElement, gles::GlesTexture}; -use super::{cursor::CursorRenderElement, GlMultiFrame, GlMultiRenderer}; +use super::{cursor::CursorRenderElement, GlMultiError, GlMultiFrame, GlMultiRenderer}; pub enum CosmicElement where @@ -167,7 +165,7 @@ impl<'a, 'b> RenderElement> for CosmicElement, dst: Rectangle, damage: &[Rectangle], - ) -> Result<(), as Renderer>::Error> { + ) -> Result<(), GlMultiError> { match self { CosmicElement::Workspace(elem) => elem.draw(frame, src, dst, damage), CosmicElement::Cursor(elem) => elem.draw(frame, src, dst, damage), diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index dab84e90..1155acaf 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -16,6 +16,7 @@ use crate::{ shell::{ element::window::CosmicWindowRenderElement, focus::target::WindowGroup, layout::floating::SeatMoveGrabState, CosmicMapped, CosmicMappedRenderElement, + WorkspaceRenderElement, }, state::{Common, Fps}, utils::prelude::SeatExt, @@ -44,7 +45,7 @@ use smithay::{ UniformName, UniformType, }, glow::GlowRenderer, - multigpu::{gbm::GbmGlesBackend, MultiFrame, MultiRenderer}, + multigpu::{gbm::GbmGlesBackend, Error as MultiError, MultiFrame, MultiRenderer}, Bind, Blit, ExportMem, ImportAll, ImportMem, Offscreen, Renderer, TextureFilter, }, }, @@ -66,6 +67,7 @@ pub type GlMultiRenderer<'a, 'b> = MultiRenderer<'a, 'a, 'b, GbmGlesBackend, GbmGlesBackend>; pub type GlMultiFrame<'a, 'b, 'frame> = MultiFrame<'a, 'a, 'b, 'frame, GbmGlesBackend, GbmGlesBackend>; +pub type GlMultiError = MultiError, GbmGlesBackend>; pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0]; pub static ACTIVE_GROUP_COLOR: [f32; 3] = [0.678, 0.635, 0.619]; @@ -298,6 +300,7 @@ where ::Error: From, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + WorkspaceRenderElement: RenderElement, { #[cfg(feature = "debug")] puffin::profile_function!(); @@ -346,6 +349,7 @@ where .space_for_handle_mut(&handle) .ok_or(OutputNoMode)? .update_animations(&state.event_loop_handle); + let overview = state.shell.overview_mode(); let workspace = state.shell.space_for_handle(&handle).ok_or(OutputNoMode)?; let last_active_seat = state.last_active_seat().clone(); let move_active = last_active_seat @@ -365,7 +369,7 @@ where &state.shell.override_redirect_windows, state.xwayland_state.as_mut(), (!move_active && is_active_space).then_some(&last_active_seat), - true, + overview, state.config.static_conf.active_hint, exclude_workspace_overview, ) @@ -377,7 +381,7 @@ where Ok(elements) } -pub fn render_output<'frame, R, Target, OffTarget, Source>( +pub fn render_output( gpu: Option<&DrmNode>, renderer: &mut R, target: Target, @@ -404,6 +408,7 @@ where CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + WorkspaceRenderElement: RenderElement, Source: Clone, { let handle = state.shell.workspaces.active(output).handle; @@ -425,7 +430,7 @@ where result } -pub fn render_workspace<'frame, R, Target, OffTarget, Source>( +pub fn render_workspace( gpu: Option<&DrmNode>, renderer: &mut R, target: Target, @@ -454,6 +459,7 @@ where CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + WorkspaceRenderElement: RenderElement, Source: Clone, { #[cfg(feature = "debug")] diff --git a/src/config/mod.rs b/src/config/mod.rs index 25aff4c0..1feb854e 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -772,12 +772,12 @@ pub enum KeyModifier { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct KeyModifiers { - ctrl: bool, - alt: bool, - shift: bool, - logo: bool, - caps_lock: bool, - num_lock: bool, + pub ctrl: bool, + pub alt: bool, + pub shift: bool, + pub logo: bool, + pub caps_lock: bool, + pub num_lock: bool, } impl PartialEq for KeyModifiers { diff --git a/src/input/mod.rs b/src/input/mod.rs index cc171df1..93f9615f 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1,14 +1,14 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - config::{Action, Config}, + config::{Action, Config, KeyModifiers}, shell::{ focus::{target::PointerFocusTarget, FocusDirection}, layout::{ floating::SeatMoveGrabState, tiling::{Direction, FocusResult}, }, - Workspace, + OverviewMode, Workspace, }, // shell::grabs::SeatMoveGrabState state::Common, utils::prelude::*, @@ -219,7 +219,7 @@ impl State { let serial = SERIAL_COUNTER.next_serial(); let time = Event::time_msec(&event); - if let Some(action) = seat + if let Some((action, mods)) = seat .get_keyboard() .unwrap() .input( @@ -229,6 +229,18 @@ impl State { serial, time, |data, modifiers, handle| { + if let OverviewMode::Started(action_modifiers, _) = + data.common.shell.overview_mode() + { + if !(action_modifiers.ctrl && modifiers.ctrl) + && !(action_modifiers.alt && modifiers.alt) + && !(action_modifiers.logo && modifiers.logo) + && !(action_modifiers.shift && modifiers.shift) + { + data.common.shell.set_overview_mode(None); + } + } + if state == KeyState::Released && userdata.get::().unwrap().filter(&handle) { @@ -283,9 +295,10 @@ impl State { .get::() .unwrap() .add(&handle); - return FilterResult::Intercept(Some( + return FilterResult::Intercept(Some(( action.clone(), - )); + binding.modifiers.clone(), + ))); } } } @@ -295,7 +308,7 @@ impl State { ) .flatten() { - self.handle_action(action, seat, serial, time) + self.handle_action(action, seat, serial, time, mods) } break; } @@ -640,7 +653,14 @@ impl State { } } - fn handle_action(&mut self, action: Action, seat: &Seat, serial: Serial, time: u32) { + fn handle_action( + &mut self, + action: Action, + seat: &Seat, + serial: Serial, + time: u32, + mods: KeyModifiers, + ) { match action { Action::Terminate => { self.common.should_stop = true; @@ -920,17 +940,21 @@ impl State { FocusResult::None => { // TODO: Handle Workspace orientation match focus { - FocusDirection::Left => { - self.handle_action(Action::PreviousWorkspace, seat, serial, time) - } + FocusDirection::Left => self.handle_action( + Action::PreviousWorkspace, + seat, + serial, + time, + mods, + ), FocusDirection::Right => { - self.handle_action(Action::NextWorkspace, seat, serial, time) + self.handle_action(Action::NextWorkspace, seat, serial, time, mods) } FocusDirection::Up => { - self.handle_action(Action::PreviousOutput, seat, serial, time) + self.handle_action(Action::PreviousOutput, seat, serial, time, mods) } FocusDirection::Down => { - self.handle_action(Action::NextOutput, seat, serial, time) + self.handle_action(Action::NextOutput, seat, serial, time, mods) } _ => {} } @@ -955,17 +979,36 @@ impl State { // TODO: Handle Workspace orientation // TODO: Being able to move Groups (move_further should be KeyboardFocusTarget instead) match direction { - Direction::Left => { - self.handle_action(Action::MoveToPreviousWorkspace, seat, serial, time) - } - Direction::Right => { - self.handle_action(Action::MoveToNextWorkspace, seat, serial, time) - } - Direction::Up => { - self.handle_action(Action::MoveToPreviousOutput, seat, serial, time) - } + Direction::Left => self.handle_action( + Action::MoveToPreviousWorkspace, + seat, + serial, + time, + mods, + ), + Direction::Right => self.handle_action( + Action::MoveToNextWorkspace, + seat, + serial, + time, + mods, + ), + Direction::Up => self.handle_action( + Action::MoveToPreviousOutput, + seat, + serial, + time, + mods, + ), Direction::Down => { - self.handle_action(Action::MoveToNextOutput, seat, serial, time) + self.handle_action(Action::MoveToNextOutput, seat, serial, time, mods) + } + } + } else { + let focus_stack = workspace.focus_stack.get(seat); + if let Some(focused_window) = focus_stack.last() { + if workspace.is_tiled(focused_window) { + self.common.shell.set_overview_mode(Some(mods)); } } } diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 818d5a2a..dd4d1a72 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -1,7 +1,7 @@ use crate::{ backend::render::{ element::{AsGlowFrame, AsGlowRenderer}, - GlMultiFrame, GlMultiRenderer, + GlMultiError, GlMultiFrame, GlMultiRenderer, }, state::State, utils::prelude::SeatExt, @@ -17,7 +17,6 @@ use smithay::{ }, gles::element::PixelShaderElement, glow::GlowRenderer, - multigpu::Error as MultiError, ImportAll, ImportMem, Renderer, }, }, @@ -859,7 +858,7 @@ impl<'a, 'b> RenderElement> src: Rectangle, dst: Rectangle, damage: &[Rectangle], - ) -> Result<(), as Renderer>::Error> { + ) -> Result<(), GlMultiError> { match self { CosmicMappedRenderElement::Stack(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), @@ -867,13 +866,13 @@ impl<'a, 'b> RenderElement> CosmicMappedRenderElement::TiledWindow(elem) => elem.draw(frame, src, dst, damage), CosmicMappedRenderElement::Indicator(elem) => { RenderElement::::draw(elem, frame.glow_frame_mut(), src, dst, damage) - .map_err(|err| MultiError::Render(err)) + .map_err(|err| GlMultiError::Render(err)) } #[cfg(feature = "debug")] CosmicMappedRenderElement::Egui(elem) => { let glow_frame = frame.glow_frame_mut(); RenderElement::::draw(elem, glow_frame, src, dst, damage) - .map_err(|err| MultiError::Render(err)) + .map_err(|err| GlMultiError::Render(err)) } } } diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 35416758..c611be88 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -1,7 +1,7 @@ use crate::{ backend::render::{ element::{AsGlowFrame, AsGlowRenderer}, - GlMultiFrame, GlMultiRenderer, + GlMultiError, GlMultiFrame, GlMultiRenderer, }, shell::Shell, state::State, @@ -24,7 +24,6 @@ use smithay::{ AsRenderElements, Element, Id, RenderElement, }, glow::GlowRenderer, - multigpu::Error as MultiError, utils::CommitCounter, ImportAll, ImportMem, Renderer, }, @@ -683,11 +682,11 @@ impl<'a, 'b> RenderElement> src: Rectangle, dst: Rectangle, damage: &[Rectangle], - ) -> Result<(), as Renderer>::Error> { + ) -> Result<(), GlMultiError> { match self { CosmicWindowRenderElement::Header(h) => h .draw(frame.glow_frame_mut(), src, dst, damage) - .map_err(|err| MultiError::Render(err)), + .map_err(|err| GlMultiError::Render(err)), CosmicWindowRenderElement::Window(w) => w.draw(frame, src, dst, damage), } } diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index a82c2041..73c1b173 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -351,6 +351,7 @@ impl FloatingLayout { output: &Output, focused: Option<&CosmicMapped>, indicator_thickness: u8, + alpha: f32, ) -> Vec> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, @@ -374,7 +375,7 @@ impl FloatingLayout { renderer, render_location.to_physical_precise_round(output_scale), output_scale.into(), - 1.0, + alpha, ); if focused == Some(elem) { if indicator_thickness > 0 { @@ -386,7 +387,7 @@ impl FloatingLayout { elem.geometry().size, ), indicator_thickness, - 1.0, + alpha, FOCUS_INDICATOR_COLOR, ); elements.insert(0, element.into()); diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index d0d2d805..8a445c2c 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -13,7 +13,7 @@ use crate::{ }, grabs::ResizeEdge, layout::Orientation, - CosmicSurface, OutputNotMapped, + CosmicSurface, OutputNotMapped, OverviewMode, }, utils::prelude::*, wayland::{ @@ -52,7 +52,7 @@ mod grabs; pub use self::blocker::*; pub use self::grabs::*; -const ANIMATION_DURATION: Duration = Duration::from_millis(200); +pub const ANIMATION_DURATION: Duration = Duration::from_millis(200); #[derive(Debug, Clone)] struct OutputData { @@ -1439,7 +1439,7 @@ impl TilingLayout { output: &Output, focused: Option<&CosmicMapped>, non_exclusive_zone: Rectangle, - draw_groups: bool, + overview: OverviewMode, indicator_thickness: u8, ) -> Result>, OutputNotMapped> where @@ -1478,12 +1478,32 @@ impl TilingLayout { } else { 1.0 }; + let draw_groups = match overview { + OverviewMode::Started(_, start) => { + let percentage = (Instant::now().duration_since(start).as_millis() as f32 + / ANIMATION_DURATION.as_millis() as f32) + .min(1.0); + Some(Ease::Cubic(Cubic::Out).tween(percentage)) + } + OverviewMode::Ended(end) => { + let percentage = (1.0 + - Instant::now().duration_since(end).as_millis() as f32 + / ANIMATION_DURATION.as_millis() as f32) + .max(0.0); + if percentage > 0.0 { + Some(Ease::Cubic(Cubic::Out).tween(percentage)) + } else { + None + } + } + OverviewMode::None => None, + }; let mut elements = Vec::new(); // all gone windows and fade them out let old_geometries = if let Some(reference_tree) = reference_tree.as_ref() { - let (geometries, _) = if draw_groups { + let (geometries, _) = if let Some(transition) = draw_groups { geometries_for_groupview( reference_tree, renderer, @@ -1491,6 +1511,7 @@ impl TilingLayout { focused, // TODO: Would be better to be an old focus, // but for that we have to associate focus with a tree (and animate focus changes properly) 1.0 - percentage, + transition, ) } else { None @@ -1512,13 +1533,14 @@ impl TilingLayout { None }; - let (geometries, group_elements) = if draw_groups { + let (geometries, group_elements) = if let Some(transition) = draw_groups { geometries_for_groupview( target_tree, renderer, non_exclusive_zone, focused, percentage, + transition, ) } else { None @@ -1540,7 +1562,16 @@ impl TilingLayout { focused, output_scale, percentage, - if draw_groups { 3 } else { indicator_thickness }, + if let Some(transition) = draw_groups { + let diff = (3u8.abs_diff(indicator_thickness) as f32 * transition).round() as u8; + if 3 > indicator_thickness { + indicator_thickness + diff + } else { + indicator_thickness - diff + } + } else { + indicator_thickness + }, )); Ok(elements) @@ -1553,6 +1584,7 @@ fn geometries_for_groupview( non_exclusive_zone: Rectangle, focused: Option<&CosmicMapped>, alpha: f32, + transition: f32, ) -> Option<( HashMap>, Vec>, @@ -1570,11 +1602,14 @@ where let mut geometries = HashMap::new(); const GAP: i32 = 16; + let gap: i32 = (GAP as f32 * transition).round() as i32; + let alpha = alpha * transition; + for node_id in tree.traverse_pre_order_ids(root).unwrap() { if let Some(mut geo) = stack.pop() { // zoom in windows - geo.loc += (GAP, GAP).into(); - geo.size -= (GAP * 2, GAP * 2).into(); + geo.loc += (gap, gap).into(); + geo.size -= (gap * 2, gap * 2).into(); let node: &Node = tree.get(&node_id).unwrap(); let data = node.data(); @@ -1715,8 +1750,8 @@ where .into(), ); - geo.loc += (GAP, GAP).into(); - geo.size -= (GAP * 2, GAP * 2).into(); + geo.loc += (gap, gap).into(); + geo.size -= (gap * 2, gap * 2).into(); } geometries.insert(node_id.clone(), geo); diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 47f11785..2d704c20 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1,6 +1,6 @@ use calloop::LoopHandle; use serde::{Deserialize, Serialize}; -use std::{cell::RefCell, collections::HashMap}; +use std::{cell::RefCell, collections::HashMap, time::Instant}; use tracing::warn; use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState; @@ -29,7 +29,7 @@ use smithay::{ }; use crate::{ - config::{Config, OutputConfig, WorkspaceMode as ConfigMode}, + config::{Config, KeyModifiers, OutputConfig, WorkspaceMode as ConfigMode}, utils::prelude::*, wayland::protocols::{ toplevel_info::ToplevelInfoState, @@ -52,9 +52,19 @@ use self::{ element::CosmicWindow, focus::target::KeyboardFocusTarget, grabs::ResizeEdge, - layout::{floating::FloatingLayout, tiling::TilingLayout}, + layout::{ + floating::FloatingLayout, + tiling::{TilingLayout, ANIMATION_DURATION}, + }, }; +#[derive(Debug, Clone)] +pub enum OverviewMode { + None, + Started(KeyModifiers, Instant), + Ended(Instant), +} + pub struct Shell { pub popups: PopupManager, pub outputs: Vec, @@ -72,6 +82,7 @@ pub struct Shell { pub workspace_state: WorkspaceState, gaps: (u8, u8), + overview_mode: OverviewMode, } #[derive(Debug)] @@ -498,6 +509,7 @@ impl Shell { workspace_state, gaps: config.static_conf.gaps, + overview_mode: OverviewMode::None, } } @@ -1038,9 +1050,11 @@ impl Shell { } pub fn animations_going(&self) -> bool { - self.workspaces - .spaces() - .any(|workspace| workspace.animations_going()) + matches!(self.overview_mode, OverviewMode::None) + || self + .workspaces + .spaces() + .any(|workspace| workspace.animations_going()) } pub fn update_animations(&mut self, handle: &LoopHandle<'static, crate::state::Data>) { @@ -1049,6 +1063,28 @@ impl Shell { } } + pub fn set_overview_mode(&mut self, enabled: Option) { + if let Some(modifiers) = enabled { + if !matches!(self.overview_mode, OverviewMode::Started(_, _)) { + self.overview_mode = OverviewMode::Started(modifiers, Instant::now()); + } + } else { + if !matches!(self.overview_mode, OverviewMode::Ended(_)) { + self.overview_mode = OverviewMode::Ended(Instant::now()); + } + } + } + + pub fn overview_mode(&mut self) -> OverviewMode { + if let OverviewMode::Ended(timestamp) = self.overview_mode { + if Instant::now().duration_since(timestamp) > ANIMATION_DURATION { + self.overview_mode = OverviewMode::None; + } + } + + self.overview_mode.clone() + } + pub fn refresh(&mut self) { #[cfg(feature = "debug")] puffin::profile_function!(); @@ -1235,7 +1271,7 @@ impl Shell { } } let elements = from_workspace.mapped().cloned().collect::>(); - std::mem::drop(from_workspace); + for mapped in elements.into_iter() { state.common.shell.update_reactive_popups(&mapped); } diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index b5383f5b..f74b70f8 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -1,8 +1,14 @@ use crate::{ - backend::render::element::AsGlowRenderer, - shell::layout::{ - floating::{FloatingLayout, MoveSurfaceGrab}, - tiling::TilingLayout, + backend::render::{ + element::{AsGlowFrame, AsGlowRenderer}, + GlMultiError, GlMultiFrame, GlMultiRenderer, + }, + shell::{ + layout::{ + floating::{FloatingLayout, MoveSurfaceGrab}, + tiling::{TilingLayout, ANIMATION_DURATION}, + }, + OverviewMode, }, state::State, utils::prelude::*, @@ -20,19 +26,30 @@ use crate::{ use calloop::LoopHandle; use indexmap::IndexSet; use smithay::{ - backend::renderer::{ - element::{surface::WaylandSurfaceRenderElement, AsRenderElements, Element, RenderElement}, - ImportAll, ImportMem, Renderer, + backend::{ + allocator::Fourcc, + renderer::{ + element::{ + surface::WaylandSurfaceRenderElement, texture::TextureRenderElement, + AsRenderElements, Element, Id, RenderElement, + }, + gles::{GlesError, GlesTexture}, + glow::{GlowFrame, GlowRenderer}, + ImportAll, ImportMem, Renderer, + }, }, desktop::{layer_map_for_output, space::SpaceElement, LayerSurface}, input::{pointer::GrabStartData as PointerGrabStartData, Seat}, output::Output, reexports::wayland_server::protocol::wl_surface::WlSurface, - utils::{Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Size}, + utils::{ + Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Size, + Transform, + }, wayland::{seat::WaylandFocus, shell::wlr_layer::Layer}, xwayland::X11Surface, }; -use std::collections::HashMap; +use std::{collections::HashMap, time::Instant}; use tracing::warn; use super::{ @@ -454,7 +471,7 @@ impl Workspace { override_redirect_windows: &[X11Surface], xwm_state: Option<&'a mut XWaylandState>, draw_focus_indicator: Option<&Seat>, - draw_groups: bool, + overview: OverviewMode, indicator_thickness: u8, exclude_workspace_overview: bool, ) -> Result>, OutputNotMapped> @@ -463,6 +480,7 @@ impl Workspace { ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + WorkspaceRenderElement: RenderElement, { #[cfg(feature = "debug")] puffin::profile_function!(); @@ -540,7 +558,7 @@ impl Workspace { } else { // TODO: Handle modes like // - keyboard window swapping - // - resizing / moving in tiling + // - resizing in tiling // overlay and top layer surfaces let lower = { @@ -595,9 +613,31 @@ impl Workspace { let focused = draw_focus_indicator.and_then(|seat| self.focus_stack.get(seat).last().cloned()); // floating surfaces + let alpha = match &overview { + OverviewMode::Started(_, started) => { + (1.0 - (Instant::now().duration_since(*started).as_millis() + / ANIMATION_DURATION.as_millis()) as f32) + .max(0.0) + * 0.4 + + 0.6 + } + OverviewMode::Ended(ended) => { + ((Instant::now().duration_since(*ended).as_millis() + / ANIMATION_DURATION.as_millis()) as f32) + * 0.4 + + 0.6 + } + OverviewMode::None => 1.0, + }; render_elements.extend( self.floating_layer - .render_output::(renderer, output, focused.as_ref(), indicator_thickness) + .render_output::( + renderer, + output, + focused.as_ref(), + indicator_thickness, + alpha, + ) .into_iter() .map(WorkspaceRenderElement::from), ); @@ -610,7 +650,7 @@ impl Workspace { output, focused.as_ref(), layer_map.non_exclusive_zone(), - draw_groups, + overview.clone(), indicator_thickness, )? .into_iter() @@ -629,6 +669,64 @@ impl Workspace { } } + if let OverviewMode::Started(_, start) = overview { + let alpha = Instant::now().duration_since(start).as_millis() as f64 / 100.0; + + #[derive(Clone)] + struct BackdropTexture(Id, GlesTexture); + + if renderer + .glow_renderer() + .egl_context() + .user_data() + .get::() + .is_none() + { + let tex = BackdropTexture( + Id::new(), + renderer + .glow_renderer_mut() + .import_memory(&[0, 0, 0, 255], Fourcc::Argb8888, (1, 1).into(), false) + .unwrap(), + ); + renderer + .glow_renderer() + .egl_context() + .user_data() + .insert_if_missing(|| tex); + }; + let BackdropTexture(id, tex) = renderer + .glow_renderer() + .egl_context() + .user_data() + .get::() + .unwrap() + .clone(); + + render_elements.push( + TextureRenderElement::from_static_texture( + id, + renderer.id(), + (0.0, 0.0), + tex, + 1, + smithay::utils::Transform::Normal, + Some(alpha as f32), + Some(Rectangle::from_loc_and_size((0., 0.), (1., 1.))), + Some(output.geometry().size), + if alpha >= 1.0 { + Some(vec![Rectangle::from_loc_and_size( + (0, 0), + output.geometry().size.to_buffer(1, Transform::Normal), + )]) + } else { + None + }, + ) + .into(), + ) + } + // bottom and background layer surfaces { render_elements.extend( @@ -675,6 +773,7 @@ where { Wayland(WaylandSurfaceRenderElement), Window(CosmicMappedRenderElement), + Backdrop(TextureRenderElement), } impl Element for WorkspaceRenderElement @@ -686,6 +785,7 @@ where match self { WorkspaceRenderElement::Wayland(elem) => elem.id(), WorkspaceRenderElement::Window(elem) => elem.id(), + WorkspaceRenderElement::Backdrop(elem) => elem.id(), } } @@ -693,6 +793,7 @@ where match self { WorkspaceRenderElement::Wayland(elem) => elem.current_commit(), WorkspaceRenderElement::Window(elem) => elem.current_commit(), + WorkspaceRenderElement::Backdrop(elem) => elem.current_commit(), } } @@ -700,6 +801,7 @@ where match self { WorkspaceRenderElement::Wayland(elem) => elem.src(), WorkspaceRenderElement::Window(elem) => elem.src(), + WorkspaceRenderElement::Backdrop(elem) => elem.src(), } } @@ -707,6 +809,7 @@ where match self { WorkspaceRenderElement::Wayland(elem) => elem.geometry(scale), WorkspaceRenderElement::Window(elem) => elem.geometry(scale), + WorkspaceRenderElement::Backdrop(elem) => elem.geometry(scale), } } @@ -714,6 +817,7 @@ where match self { WorkspaceRenderElement::Wayland(elem) => elem.location(scale), WorkspaceRenderElement::Window(elem) => elem.location(scale), + WorkspaceRenderElement::Backdrop(elem) => elem.location(scale), } } @@ -721,6 +825,7 @@ where match self { WorkspaceRenderElement::Wayland(elem) => elem.transform(), WorkspaceRenderElement::Window(elem) => elem.transform(), + WorkspaceRenderElement::Backdrop(elem) => elem.transform(), } } @@ -732,6 +837,7 @@ where match self { WorkspaceRenderElement::Wayland(elem) => elem.damage_since(scale, commit), WorkspaceRenderElement::Window(elem) => elem.damage_since(scale, commit), + WorkspaceRenderElement::Backdrop(elem) => elem.damage_since(scale, commit), } } @@ -739,6 +845,7 @@ where match self { WorkspaceRenderElement::Wayland(elem) => elem.opaque_regions(scale), WorkspaceRenderElement::Window(elem) => elem.opaque_regions(scale), + WorkspaceRenderElement::Backdrop(elem) => elem.opaque_regions(scale), } } @@ -746,36 +853,70 @@ where match self { WorkspaceRenderElement::Wayland(elem) => elem.alpha(), WorkspaceRenderElement::Window(elem) => elem.alpha(), + WorkspaceRenderElement::Backdrop(elem) => elem.alpha(), } } } -impl RenderElement for WorkspaceRenderElement -where - R: Renderer + ImportAll + ImportMem + AsGlowRenderer, - ::TextureId: 'static, - CosmicMappedRenderElement: RenderElement, +impl RenderElement for WorkspaceRenderElement { + fn draw<'frame>( + &self, + frame: &mut GlowFrame<'frame>, + src: Rectangle, + dst: Rectangle, + damage: &[Rectangle], + ) -> Result<(), GlesError> { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.draw(frame, src, dst, damage), + WorkspaceRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), + WorkspaceRenderElement::Backdrop(elem) => { + RenderElement::::draw(elem, frame, src, dst, damage) + } + } + } + + fn underlying_storage( + &self, + renderer: &mut GlowRenderer, + ) -> Option { + match self { + WorkspaceRenderElement::Wayland(elem) => elem.underlying_storage(renderer), + WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer), + WorkspaceRenderElement::Backdrop(elem) => elem.underlying_storage(renderer), + } + } +} + +impl<'a, 'b> RenderElement> + for WorkspaceRenderElement> { fn draw<'frame>( &self, - frame: &mut ::Frame<'frame>, + frame: &mut GlMultiFrame<'a, 'b, 'frame>, src: Rectangle, dst: Rectangle, damage: &[Rectangle], - ) -> Result<(), ::Error> { + ) -> Result<(), GlMultiError> { match self { WorkspaceRenderElement::Wayland(elem) => elem.draw(frame, src, dst, damage), WorkspaceRenderElement::Window(elem) => elem.draw(frame, src, dst, damage), + WorkspaceRenderElement::Backdrop(elem) => { + RenderElement::::draw(elem, frame.glow_frame_mut(), src, dst, damage) + .map_err(GlMultiError::Render) + } } } fn underlying_storage( &self, - renderer: &mut R, + renderer: &mut GlMultiRenderer<'a, 'b>, ) -> Option { match self { WorkspaceRenderElement::Wayland(elem) => elem.underlying_storage(renderer), WorkspaceRenderElement::Window(elem) => elem.underlying_storage(renderer), + WorkspaceRenderElement::Backdrop(elem) => { + elem.underlying_storage(renderer.glow_renderer_mut()) + } } } } @@ -801,3 +942,14 @@ where WorkspaceRenderElement::Window(elem) } } + +impl From> for WorkspaceRenderElement +where + R: Renderer + ImportAll + ImportMem + AsGlowRenderer, + ::TextureId: 'static, + CosmicMappedRenderElement: RenderElement, +{ + fn from(elem: TextureRenderElement) -> Self { + WorkspaceRenderElement::Backdrop(elem) + } +} diff --git a/src/wayland/handlers/screencopy.rs b/src/wayland/handlers/screencopy.rs index aebef716..467d9d9e 100644 --- a/src/wayland/handlers/screencopy.rs +++ b/src/wayland/handlers/screencopy.rs @@ -48,7 +48,10 @@ use crate::{ element::{AsGlowRenderer, CosmicElement}, render_output, render_workspace, CursorMode, CLEAR_COLOR, }, - shell::{element::window::CosmicWindowRenderElement, CosmicMappedRenderElement, CosmicSurface}, + shell::{ + element::window::CosmicWindowRenderElement, CosmicMappedRenderElement, CosmicSurface, + WorkspaceRenderElement, + }, state::{BackendData, ClientState, Common, Data, State}, utils::prelude::OutputExt, wayland::protocols::{ @@ -663,6 +666,7 @@ pub fn render_output_to_buffer( CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + WorkspaceRenderElement: RenderElement, { let cursor_mode = match session.cursor_mode() { ScreencopyCursorMode::Embedded => CursorMode::All, @@ -795,6 +799,7 @@ pub fn render_workspace_to_buffer( CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + WorkspaceRenderElement: RenderElement, { let cursor_mode = match session.cursor_mode() { ScreencopyCursorMode::Embedded => CursorMode::All, From 9be6c854591ea51962e9d341e63d05c601d977da Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 19 May 2023 19:47:59 +0200 Subject: [PATCH 006/264] clippy fixes --- src/backend/kms/mod.rs | 2 +- src/wayland/handlers/toplevel_management.rs | 1 - src/xwayland.rs | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index e3e3fc4b..af103b26 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -1201,7 +1201,7 @@ impl KmsState { .values_mut() .find(|dev| dev.surfaces.values().any(|s| s.output == *output)) { - let (crtc, mut surface) = device + let (crtc, surface) = device .surfaces .iter_mut() .find(|(_, s)| s.output == *output) diff --git a/src/wayland/handlers/toplevel_management.rs b/src/wayland/handlers/toplevel_management.rs index 55ff08e9..786be8bd 100644 --- a/src/wayland/handlers/toplevel_management.rs +++ b/src/wayland/handlers/toplevel_management.rs @@ -48,7 +48,6 @@ impl ToplevelManagementHandler for State { .unwrap() .clone(); - std::mem::drop(workspace); self.common.shell.activate(&output, idx as usize); mapped.focus_window(window); Common::set_focus(self, Some(&mapped.clone().into()), &seat, None); diff --git a/src/xwayland.rs b/src/xwayland.rs index 80925442..d6b802b8 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -81,7 +81,7 @@ impl State { ); } - let mut xwayland_state = data.state.common.xwayland_state.as_mut().unwrap(); + let xwayland_state = data.state.common.xwayland_state.as_mut().unwrap(); xwayland_state.xwm = Some(wm); } XWaylandEvent::Exited => { From 0d1894e08f1999a25120c8afc69a325602ea600c Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 22 May 2023 16:55:29 +0200 Subject: [PATCH 007/264] tiling: Fix misaligned positioning --- src/shell/layout/tiling/mod.rs | 167 ++++++++++++++++++--------------- src/shell/workspace.rs | 18 +--- 2 files changed, 96 insertions(+), 89 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 8a445c2c..e5e53453 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1837,37 +1837,47 @@ where ) .into_iter() .flat_map(|element| match element { - CosmicMappedRenderElement::Stack(elem) => Some( - CosmicMappedRenderElement::TiledStack(RelocateRenderElement::from_element( - RescaleRenderElement::from_element( - CropRenderElement::from_element( - elem, - output_scale, - crop_rect.to_physical_precise_round(output_scale), - )?, + CosmicMappedRenderElement::Stack(elem) => { + Some(CosmicMappedRenderElement::TiledStack({ + let cropped = CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + )?; + let rescaled = RescaleRenderElement::from_element( + cropped, original_location, scale, - ), - geo.loc.to_physical_precise_round(output_scale), - Relocate::Absolute, - )), - ), + ); + let relocated = RelocateRenderElement::from_element( + rescaled, + (geo.loc - original_geo.loc) + .to_physical_precise_round(output_scale), + Relocate::Relative, + ); + relocated + })) + } CosmicMappedRenderElement::Window(elem) => { - Some(CosmicMappedRenderElement::TiledWindow( - RelocateRenderElement::from_element( - RescaleRenderElement::from_element( - CropRenderElement::from_element( - elem, - output_scale, - crop_rect.to_physical_precise_round(output_scale), - )?, - (0, 0).into(), - scale, - ), - geo.loc.to_physical_precise_round(output_scale), - Relocate::Absolute, - ), - )) + Some(CosmicMappedRenderElement::TiledWindow({ + let cropped = CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + )?; + let rescaled = RescaleRenderElement::from_element( + cropped, + original_location, + scale, + ); + let relocated = RelocateRenderElement::from_element( + rescaled, + (geo.loc - original_geo.loc) + .to_physical_precise_round(output_scale), + Relocate::Relative, + ); + relocated + })) } x => Some(x), }) @@ -2001,57 +2011,64 @@ where (new_geo, percentage) }; - let original_location = original_geo.loc.to_physical_precise_round(output_scale) - - mapped - .geometry() - .loc - .to_physical_precise_round(output_scale); - let mut elements = AsRenderElements::::render_elements::< - CosmicMappedRenderElement, - >( - mapped, - renderer, - original_location, - Scale::from(output_scale), - alpha, - ) - .into_iter() - .flat_map(|element| match element { - CosmicMappedRenderElement::Stack(elem) => Some( - CosmicMappedRenderElement::TiledStack(RelocateRenderElement::from_element( - RescaleRenderElement::from_element( - CropRenderElement::from_element( + let original_location = (original_geo.loc - mapped.geometry().loc) + .to_physical_precise_round(output_scale); + + let mut elements = + AsRenderElements::::render_elements::>( + mapped, + renderer, + original_location, + Scale::from(output_scale), + alpha, + ) + .into_iter() + .flat_map(|element| match element { + CosmicMappedRenderElement::Stack(elem) => { + Some(CosmicMappedRenderElement::TiledStack({ + let cropped = CropRenderElement::from_element( elem, output_scale, crop_rect.to_physical_precise_round(output_scale), - )?, - original_location, - scale, - ), - geo.loc.to_physical_precise_round(output_scale), - Relocate::Absolute, - )), - ), - CosmicMappedRenderElement::Window(elem) => { - Some(CosmicMappedRenderElement::TiledWindow( - RelocateRenderElement::from_element( - RescaleRenderElement::from_element( - CropRenderElement::from_element( - elem, - output_scale, - crop_rect.to_physical_precise_round(output_scale), - )?, - (0, 0).into(), + )?; + let rescaled = RescaleRenderElement::from_element( + cropped, + original_location, scale, - ), - geo.loc.to_physical_precise_round(output_scale), - Relocate::Absolute, - ), - )) - } - x => Some(x), - }) - .collect::>(); + ); + let relocated = RelocateRenderElement::from_element( + rescaled, + (geo.loc - original_geo.loc) + .to_physical_precise_round(output_scale), + Relocate::Relative, + ); + relocated + })) + } + CosmicMappedRenderElement::Window(elem) => { + Some(CosmicMappedRenderElement::TiledWindow({ + let cropped = CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + )?; + let rescaled = RescaleRenderElement::from_element( + cropped, + original_location, + scale, + ); + let relocated = RelocateRenderElement::from_element( + rescaled, + (geo.loc - original_geo.loc) + .to_physical_precise_round(output_scale), + Relocate::Relative, + ); + relocated + })) + } + x => Some(x), + }) + .collect::>(); if focused == Some(mapped) { if indicator_thickness > 0 { diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index f74b70f8..e03abacc 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -42,10 +42,7 @@ use smithay::{ input::{pointer::GrabStartData as PointerGrabStartData, Seat}, output::Output, reexports::wayland_server::protocol::wl_surface::WlSurface, - utils::{ - Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Size, - Transform, - }, + utils::{Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Size}, wayland::{seat::WaylandFocus, shell::wlr_layer::Layer}, xwayland::X11Surface, }; @@ -686,7 +683,7 @@ impl Workspace { Id::new(), renderer .glow_renderer_mut() - .import_memory(&[0, 0, 0, 255], Fourcc::Argb8888, (1, 1).into(), false) + .import_memory(&[0, 0, 0, 255], Fourcc::Abgr8888, (1, 1).into(), false) .unwrap(), ); renderer @@ -711,17 +708,10 @@ impl Workspace { tex, 1, smithay::utils::Transform::Normal, - Some(alpha as f32), + Some(alpha.min(0.8) as f32), Some(Rectangle::from_loc_and_size((0., 0.), (1., 1.))), Some(output.geometry().size), - if alpha >= 1.0 { - Some(vec![Rectangle::from_loc_and_size( - (0, 0), - output.geometry().size.to_buffer(1, Transform::Normal), - )]) - } else { - None - }, + None, ) .into(), ) From 7b3ac7fa777bac6e9197cb921ca820c397af1af9 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 22 May 2023 20:19:11 +0200 Subject: [PATCH 008/264] render: Implement workspace transitions --- src/backend/kms/mod.rs | 11 +- src/backend/render/element.rs | 13 +- src/backend/render/mod.rs | 262 ++++++++++++++++++++++++++--- src/config/mod.rs | 6 + src/input/mod.rs | 8 +- src/shell/mod.rs | 41 ++++- src/shell/workspace.rs | 89 +--------- src/wayland/handlers/screencopy.rs | 16 +- 8 files changed, 320 insertions(+), 126 deletions(-) diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index af103b26..8cb229b9 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -1041,13 +1041,20 @@ impl Surface { ); } - let handle = state.shell.workspaces.active(&self.output).handle; + let (previous_workspace, workspace) = state.shell.workspaces.active(&self.output); + let (previous_idx, idx) = state.shell.workspaces.active_num(&self.output); + let previous_workspace = previous_workspace + .zip(previous_idx) + .map(|((w, start), idx)| (w.handle, idx, start)); + let workspace = (workspace.handle, idx); + let elements = workspace_elements( Some(&render_node), &mut renderer, state, &self.output, - &handle, + previous_workspace, + workspace, CursorMode::All, &mut Some(&mut self.fps), false, diff --git a/src/backend/render/element.rs b/src/backend/render/element.rs index 07f5ad11..25ef71a3 100644 --- a/src/backend/render/element.rs +++ b/src/backend/render/element.rs @@ -2,7 +2,10 @@ use crate::shell::{CosmicMappedRenderElement, WorkspaceRenderElement}; use smithay::{ backend::renderer::{ - element::{Element, RenderElement, UnderlyingStorage}, + element::{ + utils::{Relocate, RelocateRenderElement}, + Element, RenderElement, UnderlyingStorage, + }, glow::{GlowFrame, GlowRenderer}, Frame, ImportAll, ImportMem, Renderer, }, @@ -20,7 +23,7 @@ where ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, { - Workspace(WorkspaceRenderElement), + Workspace(RelocateRenderElement>), Cursor(CursorRenderElement), MoveGrab(CosmicMappedRenderElement), #[cfg(feature = "debug")] @@ -211,7 +214,11 @@ where CosmicMappedRenderElement: RenderElement, { fn from(elem: WorkspaceRenderElement) -> Self { - Self::Workspace(elem) + Self::Workspace(RelocateRenderElement::from_element( + elem, + (0, 0), + Relocate::Relative, + )) } } diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 1155acaf..ec765b6d 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -5,23 +5,24 @@ use std::{ cell::RefCell, collections::HashMap, sync::Weak, + time::Instant, }; -#[cfg(feature = "debug")] -use crate::{ - debug::{fps_ui, profiler_ui}, - utils::prelude::*, -}; use crate::{ + config::WorkspaceLayout, shell::{ - element::window::CosmicWindowRenderElement, focus::target::WindowGroup, - layout::floating::SeatMoveGrabState, CosmicMapped, CosmicMappedRenderElement, - WorkspaceRenderElement, + element::window::CosmicWindowRenderElement, + focus::target::WindowGroup, + layout::{floating::SeatMoveGrabState, tiling::ANIMATION_DURATION}, + CosmicMapped, CosmicMappedRenderElement, WorkspaceRenderElement, }, state::{Common, Fps}, - utils::prelude::SeatExt, + utils::prelude::{OutputExt, SeatExt}, wayland::{ - handlers::{data_device::get_dnd_icon, screencopy::render_session}, + handlers::{ + data_device::get_dnd_icon, + screencopy::{render_session, WORKSPACE_OVERVIEW_NAMESPACE}, + }, protocols::{ screencopy::{ BufferParams, CursorMode as ScreencopyCursorMode, Session as ScreencopySession, @@ -30,8 +31,14 @@ use crate::{ }, }, }; +#[cfg(feature = "debug")] +use crate::{ + debug::{fps_ui, profiler_ui}, + utils::prelude::*, +}; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::FailureReason; +use cosmic_time::{Cubic, Ease, Tween}; use smithay::{ backend::{ allocator::dmabuf::Dmabuf, @@ -39,7 +46,10 @@ use smithay::{ renderer::{ buffer_dimensions, damage::{Error as RenderError, OutputDamageTracker, OutputNoMode}, - element::{Element, RenderElement, RenderElementStates}, + element::{ + utils::{Relocate, RelocateRenderElement}, + AsRenderElements, Element, RenderElement, RenderElementStates, + }, gles::{ element::PixelShaderElement, GlesError, GlesPixelProgram, GlesRenderer, Uniform, UniformName, UniformType, @@ -49,10 +59,12 @@ use smithay::{ Bind, Blit, ExportMem, ImportAll, ImportMem, Offscreen, Renderer, TextureFilter, }, }, + desktop::layer_map_for_output, output::Output, - utils::{IsAlive, Logical, Physical, Point, Rectangle, Size}, + utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Size}, wayland::{ dmabuf::get_dmabuf, + shell::wlr_layer::Layer, shm::{shm_format_to_fourcc, with_buffer_contents}, }, }; @@ -289,7 +301,8 @@ pub fn workspace_elements( renderer: &mut R, state: &mut Common, output: &Output, - handle: &WorkspaceHandle, + previous: Option<(WorkspaceHandle, usize, Instant)>, + current: (WorkspaceHandle, usize), cursor_mode: CursorMode, _fps: &mut Option<&mut Fps>, exclude_workspace_overview: bool, @@ -346,11 +359,17 @@ where state .shell - .space_for_handle_mut(&handle) + .space_for_handle_mut(¤t.0) .ok_or(OutputNoMode)? .update_animations(&state.event_loop_handle); + if let Some((previous, _, _)) = previous.as_ref() { + state + .shell + .space_for_handle_mut(&previous) + .ok_or(OutputNoMode)? + .update_animations(&state.event_loop_handle); + } let overview = state.shell.overview_mode(); - let workspace = state.shell.space_for_handle(&handle).ok_or(OutputNoMode)?; let last_active_seat = state.last_active_seat().clone(); let move_active = last_active_seat .user_data() @@ -359,6 +378,96 @@ where .borrow() .is_some(); let active_output = last_active_seat.active_output(); + let output_size = output.geometry().size; + let output_scale = output.current_scale().fractional_scale(); + + let workspace = state + .shell + .space_for_handle(¤t.0) + .ok_or(OutputNoMode)?; + let has_fullscreen = workspace.fullscreen.contains_key(output); + + // foreground layers are static + elements.extend( + foreground_layer_elements(renderer, output, has_fullscreen, exclude_workspace_overview) + .into_iter() + .map(Into::into), + ); + + let offset = match previous.as_ref() { + Some((previous, previous_idx, start)) => { + let layout = WorkspaceLayout::Vertical; + + let workspace = state + .shell + .space_for_handle(&previous) + .ok_or(OutputNoMode)?; + let is_active_space = workspace.outputs().any(|o| o == &active_output); + + let percentage = { + let percentage = Instant::now().duration_since(*start).as_millis() as f32 + / ANIMATION_DURATION.as_millis() as f32; + Ease::Cubic(Cubic::InOut).tween(percentage) + }; + let offset = Point::::from(match (layout, *previous_idx < current.1) { + (WorkspaceLayout::Vertical, true) => { + (0, (-output_size.h as f32 * percentage).round() as i32) + } + (WorkspaceLayout::Vertical, false) => { + (0, (output_size.h as f32 * percentage).round() as i32) + } + (WorkspaceLayout::Horizontal, true) => { + ((-output_size.w as f32 * percentage).round() as i32, 0) + } + (WorkspaceLayout::Horizontal, false) => { + ((output_size.w as f32 * percentage).round() as i32, 0) + } + }); + + elements.extend( + workspace + .render_output::( + renderer, + output, + &state.shell.override_redirect_windows, + state.xwayland_state.as_mut(), + (!move_active && is_active_space).then_some(&last_active_seat), + overview.clone(), + state.config.static_conf.active_hint, + ) + .map_err(|_| OutputNoMode)? + .into_iter() + .map(|w_element| { + CosmicElement::Workspace(RelocateRenderElement::from_element( + w_element, + offset.to_physical_precise_round(output_scale), + Relocate::Relative, + )) + }), + ); + + elements.extend( + background_layer_elements(renderer, output, exclude_workspace_overview) + .into_iter() + .map(|w_element| { + CosmicElement::Workspace(RelocateRenderElement::from_element( + w_element, + offset.to_physical_precise_round(output_scale), + Relocate::Relative, + )) + }), + ); + + Point::::from(match (layout, *previous_idx < current.1) { + (WorkspaceLayout::Vertical, true) => (0, output_size.h + offset.y), + (WorkspaceLayout::Vertical, false) => (0, -(output_size.h - offset.y)), + (WorkspaceLayout::Horizontal, true) => (output_size.w + offset.x, 0), + (WorkspaceLayout::Horizontal, false) => (-(output_size.w - offset.y), 0), + }) + } + None => (0, 0).into(), + }; + let is_active_space = workspace.outputs().any(|o| o == &active_output); elements.extend( @@ -371,16 +480,118 @@ where (!move_active && is_active_space).then_some(&last_active_seat), overview, state.config.static_conf.active_hint, - exclude_workspace_overview, ) .map_err(|_| OutputNoMode)? .into_iter() - .map(Into::into), + .map(|w_element| { + CosmicElement::Workspace(RelocateRenderElement::from_element( + w_element, + offset.to_physical_precise_round(output_scale), + Relocate::Relative, + )) + }), + ); + + elements.extend( + background_layer_elements(renderer, output, exclude_workspace_overview) + .into_iter() + .map(|w_element| { + CosmicElement::Workspace(RelocateRenderElement::from_element( + w_element, + offset.to_physical_precise_round(output_scale), + Relocate::Relative, + )) + }), ); Ok(elements) } +// bottom and background layer surfaces +pub fn foreground_layer_elements( + renderer: &mut R, + output: &Output, + has_fullscreen: bool, + exclude_workspace_overview: bool, +) -> Vec> +where + R: Renderer + ImportAll + ImportMem + AsGlowRenderer, + ::TextureId: Clone + 'static, + ::Error: From, + CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, + WorkspaceRenderElement: RenderElement, +{ + let layer_map = layer_map_for_output(output); + let output_scale = output.current_scale().fractional_scale(); + + layer_map + .layers() + .rev() + .filter(|s| !(exclude_workspace_overview && s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)) + .filter(|s| { + if has_fullscreen { + matches!(s.layer(), Layer::Overlay) + } else { + matches!(s.layer(), Layer::Top | Layer::Overlay) + } + }) + .filter_map(|surface| { + layer_map + .layer_geometry(surface) + .map(|geo| (geo.loc, surface)) + }) + .flat_map(|(loc, surface)| { + AsRenderElements::::render_elements::>( + surface, + renderer, + loc.to_physical_precise_round(output_scale), + Scale::from(output_scale), + 1.0, + ) + }) + .collect() +} + +// bottom and background layer surfaces +pub fn background_layer_elements( + renderer: &mut R, + output: &Output, + exclude_workspace_overview: bool, +) -> Vec> +where + R: Renderer + ImportAll + ImportMem + AsGlowRenderer, + ::TextureId: Clone + 'static, + ::Error: From, + CosmicMappedRenderElement: RenderElement, + CosmicWindowRenderElement: RenderElement, + WorkspaceRenderElement: RenderElement, +{ + let layer_map = layer_map_for_output(output); + let output_scale = output.current_scale().fractional_scale(); + + layer_map + .layers() + .rev() + .filter(|s| !(exclude_workspace_overview && s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE)) + .filter(|s| matches!(s.layer(), Layer::Background | Layer::Bottom)) + .filter_map(|surface| { + layer_map + .layer_geometry(surface) + .map(|geo| (geo.loc, surface)) + }) + .flat_map(|(loc, surface)| { + AsRenderElements::::render_elements::>( + surface, + renderer, + loc.to_physical_precise_round(output_scale), + Scale::from(output_scale), + 1.0, + ) + }) + .collect() +} + pub fn render_output( gpu: Option<&DrmNode>, renderer: &mut R, @@ -411,7 +622,13 @@ where WorkspaceRenderElement: RenderElement, Source: Clone, { - let handle = state.shell.workspaces.active(output).handle; + let (previous_workspace, workspace) = state.shell.workspaces.active(output); + let (previous_idx, idx) = state.shell.workspaces.active_num(output); + let previous_workspace = previous_workspace + .zip(previous_idx) + .map(|((w, start), idx)| (w.handle, idx, start)); + let workspace = (workspace.handle, idx); + let result = render_workspace( gpu, renderer, @@ -420,7 +637,8 @@ where age, state, output, - &handle, + previous_workspace, + workspace, cursor_mode, screencopy, fps, @@ -438,7 +656,8 @@ pub fn render_workspace( age: usize, state: &mut Common, output: &Output, - handle: &WorkspaceHandle, + previous: Option<(WorkspaceHandle, usize, Instant)>, + current: (WorkspaceHandle, usize), mut cursor_mode: CursorMode, screencopy: Option<(Source, &[(ScreencopySession, BufferParams)])>, mut fps: Option<&mut Fps>, @@ -496,7 +715,8 @@ where renderer, state, output, - handle, + previous, + current, cursor_mode, &mut fps, exclude_workspace_overview, diff --git a/src/config/mod.rs b/src/config/mod.rs index 1feb854e..19657c55 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -49,6 +49,12 @@ pub enum WorkspaceMode { Global, } +#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Eq)] +pub enum WorkspaceLayout { + Vertical, + Horizontal, +} + pub struct DynamicConfig { outputs: (Option, OutputsConfig), inputs: (Option, InputsConfig), diff --git a/src/input/mod.rs b/src/input/mod.rs index 93f9615f..8640fe78 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -708,6 +708,7 @@ impl State { .shell .workspaces .active_num(¤t_output) + .1 .saturating_add(1); // TODO: Possibly move to next output, if idx to large let _ = self.common.shell.activate(¤t_output, workspace); @@ -719,6 +720,7 @@ impl State { .shell .workspaces .active_num(¤t_output) + .1 .saturating_sub(1); // TODO: Possibly move to prev output, if idx < 0 let _ = self.common.shell.activate(¤t_output, workspace); @@ -756,6 +758,7 @@ impl State { .shell .workspaces .active_num(¤t_output) + .1 .saturating_add(1); // TODO: Possibly move to next output, if idx too large Shell::move_current_window( @@ -773,6 +776,7 @@ impl State { .shell .workspaces .active_num(¤t_output) + .1 .saturating_sub(1); // TODO: Possibly move to prev output, if idx < 0 Shell::move_current_window( @@ -811,7 +815,7 @@ impl State { .next() .cloned() { - let idx = self.common.shell.workspaces.active_num(&next_output); + let idx = self.common.shell.workspaces.active_num(&next_output).1; if let Some(new_pos) = self.common.shell.activate(&next_output, idx) { seat.set_active_output(&next_output); if let Some(ptr) = seat.get_pointer() { @@ -841,7 +845,7 @@ impl State { .next() .cloned() { - let idx = self.common.shell.workspaces.active_num(&prev_output); + let idx = self.common.shell.workspaces.active_num(&prev_output).1; if let Some(new_pos) = self.common.shell.activate(&prev_output, idx) { seat.set_active_output(&prev_output); if let Some(ptr) = seat.get_pointer() { diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 2d704c20..e19fba27 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -87,6 +87,7 @@ pub struct Shell { #[derive(Debug)] pub struct WorkspaceSet { + previously_active: Option<(usize, Instant)>, active: usize, amount: WorkspaceAmount, group: WorkspaceGroupHandle, @@ -155,6 +156,7 @@ impl WorkspaceSet { }; WorkspaceSet { + previously_active: None, active: 0, amount, group: group_handle, @@ -170,6 +172,7 @@ impl WorkspaceSet { let old_active = self.active; state.remove_workspace_state(&self.workspaces[old_active].handle, WState::Active); state.add_workspace_state(&self.workspaces[idx].handle, WState::Active); + self.previously_active = Some((old_active, Instant::now())); self.active = idx; } } @@ -180,12 +183,19 @@ impl WorkspaceSet { toplevel_info: &mut ToplevelInfoState, outputs: impl Iterator)>, ) { + if let Some((_, start)) = self.previously_active { + if Instant::now().duration_since(start).as_millis() >= ANIMATION_DURATION.as_millis() { + self.previously_active = None; + } + } + match self.amount { WorkspaceAmount::Dynamic => self.ensure_last_empty(state, outputs), WorkspaceAmount::Static(len) => { self.ensure_static(len as usize, state, toplevel_info, outputs) } } + self.workspaces[self.active].refresh(); } @@ -371,12 +381,20 @@ impl WorkspaceMode { } } - pub fn active(&self, output: &Output) -> &Workspace { + pub fn active(&self, output: &Output) -> (Option<(&Workspace, Instant)>, &Workspace) { match self { - WorkspaceMode::Global(set) => &set.workspaces[set.active], + WorkspaceMode::Global(set) => ( + set.previously_active + .map(|(idx, start)| (&set.workspaces[idx], start)), + &set.workspaces[set.active], + ), WorkspaceMode::OutputBound(sets, _) => { let set = sets.get(output).unwrap(); - &set.workspaces[set.active] + ( + set.previously_active + .map(|(idx, start)| (&set.workspaces[idx], start)), + &set.workspaces[set.active], + ) } } } @@ -391,12 +409,12 @@ impl WorkspaceMode { } } - pub fn active_num(&self, output: &Output) -> usize { + pub fn active_num(&self, output: &Output) -> (Option, usize) { match self { - WorkspaceMode::Global(set) => set.active, + WorkspaceMode::Global(set) => (set.previously_active.map(|(idx, _)| idx), set.active), WorkspaceMode::OutputBound(sets, _) => { let set = sets.get(output).unwrap(); - set.active + (set.previously_active.map(|(idx, _)| idx), set.active) } } } @@ -1050,7 +1068,12 @@ impl Shell { } pub fn animations_going(&self) -> bool { - matches!(self.overview_mode, OverviewMode::None) + (match &self.workspaces { + WorkspaceMode::Global(set) => set.previously_active.is_some(), + WorkspaceMode::OutputBound(sets, _) => { + sets.values().any(|set| set.previously_active.is_some()) + } + }) || matches!(self.overview_mode, OverviewMode::None) || self .workspaces .spaces() @@ -1233,7 +1256,7 @@ impl Shell { follow: bool, ) -> Option> { let (to_output, to_idx) = to; - let to_idx = to_idx.unwrap_or(state.common.shell.workspaces.active_num(to_output)); + let to_idx = to_idx.unwrap_or(state.common.shell.workspaces.active_num(to_output).1); if state .common .shell @@ -1245,7 +1268,7 @@ impl Shell { } if from_output == to_output - && to_idx == state.common.shell.workspaces.active_num(from_output) + && to_idx == state.common.shell.workspaces.active_num(from_output).1 { return None; } diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index e03abacc..832f7b6f 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -13,7 +13,7 @@ use crate::{ state::State, utils::prelude::*, wayland::{ - handlers::screencopy::{DropableSession, WORKSPACE_OVERVIEW_NAMESPACE}, + handlers::screencopy::DropableSession, protocols::{ screencopy::{BufferParams, Session as ScreencopySession}, toplevel_info::ToplevelInfoState, @@ -38,12 +38,12 @@ use smithay::{ ImportAll, ImportMem, Renderer, }, }, - desktop::{layer_map_for_output, space::SpaceElement, LayerSurface}, + desktop::{layer_map_for_output, space::SpaceElement}, input::{pointer::GrabStartData as PointerGrabStartData, Seat}, output::Output, reexports::wayland_server::protocol::wl_surface::WlSurface, utils::{Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Size}, - wayland::{seat::WaylandFocus, shell::wlr_layer::Layer}, + wayland::seat::WaylandFocus, xwayland::X11Surface, }; use std::{collections::HashMap, time::Instant}; @@ -470,7 +470,6 @@ impl Workspace { draw_focus_indicator: Option<&Seat>, overview: OverviewMode, indicator_thickness: u8, - exclude_workspace_overview: bool, ) -> Result>, OutputNotMapped> where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, @@ -488,32 +487,6 @@ impl Workspace { let layer_map = layer_map_for_output(output); if let Some(fullscreen) = self.fullscreen.get(output) { - // overlay layer surfaces - render_elements.extend( - layer_map - .layers() - .rev() - .filter(|s| { - s.layer() == Layer::Overlay - && !(exclude_workspace_overview - && s.namespace() == WORKSPACE_OVERVIEW_NAMESPACE) - }) - .filter_map(|surface| { - layer_map - .layer_geometry(surface) - .map(|geo| (geo.loc, surface)) - }) - .flat_map(|(loc, surface)| { - AsRenderElements::::render_elements::>( - surface, - renderer, - loc.to_physical_precise_round(output_scale), - Scale::from(output_scale), - 1.0, - ) - }), - ); - render_elements.extend( override_redirect_windows .iter() @@ -557,39 +530,6 @@ impl Workspace { // - keyboard window swapping // - resizing in tiling - // overlay and top layer surfaces - let lower = { - let (lower, upper): (Vec<&LayerSurface>, Vec<&LayerSurface>) = layer_map - .layers() - .rev() - .filter(|s| { - !(exclude_workspace_overview - && s.namespace() == "cosmic-workspace-overview") - }) - .partition(|s| matches!(s.layer(), Layer::Background | Layer::Bottom)); - - render_elements.extend( - upper - .into_iter() - .filter_map(|surface| { - layer_map - .layer_geometry(surface) - .map(|geo| (geo.loc, surface)) - }) - .flat_map(|(loc, surface)| { - AsRenderElements::::render_elements::>( - surface, - renderer, - loc.to_physical_precise_round(output_scale), - Scale::from(output_scale), - 1.0, - ) - }), - ); - - lower - }; - // OR windows above all render_elements.extend( override_redirect_windows @@ -609,6 +549,7 @@ impl Workspace { let focused = draw_focus_indicator.and_then(|seat| self.focus_stack.get(seat).last().cloned()); + // floating surfaces let alpha = match &overview { OverviewMode::Started(_, started) => { @@ -716,28 +657,6 @@ impl Workspace { .into(), ) } - - // bottom and background layer surfaces - { - render_elements.extend( - lower - .into_iter() - .filter_map(|surface| { - layer_map - .layer_geometry(surface) - .map(|geo| (geo.loc, surface)) - }) - .flat_map(|(loc, surface)| { - AsRenderElements::::render_elements::>( - surface, - renderer, - loc.to_physical_precise_round(output_scale), - Scale::from(output_scale), - 1.0, - ) - }), - ); - } } Ok(render_elements) diff --git a/src/wayland/handlers/screencopy.rs b/src/wayland/handlers/screencopy.rs index 467d9d9e..cc920b65 100644 --- a/src/wayland/handlers/screencopy.rs +++ b/src/wayland/handlers/screencopy.rs @@ -372,7 +372,13 @@ impl ScreencopyHandler for State { render_output_to_buffer(self, &session, params, &output) } SessionType::Workspace(output, handle) => { - render_workspace_to_buffer(self, &session, params, &output, &handle) + render_workspace_to_buffer( + self, + &session, + params, + &output, + (handle, 0), /* TODO: hack, we should have the index */ + ) } SessionType::Window(window) => { render_window_to_buffer(self, &session, params, &window) @@ -764,7 +770,7 @@ pub fn render_workspace_to_buffer( session: &Session, params: BufferParams, output: &Output, - handle: &WorkspaceHandle, + handle: (WorkspaceHandle, usize), ) -> Result { let mode = output .current_mode() @@ -783,7 +789,7 @@ pub fn render_workspace_to_buffer( common: &mut Common, session: &Session, output: &Output, - handle: &WorkspaceHandle, + handle: (WorkspaceHandle, usize), ) -> Result<(Option>>, RenderElementStates), DTError> where R: Renderer @@ -814,6 +820,7 @@ pub fn render_workspace_to_buffer( age, common, &output, + None, handle, cursor_mode, None, @@ -837,6 +844,7 @@ pub fn render_workspace_to_buffer( age, common, &output, + None, handle, cursor_mode, None, @@ -1304,7 +1312,7 @@ pub fn schedule_offscreen_workspace_session( &session, params.clone(), &output, - &handle, + (handle, 0), /* TODO: Hack, we should know the idx */ ) { Ok(false) => { // rendering yielded no new damage, buffer still pending From cb3e8d42a79438de521b4163ccf4b123479f0430 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 23 May 2023 19:21:25 +0200 Subject: [PATCH 009/264] shell: Fix animation getting stuck --- src/shell/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/mod.rs b/src/shell/mod.rs index e19fba27..961e01bf 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1073,7 +1073,7 @@ impl Shell { WorkspaceMode::OutputBound(sets, _) => { sets.values().any(|set| set.previously_active.is_some()) } - }) || matches!(self.overview_mode, OverviewMode::None) + }) || !matches!(self.overview_mode, OverviewMode::None) || self .workspaces .spaces() From be918152d5e20c01a8037536339ec2a6922d24c2 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 25 May 2023 00:10:24 +0200 Subject: [PATCH 010/264] shell: Implement Workspace Layout --- config.ron | 23 +--- src/backend/render/mod.rs | 2 +- src/config/mod.rs | 139 +++++++++++++++++++- src/input/mod.rs | 116 ++++++++++------ src/shell/mod.rs | 57 +++++--- src/wayland/handlers/toplevel_management.rs | 2 +- src/wayland/handlers/workspace.rs | 2 +- 7 files changed, 261 insertions(+), 80 deletions(-) diff --git a/config.ron b/config.ron index 19fd729f..8b8acdf6 100644 --- a/config.ron +++ b/config.ron @@ -25,24 +25,10 @@ (modifiers: [Super, Shift], key: "9"): MoveToWorkspace(9), (modifiers: [Super, Shift], key: "0"): MoveToLastWorkspace, - // TODO: Depends on workspace orientation - (modifiers: [Super, Ctrl], key: "Right"): NextWorkspace, - (modifiers: [Super, Ctrl], key: "Left"): PreviousWorkspace, - (modifiers: [Super, Ctrl, Shift], key: "Right"): MoveToNextWorkspace, - (modifiers: [Super, Ctrl, Shift], key: "Left"): MoveToPreviousWorkspace, - (modifiers: [Super, Ctrl], key: "l"): NextWorkspace, - (modifiers: [Super, Ctrl], key: "h"): PreviousWorkspace, - (modifiers: [Super, Ctrl, Shift], key: "l"): MoveToNextWorkspace, - (modifiers: [Super, Ctrl, Shift], key: "h"): MoveToPreviousWorkspace, - - (modifiers: [Super, Ctrl], key: "Down"): NextOutput, - (modifiers: [Super, Ctrl], key: "Up"): PreviousOutput, - (modifiers: [Super, Ctrl, Alt], key: "Down"): NextOutput, - (modifiers: [Super, Ctrl, Alt], key: "Up"): PreviousOutput, - (modifiers: [Super, Ctrl], key: "j"): NextOutput, - (modifiers: [Super, Ctrl], key: "k"): PreviousOutput, - (modifiers: [Super, Ctrl, Alt], key: "j"): NextOutput, - (modifiers: [Super, Ctrl, Alt], key: "k"): PreviousOutput, + (modifiers: [Super, Ctrl, Alt], key: "Down"): MoveToNextOutput, + (modifiers: [Super, Ctrl, Alt], key: "Up"): MoveToPreviousOutput, + (modifiers: [Super, Ctrl, Alt], key: "j"): MoveToNextOutput, + (modifiers: [Super, Ctrl, Alt], key: "k"): MoveToPreviousOutput, (modifiers: [Super], key: "Period"): NextOutput, (modifiers: [Super], key: "Comma"): PreviousOutput, @@ -93,5 +79,6 @@ }, workspace_mode: OutputBound, workspace_amount: Dynamic, + workspace_layout: Vertical, tiling_enabled: false, ) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index ec765b6d..88b34d09 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -396,7 +396,7 @@ where let offset = match previous.as_ref() { Some((previous, previous_idx, start)) => { - let layout = WorkspaceLayout::Vertical; + let layout = state.config.static_conf.workspace_layout; let workspace = state .shell diff --git a/src/config/mod.rs b/src/config/mod.rs index 19657c55..45143d5d 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -36,6 +36,8 @@ pub struct StaticConfig { pub key_bindings: HashMap, pub workspace_mode: WorkspaceMode, pub workspace_amount: WorkspaceAmount, + #[serde(default = "default_workspace_layout")] + pub workspace_layout: WorkspaceLayout, pub tiling_enabled: bool, #[serde(default = "default_active_hint")] pub active_hint: u8, @@ -95,6 +97,10 @@ fn default_gaps() -> (u8, u8) { (0, 4) } +fn default_workspace_layout() -> WorkspaceLayout { + WorkspaceLayout::Vertical +} + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] pub struct OutputConfig { pub mode: ((i32, i32), Option), @@ -232,8 +238,132 @@ impl Config { debug!("Trying config location: {}", path.display()); if path.exists() { info!("Using config at {}", path.display()); - return ron::de::from_reader(OpenOptions::new().read(true).open(path).unwrap()) - .expect("Malformed config file"); + let mut config: StaticConfig = + ron::de::from_reader(OpenOptions::new().read(true).open(path).unwrap()) + .expect("Malformed config file"); + + let (workspace_previous, workspace_next, output_previous, output_next) = + match config.workspace_layout { + WorkspaceLayout::Horizontal => ( + [KeySyms::KEY_Left, KeySyms::KEY_h], + [KeySyms::KEY_Right, KeySyms::KEY_j], + [KeySyms::KEY_Up, KeySyms::KEY_k], + [KeySyms::KEY_Down, KeySyms::KEY_j], + ), + WorkspaceLayout::Vertical => ( + [KeySyms::KEY_Up, KeySyms::KEY_k], + [KeySyms::KEY_Down, KeySyms::KEY_j], + [KeySyms::KEY_Left, KeySyms::KEY_h], + [KeySyms::KEY_Right, KeySyms::KEY_j], + ), + }; + + fn insert_binding( + key_bindings: &mut HashMap, + modifiers: KeyModifiers, + keys: impl Iterator, + action: Action, + ) { + if !key_bindings.values().any(|a| a == &action) { + for key in keys { + let pattern = KeyPattern { + modifiers: modifiers.clone(), + key, + }; + if !key_bindings.contains_key(&pattern) { + key_bindings.insert(pattern, action.clone()); + } + } + } + } + + insert_binding( + &mut config.key_bindings, + KeyModifiers { + logo: true, + ctrl: true, + ..Default::default() + }, + workspace_previous.iter().copied(), + Action::PreviousWorkspace, + ); + insert_binding( + &mut config.key_bindings, + KeyModifiers { + logo: true, + ctrl: true, + ..Default::default() + }, + workspace_next.iter().copied(), + Action::NextWorkspace, + ); + insert_binding( + &mut config.key_bindings, + KeyModifiers { + logo: true, + ctrl: true, + shift: true, + ..Default::default() + }, + workspace_previous.iter().copied(), + Action::MoveToPreviousWorkspace, + ); + insert_binding( + &mut config.key_bindings, + KeyModifiers { + logo: true, + ctrl: true, + shift: true, + ..Default::default() + }, + workspace_next.iter().copied(), + Action::MoveToNextWorkspace, + ); + + insert_binding( + &mut config.key_bindings, + KeyModifiers { + logo: true, + ctrl: true, + ..Default::default() + }, + output_previous.iter().copied(), + Action::PreviousOutput, + ); + insert_binding( + &mut config.key_bindings, + KeyModifiers { + logo: true, + ctrl: true, + ..Default::default() + }, + output_next.iter().copied(), + Action::NextOutput, + ); + insert_binding( + &mut config.key_bindings, + KeyModifiers { + logo: true, + ctrl: true, + shift: true, + ..Default::default() + }, + output_previous.iter().copied(), + Action::MoveToPreviousOutput, + ); + insert_binding( + &mut config.key_bindings, + KeyModifiers { + logo: true, + ctrl: true, + shift: true, + ..Default::default() + }, + output_next.iter().copied(), + Action::MoveToNextOutput, + ); + + return config; } } @@ -241,6 +371,7 @@ impl Config { key_bindings: HashMap::new(), workspace_mode: WorkspaceMode::Global, workspace_amount: WorkspaceAmount::Dynamic, + workspace_layout: WorkspaceLayout::Vertical, tiling_enabled: false, active_hint: default_active_hint(), gaps: default_gaps(), @@ -776,7 +907,7 @@ pub enum KeyModifier { NumLock, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] pub struct KeyModifiers { pub ctrl: bool, pub alt: bool, @@ -880,6 +1011,8 @@ pub enum Action { PreviousOutput, MoveToNextOutput, MoveToPreviousOutput, + SendToNextOutput, + SendToPreviousOutput, Focus(FocusDirection), Move(Direction), diff --git a/src/input/mod.rs b/src/input/mod.rs index 8640fe78..05bb3b54 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - config::{Action, Config, KeyModifiers}, + config::{Action, Config, KeyModifiers, WorkspaceLayout}, shell::{ focus::{target::PointerFocusTarget, FocusDirection}, layout::{ @@ -710,8 +710,14 @@ impl State { .active_num(¤t_output) .1 .saturating_add(1); - // TODO: Possibly move to next output, if idx to large - let _ = self.common.shell.activate(¤t_output, workspace); + if self + .common + .shell + .activate(¤t_output, workspace) + .is_err() + { + self.handle_action(Action::NextOutput, seat, serial, time, mods); + } } Action::PreviousWorkspace => { let current_output = seat.active_output(); @@ -722,8 +728,14 @@ impl State { .active_num(¤t_output) .1 .saturating_sub(1); - // TODO: Possibly move to prev output, if idx < 0 - let _ = self.common.shell.activate(¤t_output, workspace); + if self + .common + .shell + .activate(¤t_output, workspace) + .is_err() + { + self.handle_action(Action::PreviousOutput, seat, serial, time, mods); + } } Action::LastWorkspace => { let current_output = seat.active_output(); @@ -743,7 +755,7 @@ impl State { Action::MoveToWorkspace(x) | Action::SendToWorkspace(x) => x - 1, _ => unreachable!(), }; - Shell::move_current_window( + let _ = Shell::move_current_window( self, seat, ¤t_output, @@ -760,14 +772,27 @@ impl State { .active_num(¤t_output) .1 .saturating_add(1); - // TODO: Possibly move to next output, if idx too large - Shell::move_current_window( + if Shell::move_current_window( self, seat, ¤t_output, (¤t_output, Some(workspace as usize)), matches!(x, Action::MoveToNextWorkspace), - ); + ) + .is_err() + { + self.handle_action( + if matches!(x, Action::MoveToNextWorkspace) { + Action::MoveToNextOutput + } else { + Action::SendToNextOutput + }, + seat, + serial, + time, + mods, + ) + } } x @ Action::MoveToPreviousWorkspace | x @ Action::SendToPreviousWorkspace => { let current_output = seat.active_output(); @@ -779,13 +804,27 @@ impl State { .1 .saturating_sub(1); // TODO: Possibly move to prev output, if idx < 0 - Shell::move_current_window( + if Shell::move_current_window( self, seat, ¤t_output, (¤t_output, Some(workspace as usize)), matches!(x, Action::MoveToPreviousWorkspace), - ); + ) + .is_err() + { + self.handle_action( + if matches!(x, Action::MoveToNextWorkspace) { + Action::MoveToPreviousOutput + } else { + Action::SendToPreviousOutput + }, + seat, + serial, + time, + mods, + ) + } } x @ Action::MoveToLastWorkspace | x @ Action::SendToLastWorkspace => { let current_output = seat.active_output(); @@ -795,7 +834,7 @@ impl State { .workspaces .len(¤t_output) .saturating_sub(1); - Shell::move_current_window( + let _ = Shell::move_current_window( self, seat, ¤t_output, @@ -816,7 +855,7 @@ impl State { .cloned() { let idx = self.common.shell.workspaces.active_num(&next_output).1; - if let Some(new_pos) = self.common.shell.activate(&next_output, idx) { + if let Ok(Some(new_pos)) = self.common.shell.activate(&next_output, idx) { seat.set_active_output(&next_output); if let Some(ptr) = seat.get_pointer() { ptr.motion( @@ -846,7 +885,7 @@ impl State { .cloned() { let idx = self.common.shell.workspaces.active_num(&prev_output).1; - if let Some(new_pos) = self.common.shell.activate(&prev_output, idx) { + if let Ok(Some(new_pos)) = self.common.shell.activate(&prev_output, idx) { seat.set_active_output(&prev_output); if let Some(ptr) = seat.get_pointer() { ptr.motion( @@ -862,7 +901,7 @@ impl State { } } } - Action::MoveToNextOutput => { + x @ Action::MoveToNextOutput | x @ Action::SendToNextOutput => { let current_output = seat.active_output(); if let Some(next_output) = self .common @@ -874,12 +913,12 @@ impl State { .next() .cloned() { - if let Some(new_pos) = Shell::move_current_window( + if let Ok(Some(new_pos)) = Shell::move_current_window( self, seat, ¤t_output, (&next_output, None), - true, + matches!(x, Action::MoveToNextOutput), ) { if let Some(ptr) = seat.get_pointer() { ptr.motion( @@ -895,7 +934,7 @@ impl State { } } } - Action::MoveToPreviousOutput => { + x @ Action::MoveToPreviousOutput | x @ Action::SendToPreviousOutput => { let current_output = seat.active_output(); if let Some(prev_output) = self .common @@ -908,12 +947,12 @@ impl State { .next() .cloned() { - if let Some(new_pos) = Shell::move_current_window( + if let Ok(Some(new_pos)) = Shell::move_current_window( self, seat, ¤t_output, (&prev_output, None), - true, + matches!(x, Action::MoveToPreviousOutput), ) { if let Some(ptr) = seat.get_pointer() { ptr.motion( @@ -942,22 +981,20 @@ impl State { match result { FocusResult::None => { - // TODO: Handle Workspace orientation - match focus { - FocusDirection::Left => self.handle_action( - Action::PreviousWorkspace, - seat, - serial, - time, - mods, - ), - FocusDirection::Right => { + match (focus, self.common.config.static_conf.workspace_layout) { + (FocusDirection::Left, WorkspaceLayout::Horizontal) + | (FocusDirection::Up, WorkspaceLayout::Vertical) => self + .handle_action(Action::PreviousWorkspace, seat, serial, time, mods), + (FocusDirection::Right, WorkspaceLayout::Horizontal) + | (FocusDirection::Down, WorkspaceLayout::Vertical) => { self.handle_action(Action::NextWorkspace, seat, serial, time, mods) } - FocusDirection::Up => { + (FocusDirection::Left, WorkspaceLayout::Vertical) + | (FocusDirection::Up, WorkspaceLayout::Horizontal) => { self.handle_action(Action::PreviousOutput, seat, serial, time, mods) } - FocusDirection::Down => { + (FocusDirection::Right, WorkspaceLayout::Vertical) + | (FocusDirection::Down, WorkspaceLayout::Horizontal) => { self.handle_action(Action::NextOutput, seat, serial, time, mods) } _ => {} @@ -980,31 +1017,34 @@ impl State { if let Some(_move_further) = workspace.tiling_layer.move_current_window(direction, seat) { - // TODO: Handle Workspace orientation // TODO: Being able to move Groups (move_further should be KeyboardFocusTarget instead) - match direction { - Direction::Left => self.handle_action( + match (direction, self.common.config.static_conf.workspace_layout) { + (Direction::Left, WorkspaceLayout::Horizontal) + | (Direction::Up, WorkspaceLayout::Vertical) => self.handle_action( Action::MoveToPreviousWorkspace, seat, serial, time, mods, ), - Direction::Right => self.handle_action( + (Direction::Right, WorkspaceLayout::Horizontal) + | (Direction::Down, WorkspaceLayout::Vertical) => self.handle_action( Action::MoveToNextWorkspace, seat, serial, time, mods, ), - Direction::Up => self.handle_action( + (Direction::Left, WorkspaceLayout::Vertical) + | (Direction::Up, WorkspaceLayout::Horizontal) => self.handle_action( Action::MoveToPreviousOutput, seat, serial, time, mods, ), - Direction::Down => { + (Direction::Right, WorkspaceLayout::Vertical) + | (Direction::Down, WorkspaceLayout::Horizontal) => { self.handle_action(Action::MoveToNextOutput, seat, serial, time, mods) } } diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 961e01bf..bc24d642 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -167,13 +167,24 @@ impl WorkspaceSet { } } - fn activate(&mut self, idx: usize, state: &mut WorkspaceUpdateGuard<'_, State>) { - if idx < self.workspaces.len() && self.active != idx { + fn activate( + &mut self, + idx: usize, + state: &mut WorkspaceUpdateGuard<'_, State>, + ) -> Result { + if idx >= self.workspaces.len() { + return Err(InvalidWorkspaceIndex); + } + + if self.active != idx { let old_active = self.active; state.remove_workspace_state(&self.workspaces[old_active].handle, WState::Active); state.add_workspace_state(&self.workspaces[idx].handle, WState::Active); self.previously_active = Some((old_active, Instant::now())); self.active = idx; + Ok(true) + } else { + Ok(false) } } @@ -476,6 +487,8 @@ impl WorkspaceMode { } } +pub struct InvalidWorkspaceIndex; + impl Shell { pub fn new(config: &Config, dh: &DisplayHandle) -> Self { // TODO: Privileged protocols @@ -893,20 +906,28 @@ impl Shell { self.refresh(); // get rid of empty workspaces and enforce potential maximum } - pub fn activate(&mut self, output: &Output, idx: usize) -> Option> { - match &mut self.workspaces { + pub fn activate( + &mut self, + output: &Output, + idx: usize, + ) -> Result>, InvalidWorkspaceIndex> { + if match &mut self.workspaces { WorkspaceMode::OutputBound(sets, _) => { if let Some(set) = sets.get_mut(output) { - set.activate(idx, &mut self.workspace_state.update()); + set.activate(idx, &mut self.workspace_state.update())? + } else { + false } } - WorkspaceMode::Global(set) => { - set.activate(idx, &mut self.workspace_state.update()); - } + WorkspaceMode::Global(set) => set.activate(idx, &mut self.workspace_state.update())?, + } { + let output_geo = output.geometry(); + Ok(Some( + output_geo.loc + Point::from((output_geo.size.w / 2, output_geo.size.h / 2)), + )) + } else { + Ok(None) } - - let output_geo = output.geometry(); - Some(output_geo.loc + Point::from((output_geo.size.w / 2, output_geo.size.h / 2))) } pub fn active_space(&self, output: &Output) -> &Workspace { @@ -1254,7 +1275,7 @@ impl Shell { from_output: &Output, to: (&Output, Option), follow: bool, - ) -> Option> { + ) -> Result>, InvalidWorkspaceIndex> { let (to_output, to_idx) = to; let to_idx = to_idx.unwrap_or(state.common.shell.workspaces.active_num(to_output).1); if state @@ -1264,20 +1285,20 @@ impl Shell { .get(to_idx, to_output) .is_none() { - return None; + return Err(InvalidWorkspaceIndex); } if from_output == to_output && to_idx == state.common.shell.workspaces.active_num(from_output).1 { - return None; + return Ok(None); } let from_workspace = state.common.shell.workspaces.active_mut(from_output); let maybe_window = from_workspace.focus_stack.get(seat).last().cloned(); - let Some(mapped) = maybe_window else { return None; }; - let Some(window_state) = from_workspace.unmap(&mapped) else { return None; }; + let Some(mapped) = maybe_window else { return Ok(None); }; + let Some(window_state) = from_workspace.unmap(&mapped) else { return Ok(None); }; for (toplevel, _) in mapped.windows() { state @@ -1300,7 +1321,7 @@ impl Shell { } let new_pos = if follow { seat.set_active_output(&to_output); - state.common.shell.activate(to_output, to_idx) + state.common.shell.activate(to_output, to_idx)? } else { None }; @@ -1345,7 +1366,7 @@ impl Shell { if follow { Common::set_focus(state, Some(&KeyboardFocusTarget::from(mapped)), &seat, None); } - new_pos + Ok(new_pos) } pub fn update_reactive_popups(&self, mapped: &CosmicMapped) { diff --git a/src/wayland/handlers/toplevel_management.rs b/src/wayland/handlers/toplevel_management.rs index 786be8bd..d4440908 100644 --- a/src/wayland/handlers/toplevel_management.rs +++ b/src/wayland/handlers/toplevel_management.rs @@ -48,7 +48,7 @@ impl ToplevelManagementHandler for State { .unwrap() .clone(); - self.common.shell.activate(&output, idx as usize); + let _ = self.common.shell.activate(&output, idx as usize); // TODO: Move pointer? mapped.focus_window(window); Common::set_focus(self, Some(&mapped.clone().into()), &seat, None); return; diff --git a/src/wayland/handlers/workspace.rs b/src/wayland/handlers/workspace.rs index eecc24c6..56b268b7 100644 --- a/src/wayland/handlers/workspace.rs +++ b/src/wayland/handlers/workspace.rs @@ -45,7 +45,7 @@ impl WorkspaceHandler for State { }; if let Some((output, idx)) = maybe { - self.common.shell.activate(&output, idx); + let _ = self.common.shell.activate(&output, idx); // TODO: move cursor? } } _ => {} From bc9f673c7b7473647b241074343f2703690c0249 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 25 May 2023 00:15:00 +0200 Subject: [PATCH 011/264] chore: Update smithay --- Cargo.lock | 392 +++++++++++++++++++++++++++++++++++------------------ Cargo.toml | 2 +- 2 files changed, 261 insertions(+), 133 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8082ce9f..9038236d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,6 +76,30 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" +[[package]] +name = "android-activity" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c77a0045eda8b888c76ea473c2b0515ba6f471d318f8927c5c72240937035a6" +dependencies = [ + "android-properties", + "bitflags 1.3.2", + "cc", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -148,7 +172,7 @@ version = "0.37.2+1.3.238" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28bf19c1f0a470be5fbf7522a308a05df06610252c5bcf5143e1b23f629a9a03" dependencies = [ - "libloading", + "libloading 0.7.4", ] [[package]] @@ -220,6 +244,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" + [[package]] name = "block" version = "0.1.6" @@ -235,11 +265,30 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-sys" +version = "0.1.0-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "block2" +version = "0.2.0-alpha.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" +dependencies = [ + "block-sys", + "objc2-encode", +] + [[package]] name = "bumpalo" -version = "3.12.2" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytemuck" @@ -258,7 +307,7 @@ checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -368,7 +417,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "block", "cocoa-foundation", "core-foundation", @@ -384,7 +433,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "931d3837c286f56e3c58423ce4eba12d08db2374461a785c86f672b08b5650d6" dependencies = [ - "bitflags", + "bitflags 1.3.2", "block", "core-foundation", "core-graphics-types", @@ -443,7 +492,7 @@ version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-graphics-types", "foreign-types 0.3.2", @@ -456,7 +505,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "foreign-types 0.3.2", "libc", @@ -479,7 +528,7 @@ name = "cosmic-comp" version = "0.1.0" dependencies = [ "anyhow", - "bitflags", + "bitflags 1.3.2", "bytemuck", "calloop", "cosmic-protocols", @@ -522,7 +571,7 @@ name = "cosmic-protocols" version = "0.1.0" source = "git+https://github.com/pop-os/cosmic-protocols?branch=main#7d80b59afc464a8ecdb8001333f18de554f299f4" dependencies = [ - "bitflags", + "bitflags 1.3.2", "wayland-backend", "wayland-protocols 0.30.0", "wayland-scanner 0.30.0", @@ -551,7 +600,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-theme.git#a1258308a894c5c7bbe6e261271e8476d55955d3" +source = "git+https://github.com/pop-os/cosmic-theme.git#ce3a63a10638195c7b5a47224c89a82c2fa9494d" dependencies = [ "anyhow", "csscolorparser", @@ -697,8 +746,8 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "827914e1f53b1e0e025ecd3d967a7836b7bcb54520f90e21ef8df7b4d88a2759" dependencies = [ - "bitflags", - "libloading", + "bitflags 1.3.2", + "libloading 0.7.4", "winapi", ] @@ -708,8 +757,8 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8f0de2f5a8e7bd4a9eec0e3c781992a4ce1724f68aec7d7a3715344de8b39da" dependencies = [ - "bitflags", - "libloading", + "bitflags 1.3.2", + "libloading 0.7.4", "winapi", ] @@ -812,9 +861,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", "crypto-common", @@ -862,7 +911,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" dependencies = [ - "libloading", + "libloading 0.7.4", ] [[package]] @@ -883,7 +932,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edf9159ef4bcecd0c5e4cbeb573b8d0037493403d542780dba5d840bbf9df56f" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytemuck", "drm-ffi", "drm-fourcc", @@ -1308,7 +1357,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -1352,7 +1401,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb" dependencies = [ - "bitflags", + "bitflags 1.3.2", "freetype-sys", "libc", ] @@ -1425,7 +1474,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -1473,7 +1522,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ec389cda876966cf824111bf6e533fb934c711d473498279964a990853b3c6" dependencies = [ - "bitflags", + "bitflags 1.3.2", "drm", "drm-fourcc", "gbm-sys", @@ -1637,7 +1686,7 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22beaafc29b38204457ea030f6fb7a84c9e4dd1b86e311ba0542533453d87f62" dependencies = [ - "bitflags", + "bitflags 1.3.2", "gpu-alloc-types", ] @@ -1647,7 +1696,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1669,7 +1718,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b0c02e1ba0bdb14e965058ca34e09c020f8e507a760df1121728e0aef68d57a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "gpu-descriptor-types", "hashbrown", ] @@ -1680,7 +1729,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1717,10 +1766,10 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90601c6189668c7345fc53842cb3f3a3d872203d523be1b3cb44a36a3e62fb85" dependencies = [ - "bitflags", + "bitflags 1.3.2", "com-rs", "libc", - "libloading", + "libloading 0.7.4", "thiserror", "widestring", "winapi", @@ -1802,7 +1851,7 @@ name = "iced_core" version = "0.6.2" source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "palette", "wasm-timer", ] @@ -1813,7 +1862,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11e1942e28dedee756cc27e67e7a838cdc1e59fb6bf9627ec9f709ab3b135782" dependencies = [ - "bitflags", + "bitflags 1.3.2", "instant", "palette", ] @@ -1876,7 +1925,7 @@ name = "iced_graphics" version = "0.5.0" source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytemuck", "glam", "iced_native 0.7.0", @@ -1897,7 +1946,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "338a6aff7db906537074ad0fe8b720cfdb9512cdfea43c628c76bd1cf50fdcc0" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytemuck", "glam", "iced_native 0.10.3", @@ -1985,7 +2034,7 @@ name = "iced_wgpu" version = "0.7.0" source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytemuck", "encase", "futures", @@ -2006,7 +2055,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478803c56061f567ce5ddf223b20d11d3c118cc46bb0d0552370dc65cdc4cb9c" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytemuck", "encase", "futures", @@ -2035,7 +2084,7 @@ dependencies = [ "web-sys", "winapi", "window_clipboard", - "winit", + "winit 0.27.5", ] [[package]] @@ -2094,7 +2143,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eeb3afdf1f8137428002b354eaf87aa629178995683941d94b04c6d145ec8937" dependencies = [ - "bitflags", + "bitflags 1.3.2", "input-sys", "io-lifetimes", "libc", @@ -2171,9 +2220,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.62" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5" +checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" dependencies = [ "wasm-bindgen", ] @@ -2194,7 +2243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" dependencies = [ "libc", - "libloading", + "libloading 0.7.4", "pkg-config", ] @@ -2262,11 +2311,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "libloading" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "libm" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "libseat" @@ -2324,9 +2383,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "lock_api" @@ -2449,7 +2508,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de11355d1f6781482d027a3b4d4de7825dcedb197bf573e0596d00008402d060" dependencies = [ - "bitflags", + "bitflags 1.3.2", "block", "core-graphics-types", "foreign-types 0.3.2", @@ -2507,7 +2566,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "262d2840e72dbe250e8cf2f522d080988dfca624c4112c096238a4845f591707" dependencies = [ "bit-set", - "bitflags", + "bitflags 1.3.2", "codespan-reporting", "hexf-parse", "indexmap", @@ -2522,12 +2581,12 @@ dependencies = [ [[package]] name = "naga" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eafe22a23b797c9bc227c6c896419b26b5bb88fa903417a3adaed08778850d5" +checksum = "6c3d4269bcb7d50121097702fde1afb75f4ea8083aeb7a55688dcf289a853271" dependencies = [ "bit-set", - "bitflags", + "bitflags 1.3.2", "codespan-reporting", "hexf-parse", "indexmap", @@ -2561,7 +2620,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" dependencies = [ - "bitflags", + "bitflags 1.3.2", "jni-sys", "ndk-sys", "num_enum", @@ -2619,7 +2678,7 @@ version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cc", "cfg-if", "libc", @@ -2632,7 +2691,7 @@ version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cc", "cfg-if", "libc", @@ -2645,7 +2704,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.6.5", @@ -2658,7 +2717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ "autocfg", - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.6.5", @@ -2670,7 +2729,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "memoffset 0.7.1", @@ -2832,6 +2891,32 @@ dependencies = [ "objc_id", ] +[[package]] +name = "objc-sys" +version = "0.2.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" + +[[package]] +name = "objc2" +version = "0.3.0-beta.3.patch-leaks.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" +dependencies = [ + "block2", + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "2.0.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" +dependencies = [ + "objc-sys", +] + [[package]] name = "objc_exception" version = "0.1.2" @@ -2865,6 +2950,15 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "orbclient" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "221d488cd70617f1bd599ed8ceb659df2147d9393717954d82a0f5e8032a6ab1" +dependencies = [ + "redox_syscall 0.3.5", +] + [[package]] name = "ordered-float" version = "3.7.0" @@ -3081,22 +3175,22 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", ] [[package]] @@ -3123,7 +3217,7 @@ version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aaeebc51f9e7d2c150d3f3bfeb667f2aa985db5ef1e3d212847bdedb488beeaa" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crc32fast", "fdeflate", "flate2", @@ -3172,9 +3266,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" dependencies = [ "unicode-ident", ] @@ -3375,7 +3469,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -3384,7 +3478,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -3400,13 +3494,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +checksum = "d1a59b5d8e97dee33696bf13c5ba8ab85341c002922fba050069326b9c498974" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.1", + "regex-syntax 0.7.2", ] [[package]] @@ -3426,9 +3520,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "renderdoc" @@ -3436,9 +3530,9 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42e14087d51efd3b42eb341e37b6f320af2b0750519ea849cb68bb7289643ed" dependencies = [ - "bitflags", + "bitflags 1.3.2", "float-cmp 0.8.0", - "libloading", + "libloading 0.7.4", "once_cell", "renderdoc-sys", "winapi", @@ -3497,7 +3591,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" dependencies = [ "base64", - "bitflags", + "bitflags 1.3.2", "serde", ] @@ -3508,7 +3602,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300a51053b1cb55c80b7a9fde4120726ddf25ca241a1cbb926626f62fb136bff" dependencies = [ "base64", - "bitflags", + "bitflags 1.3.2", "serde", ] @@ -3558,7 +3652,7 @@ version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno 0.3.1", "io-lifetimes", "libc", @@ -3572,7 +3666,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44561062e583c4873162861261f16fd1d85fe927c4904d71329a4fe43dc355ef" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytemuck", "smallvec", "ttf-parser 0.12.3", @@ -3588,7 +3682,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "162bdf42e261bee271b3957691018634488084ef577dddeb6420a9684cab2a6a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytemuck", "libm", "smallvec", @@ -3681,7 +3775,7 @@ checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -3790,11 +3884,11 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "smithay" version = "0.3.0" -source = "git+https://github.com/pop-os/smithay?branch=tiling_rework#920556dd8f5b16609fee20a44191add364740e61" +source = "git+https://github.com/smithay//smithay?rev=1966c6c8e4#1966c6c8e42273b5d6f356e94dc683a230b3fc21" dependencies = [ "appendlist", "ash", - "bitflags", + "bitflags 2.3.1", "calloop", "cc", "cgmath", @@ -3810,7 +3904,7 @@ dependencies = [ "input", "lazy_static", "libc", - "libloading", + "libloading 0.8.0", "libseat", "nix 0.26.2", "once_cell", @@ -3829,7 +3923,7 @@ dependencies = [ "wayland-protocols-wlr", "wayland-server", "wayland-sys 0.30.1", - "winit", + "winit 0.28.6", "x11rb 0.11.1", "xkbcommon 0.5.0", ] @@ -3840,7 +3934,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454" dependencies = [ - "bitflags", + "bitflags 1.3.2", "calloop", "dlib", "lazy_static", @@ -3927,7 +4021,7 @@ version = "0.2.0+1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" dependencies = [ - "bitflags", + "bitflags 1.3.2", "num-traits", ] @@ -3972,9 +4066,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "svg_fmt" @@ -4030,9 +4124,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.15" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" dependencies = [ "proc-macro2", "quote", @@ -4091,7 +4185,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4229,15 +4323,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" [[package]] name = "toml_edit" -version = "0.19.8" +version = "0.19.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" dependencies = [ "indexmap", "toml_datetime", @@ -4264,7 +4358,7 @@ checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4533,9 +4627,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" +checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4543,24 +4637,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" +checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.35" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "083abe15c5d88556b77bdf7aef403625be9e327ad37c62c4e4129af740168163" +checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" dependencies = [ "cfg-if", "js-sys", @@ -4570,9 +4664,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" +checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4580,22 +4674,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" +checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" +checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" [[package]] name = "wasm-timer" @@ -4633,7 +4727,7 @@ version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" dependencies = [ - "bitflags", + "bitflags 1.3.2", "downcast-rs", "libc", "nix 0.24.3", @@ -4649,7 +4743,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85bde68449abab1a808e5227b6e295f4ae3680911eb7711b4a2cb90141edb780" dependencies = [ - "bitflags", + "bitflags 1.3.2", "nix 0.26.2", "wayland-backend", "wayland-scanner 0.30.0", @@ -4694,7 +4788,7 @@ version = "0.29.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" dependencies = [ - "bitflags", + "bitflags 1.3.2", "wayland-client 0.29.5", "wayland-commons", "wayland-scanner 0.29.5", @@ -4706,7 +4800,7 @@ version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fefbeb8a360abe67ab7c2efe1d297a1a50ee011f5460791bc18870c26bb84e2" dependencies = [ - "bitflags", + "bitflags 1.3.2", "wayland-backend", "wayland-scanner 0.30.0", "wayland-server", @@ -4718,7 +4812,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897d4e99645e1ed9245e9e6b5efa78828d2b23b661016d63d55251243d812f8b" dependencies = [ - "bitflags", + "bitflags 1.3.2", "wayland-backend", "wayland-protocols 0.30.0", "wayland-scanner 0.30.0", @@ -4731,7 +4825,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fce991093320e4a6a525876e6b629ab24da25f9baef0c2e0080ad173ec89588a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "wayland-backend", "wayland-protocols 0.30.0", "wayland-scanner 0.30.0", @@ -4766,7 +4860,7 @@ version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9062def387c1b1d80e366d8243c2b3bd6d9e4f343032a3e5da8d4aa03866cf89" dependencies = [ - "bitflags", + "bitflags 1.3.2", "downcast-rs", "io-lifetimes", "nix 0.26.2", @@ -4801,9 +4895,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.62" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721" +checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" dependencies = [ "js-sys", "wasm-bindgen", @@ -4847,7 +4941,7 @@ dependencies = [ "cfg-if", "js-sys", "log", - "naga 0.11.0", + "naga 0.11.1", "parking_lot 0.12.1", "profiling", "raw-window-handle 0.5.2", @@ -4869,7 +4963,7 @@ checksum = "6000d1284ef8eec6076fd5544a73125fd7eb9b635f18dceeb829d826f41724ca" dependencies = [ "arrayvec 0.7.2", "bit-vec", - "bitflags", + "bitflags 1.3.2", "cfg_aliases", "codespan-reporting", "fxhash", @@ -4893,11 +4987,11 @@ checksum = "7131408d940e335792645a98f03639573b0480e9e2e7cddbbab74f7c6d9f3fff" dependencies = [ "arrayvec 0.7.2", "bit-vec", - "bitflags", + "bitflags 1.3.2", "codespan-reporting", "fxhash", "log", - "naga 0.11.0", + "naga 0.11.1", "parking_lot 0.12.1", "profiling", "raw-window-handle 0.5.2", @@ -4918,7 +5012,7 @@ dependencies = [ "arrayvec 0.7.2", "ash", "bit-set", - "bitflags", + "bitflags 1.3.2", "block", "core-graphics-types", "d3d12 0.5.0", @@ -4929,7 +5023,7 @@ dependencies = [ "gpu-descriptor", "js-sys", "khronos-egl", - "libloading", + "libloading 0.7.4", "log", "metal", "naga 0.10.0", @@ -4957,7 +5051,7 @@ dependencies = [ "arrayvec 0.7.2", "ash", "bit-set", - "bitflags", + "bitflags 1.3.2", "block", "core-graphics-types", "d3d12 0.6.0", @@ -4971,10 +5065,10 @@ dependencies = [ "js-sys", "khronos-egl", "libc", - "libloading", + "libloading 0.7.4", "log", "metal", - "naga 0.11.0", + "naga 0.11.1", "objc", "parking_lot 0.12.1", "profiling", @@ -4995,7 +5089,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb6b28ef22cac17b9109b25b3bf8c9a103eeb293d7c5f78653979b09140375f6" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -5004,7 +5098,7 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32444e121b0bd00cb02c0de32fde457a9491bd44e03e7a5db6df9b1da2f6f110" dependencies = [ - "bitflags", + "bitflags 1.3.2", "js-sys", "web-sys", ] @@ -5298,7 +5392,7 @@ version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cocoa", "core-foundation", "core-graphics", @@ -5325,6 +5419,40 @@ dependencies = [ "x11-dl", ] +[[package]] +name = "winit" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "866db3f712fffba75d31bf0cdecf357c8aeafd158c5b7ab51dba2a2b2d47f196" +dependencies = [ + "android-activity", + "bitflags 1.3.2", + "cfg_aliases", + "core-foundation", + "core-graphics", + "dispatch", + "instant", + "libc", + "log", + "mio", + "ndk", + "objc2", + "once_cell", + "orbclient", + "percent-encoding", + "raw-window-handle 0.5.2", + "redox_syscall 0.3.5", + "smithay-client-toolkit", + "wasm-bindgen", + "wayland-client 0.29.5", + "wayland-commons", + "wayland-protocols 0.29.5", + "wayland-scanner 0.29.5", + "web-sys", + "windows-sys 0.45.0", + "x11-dl", +] + [[package]] name = "winnow" version = "0.4.6" @@ -5374,7 +5502,7 @@ checksum = "cdf3c79412dd91bae7a7366b8ad1565a85e35dd049affc3a6a2c549e97419617" dependencies = [ "gethostname", "libc", - "libloading", + "libloading 0.7.4", "nix 0.25.1", "once_cell", "winapi", @@ -5436,9 +5564,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.10" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc95a04ea24f543cd9be5aab44f963fa35589c99e18415c38fb2b17e133bf8d2" +checksum = "2d8f380ae16a37b30e6a2cf67040608071384b1450c189e61bea3ff57cde922d" [[package]] name = "xmlparser" diff --git a/Cargo.toml b/Cargo.toml index 38d8b160..3bd90880 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,4 +74,4 @@ debug = true lto = "fat" [patch."https://github.com/Smithay/smithay.git"] -smithay = { git = "https://github.com/pop-os/smithay", branch = "tiling_rework" } +smithay = { git = "https://github.com/smithay//smithay", rev = "1966c6c8e4" } From 8201ba023d44dc6a113a60a4b8cb29da4c8f9f1b Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 25 May 2023 14:49:41 +0200 Subject: [PATCH 012/264] input: Consider any unpressed modifier to cancel overview mode Fixes #115. --- src/input/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index 05bb3b54..8427827f 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -232,10 +232,10 @@ impl State { if let OverviewMode::Started(action_modifiers, _) = data.common.shell.overview_mode() { - if !(action_modifiers.ctrl && modifiers.ctrl) - && !(action_modifiers.alt && modifiers.alt) - && !(action_modifiers.logo && modifiers.logo) - && !(action_modifiers.shift && modifiers.shift) + if (!action_modifiers.ctrl || modifiers.ctrl) + && (!action_modifiers.alt || modifiers.alt) + && (!action_modifiers.logo || modifiers.logo) + && (!action_modifiers.shift || modifiers.shift) { data.common.shell.set_overview_mode(None); } From 82553311428be5c248068bb75ff9fd642e115e7c Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 25 May 2023 14:52:09 +0200 Subject: [PATCH 013/264] tiling: Align root level windows with root-level group windows Fixes #119. --- src/shell/layout/tiling/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index e5e53453..69dbea82 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1749,7 +1749,11 @@ where ) .into(), ); + } + if is_potential_group + || node.parent().map(|parent| parent == root).unwrap_or(false) + { geo.loc += (gap, gap).into(); geo.size -= (gap * 2, gap * 2).into(); } From 6078fc30bad23d62edf04df5bcee7ca458b72a9d Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 25 May 2023 16:42:01 +0200 Subject: [PATCH 014/264] tiling: Fix sizing when removing windows from group. At least partially fixes #118. --- src/shell/layout/tiling/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 69dbea82..12d9e997 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -217,9 +217,11 @@ impl Data { Orientation::Vertical => last_geometry.size.w, }; let old_size = sizes.remove(idx); + let remaining_size: i32 = sizes.iter().sum(); + for size in sizes.iter_mut() { *size += - ((old_size as f64 / last_length as f64) * (*size as f64)).round() as i32; + ((*size as f64 / remaining_size as f64) * old_size as f64).round() as i32; } let used_size: i32 = sizes.iter().sum(); let overflow = last_length - used_size; From 985a49483fd640f26e4adee56e2e26048b4259c0 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 25 May 2023 16:42:27 +0200 Subject: [PATCH 015/264] tiling: Move window into sibling group, if orientation matches Fixes #114. --- src/shell/layout/tiling/mod.rs | 47 +++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 12d9e997..d6acc0ff 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -597,7 +597,7 @@ impl TilingLayout { .position(|id| id == &child_id) .unwrap(); - // if the orientation does not match, we want to create a new group with our parent. + // if the orientation does not match.. if matches!( (orientation, direction), (Orientation::Horizontal, Direction::Right) @@ -605,6 +605,51 @@ impl TilingLayout { | (Orientation::Vertical, Direction::Up) | (Orientation::Vertical, Direction::Down) ) { + if parent_data.len() == 2 { + if let Some(sibling) = tree + .children_ids(&parent) + .unwrap() + .find(|id| *id != &child_id) + .cloned() + { + let sibling_data = tree.get(&sibling).unwrap().data(); + if sibling_data.is_group() { + let sibling_orientation = sibling_data.orientation(); + if matches!( + (sibling_orientation, direction), + (Orientation::Vertical, Direction::Right) + | (Orientation::Vertical, Direction::Left) + | (Orientation::Horizontal, Direction::Up) + | (Orientation::Horizontal, Direction::Down) + ) { + // ..lets move into our sibling group instead + + let idx = + if direction == Direction::Left || direction == Direction::Up { + 0 + } else { + sibling_data.len() + }; + tree.move_node(&node_id, MoveBehavior::ToParent(&sibling)) + .unwrap(); + tree.make_nth_sibling(&node_id, idx).unwrap(); + + tree.get_mut(&sibling).unwrap().data_mut().add_window(idx); + tree.get_mut(&og_parent) + .unwrap() + .data_mut() + .remove_window(og_idx); + + let blocker = + TilingLayout::update_positions(&output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); + return None; + } + } + } + } + + // or create a new group with our parent (cleanup will remove any one-child-groups afterwards) TilingLayout::new_group( &mut tree, &parent, From bf0eb97bea5d46cd0de53057ceb093040bef85aa Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 25 May 2023 17:07:14 +0200 Subject: [PATCH 016/264] tiling: Fix reversed direction, when grouping with middle nodes Fixes first case of #113 --- src/shell/layout/tiling/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index d6acc0ff..127ccfd7 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -722,7 +722,7 @@ impl TilingLayout { } _ => None, } { - // if we can, we need to check the next element and move "into" it (down) + // if we can, we need to check the next element and move "into" it let next_child_id = tree .children_ids(&parent) .unwrap() @@ -777,9 +777,9 @@ impl TilingLayout { tree.make_nth_sibling( &node_id, if direction == Direction::Left || direction == Direction::Up { - 0 - } else { 1 + } else { + 0 }, ) .unwrap(); From 2f6d4da7124b8a6d176aa9fd806b2c85dd7e0dd9 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 25 May 2023 17:51:53 +0200 Subject: [PATCH 017/264] tiling: Consider direction when moving across workspaces and outputs Fixes second case of #113. --- src/input/mod.rs | 74 ++++++++++++++++++++++++++-------- src/shell/layout/tiling/mod.rs | 67 ++++++++++++++++++++---------- src/shell/mod.rs | 7 ++-- src/shell/workspace.rs | 6 ++- 4 files changed, 112 insertions(+), 42 deletions(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index 8427827f..733fb479 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -308,7 +308,7 @@ impl State { ) .flatten() { - self.handle_action(action, seat, serial, time, mods) + self.handle_action(action, seat, serial, time, mods, None) } break; } @@ -660,6 +660,7 @@ impl State { serial: Serial, time: u32, mods: KeyModifiers, + direction: Option, ) { match action { Action::Terminate => { @@ -716,7 +717,7 @@ impl State { .activate(¤t_output, workspace) .is_err() { - self.handle_action(Action::NextOutput, seat, serial, time, mods); + self.handle_action(Action::NextOutput, seat, serial, time, mods, direction); } } Action::PreviousWorkspace => { @@ -734,7 +735,7 @@ impl State { .activate(¤t_output, workspace) .is_err() { - self.handle_action(Action::PreviousOutput, seat, serial, time, mods); + self.handle_action(Action::PreviousOutput, seat, serial, time, mods, direction); } } Action::LastWorkspace => { @@ -761,6 +762,7 @@ impl State { ¤t_output, (¤t_output, Some(workspace as usize)), follow, + None, ); } x @ Action::MoveToNextWorkspace | x @ Action::SendToNextWorkspace => { @@ -778,6 +780,7 @@ impl State { ¤t_output, (¤t_output, Some(workspace as usize)), matches!(x, Action::MoveToNextWorkspace), + direction, ) .is_err() { @@ -791,6 +794,7 @@ impl State { serial, time, mods, + direction, ) } } @@ -810,6 +814,7 @@ impl State { ¤t_output, (¤t_output, Some(workspace as usize)), matches!(x, Action::MoveToPreviousWorkspace), + direction, ) .is_err() { @@ -823,6 +828,7 @@ impl State { serial, time, mods, + direction, ) } } @@ -840,6 +846,7 @@ impl State { ¤t_output, (¤t_output, Some(workspace as usize)), matches!(x, Action::MoveToLastWorkspace), + None, ); } Action::NextOutput => { @@ -919,6 +926,7 @@ impl State { ¤t_output, (&next_output, None), matches!(x, Action::MoveToNextOutput), + direction, ) { if let Some(ptr) = seat.get_pointer() { ptr.motion( @@ -953,6 +961,7 @@ impl State { ¤t_output, (&prev_output, None), matches!(x, Action::MoveToPreviousOutput), + direction, ) { if let Some(ptr) = seat.get_pointer() { ptr.motion( @@ -984,19 +993,44 @@ impl State { match (focus, self.common.config.static_conf.workspace_layout) { (FocusDirection::Left, WorkspaceLayout::Horizontal) | (FocusDirection::Up, WorkspaceLayout::Vertical) => self - .handle_action(Action::PreviousWorkspace, seat, serial, time, mods), + .handle_action( + Action::PreviousWorkspace, + seat, + serial, + time, + mods, + direction, + ), (FocusDirection::Right, WorkspaceLayout::Horizontal) - | (FocusDirection::Down, WorkspaceLayout::Vertical) => { - self.handle_action(Action::NextWorkspace, seat, serial, time, mods) - } + | (FocusDirection::Down, WorkspaceLayout::Vertical) => self + .handle_action( + Action::NextWorkspace, + seat, + serial, + time, + mods, + direction, + ), (FocusDirection::Left, WorkspaceLayout::Vertical) - | (FocusDirection::Up, WorkspaceLayout::Horizontal) => { - self.handle_action(Action::PreviousOutput, seat, serial, time, mods) - } + | (FocusDirection::Up, WorkspaceLayout::Horizontal) => self + .handle_action( + Action::PreviousOutput, + seat, + serial, + time, + mods, + direction, + ), (FocusDirection::Right, WorkspaceLayout::Vertical) - | (FocusDirection::Down, WorkspaceLayout::Horizontal) => { - self.handle_action(Action::NextOutput, seat, serial, time, mods) - } + | (FocusDirection::Down, WorkspaceLayout::Horizontal) => self + .handle_action( + Action::NextOutput, + seat, + serial, + time, + mods, + direction, + ), _ => {} } } @@ -1026,6 +1060,7 @@ impl State { serial, time, mods, + Some(direction), ), (Direction::Right, WorkspaceLayout::Horizontal) | (Direction::Down, WorkspaceLayout::Vertical) => self.handle_action( @@ -1034,6 +1069,7 @@ impl State { serial, time, mods, + Some(direction), ), (Direction::Left, WorkspaceLayout::Vertical) | (Direction::Up, WorkspaceLayout::Horizontal) => self.handle_action( @@ -1042,11 +1078,17 @@ impl State { serial, time, mods, + Some(direction), ), (Direction::Right, WorkspaceLayout::Vertical) - | (Direction::Down, WorkspaceLayout::Horizontal) => { - self.handle_action(Action::MoveToNextOutput, seat, serial, time, mods) - } + | (Direction::Down, WorkspaceLayout::Horizontal) => self.handle_action( + Action::MoveToNextOutput, + seat, + serial, + time, + mods, + Some(direction), + ), } } else { let focus_stack = workspace.focus_stack.get(seat); diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 127ccfd7..5fcb7683 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -374,11 +374,12 @@ impl TilingLayout { window: CosmicMapped, seat: &Seat, focus_stack: impl Iterator + 'a, + direction: Option, ) { let output = seat.active_output(); window.output_enter(&output, window.bbox()); window.set_bounds(output.geometry().size); - self.map_internal(window, &output, Some(focus_stack)); + self.map_internal(window, &output, Some(focus_stack), direction); } fn map_internal<'a>( @@ -386,6 +387,7 @@ impl TilingLayout { window: impl Into, output: &Output, focus_stack: Option + 'a>, + direction: Option, ) { let queue = self.queues.get_mut(output).expect("Output not mapped?"); let mut tree = queue.trees.back().unwrap().0.copy_clone(); @@ -396,37 +398,60 @@ impl TilingLayout { last_geometry: Rectangle::from_loc_and_size((0, 0), (100, 100)), }); - let last_active = focus_stack - .and_then(|focus_stack| TilingLayout::last_active_window(&mut tree, focus_stack)); + let window_id = if let Some(direction) = direction { + if let Some(root_id) = tree.root_node_id().cloned() { + let orientation = match direction { + Direction::Left | Direction::Right => Orientation::Vertical, + Direction::Up | Direction::Down => Orientation::Horizontal, + }; - let window_id = if let Some((_last_active_window, ref node_id)) = last_active { - let orientation = { - let window_size = tree.get(node_id).unwrap().data().geometry().size; - if window_size.w > window_size.h { - Orientation::Vertical - } else { - Orientation::Horizontal - } - }; - let new_id = tree.insert(new_window, InsertBehavior::AsRoot).unwrap(); - TilingLayout::new_group(&mut tree, &node_id, &new_id, orientation).unwrap(); - new_id + let new_id = tree.insert(new_window, InsertBehavior::AsRoot).unwrap(); + TilingLayout::new_group(&mut tree, &root_id, &new_id, orientation).unwrap(); + tree.make_nth_sibling( + &new_id, + match direction { + Direction::Left | Direction::Up => 1, + Direction::Right | Direction::Down => 0, + }, + ) + .unwrap(); + new_id + } else { + tree.insert(new_window, InsertBehavior::AsRoot).unwrap() + } } else { - // nothing? then we add to the root - if let Some(root_id) = tree.root_node_id().cloned() { + let last_active = focus_stack + .and_then(|focus_stack| TilingLayout::last_active_window(&mut tree, focus_stack)); + + if let Some((_last_active_window, ref node_id)) = last_active { let orientation = { - let output_size = output.geometry().size; - if output_size.w > output_size.h { + let window_size = tree.get(node_id).unwrap().data().geometry().size; + if window_size.w > window_size.h { Orientation::Vertical } else { Orientation::Horizontal } }; let new_id = tree.insert(new_window, InsertBehavior::AsRoot).unwrap(); - TilingLayout::new_group(&mut tree, &root_id, &new_id, orientation).unwrap(); + TilingLayout::new_group(&mut tree, &node_id, &new_id, orientation).unwrap(); new_id } else { - tree.insert(new_window, InsertBehavior::AsRoot).unwrap() + // nothing? then we add to the root + if let Some(root_id) = tree.root_node_id().cloned() { + let orientation = { + let output_size = output.geometry().size; + if output_size.w > output_size.h { + Orientation::Vertical + } else { + Orientation::Horizontal + } + }; + let new_id = tree.insert(new_window, InsertBehavior::AsRoot).unwrap(); + TilingLayout::new_group(&mut tree, &root_id, &new_id, orientation).unwrap(); + new_id + } else { + tree.insert(new_window, InsertBehavior::AsRoot).unwrap() + } } }; diff --git a/src/shell/mod.rs b/src/shell/mod.rs index bc24d642..f08e9081 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -54,7 +54,7 @@ use self::{ grabs::ResizeEdge, layout::{ floating::FloatingLayout, - tiling::{TilingLayout, ANIMATION_DURATION}, + tiling::{Direction, TilingLayout, ANIMATION_DURATION}, }, }; @@ -1204,7 +1204,7 @@ impl Shell { let focus_stack = workspace.focus_stack.get(&seat); workspace .tiling_layer - .map(mapped.clone(), &seat, focus_stack.iter()); + .map(mapped.clone(), &seat, focus_stack.iter(), None); } if let CosmicSurface::X11(_) = window { @@ -1275,6 +1275,7 @@ impl Shell { from_output: &Output, to: (&Output, Option), follow: bool, + direction: Option, ) -> Result>, InvalidWorkspaceIndex> { let (to_output, to_idx) = to; let to_idx = to_idx.unwrap_or(state.common.shell.workspaces.active_num(to_output).1); @@ -1338,7 +1339,7 @@ impl Shell { } else { to_workspace .tiling_layer - .map(mapped.clone(), &seat, focus_stack.iter()); + .map(mapped.clone(), &seat, focus_stack.iter(), direction); } for (toplevel, _) in mapped.windows() { if from_output != to_output { diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 832f7b6f..2ee47c93 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -402,7 +402,8 @@ impl Workspace { .into_iter() { self.floating_layer.unmap(&window); - self.tiling_layer.map(window, seat, focus_stack.iter()) + self.tiling_layer + .map(window, seat, focus_stack.iter(), None) } self.tiling_enabled = true; } @@ -417,7 +418,8 @@ impl Workspace { } else if self.floating_layer.mapped().any(|w| w == &window) { let focus_stack = self.focus_stack.get(seat); self.floating_layer.unmap(&window); - self.tiling_layer.map(window, seat, focus_stack.iter()) + self.tiling_layer + .map(window, seat, focus_stack.iter(), None) } } } From bd7a4ca89828556af51cff076918b17b5333b160 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 25 May 2023 21:36:44 +0200 Subject: [PATCH 018/264] render: Fixed #108 active hint overlapping --- src/backend/render/mod.rs | 21 +++++++++++++------ .../render/shaders/focus_indicator.frag | 4 ++-- src/shell/layout/floating/mod.rs | 2 +- src/shell/layout/tiling/mod.rs | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 88b34d09..5a51f37e 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -142,6 +142,21 @@ impl IndicatorShader { .clone() } + pub fn focus_element( + renderer: &R, + key: impl Into, + mut element_geo: Rectangle, + thickness: u8, + alpha: f32, + color: [f32; 3], + ) -> PixelShaderElement { + let t = thickness as i32; + element_geo.loc -= (t, t).into(); + element_geo.size += (t * 2, t * 2).into(); + + IndicatorShader::element(renderer, key, element_geo, thickness, alpha, color) + } + pub fn element( renderer: &R, key: impl Into, @@ -174,12 +189,6 @@ impl IndicatorShader { .is_none() { let thickness: f32 = thickness as f32; - let thickness_loc = (thickness as i32, thickness as i32); - let thickness_size = ((thickness * 2.0) as i32, (thickness * 2.0) as i32); - let geo = Rectangle::from_loc_and_size( - geo.loc - Point::from(thickness_loc), - geo.size + Size::from(thickness_size), - ); let shader = Self::get(renderer); let elem = PixelShaderElement::new( diff --git a/src/backend/render/shaders/focus_indicator.frag b/src/backend/render/shaders/focus_indicator.frag index cebaf8db..f94aa116 100644 --- a/src/backend/render/shaders/focus_indicator.frag +++ b/src/backend/render/shaders/focus_indicator.frag @@ -15,12 +15,12 @@ float rounded_box(vec2 center, vec2 size, float radius) { } void main() { - vec2 center = size / 2.0 - vec2(0.5); + vec2 center = size / 2.0; vec2 location = v_coords * size; vec4 mix_color; float distance = rounded_box(location - center, size / 2.0 - vec2(thickness / 2.0), radius); - float smoothedAlpha = 1.0 - smoothstep(0.0, 2.0, abs(distance) - (thickness / 2.0)); + float smoothedAlpha = 1.0 - smoothstep(0.0, 1.0, abs(distance) - (thickness / 2.0)); mix_color = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(color, alpha), smoothedAlpha); diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 73c1b173..8e88bb60 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -379,7 +379,7 @@ impl FloatingLayout { ); if focused == Some(elem) { if indicator_thickness > 0 { - let element = IndicatorShader::element( + let element = IndicatorShader::focus_element( renderer, elem.clone(), Rectangle::from_loc_and_size( diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 5fcb7683..619c312a 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -2148,7 +2148,7 @@ where if focused == Some(mapped) { if indicator_thickness > 0 { - let element = IndicatorShader::element( + let element = IndicatorShader::focus_element( renderer, mapped.clone(), geo, From a2bf14804696e36eb6e185d32e689f59d1803c67 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Wed, 24 May 2023 16:08:37 +0200 Subject: [PATCH 019/264] chore: use --offline with vendored builds --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 898f4afd..76d3b4d4 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ endif VENDOR ?= 0 ifneq ($(VENDOR),0) - ARGS += --locked + ARGS += --offline --locked endif TARGET_BIN="$(DESTDIR)$(bindir)/$(BINARY)" From d9fee40124b54d27b12b0e9a5e3a0afc57bffbc8 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Wed, 24 May 2023 16:09:02 +0200 Subject: [PATCH 020/264] chore(deb): faster debian package builds It's not necessary to define CARGO_HOME. --- debian/rules | 3 --- 1 file changed, 3 deletions(-) diff --git a/debian/rules b/debian/rules index c8f4dd04..5a266947 100755 --- a/debian/rules +++ b/debian/rules @@ -15,9 +15,6 @@ ifeq ($(VENDOR),1) ischroot || make vendor endif -override_dh_auto_build: - CARGO_HOME="$$(pwd)/target/cargo" make - override_dh_installinit: dh_installinit -r From 70fbad69e63ff0bb25d9de99b27af4b307282ea0 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Wed, 24 May 2023 16:10:31 +0200 Subject: [PATCH 021/264] chore(deb): ignore vendor/ and target/ in source tar Results in faster and smaller source tarball creation if they exist --- debian/source/options | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 debian/source/options diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 00000000..97d96f63 --- /dev/null +++ b/debian/source/options @@ -0,0 +1,2 @@ +tar-ignore=target +tar-ignore=vendor \ No newline at end of file From 9d0e1e88cea6bf9cbb59dd508d91e19014635ffa Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Wed, 24 May 2023 16:12:44 +0200 Subject: [PATCH 022/264] fix(input): zombie process from Action::Spawn Each invocation of `Action::Spawn` was spawning a process without waiting on the child; resulting in an accumulation of zombie sh processes. This will create background threads which waits on the child to ensure that they are reaped on exit. --- src/input/mod.rs | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index 733fb479..4208fafc 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1137,24 +1137,33 @@ impl State { workspace.toggle_floating_window(seat); } Action::Spawn(command) => { - if let Err(err) = std::process::Command::new("/bin/sh") - .arg("-c") - .arg(command.clone()) - .env("WAYLAND_DISPLAY", &self.common.socket) - .env( - "DISPLAY", - &self - .common - .xwayland_state - .as_ref() - .map(|s| format!(":{}", s.display)) - .unwrap_or(String::new()), - ) - .env_remove("COSMIC_SESSION_SOCK") - .spawn() - { - warn!(?err, "Failed to spawn \"{}\"", command); - } + let wayland_display = self.common.socket.clone(); + + let display = self + .common + .xwayland_state + .as_ref() + .map(|s| format!(":{}", s.display)) + .unwrap_or_default(); + + std::thread::spawn(move || { + let mut cmd = std::process::Command::new("/bin/sh"); + + cmd.arg("-c") + .arg(command.clone()) + .env("WAYLAND_DISPLAY", &wayland_display) + .env("DISPLAY", &display) + .env_remove("COSMIC_SESSION_SOCK"); + + match cmd.spawn() { + Ok(mut child) => { + let _res = child.wait(); + } + Err(err) => { + tracing::warn!(?err, "Failed to spawn \"{}\"", command); + } + } + }); } } } From 506334e1af81ee54db84f0f6ec2ee90edba13ac0 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 26 May 2023 11:47:45 +0200 Subject: [PATCH 023/264] Fix #123 --- src/input/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index 4208fafc..9e8a526f 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -232,10 +232,10 @@ impl State { if let OverviewMode::Started(action_modifiers, _) = data.common.shell.overview_mode() { - if (!action_modifiers.ctrl || modifiers.ctrl) - && (!action_modifiers.alt || modifiers.alt) - && (!action_modifiers.logo || modifiers.logo) - && (!action_modifiers.shift || modifiers.shift) + if (action_modifiers.ctrl && !modifiers.ctrl) + || (action_modifiers.alt && !modifiers.alt) + || (action_modifiers.logo && !modifiers.logo) + || (action_modifiers.shift && !modifiers.shift) { data.common.shell.set_overview_mode(None); } From 15b12dc3e2b8fe2dde931ed016d215782c49cb8d Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 26 May 2023 11:57:23 +0200 Subject: [PATCH 024/264] chore: Update smithay --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9038236d..828323c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3884,7 +3884,7 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "smithay" version = "0.3.0" -source = "git+https://github.com/smithay//smithay?rev=1966c6c8e4#1966c6c8e42273b5d6f356e94dc683a230b3fc21" +source = "git+https://github.com/smithay//smithay?rev=43ce6b4372#43ce6b437257151acfdd00d633d2bd69c3114376" dependencies = [ "appendlist", "ash", diff --git a/Cargo.toml b/Cargo.toml index 3bd90880..423a45e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,4 +74,4 @@ debug = true lto = "fat" [patch."https://github.com/Smithay/smithay.git"] -smithay = { git = "https://github.com/smithay//smithay", rev = "1966c6c8e4" } +smithay = { git = "https://github.com/smithay//smithay", rev = "43ce6b4372" } From 06ac701349d9ef6ae1be583abbcc35f591992c84 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 26 May 2023 12:14:15 +0200 Subject: [PATCH 025/264] Fix #124 --- src/shell/layout/tiling/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 619c312a..1358e41d 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -754,7 +754,7 @@ impl TilingLayout { .nth(next_idx) .unwrap() .clone(); - if tree.get(&next_child_id).unwrap().data().is_group() { + if tree.get(&next_child_id).unwrap().data().is_group() && len == 2 { // if it is a group, we want to move into the group tree.move_node(&node_id, MoveBehavior::ToParent(&next_child_id)) .unwrap(); From b1e39452d0940544e9b73036209a12e611fb912b Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 26 May 2023 12:47:39 +0200 Subject: [PATCH 026/264] Fix #120 --- src/shell/focus/mod.rs | 10 +++++----- src/shell/mod.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/shell/focus/mod.rs b/src/shell/focus/mod.rs index bd53c4fa..60eabcde 100644 --- a/src/shell/focus/mod.rs +++ b/src/shell/focus/mod.rs @@ -147,12 +147,12 @@ impl Shell { for output in self.outputs.iter() { let workspace = self.workspaces.active_mut(output); for focused in focused_windows.iter() { - if workspace.floating_layer.mapped().any(|m| m == focused) { - if let CosmicSurface::X11(window) = focused.active_window() { - if let Some(xwm) = xwm.as_mut().and_then(|state| state.xwm.as_mut()) { - let _ = xwm.raise_window(&window); - } + if let CosmicSurface::X11(window) = focused.active_window() { + if let Some(xwm) = xwm.as_mut().and_then(|state| state.xwm.as_mut()) { + let _ = xwm.raise_window(&window); } + } + if workspace.floating_layer.mapped().any(|m| m == focused) { workspace.floating_layer.space.raise_element(focused, true); } } diff --git a/src/shell/mod.rs b/src/shell/mod.rs index f08e9081..c8b81d6e 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1207,14 +1207,14 @@ impl Shell { .map(mapped.clone(), &seat, focus_stack.iter(), None); } - if let CosmicSurface::X11(_) = window { + if let CosmicSurface::X11(surface) = window { if let Some(xwm) = state .common .xwayland_state .as_mut() .and_then(|state| state.xwm.as_mut()) { - if let Err(err) = xwm.update_stacking_order_downwards(workspace.mapped()) { + if let Err(err) = xwm.raise_window(&surface) { warn!(?err, "Failed to update Xwayland stacking order."); } } From 2466e70ee2f13565ff4e2efb878acc6beac78629 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Tue, 30 May 2023 13:15:45 -0700 Subject: [PATCH 027/264] Update smithay to latest commit Includes output transform fix: https://github.com/Smithay/smithay/pull/1039. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 423a45e8..05f1b269 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ branch = "feature/copy_clone" [dependencies.smithay] version = "0.3" git = "https://github.com/smithay/smithay.git" -rev = "9459ddd14e" +rev = "138921bff4" default-features = false features = ["backend_drm", "backend_gbm", "backend_egl", "backend_libinput", "backend_session_libseat", "backend_udev", "backend_winit", "backend_vulkan", "backend_x11", "desktop", "use_system_lib", "renderer_glow", "renderer_multi", "wayland_frontend", "xwayland"] From 14c0711287b4c10cb65b87f228465db9486950fa Mon Sep 17 00:00:00 2001 From: Shuxian Wang Date: Thu, 1 Jun 2023 21:26:08 -0700 Subject: [PATCH 028/264] Update Nix flake and CI. --- .github/workflows/build.yml | 2 +- flake.lock | 90 ++++++++++++++++++++++++++----------- flake.nix | 12 ++++- 3 files changed, 74 insertions(+), 30 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 95999ff2..8b0e5e48 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: cachix/install-nix-action@v18 + - uses: cachix/install-nix-action@v21 with: nix_path: nixpkgs=channel:nixpkgs-unstable - run: nix build diff --git a/flake.lock b/flake.lock index 9e570c51..a0e224df 100644 --- a/flake.lock +++ b/flake.lock @@ -10,11 +10,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1672095661, - "narHash": "sha256-7NTsdCn3qsvU7A+1/7tY8pxbq0DYy1pFYNpzN6he9lI=", + "lastModified": 1684981077, + "narHash": "sha256-68X9cFm0RTZm8u0rXPbeBzOVUH5OoUGAfeHHVoxGd9o=", "owner": "ipetkov", "repo": "crane", - "rev": "98894bb39b03bfb379c5e10523cd61160e1ac782", + "rev": "35110cccf28823320f4fd697fcafcb5038683982", "type": "github" }, "original": { @@ -31,11 +31,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1672468395, - "narHash": "sha256-eIrQGHZub98IiLqtFXa00ooHBCjtKY+rfKJs5lhyF/c=", + "lastModified": 1685600533, + "narHash": "sha256-7oly5/7xJMtFH44I/Bsrnc2VG4M6HyUVhph3WoZrG64=", "owner": "nix-community", "repo": "fenix", - "rev": "d6f9bdfb4a25395b15f6c6feba3d0bba5e62b3ce", + "rev": "360c6a0bc9b78b896fdd60c8803ba98298a37f7c", "type": "github" }, "original": { @@ -47,11 +47,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1668681692, - "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=", + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", "owner": "edolstra", "repo": "flake-compat", - "rev": "009399224d5e398d03b22badca40a37ac85412a1", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", "type": "github" }, "original": { @@ -61,12 +61,15 @@ } }, "flake-utils": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", "owner": "numtide", "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", "type": "github" }, "original": { @@ -76,12 +79,15 @@ } }, "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, "locked": { - "lastModified": 1667395993, - "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", "owner": "numtide", "repo": "flake-utils", - "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", "type": "github" }, "original": { @@ -92,11 +98,11 @@ }, "nix-filter": { "locked": { - "lastModified": 1666547822, - "narHash": "sha256-razwnAybPHyoAyhkKCwXdxihIqJi1G6e1XP4FQOJTEs=", + "lastModified": 1681154353, + "narHash": "sha256-MCJ5FHOlbfQRFwN0brqPbCunLEVw05D/3sRVoNVt2tI=", "owner": "numtide", "repo": "nix-filter", - "rev": "1a3b735e13e90a8d2fd5629f2f8363bd7ffbbec7", + "rev": "f529f42792ade8e32c4be274af6b6d60857fbee7", "type": "github" }, "original": { @@ -107,11 +113,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1672428209, - "narHash": "sha256-eejhqkDz2cb2vc5VeaWphJz8UXNuoNoM8/Op8eWv2tQ=", + "lastModified": 1685591878, + "narHash": "sha256-Ib3apaLqIFkZb94q6Q214DXrz0FnJq5C7usywTv63og=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "293a28df6d7ff3dec1e61e37cc4ee6e6c0fb0847", + "rev": "8d4d822bc0efa9de6eddc79cb0d82897a9baa750", "type": "github" }, "original": { @@ -133,11 +139,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1672438471, - "narHash": "sha256-bB/7XFnRgGhOhYY6HIov7eF/qnR5NPtKtSfDa2aWqh8=", + "lastModified": 1685541053, + "narHash": "sha256-ck8hhiuxvy8jLIv2cPsQK8bfc/aYZjrIelmLAv16T4o=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "0d76b94c90a20c20d3e57ea1ab03d9afa00dee72", + "rev": "bafa6c4ee5d3acdbb62ec289364564270357c6a2", "type": "github" }, "original": { @@ -159,11 +165,11 @@ ] }, "locked": { - "lastModified": 1670034122, - "narHash": "sha256-EqmuOKucPWtMvCZtHraHr3Q3bgVszq1x2PoZtQkUuEk=", + "lastModified": 1683080331, + "narHash": "sha256-nGDvJ1DAxZIwdn6ww8IFwzoHb2rqBP4wv/65Wt5vflk=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "a0d5773275ecd4f141d792d3a0376277c0fc0b65", + "rev": "d59c3fa0cba8336e115b376c2d9e91053aa59e56", "type": "github" }, "original": { @@ -171,6 +177,36 @@ "repo": "rust-overlay", "type": "github" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 4d9dbae7..a6b15787 100644 --- a/flake.nix +++ b/flake.nix @@ -31,7 +31,11 @@ ./resources ]; }; - nativeBuildInputs = with pkgs; [ pkg-config autoPatchelfHook ]; + nativeBuildInputs = with pkgs; [ + pkg-config + autoPatchelfHook + cmake + ]; buildInputs = with pkgs; [ wayland systemd # For libudev @@ -39,8 +43,12 @@ libxkbcommon libinput mesa # For libgbm + fontconfig + stdenv.cc.cc.lib + ]; + runtimeDependencies = with pkgs; [ + libglvnd # For libEGL ]; - runtimeDependencies = with pkgs; [ libglvnd ]; # For libEGL }; cargoArtifacts = craneLib.buildDepsOnly pkgDef; From d6bc231707482a7d15814cfb73adfa68ac8523b9 Mon Sep 17 00:00:00 2001 From: Shuxian Wang Date: Fri, 2 Jun 2023 01:53:11 -0700 Subject: [PATCH 029/264] Workaround Nix not fetching LFS files. See https://github.com/NixOS/nix/issues/4623#issuecomment-1270580999. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8b0e5e48..d25530ca 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,5 +14,5 @@ jobs: - uses: cachix/install-nix-action@v21 with: nix_path: nixpkgs=channel:nixpkgs-unstable - - run: nix build + - run: GIT_LFS_SKIP_SMUDGE=1 nix build - run: nix flake check From 64752fe31ab9e7affa14cd4f997f3bc38dd6959c Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 26 May 2023 20:51:10 +0200 Subject: [PATCH 030/264] elements: Add custom backdrop element --- src/backend/render/mod.rs | 164 +++++++++++++++--- ...us_indicator.frag => rounded_outline.frag} | 2 +- .../render/shaders/rounded_rectangle.frag | 32 ++++ src/shell/workspace.rs | 87 ++++------ 4 files changed, 205 insertions(+), 80 deletions(-) rename src/backend/render/shaders/{focus_indicator.frag => rounded_outline.frag} (88%) create mode 100644 src/backend/render/shaders/rounded_rectangle.frag diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 5a51f37e..e53e3cf9 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -48,7 +48,7 @@ use smithay::{ damage::{Error as RenderError, OutputDamageTracker, OutputNoMode}, element::{ utils::{Relocate, RelocateRenderElement}, - AsRenderElements, Element, RenderElement, RenderElementStates, + AsRenderElements, Element, Id, RenderElement, RenderElementStates, }, gles::{ element::PixelShaderElement, GlesError, GlesPixelProgram, GlesRenderer, Uniform, @@ -61,7 +61,7 @@ use smithay::{ }, desktop::layer_map_for_output, output::Output, - utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Size}, + utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale}, wayland::{ dmabuf::get_dmabuf, shell::wlr_layer::Layer, @@ -85,41 +85,43 @@ pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0]; pub static ACTIVE_GROUP_COLOR: [f32; 3] = [0.678, 0.635, 0.619]; pub static GROUP_COLOR: [f32; 3] = [0.431, 0.404, 0.396]; pub static FOCUS_INDICATOR_COLOR: [f32; 3] = [0.580, 0.921, 0.921]; -pub static FOCUS_INDICATOR_SHADER: &str = include_str!("./shaders/focus_indicator.frag"); + +pub static OUTLINE_SHADER: &str = include_str!("./shaders/rounded_outline.frag"); +pub static RECTANGLE_SHADER: &str = include_str!("./shaders/rounded_rectangle.frag"); pub struct IndicatorShader(pub GlesPixelProgram); #[derive(Clone)] -pub enum Key { +pub enum IndicatorKey { Group(Weak<()>), Window(CosmicMapped), } -impl std::hash::Hash for Key { +impl std::hash::Hash for IndicatorKey { fn hash(&self, state: &mut H) { match self { - Key::Group(arc) => (arc.as_ptr() as usize).hash(state), - Key::Window(window) => window.hash(state), + IndicatorKey::Group(arc) => (arc.as_ptr() as usize).hash(state), + IndicatorKey::Window(window) => window.hash(state), } } } -impl PartialEq for Key { +impl PartialEq for IndicatorKey { fn eq(&self, other: &Self) -> bool { match (self, other) { - (Key::Group(g1), Key::Group(g2)) => Weak::ptr_eq(g1, g2), - (Key::Window(w1), Key::Window(w2)) => w1 == w2, + (IndicatorKey::Group(g1), IndicatorKey::Group(g2)) => Weak::ptr_eq(g1, g2), + (IndicatorKey::Window(w1), IndicatorKey::Window(w2)) => w1 == w2, _ => false, } } } -impl Eq for Key {} -impl From for Key { +impl Eq for IndicatorKey {} +impl From for IndicatorKey { fn from(window: CosmicMapped) -> Self { - Key::Window(window) + IndicatorKey::Window(window) } } -impl From for Key { +impl From for IndicatorKey { fn from(group: WindowGroup) -> Self { - Key::Group(group.alive.clone()) + IndicatorKey::Group(group.alive.clone()) } } @@ -129,7 +131,7 @@ struct IndicatorSettings { alpha: f32, color: [f32; 3], } -type IndicatorCache = RefCell>; +type IndicatorCache = RefCell>; impl IndicatorShader { pub fn get(renderer: &R) -> GlesPixelProgram { @@ -144,7 +146,7 @@ impl IndicatorShader { pub fn focus_element( renderer: &R, - key: impl Into, + key: impl Into, mut element_geo: Rectangle, thickness: u8, alpha: f32, @@ -159,7 +161,7 @@ impl IndicatorShader { pub fn element( renderer: &R, - key: impl Into, + key: impl Into, geo: Rectangle, thickness: u8, alpha: f32, @@ -178,8 +180,8 @@ impl IndicatorShader { user_data.insert_if_missing(|| IndicatorCache::new(HashMap::new())); let mut cache = user_data.get::().unwrap().borrow_mut(); cache.retain(|k, _| match k { - Key::Group(w) => w.upgrade().is_some(), - Key::Window(w) => w.alive(), + IndicatorKey::Group(w) => w.upgrade().is_some(), + IndicatorKey::Window(w) => w.alive(), }); let key = key.into(); @@ -213,23 +215,139 @@ impl IndicatorShader { } } +pub struct BackdropShader(pub GlesPixelProgram); + +#[derive(Clone)] +pub enum BackdropKey { + Static(Id), + Window(CosmicMapped), +} +impl std::hash::Hash for BackdropKey { + fn hash(&self, state: &mut H) { + match self { + BackdropKey::Static(id) => id.hash(state), + BackdropKey::Window(window) => window.hash(state), + } + } +} +impl PartialEq for BackdropKey { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (BackdropKey::Static(s1), BackdropKey::Static(s2)) => s1 == s2, + (BackdropKey::Window(w1), BackdropKey::Window(w2)) => w1 == w2, + _ => false, + } + } +} +impl Eq for BackdropKey {} +impl From for BackdropKey { + fn from(window: CosmicMapped) -> Self { + BackdropKey::Window(window) + } +} +impl From for BackdropKey { + fn from(id: Id) -> Self { + BackdropKey::Static(id) + } +} + +#[derive(PartialEq)] +struct BackdropSettings { + radius: f32, + alpha: f32, + color: [f32; 3], +} +type BackdropCache = RefCell>; + +impl BackdropShader { + pub fn get(renderer: &R) -> GlesPixelProgram { + Borrow::::borrow(renderer.glow_renderer()) + .egl_context() + .user_data() + .get::() + .expect("Custom Shaders not initialized") + .0 + .clone() + } + + pub fn element( + renderer: &R, + key: impl Into, + geo: Rectangle, + radius: f32, + alpha: f32, + color: [f32; 3], + ) -> PixelShaderElement { + let settings = BackdropSettings { + radius, + alpha, + color, + }; + + let user_data = Borrow::::borrow(renderer.glow_renderer()) + .egl_context() + .user_data(); + + user_data.insert_if_missing(|| BackdropCache::new(HashMap::new())); + let mut cache = user_data.get::().unwrap().borrow_mut(); + cache.retain(|k, _| match k { + BackdropKey::Static(_) => true, + BackdropKey::Window(w) => w.alive(), + }); + + let key = key.into(); + if cache + .get(&key) + .filter(|(old_settings, _)| &settings == old_settings) + .is_none() + { + let shader = Self::get(renderer); + + let elem = PixelShaderElement::new( + shader, + geo, + None, // TODO + alpha, + vec![Uniform::new("color", color), Uniform::new("radius", radius)], + ); + cache.insert(key.clone(), (settings, elem)); + } + + let elem = &mut cache.get_mut(&key).unwrap().1; + if elem.geometry(1.0.into()).to_logical(1) != geo { + elem.resize(geo, None); + } + elem.clone() + } +} + pub fn init_shaders(renderer: &mut R) -> Result<(), GlesError> { let glow_renderer = renderer.glow_renderer_mut(); let gles_renderer: &mut GlesRenderer = glow_renderer.borrow_mut(); - let indicator_shader = gles_renderer.compile_custom_pixel_shader( - FOCUS_INDICATOR_SHADER, + let outline_shader = gles_renderer.compile_custom_pixel_shader( + OUTLINE_SHADER, &[ UniformName::new("color", UniformType::_3f), UniformName::new("thickness", UniformType::_1f), UniformName::new("radius", UniformType::_1f), ], )?; + let rectangle_shader = gles_renderer.compile_custom_pixel_shader( + RECTANGLE_SHADER, + &[ + UniformName::new("color", UniformType::_3f), + UniformName::new("radius", UniformType::_1f), + ], + )?; let egl_context = gles_renderer.egl_context(); egl_context .user_data() - .insert_if_missing(|| IndicatorShader(indicator_shader)); + .insert_if_missing(|| IndicatorShader(outline_shader)); + egl_context + .user_data() + .insert_if_missing(|| BackdropShader(rectangle_shader)); Ok(()) } diff --git a/src/backend/render/shaders/focus_indicator.frag b/src/backend/render/shaders/rounded_outline.frag similarity index 88% rename from src/backend/render/shaders/focus_indicator.frag rename to src/backend/render/shaders/rounded_outline.frag index f94aa116..749748f2 100644 --- a/src/backend/render/shaders/focus_indicator.frag +++ b/src/backend/render/shaders/rounded_outline.frag @@ -19,7 +19,7 @@ void main() { vec2 location = v_coords * size; vec4 mix_color; - float distance = rounded_box(location - center, size / 2.0 - vec2(thickness / 2.0), radius); + float distance = rounded_box(location - center, (size / 2.0) - (thickness / 2.0), radius); float smoothedAlpha = 1.0 - smoothstep(0.0, 1.0, abs(distance) - (thickness / 2.0)); mix_color = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(color, alpha), smoothedAlpha); diff --git a/src/backend/render/shaders/rounded_rectangle.frag b/src/backend/render/shaders/rounded_rectangle.frag new file mode 100644 index 00000000..30644f51 --- /dev/null +++ b/src/backend/render/shaders/rounded_rectangle.frag @@ -0,0 +1,32 @@ +precision mediump float; +uniform float alpha; +#if defined(DEBUG_FLAGS) +uniform float tint; +#endif +uniform vec2 size; +varying vec2 v_coords; + +uniform vec3 color; +uniform float radius; + +float rounded_box(vec2 center, vec2 size, float radius) { + return length(max(abs(center) - size + radius, 0.0)) - radius; +} + +void main() { + vec2 center = size / 2.0; + vec2 location = v_coords * size; + vec4 mix_color; + + float distance = rounded_box(location - center, size / 2.0, radius); + float smoothedAlpha = 1.0 - smoothstep(0.0, 1.0, distance); + + mix_color = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(color, alpha), smoothedAlpha); + +#if defined(DEBUG_FLAGS) + if (tint == 1.0) + mix_color = vec4(0.0, 0.3, 0.0, 0.2) + mix_color * 0.8; +#endif + + gl_FragColor = mix_color; +} \ No newline at end of file diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 2ee47c93..4bf7f02f 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -1,7 +1,7 @@ use crate::{ backend::render::{ element::{AsGlowFrame, AsGlowRenderer}, - GlMultiError, GlMultiFrame, GlMultiRenderer, + BackdropShader, GlMultiError, GlMultiFrame, GlMultiRenderer, }, shell::{ layout::{ @@ -26,17 +26,14 @@ use crate::{ use calloop::LoopHandle; use indexmap::IndexSet; use smithay::{ - backend::{ - allocator::Fourcc, - renderer::{ - element::{ - surface::WaylandSurfaceRenderElement, texture::TextureRenderElement, - AsRenderElements, Element, Id, RenderElement, - }, - gles::{GlesError, GlesTexture}, - glow::{GlowFrame, GlowRenderer}, - ImportAll, ImportMem, Renderer, + backend::renderer::{ + element::{ + surface::WaylandSurfaceRenderElement, texture::TextureRenderElement, AsRenderElements, + Element, Id, RenderElement, }, + gles::{GlesError, GlesTexture}, + glow::{GlowFrame, GlowRenderer}, + ImportAll, ImportMem, Renderer, }, desktop::{layer_map_for_output, space::SpaceElement}, input::{pointer::GrabStartData as PointerGrabStartData, Seat}, @@ -66,6 +63,7 @@ pub struct Workspace { pub focus_stack: FocusStacks, pub pending_buffers: Vec<(ScreencopySession, BufferParams)>, pub screencopy_sessions: Vec, + pub(super) backdrop_id: Id, } #[derive(Debug, Default)] @@ -88,6 +86,7 @@ impl Workspace { focus_stack: FocusStacks::default(), pending_buffers: Vec::new(), screencopy_sessions: Vec::new(), + backdrop_id: Id::new(), } } @@ -487,6 +486,7 @@ impl Workspace { let output_scale = output.current_scale().fractional_scale(); let layer_map = layer_map_for_output(output); + let zone = layer_map.non_exclusive_zone(); if let Some(fullscreen) = self.fullscreen.get(output) { render_elements.extend( @@ -609,53 +609,28 @@ impl Workspace { } } - if let OverviewMode::Started(_, start) = overview { - let alpha = Instant::now().duration_since(start).as_millis() as f64 / 100.0; - - #[derive(Clone)] - struct BackdropTexture(Id, GlesTexture); - - if renderer - .glow_renderer() - .egl_context() - .user_data() - .get::() - .is_none() - { - let tex = BackdropTexture( - Id::new(), - renderer - .glow_renderer_mut() - .import_memory(&[0, 0, 0, 255], Fourcc::Abgr8888, (1, 1).into(), false) - .unwrap(), - ); - renderer - .glow_renderer() - .egl_context() - .user_data() - .insert_if_missing(|| tex); - }; - let BackdropTexture(id, tex) = renderer - .glow_renderer() - .egl_context() - .user_data() - .get::() - .unwrap() - .clone(); + let alpha = match overview { + OverviewMode::Started(_, start) => Some( + (Instant::now().duration_since(start).as_millis() as f64 / 100.0).min(1.0) + as f32, + ), + OverviewMode::Ended(ended) => Some( + 1.0 - (Instant::now().duration_since(ended).as_millis() as f64 / 100.0).min(1.0) + as f32, + ), + _ => None, + }; + if let Some(alpha) = alpha { render_elements.push( - TextureRenderElement::from_static_texture( - id, - renderer.id(), - (0.0, 0.0), - tex, - 1, - smithay::utils::Transform::Normal, - Some(alpha.min(0.8) as f32), - Some(Rectangle::from_loc_and_size((0., 0.), (1., 1.))), - Some(output.geometry().size), - None, - ) + Into::>::into(BackdropShader::element( + renderer, + self.backdrop_id.clone(), + zone, + 0., + alpha * 0.65, + [0.0, 0.0, 0.0], + )) .into(), ) } From b9fff052dbc4b8e6d348cce09e6236b8bb97e5fa Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 26 May 2023 20:51:57 +0200 Subject: [PATCH 031/264] tiling: Fix offset focus indicator in overview --- src/shell/layout/tiling/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 1358e41d..976ed2e3 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -2109,7 +2109,7 @@ where )?; let rescaled = RescaleRenderElement::from_element( cropped, - original_location, + original_geo.loc.to_physical_precise_round(output_scale), scale, ); let relocated = RelocateRenderElement::from_element( @@ -2130,7 +2130,7 @@ where )?; let rescaled = RescaleRenderElement::from_element( cropped, - original_location, + original_geo.loc.to_physical_precise_round(output_scale), scale, ); let relocated = RelocateRenderElement::from_element( From 954843bc432c2e15ecd7e826b8c2d041cd0ee1c3 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 26 May 2023 20:52:26 +0200 Subject: [PATCH 032/264] tiling: Sort tiling hints below windows --- src/shell/layout/tiling/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 976ed2e3..3040859d 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1619,11 +1619,6 @@ impl TilingLayout { } .unzip(); - // tiling hints - if let Some(group_elements) = group_elements { - elements.extend(group_elements); - } - // all alive windows elements.extend(render_new_tree( target_tree, @@ -1646,6 +1641,11 @@ impl TilingLayout { }, )); + // tiling hints + if let Some(group_elements) = group_elements { + elements.extend(group_elements); + } + Ok(elements) } } From 9531b3798ea8487da13222bfbf1cb686c66a19c8 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 30 May 2023 16:22:29 +0200 Subject: [PATCH 033/264] tiling: Crop input region to tile --- src/shell/layout/tiling/mod.rs | 47 +++++++++++++++++++--------------- src/shell/workspace.rs | 15 +++++++---- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 3040859d..1c438a1c 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -2,8 +2,8 @@ use crate::{ backend::render::{ - element::AsGlowRenderer, IndicatorShader, Key, ACTIVE_GROUP_COLOR, FOCUS_INDICATOR_COLOR, - GROUP_COLOR, + element::AsGlowRenderer, IndicatorKey, IndicatorShader, ACTIVE_GROUP_COLOR, + FOCUS_INDICATOR_COLOR, GROUP_COLOR, }, shell::{ element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, @@ -1140,7 +1140,7 @@ impl TilingLayout { .position(|id| id == &node_id) .unwrap(); let idx = match edges { - x if x.intersects(ResizeEdge::TOP_LEFT) => node_idx - 1, + x if x.intersects(ResizeEdge::TOP_LEFT) => node_idx.checked_sub(1)?, _ => node_idx, }; if idx > tree.get(&group_id).unwrap().data().len() { @@ -1384,7 +1384,9 @@ impl TilingLayout { None } - pub fn mapped(&self) -> impl Iterator)> { + pub fn mapped( + &self, + ) -> impl Iterator)> { self.queues .iter() .flat_map(|(output_data, queue)| { @@ -1403,11 +1405,11 @@ impl TilingLayout { mapped, last_geometry, .. - } => ( - &output_data.output, - mapped, - output_data.location + last_geometry.loc, - ), + } => (&output_data.output, mapped, { + let mut geo = last_geometry.clone(); + geo.loc += output_data.location; + geo + }), _ => unreachable!(), }) .chain( @@ -1423,11 +1425,11 @@ impl TilingLayout { mapped, last_geometry, .. - } => ( - &output_data.output, - mapped, - output_data.location + last_geometry.loc, - ), + } => (&output_data.output, mapped, { + let mut geo = last_geometry.clone(); + geo.loc += output_data.location; + geo + }), _ => unreachable!(), }), ), @@ -1441,11 +1443,16 @@ impl TilingLayout { pub fn windows( &self, - ) -> impl Iterator)> + '_ { - self.mapped().flat_map(|(output, mapped, loc)| { - mapped - .windows() - .map(move |(w, p)| (output.clone(), w, p + loc)) + ) -> impl Iterator)> + '_ { + self.mapped().flat_map(|(output, mapped, geo)| { + mapped.windows().map(move |(w, p)| { + (output.clone(), w, { + let mut geo = geo.clone(); + geo.loc += p; + geo.size -= p.to_size(); + geo + }) + }) }) } @@ -1748,7 +1755,7 @@ where elements.push( IndicatorShader::element( renderer, - Key::Group(Arc::downgrade(&alive)), + IndicatorKey::Group(Arc::downgrade(&alive)), geo, 3, alpha, diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 4bf7f02f..a6278d3b 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -202,11 +202,16 @@ impl Workspace { .space .element_under(location) .or_else(|| { - self.tiling_layer.mapped().find_map(|(_, mapped, loc)| { - let test_point = location - loc.to_f64() + mapped.geometry().loc.to_f64(); - mapped - .is_in_input_region(&test_point) - .then_some((mapped, loc - mapped.geometry().loc)) + self.tiling_layer.mapped().find_map(|(_, mapped, geo)| { + geo.contains(location.to_i32_round()) + .then(|| { + let test_point = + location - geo.loc.to_f64() + mapped.geometry().loc.to_f64(); + mapped + .is_in_input_region(&test_point) + .then_some((mapped, geo.loc - mapped.geometry().loc)) + }) + .flatten() }) }) } From 6d270dec14d31ce25f47709267c56ec2b37185f2 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 30 May 2023 16:32:58 +0200 Subject: [PATCH 034/264] tiling: Recalculate when unmaximizing --- src/shell/layout/tiling/mod.rs | 7 +++++++ src/shell/workspace.rs | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 1c438a1c..c90b8036 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1050,6 +1050,13 @@ impl TilingLayout { } } + pub fn recalculate(&mut self, output: &Output) { + let Some(queue) = self.queues.get_mut(output) else { return }; + let mut tree = queue.trees.back().unwrap().0.copy_clone(); + let blocker = TilingLayout::update_positions(&output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); + } + pub fn refresh(&mut self) { #[cfg(feature = "debug")] puffin::profile_function!(); diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index a6278d3b..4f117fc6 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -294,10 +294,11 @@ impl Workspace { } pub fn unfullscreen_request(&mut self, window: &CosmicSurface) { - if self.fullscreen.values().any(|w| w == window) { + if let Some((output, _)) = self.fullscreen.iter().find(|(_, w)| *w == window) { window.set_maximized(false); window.set_fullscreen(false); self.floating_layer.refresh(); + self.tiling_layer.recalculate(output); self.tiling_layer.refresh(); window.send_configure(); self.fullscreen.retain(|_, w| w != window); From 56131b13ae6fc43c5a48b65c9bb7a4a814bc8ea4 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 30 May 2023 21:02:19 +0200 Subject: [PATCH 035/264] tiling: Allow selecting groups --- src/input/mod.rs | 16 +- src/shell/focus/target.rs | 1 + src/shell/layout/tiling/mod.rs | 334 +++++++++++++++++++-------------- src/shell/workspace.rs | 2 +- 4 files changed, 200 insertions(+), 153 deletions(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index 9e8a526f..b942297e 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1049,7 +1049,7 @@ impl State { } if let Some(_move_further) = - workspace.tiling_layer.move_current_window(direction, seat) + workspace.tiling_layer.move_current_node(direction, seat) { // TODO: Being able to move Groups (move_further should be KeyboardFocusTarget instead) match (direction, self.common.config.static_conf.workspace_layout) { @@ -1111,20 +1111,14 @@ impl State { Action::ToggleOrientation => { let output = seat.active_output(); let workspace = self.common.shell.active_space_mut(&output); - let focus_stack = workspace.focus_stack.get(seat); - workspace - .tiling_layer - .update_orientation(None, &seat, focus_stack.iter()); + workspace.tiling_layer.update_orientation(None, &seat); } Action::Orientation(orientation) => { let output = seat.active_output(); let workspace = self.common.shell.active_space_mut(&output); - let focus_stack = workspace.focus_stack.get(seat); - workspace.tiling_layer.update_orientation( - Some(orientation), - &seat, - focus_stack.iter(), - ); + workspace + .tiling_layer + .update_orientation(Some(orientation), &seat); } Action::ToggleTiling => { let output = seat.active_output(); diff --git a/src/shell/focus/target.rs b/src/shell/focus/target.rs index 673e9366..521c6ad2 100644 --- a/src/shell/focus/target.rs +++ b/src/shell/focus/target.rs @@ -55,6 +55,7 @@ pub struct WindowGroup { pub node: NodeId, pub output: WeakOutput, pub alive: Weak<()>, + pub focus_stack: Vec, } impl PartialEq for WindowGroup { diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index c90b8036..9ca0c75e 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -42,7 +42,7 @@ use std::{ borrow::Borrow, collections::{HashMap, VecDeque}, hash::Hash, - sync::Arc, + sync::{Arc, Weak}, time::{Duration, Instant}, }; use tracing::trace; @@ -281,6 +281,12 @@ impl Data { } } +#[derive(Debug, Clone)] +enum FocusedNodeData { + Group(Vec, Weak<()>), + Window(CosmicMapped), +} + impl TilingLayout { pub fn new(gaps: (u8, u8)) -> TilingLayout { TilingLayout { @@ -290,9 +296,7 @@ impl TilingLayout { pending_blockers: Vec::new(), } } -} -impl TilingLayout { pub fn map_output(&mut self, output: &Output, location: Point) { if !self.queues.contains_key(output) { self.queues.insert( @@ -423,7 +427,7 @@ impl TilingLayout { let last_active = focus_stack .and_then(|focus_stack| TilingLayout::last_active_window(&mut tree, focus_stack)); - if let Some((_last_active_window, ref node_id)) = last_active { + if let Some((ref node_id, _last_active_window)) = last_active { let orientation = { let window_size = tree.get(node_id).unwrap().data().geometry().size; if window_size.w > window_size.h { @@ -577,31 +581,29 @@ impl TilingLayout { None } - pub fn move_current_window<'a>( + pub fn move_current_node<'a>( &mut self, direction: Direction, seat: &Seat, - ) -> Option { + ) -> Option { let output = seat.active_output(); let queue = self.queues.get_mut(&output).unwrap(); let mut tree = queue.trees.back().unwrap().0.copy_clone(); - let node_id = match TilingLayout::currently_focused_node(&mut tree, seat) { - Some(node_id) => node_id, - None => { - return None; - } - }; + let (node_id, data) = TilingLayout::currently_focused_node(&mut tree, seat)?; let mut child_id = node_id.clone(); // Without a parent to start with, just return let Some(og_parent) = tree.get(&node_id).unwrap().parent().cloned() else { - let data = tree.get(&node_id).unwrap().data(); - assert!(data.is_mapped(None)); return match data { - Data::Mapped { mapped, .. } => Some(mapped.clone()), - _ => unreachable!(), - }; + FocusedNodeData::Window(window) => Some(window.into()), + FocusedNodeData::Group(focus_stack, alive) => Some(WindowGroup { + node: node_id, + output: output.downgrade(), + alive, + focus_stack, + }.into()), + } }; let og_idx = tree .children_ids(&og_parent) @@ -852,9 +854,17 @@ impl TilingLayout { child_id = parent.clone(); } - match tree.get(&node_id).unwrap().data() { - Data::Mapped { mapped, .. } => Some(mapped.clone()), - Data::Group { .. } => None, // TODO move groups to other screens + match data { + FocusedNodeData::Window(window) => Some(window.into()), + FocusedNodeData::Group(focus_stack, alive) => Some( + WindowGroup { + node: node_id, + output: output.downgrade(), + alive, + focus_stack, + } + .into(), + ), } } @@ -867,14 +877,47 @@ impl TilingLayout { let output = seat.active_output(); let tree = &self.queues.get(&output).unwrap().trees.back().unwrap().0; - // TODO: Rather use something like seat.current_keyboard_focus - // TODO https://github.com/Smithay/smithay/pull/777 - if let Some(last_active) = TilingLayout::last_active_window(tree, focus_stack) { - let (last_window, last_node_id) = last_active; + if let Some(focused) = TilingLayout::currently_focused_node(tree, seat).or_else(|| { + TilingLayout::last_active_window(tree, focus_stack) + .map(|(id, mapped)| (id, FocusedNodeData::Window(mapped))) + }) { + let (last_node_id, data) = focused; // stacks may handle focus internally - if last_window.handle_focus(direction) { - return FocusResult::Handled; + if let FocusedNodeData::Window(window) = data.clone() { + if window.handle_focus(direction) { + return FocusResult::Handled; + } + } + + if direction == FocusDirection::In { + if let FocusedNodeData::Group(mut stack, _) = data.clone() { + let maybe_id = stack.pop().unwrap(); + let id = if tree + .children_ids(&last_node_id) + .unwrap() + .any(|id| id == &maybe_id) + { + Some(maybe_id) + } else { + tree.children_ids(&last_node_id).unwrap().next().cloned() + }; + + if let Some(id) = id { + return match tree.get(&id).unwrap().data() { + Data::Mapped { mapped, .. } => FocusResult::Some(mapped.clone().into()), + Data::Group { alive, .. } => FocusResult::Some( + WindowGroup { + node: id, + output: output.downgrade(), + alive: Arc::downgrade(alive), + focus_stack: stack, + } + .into(), + ), + }; + } + } } let mut node_id = last_node_id.clone(); @@ -893,6 +936,13 @@ impl TilingLayout { &Data::Group { ref alive, .. } => Arc::downgrade(alive), _ => unreachable!(), }, + focus_stack: match data { + FocusedNodeData::Group(mut stack, _) => { + stack.push(child); + stack + } + _ => vec![child], + }, } .into(), ); @@ -1007,13 +1057,12 @@ impl TilingLayout { &mut self, new_orientation: Option, seat: &Seat, - focus_stack: impl Iterator + 'a, ) { let output = seat.active_output(); let Some(queue) = self.queues.get_mut(&output) else { return }; let mut tree = queue.trees.back().unwrap().0.copy_clone(); - if let Some((_, last_active)) = TilingLayout::last_active_window(&tree, focus_stack) { + if let Some((last_active, _)) = TilingLayout::currently_focused_node(&tree, seat) { if let Some(group) = tree.get(&last_active).unwrap().parent().cloned() { if let &mut Data::Group { ref mut orientation, @@ -1169,16 +1218,19 @@ impl TilingLayout { fn last_active_window<'a>( tree: &Tree, mut focus_stack: impl Iterator, - ) -> Option<(CosmicMapped, NodeId)> { + ) -> Option<(NodeId, CosmicMapped)> { focus_stack .find_map(|mapped| tree.root_node_id() .and_then(|root| tree.traverse_pre_order_ids(root).unwrap() .find(|id| matches!(tree.get(id).map(|n| n.data()), Ok(Data::Mapped { mapped: m, .. }) if m == mapped)) - ).map(|id| (mapped.clone(), id)) + ).map(|id| (id, mapped.clone())) ) } - fn currently_focused_node(tree: &mut Tree, seat: &Seat) -> Option { + fn currently_focused_node( + tree: &Tree, + seat: &Seat, + ) -> Option<(NodeId, FocusedNodeData)> { let mut target = seat.get_keyboard().unwrap().current_focus()?; // if the focus is currently on a popup, treat it's toplevel as the target @@ -1209,14 +1261,17 @@ impl TilingLayout { let node = tree.get(&node_id).ok()?; let data = node.data(); if data.is_mapped(Some(&mapped)) { - return Some(node_id); + return Some((node_id, FocusedNodeData::Window(mapped))); } } KeyboardFocusTarget::Group(window_group) => { if window_group.output == seat.active_output() { let node = tree.get(&window_group.node).ok()?; if node.data().is_group() { - return Some(window_group.node); + return Some(( + window_group.node, + FocusedNodeData::Group(window_group.focus_stack, window_group.alive), + )); } } } @@ -1523,7 +1578,7 @@ impl TilingLayout { &self, renderer: &mut R, output: &Output, - focused: Option<&CosmicMapped>, + seat: Option<&Seat>, non_exclusive_zone: Rectangle, overview: OverviewMode, indicator_thickness: u8, @@ -1594,7 +1649,7 @@ impl TilingLayout { reference_tree, renderer, non_exclusive_zone, - focused, // TODO: Would be better to be an old focus, + seat, // TODO: Would be better to be an old focus, // but for that we have to associate focus with a tree (and animate focus changes properly) 1.0 - percentage, transition, @@ -1624,7 +1679,7 @@ impl TilingLayout { target_tree, renderer, non_exclusive_zone, - focused, + seat, percentage, transition, ) @@ -1640,7 +1695,7 @@ impl TilingLayout { renderer, geometries, old_geometries, - focused, + seat, output_scale, percentage, if let Some(transition) = draw_groups { @@ -1668,7 +1723,7 @@ fn geometries_for_groupview( tree: &Tree, renderer: &mut R, non_exclusive_zone: Rectangle, - focused: Option<&CosmicMapped>, + seat: Option<&Seat>, alpha: f32, transition: f32, ) -> Option<( @@ -1691,6 +1746,10 @@ where let gap: i32 = (GAP as f32 * transition).round() as i32; let alpha = alpha * transition; + let focused = seat + .and_then(|seat| TilingLayout::currently_focused_node(&tree, seat)) + .map(|(id, _)| id); + for node_id in tree.traverse_pre_order_ids(root).unwrap() { if let Some(mut geo) = stack.pop() { // zoom in windows @@ -1700,7 +1759,7 @@ where let node: &Node = tree.get(&node_id).unwrap(); let data = node.data(); - let is_potential_group = if let Some(focused) = focused { + let is_potential_group = if let Some(focused_id) = focused.as_ref() { // 1. focused can move into us directly if let Some(parent) = node.parent() { let parent_data = tree.get(parent).unwrap().data(); @@ -1710,13 +1769,10 @@ where .unwrap() .position(|id| id == &node_id) .unwrap(); - if let Some((focused_idx, _focused_id)) = tree + if let Some(focused_idx) = tree .children_ids(parent) .unwrap() - .enumerate() - .find(|(_, child_id)| { - tree.get(child_id).unwrap().data().is_mapped(Some(focused)) - }) + .position(|id| id == focused_id) { // only direct neighbors focused_idx.abs_diff(idx) == 1 @@ -1730,14 +1786,11 @@ where } // 2. focused can move out into us else { - tree.children_ids(&node_id) - .unwrap() - .find(|child_id| { - tree.children(child_id) - .unwrap() - .any(|child| child.data().is_mapped(Some(focused))) - }) - .is_some() + tree.children_ids(&node_id).unwrap().any(|child_id| { + tree.children_ids(child_id) + .unwrap() + .any(|child_id| child_id == focused_id) + }) } } else { false @@ -1750,10 +1803,10 @@ where sizes, alive, } => { - let has_active_child = if let Some(focused) = focused { - tree.children(&node_id) + let has_active_child = if let Some(focused_id) = focused.as_ref() { + tree.children_ids(&node_id) .unwrap() - .any(|child| child.data().is_mapped(Some(focused))) + .any(|child_id| child_id == focused_id) } else { false }; @@ -1985,7 +2038,7 @@ fn render_new_tree( renderer: &mut R, geometries: Option>>, old_geometries: Option>>, - focused: Option<&CosmicMapped>, + seat: Option<&Seat>, output_scale: f64, percentage: f32, indicator_thickness: u8, @@ -1996,43 +2049,33 @@ where CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, { + let focused = seat + .and_then(|seat| TilingLayout::currently_focused_node(&target_tree, seat)) + .map(|(id, _)| id); + if let Some(root) = target_tree.root_node_id() { let old_geometries = old_geometries.unwrap_or_default(); let geometries = geometries.unwrap_or_default(); target_tree .traverse_pre_order_ids(root) .unwrap() - .filter(|node_id| target_tree.get(node_id).unwrap().data().is_mapped(None)) - .map(|node_id| match target_tree.get(&node_id).unwrap().data() { - Data::Mapped { - mapped, - last_geometry, - .. - } => (mapped, last_geometry, geometries.get(&node_id)), - _ => unreachable!(), - }) - .flat_map(|(mapped, original_geo, scaled_geo)| { + .flat_map(|node_id| { + let data = target_tree.get(&node_id).unwrap().data(); + let (original_geo, scaled_geo) = (data.geometry(), geometries.get(&node_id)); + let (old_original_geo, old_scaled_geo) = if let Some(reference_tree) = reference_tree.as_ref() { if let Some(root) = reference_tree.root_node_id() { reference_tree .traverse_pre_order_ids(root) .unwrap() - .find(|node_id| { - reference_tree - .get(node_id) - .unwrap() - .data() - .is_mapped(Some(mapped)) + .find(|id| &node_id == id) + .map(|node_id| { + ( + reference_tree.get(&node_id).unwrap().data().geometry(), + old_geometries.get(&node_id), + ) }) - .map( - |node_id| match reference_tree.get(&node_id).unwrap().data() { - Data::Mapped { last_geometry, .. } => { - (last_geometry, old_geometries.get(&node_id)) - } - _ => unreachable!(), - }, - ) } else { None } @@ -2101,79 +2144,88 @@ where (new_geo, percentage) }; - let original_location = (original_geo.loc - mapped.geometry().loc) - .to_physical_precise_round(output_scale); + let mut elements = Vec::new(); - let mut elements = - AsRenderElements::::render_elements::>( - mapped, - renderer, - original_location, - Scale::from(output_scale), - alpha, - ) - .into_iter() - .flat_map(|element| match element { - CosmicMappedRenderElement::Stack(elem) => { - Some(CosmicMappedRenderElement::TiledStack({ - let cropped = CropRenderElement::from_element( - elem, - output_scale, - crop_rect.to_physical_precise_round(output_scale), - )?; - let rescaled = RescaleRenderElement::from_element( - cropped, - original_geo.loc.to_physical_precise_round(output_scale), - scale, - ); - let relocated = RelocateRenderElement::from_element( - rescaled, - (geo.loc - original_geo.loc) - .to_physical_precise_round(output_scale), - Relocate::Relative, - ); - relocated - })) - } - CosmicMappedRenderElement::Window(elem) => { - Some(CosmicMappedRenderElement::TiledWindow({ - let cropped = CropRenderElement::from_element( - elem, - output_scale, - crop_rect.to_physical_precise_round(output_scale), - )?; - let rescaled = RescaleRenderElement::from_element( - cropped, - original_geo.loc.to_physical_precise_round(output_scale), - scale, - ); - let relocated = RelocateRenderElement::from_element( - rescaled, - (geo.loc - original_geo.loc) - .to_physical_precise_round(output_scale), - Relocate::Relative, - ); - relocated - })) - } - x => Some(x), - }) - .collect::>(); - - if focused == Some(mapped) { + if focused == Some(node_id) { if indicator_thickness > 0 { let element = IndicatorShader::focus_element( renderer, - mapped.clone(), + match data { + Data::Mapped { mapped, .. } => mapped.clone().into(), + Data::Group { alive, .. } => { + IndicatorKey::Group(Arc::downgrade(alive)) + } + }, geo, indicator_thickness, 1.0, FOCUS_INDICATOR_COLOR, ); - elements.insert(0, element.into()); + elements.push(element.into()); } } + if let Data::Mapped { mapped, .. } = data { + let original_location = (original_geo.loc - mapped.geometry().loc) + .to_physical_precise_round(output_scale); + + elements.extend( + AsRenderElements::::render_elements::>( + mapped, + renderer, + original_location, + Scale::from(output_scale), + alpha, + ) + .into_iter() + .flat_map(|element| match element { + CosmicMappedRenderElement::Stack(elem) => { + Some(CosmicMappedRenderElement::TiledStack({ + let cropped = CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + )?; + let rescaled = RescaleRenderElement::from_element( + cropped, + original_geo.loc.to_physical_precise_round(output_scale), + scale, + ); + let relocated = RelocateRenderElement::from_element( + rescaled, + (geo.loc - original_geo.loc) + .to_physical_precise_round(output_scale), + Relocate::Relative, + ); + relocated + })) + } + CosmicMappedRenderElement::Window(elem) => { + Some(CosmicMappedRenderElement::TiledWindow({ + let cropped = CropRenderElement::from_element( + elem, + output_scale, + crop_rect.to_physical_precise_round(output_scale), + )?; + let rescaled = RescaleRenderElement::from_element( + cropped, + original_geo.loc.to_physical_precise_round(output_scale), + scale, + ); + let relocated = RelocateRenderElement::from_element( + rescaled, + (geo.loc - original_geo.loc) + .to_physical_precise_round(output_scale), + Relocate::Relative, + ); + relocated + })) + } + x => Some(x), + }), + ); + } + elements }) .collect() diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 4f117fc6..84d5ee15 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -594,7 +594,7 @@ impl Workspace { .render_output::( renderer, output, - focused.as_ref(), + draw_focus_indicator, layer_map.non_exclusive_zone(), overview.clone(), indicator_thickness, From a9e06741d44ddb5a938f70534297ef9104a2fbc4 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 31 May 2023 13:27:52 +0200 Subject: [PATCH 036/264] tiling: Add group selection highlight --- src/backend/render/mod.rs | 86 ++++++++++++---------------------- src/shell/layout/tiling/mod.rs | 23 +++++++-- 2 files changed, 49 insertions(+), 60 deletions(-) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index e53e3cf9..8a383cd0 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -92,36 +92,44 @@ pub static RECTANGLE_SHADER: &str = include_str!("./shaders/rounded_rectangle.fr pub struct IndicatorShader(pub GlesPixelProgram); #[derive(Clone)] -pub enum IndicatorKey { +pub enum Key { + Static(Id), Group(Weak<()>), Window(CosmicMapped), } -impl std::hash::Hash for IndicatorKey { +impl std::hash::Hash for Key { fn hash(&self, state: &mut H) { match self { - IndicatorKey::Group(arc) => (arc.as_ptr() as usize).hash(state), - IndicatorKey::Window(window) => window.hash(state), + Key::Static(id) => id.hash(state), + Key::Group(arc) => (arc.as_ptr() as usize).hash(state), + Key::Window(window) => window.hash(state), } } } -impl PartialEq for IndicatorKey { +impl PartialEq for Key { fn eq(&self, other: &Self) -> bool { match (self, other) { - (IndicatorKey::Group(g1), IndicatorKey::Group(g2)) => Weak::ptr_eq(g1, g2), - (IndicatorKey::Window(w1), IndicatorKey::Window(w2)) => w1 == w2, + (Key::Static(s1), Key::Static(s2)) => s1 == s2, + (Key::Group(g1), Key::Group(g2)) => Weak::ptr_eq(g1, g2), + (Key::Window(w1), Key::Window(w2)) => w1 == w2, _ => false, } } } -impl Eq for IndicatorKey {} -impl From for IndicatorKey { +impl Eq for Key {} +impl From for Key { fn from(window: CosmicMapped) -> Self { - IndicatorKey::Window(window) + Key::Window(window) } } -impl From for IndicatorKey { +impl From for Key { fn from(group: WindowGroup) -> Self { - IndicatorKey::Group(group.alive.clone()) + Key::Group(group.alive.clone()) + } +} +impl From for Key { + fn from(id: Id) -> Self { + Key::Static(id) } } @@ -131,7 +139,7 @@ struct IndicatorSettings { alpha: f32, color: [f32; 3], } -type IndicatorCache = RefCell>; +type IndicatorCache = RefCell>; impl IndicatorShader { pub fn get(renderer: &R) -> GlesPixelProgram { @@ -146,7 +154,7 @@ impl IndicatorShader { pub fn focus_element( renderer: &R, - key: impl Into, + key: impl Into, mut element_geo: Rectangle, thickness: u8, alpha: f32, @@ -161,7 +169,7 @@ impl IndicatorShader { pub fn element( renderer: &R, - key: impl Into, + key: impl Into, geo: Rectangle, thickness: u8, alpha: f32, @@ -180,8 +188,9 @@ impl IndicatorShader { user_data.insert_if_missing(|| IndicatorCache::new(HashMap::new())); let mut cache = user_data.get::().unwrap().borrow_mut(); cache.retain(|k, _| match k { - IndicatorKey::Group(w) => w.upgrade().is_some(), - IndicatorKey::Window(w) => w.alive(), + Key::Static(_) => true, + Key::Group(w) => w.upgrade().is_some(), + Key::Window(w) => w.alive(), }); let key = key.into(); @@ -217,47 +226,13 @@ impl IndicatorShader { pub struct BackdropShader(pub GlesPixelProgram); -#[derive(Clone)] -pub enum BackdropKey { - Static(Id), - Window(CosmicMapped), -} -impl std::hash::Hash for BackdropKey { - fn hash(&self, state: &mut H) { - match self { - BackdropKey::Static(id) => id.hash(state), - BackdropKey::Window(window) => window.hash(state), - } - } -} -impl PartialEq for BackdropKey { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (BackdropKey::Static(s1), BackdropKey::Static(s2)) => s1 == s2, - (BackdropKey::Window(w1), BackdropKey::Window(w2)) => w1 == w2, - _ => false, - } - } -} -impl Eq for BackdropKey {} -impl From for BackdropKey { - fn from(window: CosmicMapped) -> Self { - BackdropKey::Window(window) - } -} -impl From for BackdropKey { - fn from(id: Id) -> Self { - BackdropKey::Static(id) - } -} - #[derive(PartialEq)] struct BackdropSettings { radius: f32, alpha: f32, color: [f32; 3], } -type BackdropCache = RefCell>; +type BackdropCache = RefCell>; impl BackdropShader { pub fn get(renderer: &R) -> GlesPixelProgram { @@ -272,7 +247,7 @@ impl BackdropShader { pub fn element( renderer: &R, - key: impl Into, + key: impl Into, geo: Rectangle, radius: f32, alpha: f32, @@ -291,8 +266,9 @@ impl BackdropShader { user_data.insert_if_missing(|| BackdropCache::new(HashMap::new())); let mut cache = user_data.get::().unwrap().borrow_mut(); cache.retain(|k, _| match k { - BackdropKey::Static(_) => true, - BackdropKey::Window(w) => w.alive(), + Key::Static(_) => true, + Key::Group(a) => a.upgrade().is_some(), + Key::Window(w) => w.alive(), }); let key = key.into(); diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 9ca0c75e..fe3566a7 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -2,7 +2,7 @@ use crate::{ backend::render::{ - element::AsGlowRenderer, IndicatorKey, IndicatorShader, ACTIVE_GROUP_COLOR, + element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, ACTIVE_GROUP_COLOR, FOCUS_INDICATOR_COLOR, GROUP_COLOR, }, shell::{ @@ -1815,7 +1815,7 @@ where elements.push( IndicatorShader::element( renderer, - IndicatorKey::Group(Arc::downgrade(&alive)), + Key::Group(Arc::downgrade(&alive)), geo, 3, alpha, @@ -2152,9 +2152,7 @@ where renderer, match data { Data::Mapped { mapped, .. } => mapped.clone().into(), - Data::Group { alive, .. } => { - IndicatorKey::Group(Arc::downgrade(alive)) - } + Data::Group { alive, .. } => Key::Group(Arc::downgrade(alive)), }, geo, indicator_thickness, @@ -2163,6 +2161,21 @@ where ); elements.push(element.into()); } + + if data.is_group() { + let element = BackdropShader::element( + renderer, + match data { + Data::Mapped { mapped, .. } => mapped.clone().into(), + Data::Group { alive, .. } => Key::Group(Arc::downgrade(alive)), + }, + geo, + (indicator_thickness * 2) as f32, + 0.25, + FOCUS_INDICATOR_COLOR, + ); + elements.push(element.into()); + } } if let Data::Mapped { mapped, .. } = data { From 1d51da4ed3de279128666271f9151bc533831679 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 31 May 2023 14:15:41 +0200 Subject: [PATCH 037/264] stack: Ability to modify a stacks windows --- src/shell/element/stack.rs | 42 ++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 9ecd1b34..5dd470b9 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -95,15 +95,16 @@ pub enum Focus { } impl CosmicStack { - pub fn new( - window: impl Into, + pub fn new>( + windows: impl Iterator, handle: LoopHandle<'static, crate::state::Data>, ) -> CosmicStack { - let window = window.into(); - let width = window.geometry().size.w; + let windows = windows.map(Into::into).collect::>(); + assert!(!windows.is_empty()); + let width = windows[0].geometry().size.w; CosmicStack(IcedElement::new( CosmicStackInternal { - windows: Arc::new(Mutex::new(vec![window])), + windows: Arc::new(Mutex::new(windows)), active: Arc::new(AtomicUsize::new(0)), previous_keyboard: Arc::new(AtomicUsize::new(0)), pointer_entered: None, @@ -115,9 +116,34 @@ impl CosmicStack { )) } - //pub fn add_window() - //pub fn remove_window() - //pub fn len + pub fn add_window(&self, window: CosmicSurface) { + self.0 + .with_program(|p| p.windows.lock().unwrap().push(window)); + } + + pub fn remove_window(&self, window: &CosmicSurface) { + self.0.with_program(|p| { + let mut windows = p.windows.lock().unwrap(); + let Some(idx) = windows.iter().position(|w| w == window) else { return }; + windows.remove(idx); + p.active.fetch_min(windows.len() - 1, Ordering::SeqCst); + }) + } + + pub fn remove_idx(&self, idx: usize) { + self.0.with_program(|p| { + let mut windows = p.windows.lock().unwrap(); + if windows.len() >= idx { + return; + } + windows.remove(idx); + p.active.fetch_min(windows.len(), Ordering::SeqCst); + }) + } + + pub fn len(&self) -> usize { + self.0.with_program(|p| p.windows.lock().unwrap().len()) + } pub fn active(&self) -> CosmicSurface { self.0 From 20f4dcb466248650e98038e16059d4459ce5c8a8 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 31 May 2023 20:02:39 +0200 Subject: [PATCH 038/264] chore: Upgrade to latest libcosmic --- Cargo.lock | 1153 ++++++++++++++++++++--------------- Cargo.toml | 7 +- src/shell/element/stack.rs | 46 ++ src/shell/element/window.rs | 117 ++-- src/utils/iced.rs | 164 ++--- 5 files changed, 872 insertions(+), 615 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 828323c8..b411ed33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,9 +168,9 @@ checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "ash" -version = "0.37.2+1.3.238" +version = "0.37.3+1.3.251" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28bf19c1f0a470be5fbf7522a308a05df06610252c5bcf5143e1b23f629a9a03" +checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" dependencies = [ "libloading 0.7.4", ] @@ -181,6 +181,17 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79d6dc922a2792b006573f60b2648076355daeae5ce9cb59507e5908c9625d31" +[[package]] +name = "atomicwrites" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1163d9d7c51de51a2b79d6df5e8888d11e9df17c752ce4a285fb6ca1580734e" +dependencies = [ + "rustix", + "tempfile", + "windows-sys 0.48.0", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -208,6 +219,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + [[package]] name = "bincode" version = "1.3.3" @@ -307,7 +324,7 @@ checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -536,7 +553,9 @@ dependencies = [ "edid-rs", "egui", "glow 0.11.2", - "iced_softbuffer", + "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_renderer", + "iced_tiny_skia", "id_tree", "indexmap", "lazy_static", @@ -556,6 +575,7 @@ dependencies = [ "smithay", "smithay-egui", "thiserror", + "tiny-skia 0.9.1", "tracing", "tracing-journald", "tracing-subscriber", @@ -566,10 +586,33 @@ dependencies = [ "xkbcommon 0.4.1", ] +[[package]] +name = "cosmic-config" +version = "0.1.0" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +dependencies = [ + "atomicwrites", + "cosmic-config-derive", + "dirs 5.0.1", + "iced_futures 0.6.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "notify", + "ron 0.8.0", + "serde", +] + +[[package]] +name = "cosmic-config-derive" +version = "0.1.0" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "cosmic-protocols" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-protocols?branch=main#7d80b59afc464a8ecdb8001333f18de554f299f4" +source = "git+https://github.com/pop-os/cosmic-protocols?branch=main#f0cfe0973376b31fba4a726a35633a8e39e9319e" dependencies = [ "bitflags 1.3.2", "wayland-backend", @@ -580,15 +623,15 @@ dependencies = [ [[package]] name = "cosmic-text" -version = "0.7.0" -source = "git+https://github.com/pop-os/cosmic-text?rev=e788c175#e788c175ec31094b04dcacbc0537dba4433afcfc" +version = "0.8.0" +source = "git+https://github.com/hecrj/cosmic-text.git?rev=b85d6a4f2376f8a8a7dadc0f8bcb89d4db10a1c9#b85d6a4f2376f8a8a7dadc0f8bcb89d4db10a1c9" dependencies = [ - "fontdb 0.13.1", + "fontdb", "libm", "log", "ouroboros 0.15.6", "rangemap", - "rustybuzz 0.7.0", + "rustybuzz", "swash", "sys-locale", "unicode-bidi", @@ -600,9 +643,10 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-theme.git#ce3a63a10638195c7b5a47224c89a82c2fa9494d" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" dependencies = [ "anyhow", + "cosmic-config", "csscolorparser", "directories", "lazy_static", @@ -617,11 +661,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "269b94889f152389ed39fde8a69a6083ff4ca73993360d2850d5c281e3488c11" dependencies = [ - "iced 0.9.0", - "iced_core 0.9.0", - "iced_futures 0.6.0", - "iced_native 0.10.3", - "iced_style 0.8.0", + "iced 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_futures 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_native", + "iced_style 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -740,17 +784,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" -[[package]] -name = "d3d12" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "827914e1f53b1e0e025ecd3d967a7836b7bcb54520f90e21ef8df7b4d88a2759" -dependencies = [ - "bitflags 1.3.2", - "libloading 0.7.4", - "winapi", -] - [[package]] name = "d3d12" version = "0.6.0" @@ -762,16 +795,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core 0.10.2", - "darling_macro 0.10.2", -] - [[package]] name = "darling" version = "0.13.4" @@ -783,17 +806,13 @@ dependencies = [ ] [[package]] -name = "darling_core" -version = "0.10.2" +name = "darling" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.9.3", - "syn 1.0.109", + "darling_core 0.20.1", + "darling_macro 0.20.1", ] [[package]] @@ -806,19 +825,22 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", + "strsim", "syn 1.0.109", ] [[package]] -name = "darling_macro" -version = "0.10.2" +name = "darling_core" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" dependencies = [ - "darling_core 0.10.2", + "fnv", + "ident_case", + "proc-macro2", "quote", - "syn 1.0.109", + "strsim", + "syn 2.0.18", ] [[package]] @@ -833,12 +855,14 @@ dependencies = [ ] [[package]] -name = "data-url" -version = "0.1.1" +name = "darling_macro" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30bfce702bcfa94e906ef82421f2c0e61c076ad76030c16ee5d2e9a32fe193" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ - "matches", + "darling_core 0.20.1", + "quote", + "syn 2.0.18", ] [[package]] @@ -849,14 +873,14 @@ checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5" [[package]] name = "derive_setters" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1cf41b4580a37cca5ef2ada2cc43cf5d6be3983f4522e83010d67ab6925e84b" +checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" dependencies = [ - "darling 0.10.2", + "darling 0.20.1", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.18", ] [[package]] @@ -876,7 +900,7 @@ version = "4.0.1" source = "git+https://github.com/edfloreshz/directories-rs#6a6d83d853a35ee3273034215c4defaf61286fe5" dependencies = [ "anyhow", - "dirs-sys", + "dirs-sys 0.3.7", ] [[package]] @@ -885,7 +909,16 @@ version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ - "dirs-sys", + "dirs-sys 0.3.7", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", ] [[package]] @@ -899,6 +932,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -1025,7 +1070,7 @@ checksum = "8257332fb168a965b3dca81d6a344e053153773c889cabdba0b3b76f1629ae81" dependencies = [ "bytemuck", "egui", - "glow 0.12.1", + "glow 0.12.2", "memoffset 0.6.5", "tracing", "wasm-bindgen", @@ -1201,6 +1246,16 @@ dependencies = [ "str-buf", ] +[[package]] +name = "etagere" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6301151a318f367f392c31395beb1cfba5ccd9abc44d1db0db3a4b27b9601c89" +dependencies = [ + "euclid", + "svg_fmt", +] + [[package]] name = "euclid" version = "0.22.9" @@ -1254,6 +1309,18 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "filetime" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.2.16", + "windows-sys 0.48.0", +] + [[package]] name = "find-crate" version = "0.6.3" @@ -1308,14 +1375,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "fontdb" -version = "0.6.2" +name = "fontconfig-parser" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d66551cc28351f0bc6a73da86459ee7765caaad03ce284f2dc36472dbf539cd" +checksum = "4ab2e12762761366dcb876ab8b6e0cfa4797ddcd890575919f008b5ba655672a" dependencies = [ - "log", - "memmap2 0.3.1", - "ttf-parser 0.12.3", + "roxmltree 0.18.0", ] [[package]] @@ -1324,8 +1389,9 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "237ff9f0813bbfc9de836016472e0c9ae7802f174a51594607e5f4ff334cb2f5" dependencies = [ + "fontconfig-parser", "log", - "memmap2 0.5.10", + "memmap2", "slotmap", "ttf-parser 0.18.1", ] @@ -1357,7 +1423,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -1388,7 +1454,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00e61ac115df4632b592d36b71fda3c259f4c8061c70b7fa429bac145890e880" dependencies = [ - "dirs", + "dirs 4.0.0", "once_cell", "rust-ini", "thiserror", @@ -1417,6 +1483,15 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + [[package]] name = "futures" version = "0.3.28" @@ -1474,7 +1549,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -1620,9 +1695,9 @@ dependencies = [ [[package]] name = "glow" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e007a07a24de5ecae94160f141029e9a347282cfe25d1d58d85d845cf3130f1" +checksum = "807edf58b70c0b5b2181dd39fe1839dbdb3ba02645630dc5f753e23da307f762" dependencies = [ "js-sys", "slotmap", @@ -1630,18 +1705,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "glow_glyph" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4e62c64947b9a24fe20e2bba9ad819ecb506ef5c8df7ffc4737464c6df9510" -dependencies = [ - "bytemuck", - "glow 0.11.2", - "glyph_brush", - "log", -] - [[package]] name = "glyph_brush" version = "0.7.7" @@ -1680,6 +1743,17 @@ dependencies = [ "xi-unicode", ] +[[package]] +name = "glyphon" +version = "0.2.0" +source = "git+https://github.com/hecrj/glyphon.git?rev=f145067d292082abdd1f2b2481812d4a52c394ec#f145067d292082abdd1f2b2481812d4a52c394ec" +dependencies = [ + "cosmic-text", + "etagere", + "lru", + "wgpu 0.16.1", +] + [[package]] name = "gpu-alloc" version = "0.5.4" @@ -1720,7 +1794,7 @@ checksum = "0b0c02e1ba0bdb14e965058ca34e09c020f8e507a760df1121728e0aef68d57a" dependencies = [ "bitflags 1.3.2", "gpu-descriptor-types", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -1760,6 +1834,15 @@ dependencies = [ "ahash 0.7.6", ] +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] + [[package]] name = "hassle-rs" version = "0.9.0" @@ -1771,7 +1854,22 @@ dependencies = [ "libc", "libloading 0.7.4", "thiserror", - "widestring", + "widestring 0.5.1", + "winapi", +] + +[[package]] +name = "hassle-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1397650ee315e8891a0df210707f0fc61771b0cc518c3023896064c5407cb3b0" +dependencies = [ + "bitflags 1.3.2", + "com-rs", + "libc", + "libloading 0.7.4", + "thiserror", + "widestring 1.0.2", "winapi", ] @@ -1814,46 +1912,32 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "iced" -version = "0.6.0" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" -dependencies = [ - "iced_core 0.6.2", - "iced_dyrend", - "iced_futures 0.5.1", - "iced_glow", - "iced_graphics 0.5.0", - "iced_native 0.7.0", - "iced_softbuffer", - "iced_wgpu 0.7.0", - "image", - "thiserror", -] - [[package]] name = "iced" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efbddf356d01e9d41cd394a9d04d62bfd89650a30f12fda5839cabb8c4591c88" dependencies = [ - "iced_core 0.9.0", - "iced_futures 0.6.0", - "iced_graphics 0.8.0", - "iced_native 0.10.3", - "iced_wgpu 0.10.0", + "iced_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_futures 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_graphics 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_native", + "iced_wgpu 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "iced_winit", "thiserror", ] [[package]] -name = "iced_core" -version = "0.6.2" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" +name = "iced" +version = "0.9.0" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" dependencies = [ - "bitflags 1.3.2", - "palette", - "wasm-timer", + "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_futures 0.6.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_renderer", + "iced_widget", + "image", + "thiserror", ] [[package]] @@ -1868,26 +1952,27 @@ dependencies = [ ] [[package]] -name = "iced_dyrend" -version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" +name = "iced_core" +version = "0.9.0" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" dependencies = [ - "iced_glow", - "iced_graphics 0.5.0", - "iced_native 0.7.0", - "iced_softbuffer", - "iced_wgpu 0.7.0", + "bitflags 1.3.2", + "instant", "log", - "raw-window-handle 0.5.2", + "palette", + "thiserror", + "twox-hash", ] [[package]] name = "iced_futures" -version = "0.5.1" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "215d51fa4f70dbb63775d7141243c4d98d4d525d8949695601f8fbac7dcbc04e" dependencies = [ "futures", "log", + "tokio", "wasm-bindgen-futures", "wasm-timer", ] @@ -1895,87 +1980,46 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "215d51fa4f70dbb63775d7141243c4d98d4d525d8949695601f8fbac7dcbc04e" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" dependencies = [ "futures", + "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", "log", - "tokio", "wasm-bindgen-futures", "wasm-timer", ] -[[package]] -name = "iced_glow" -version = "0.5.1" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" -dependencies = [ - "bytemuck", - "euclid", - "glow 0.11.2", - "glow_glyph", - "glyph_brush", - "iced_graphics 0.5.0", - "iced_native 0.7.0", - "log", -] - [[package]] name = "iced_graphics" -version = "0.5.0" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338a6aff7db906537074ad0fe8b720cfdb9512cdfea43c628c76bd1cf50fdcc0" dependencies = [ "bitflags 1.3.2", "bytemuck", "glam", - "iced_native 0.7.0", - "iced_style 0.5.1", - "image", - "kamadak-exif", + "iced_native", + "iced_style 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "log", "raw-window-handle 0.5.2", - "resvg 0.18.0", "thiserror", - "tiny-skia 0.6.6", - "usvg 0.18.0", ] [[package]] name = "iced_graphics" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "338a6aff7db906537074ad0fe8b720cfdb9512cdfea43c628c76bd1cf50fdcc0" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" dependencies = [ "bitflags 1.3.2", "bytemuck", "glam", - "iced_native 0.10.3", - "iced_style 0.8.0", + "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "image", + "kamadak-exif", "log", "raw-window-handle 0.5.2", "thiserror", -] - -[[package]] -name = "iced_lazy" -version = "0.3.0" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" -dependencies = [ - "iced_native 0.7.0", - "ouroboros 0.13.0", -] - -[[package]] -name = "iced_native" -version = "0.7.0" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" -dependencies = [ - "iced_core 0.6.2", - "iced_futures 0.5.1", - "iced_style 0.5.1", - "num-traits", - "twox-hash", - "unicode-segmentation", + "tiny-skia 0.9.1", ] [[package]] @@ -1984,9 +2028,9 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d012eb06da490fe46a695b39721c20da9643f35cf2ecb9d30618fdeb96170616" dependencies = [ - "iced_core 0.9.0", - "iced_futures 0.6.0", - "iced_style 0.8.0", + "iced_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_futures 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_style 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits", "thiserror", "twox-hash", @@ -1994,26 +2038,34 @@ dependencies = [ ] [[package]] -name = "iced_softbuffer" +name = "iced_renderer" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" dependencies = [ - "cosmic-text", - "iced_graphics 0.5.0", - "iced_native 0.7.0", - "lazy_static", - "log", - "raqote", + "iced_graphics 0.8.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_tiny_skia", + "iced_wgpu 0.10.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", "raw-window-handle 0.5.2", - "softbuffer", + "thiserror", +] + +[[package]] +name = "iced_runtime" +version = "0.1.0" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +dependencies = [ + "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_futures 0.6.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "thiserror", ] [[package]] name = "iced_style" -version = "0.5.1" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e37333dc2991201140302cd0d4cea051bd37ca3671d5008ec85df86d232ff30" dependencies = [ - "iced_core 0.6.2", + "iced_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell", "palette", ] @@ -2021,18 +2073,36 @@ dependencies = [ [[package]] name = "iced_style" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e37333dc2991201140302cd0d4cea051bd37ca3671d5008ec85df86d232ff30" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" dependencies = [ - "iced_core 0.9.0", + "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", "once_cell", "palette", ] +[[package]] +name = "iced_tiny_skia" +version = "0.1.0" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +dependencies = [ + "bytemuck", + "cosmic-text", + "iced_graphics 0.8.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "kurbo 0.9.5", + "log", + "raw-window-handle 0.5.2", + "resvg 0.32.0", + "rustc-hash", + "softbuffer", + "tiny-skia 0.9.1", + "twox-hash", +] + [[package]] name = "iced_wgpu" -version = "0.7.0" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478803c56061f567ce5ddf223b20d11d3c118cc46bb0d0552370dc65cdc4cb9c" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -2041,33 +2111,48 @@ dependencies = [ "glam", "glyph_brush", "guillotiere", - "iced_graphics 0.5.0", - "iced_native 0.7.0", + "iced_graphics 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_native", "log", "raw-window-handle 0.5.2", - "wgpu 0.14.2", - "wgpu_glyph 0.18.0", + "wgpu 0.15.1", + "wgpu_glyph", ] [[package]] name = "iced_wgpu" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478803c56061f567ce5ddf223b20d11d3c118cc46bb0d0552370dc65cdc4cb9c" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" dependencies = [ "bitflags 1.3.2", "bytemuck", "encase", "futures", "glam", - "glyph_brush", + "glyphon", "guillotiere", - "iced_graphics 0.8.0", - "iced_native 0.10.3", + "iced_graphics 0.8.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", "log", + "once_cell", "raw-window-handle 0.5.2", - "wgpu 0.15.1", - "wgpu_glyph 0.19.0", + "resvg 0.32.0", + "rustc-hash", + "twox-hash", + "wgpu 0.16.1", +] + +[[package]] +name = "iced_widget" +version = "0.1.0" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +dependencies = [ + "iced_renderer", + "iced_runtime", + "iced_style 0.8.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "num-traits", + "ouroboros 0.13.0", + "thiserror", + "unicode-segmentation", ] [[package]] @@ -2076,9 +2161,9 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a59ea3a85149a6a1f9e92b6c740ce90f04e5c7d848cfd05742336863fceb955" dependencies = [ - "iced_futures 0.6.0", - "iced_graphics 0.8.0", - "iced_native 0.10.3", + "iced_futures 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_graphics 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "iced_native", "log", "thiserror", "web-sys", @@ -2090,7 +2175,7 @@ dependencies = [ [[package]] name = "id_tree" version = "1.8.0" -source = "git+https://github.com/Drakulix/id-tree.git?branch=feature/copy_clone#c9a2b8c325566d223cf06362c902636b0405e28c" +source = "git+https://github.com/Drakulix/id-tree.git?branch=feature/copy_clone#632a57d6d49160e18d7300fa7edae52281ec5482" dependencies = [ "snowflake", ] @@ -2112,7 +2197,7 @@ dependencies = [ "color_quant", "exr", "gif", - "jpeg-decoder 0.3.0", + "jpeg-decoder", "num-rational", "num-traits", "png", @@ -2126,6 +2211,12 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df19da1e92fbfec043ca97d622955381b1f3ee72a180ec999912df31b1ccd951" +[[package]] +name = "imagesize" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72ad49b554c1728b1e83254a1b1565aea4161e28dabbfa171fc15fe62299caf" + [[package]] name = "indexmap" version = "1.9.3" @@ -2133,10 +2224,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", "serde", ] +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + [[package]] name = "input" version = "0.8.2" @@ -2173,9 +2284,9 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi 0.3.1", "libc", @@ -2203,12 +2314,6 @@ dependencies = [ "libc", ] -[[package]] -name = "jpeg-decoder" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" - [[package]] name = "jpeg-decoder" version = "0.3.0" @@ -2253,13 +2358,42 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "kqueue" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + [[package]] name = "kurbo" -version = "0.8.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb348d766edbac91ba1eb83020d96f4f8867924d194393083c15a51f185e6a82" +checksum = "7a53776d271cfb873b17c618af0298445c88afc52837f3e948fa3fafd131f449" dependencies = [ - "arrayvec 0.5.2", + "arrayvec 0.7.2", +] + +[[package]] +name = "kurbo" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd85a5776cd9500c2e2059c8c76c3b01528566b7fcbaf8098b55a33fc298849b" +dependencies = [ + "arrayvec 0.7.2", ] [[package]] @@ -2283,19 +2417,20 @@ checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=24709e9c3b#24709e9c3b56c49a0af168d1e37ebef85f112c8a" +source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" dependencies = [ "apply", + "cosmic-config", "cosmic-theme", "derive_setters", "fraction", "freedesktop-icons", - "iced 0.6.0", - "iced_core 0.6.2", - "iced_lazy", - "iced_native 0.7.0", - "iced_softbuffer", - "iced_style 0.5.1", + "iced 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_runtime", + "iced_style 0.8.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_tiny_skia", + "iced_widget", "lazy_static", "palette", "slotmap", @@ -2399,12 +2534,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" [[package]] name = "log-panics" @@ -2417,14 +2549,12 @@ dependencies = [ ] [[package]] -name = "lyon_geom" -version = "0.17.7" +name = "lru" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d89ccbdafd83d259403e22061be27bccc3254bba65cdc5303250c4227c8c8e" +checksum = "71e7d46de488603ffdd5f30afbc64fbba2378214a2c3a2fb83abf3d33126df17" dependencies = [ - "arrayvec 0.5.2", - "euclid", - "num-traits", + "hashbrown 0.13.2", ] [[package]] @@ -2445,27 +2575,12 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memmap2" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357" -dependencies = [ - "libc", -] - [[package]] name = "memmap2" version = "0.5.10" @@ -2543,14 +2658,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "log", "wasi", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -2561,9 +2676,9 @@ checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" [[package]] name = "naga" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "262d2840e72dbe250e8cf2f522d080988dfca624c4112c096238a4845f591707" +checksum = "6c3d4269bcb7d50121097702fde1afb75f4ea8083aeb7a55688dcf289a853271" dependencies = [ "bit-set", "bitflags 1.3.2", @@ -2581,9 +2696,9 @@ dependencies = [ [[package]] name = "naga" -version = "0.11.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c3d4269bcb7d50121097702fde1afb75f4ea8083aeb7a55688dcf289a853271" +checksum = "80cd00bd6180a8790f1c020ed258a46b8d73dd5bd6af104a238c9d71f806938e" dependencies = [ "bit-set", "bitflags 1.3.2", @@ -2747,10 +2862,28 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" name = "nom" version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "notify" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d9ba6c734de18ca27c8cef5cd7058aa4ac9f63596131e4c7e41e579319032a2" dependencies = [ - "memchr", - "minimal-lexical", + "bitflags 1.3.2", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "mio", + "walkdir", + "windows-sys 0.45.0", ] [[package]] @@ -2946,9 +3079,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" @@ -2975,7 +3114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" dependencies = [ "dlv-list", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -3161,12 +3300,6 @@ dependencies = [ "siphasher", ] -[[package]] -name = "pico-args" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468" - [[package]] name = "pico-args" version = "0.5.0" @@ -3190,7 +3323,7 @@ checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -3266,9 +3399,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.58" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" dependencies = [ "unicode-ident", ] @@ -3343,9 +3476,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -3392,18 +3525,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b9283c6b06096b47afc7109834fdedab891175bb5241ee5d4f7d2546549f263" -[[package]] -name = "raqote" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5b6cb89f8be6a645e5834f3ad44a7960d12343d97b5b7fb07cb0365ae36aa2d" -dependencies = [ - "euclid", - "lyon_geom", - "sw-composite", - "typed-arena", -] - [[package]] name = "raw-window-handle" version = "0.3.4" @@ -3451,12 +3572,6 @@ dependencies = [ "num_cpus", ] -[[package]] -name = "rctree" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae028b272a6e99d9f8260ceefa3caa09300a8d6c8d2b2001316474bc52122e9" - [[package]] name = "rctree" version = "0.5.0" @@ -3494,9 +3609,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.2" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1a59b5d8e97dee33696bf13c5ba8ab85341c002922fba050069326b9c498974" +checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" dependencies = [ "aho-corasick", "memchr", @@ -3534,7 +3649,7 @@ dependencies = [ "float-cmp 0.8.0", "libloading 0.7.4", "once_cell", - "renderdoc-sys", + "renderdoc-sys 0.7.1", "winapi", "wio", ] @@ -3545,34 +3660,42 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" +[[package]] +name = "renderdoc-sys" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b" + [[package]] name = "resvg" -version = "0.18.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608c6e8aa6fb2c13bc06e4184d7c7b2cc1b7c138f88a539da8be55c3c033d7f4" +checksum = "c115863f2d3621999cf187e318bc92b16402dfeff6a48c74df700d77381394c1" dependencies = [ - "jpeg-decoder 0.1.22", "log", - "pico-args 0.4.2", - "png", + "pico-args", "rgb", - "svgfilters", - "tiny-skia 0.6.6", - "usvg 0.18.0", + "svgtypes 0.8.2", + "tiny-skia 0.8.4", + "usvg 0.28.0", ] [[package]] name = "resvg" -version = "0.28.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c115863f2d3621999cf187e318bc92b16402dfeff6a48c74df700d77381394c1" +checksum = "142e83d8ae8c8c639f304698a5567b229ba65caba867bf4387bbc0ae158827cf" dependencies = [ + "gif", + "jpeg-decoder", "log", - "pico-args 0.5.0", + "pico-args", + "png", "rgb", - "svgtypes", - "tiny-skia 0.8.4", - "usvg 0.28.0", + "svgfilters", + "svgtypes 0.11.0", + "tiny-skia 0.9.1", + "usvg 0.32.0", ] [[package]] @@ -3590,7 +3713,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" dependencies = [ - "base64", + "base64 0.13.1", "bitflags 1.3.2", "serde", ] @@ -3601,18 +3724,22 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "300a51053b1cb55c80b7a9fde4120726ddf25ca241a1cbb926626f62fb136bff" dependencies = [ - "base64", + "base64 0.13.1", "bitflags 1.3.2", "serde", ] [[package]] -name = "roxmltree" -version = "0.14.1" +name = "rosvgtree" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b" +checksum = "ad747e7384940e7bf33b15ba433b7bad9f44c0c6d5287a67c2cb22cd1743d497" dependencies = [ - "xmlparser", + "log", + "roxmltree 0.18.0", + "simplecss", + "siphasher", + "svgtypes 0.11.0", ] [[package]] @@ -3624,6 +3751,15 @@ dependencies = [ "xmlparser", ] +[[package]] +name = "roxmltree" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8f595a457b6b8c6cda66a48503e92ee8d19342f905948f29c383200ec9eb1d8" +dependencies = [ + "xmlparser", +] + [[package]] name = "rust-ini" version = "0.18.0" @@ -3660,22 +3796,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "rustybuzz" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44561062e583c4873162861261f16fd1d85fe927c4904d71329a4fe43dc355ef" -dependencies = [ - "bitflags 1.3.2", - "bytemuck", - "smallvec", - "ttf-parser 0.12.3", - "unicode-bidi-mirroring", - "unicode-ccc", - "unicode-general-category 0.4.0", - "unicode-script", -] - [[package]] name = "rustybuzz" version = "0.7.0" @@ -3689,7 +3809,7 @@ dependencies = [ "ttf-parser 0.18.1", "unicode-bidi-mirroring", "unicode-ccc", - "unicode-general-category 0.6.0", + "unicode-general-category", "unicode-script", ] @@ -3719,6 +3839,15 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scan_fmt" version = "0.2.6" @@ -3775,7 +3904,7 @@ checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -3899,7 +4028,7 @@ dependencies = [ "encoding", "gbm", "gl_generator", - "glow 0.12.1", + "glow 0.12.2", "indexmap", "input", "lazy_static", @@ -3939,7 +4068,7 @@ dependencies = [ "dlib", "lazy_static", "log", - "memmap2 0.5.10", + "memmap2", "nix 0.24.3", "pkg-config", "wayland-client 0.29.5", @@ -3982,7 +4111,7 @@ checksum = "27207bb65232eda1f588cf46db2fee75c0808d557f6b3cf19a75f5d6d7c94df1" [[package]] name = "softbuffer" version = "0.2.0" -source = "git+https://github.com/pop-os/softbuffer?rev=8dcb6438b#8dcb6438b6c1688a0015b477dfa76c6c0bee3318" +source = "git+https://github.com/pop-os/softbuffer?tag=cosmic-2.0-old#ece901a9f60dc89ca740dc3bd11f3c909e801723" dependencies = [ "bytemuck", "cfg_aliases", @@ -3998,7 +4127,7 @@ dependencies = [ "thiserror", "wasm-bindgen", "wayland-backend", - "wayland-client 0.30.1", + "wayland-client 0.30.2", "wayland-sys 0.30.1", "web-sys", "windows-sys 0.42.0", @@ -4045,19 +4174,13 @@ checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" [[package]] name = "strict-num" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9df65f20698aeed245efdde3628a6b559ea1239bbb871af1b6e3b58c413b2bd1" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" dependencies = [ "float-cmp 0.9.0", ] -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - [[package]] name = "strsim" version = "0.10.0" @@ -4096,10 +4219,14 @@ dependencies = [ ] [[package]] -name = "sw-composite" -version = "0.7.16" +name = "svgtypes" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac8fb7895b4afa060ad731a32860db8755da3449a47e796d5ecf758db2671d4" +checksum = "ed4b0611e7f3277f68c0fa18e385d9e2d26923691379690039548f867cef02a7" +dependencies = [ + "kurbo 0.9.5", + "siphasher", +] [[package]] name = "swash" @@ -4124,9 +4251,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.16" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -4135,14 +4262,11 @@ dependencies = [ [[package]] name = "sys-locale" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8a11bd9c338fdba09f7881ab41551932ad42e405f61d01e8406baea71c07aee" +checksum = "ea0b9eefabb91675082b41eb94c3ecd91af7656caee3fb4961a07c0ec8c7ca6f" dependencies = [ - "js-sys", "libc", - "wasm-bindgen", - "web-sys", "windows-sys 0.45.0", ] @@ -4185,7 +4309,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -4205,7 +4329,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" dependencies = [ "flate2", - "jpeg-decoder 0.3.0", + "jpeg-decoder", "weezl", ] @@ -4238,9 +4362,9 @@ dependencies = [ [[package]] name = "tiny-skia" -version = "0.6.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d049bfef0eaa2521e75d9ffb5ce86ad54480932ae19b85f78bec6f52c4d30d78" +checksum = "642680569bb895b16e4b9d181c60be1ed136fa0c9c7f11d004daf053ba89bf82" dependencies = [ "arrayref", "arrayvec 0.5.2", @@ -4248,35 +4372,36 @@ dependencies = [ "cfg-if", "png", "safe_arch", + "tiny-skia-path 0.7.0", ] [[package]] name = "tiny-skia" -version = "0.7.0" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642680569bb895b16e4b9d181c60be1ed136fa0c9c7f11d004daf053ba89bf82" +checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" dependencies = [ "arrayref", - "arrayvec 0.5.2", + "arrayvec 0.7.2", "bytemuck", "cfg-if", "png", - "safe_arch", - "tiny-skia-path 0.7.0", + "tiny-skia-path 0.8.4", ] [[package]] name = "tiny-skia" -version = "0.8.4" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" +checksum = "ce2986c82f77818c7b9144c70818fdde98db15308e329ae2f7204d767808fd3c" dependencies = [ "arrayref", "arrayvec 0.7.2", "bytemuck", "cfg-if", + "log", "png", - "tiny-skia-path 0.8.4", + "tiny-skia-path 0.9.0", ] [[package]] @@ -4300,11 +4425,22 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tiny-skia-path" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7acb0ccda1ac91084353a56d0b69b0e29c311fd809d2088b1ed2f9ae1841c47" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + [[package]] name = "tokio" -version = "1.28.1" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg", "num_cpus", @@ -4358,7 +4494,7 @@ checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", ] [[package]] @@ -4411,12 +4547,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "ttf-parser" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ae2f58a822f08abdaf668897e96a5656fe72f5a9ce66422423e8849384872e6" - [[package]] name = "ttf-parser" version = "0.18.1" @@ -4440,12 +4570,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - [[package]] name = "typenum" version = "1.16.0" @@ -4481,12 +4605,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc2520efa644f8268dce4dcd3050eaa7fc044fca03961e9998ac7e2e92b77cf1" -[[package]] -name = "unicode-general-category" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07547e3ee45e28326cc23faac56d44f58f16ab23e413db526debce3b0bfd2742" - [[package]] name = "unicode-general-category" version = "0.6.0" @@ -4495,9 +4613,9 @@ checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-linebreak" @@ -4505,7 +4623,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137" dependencies = [ - "hashbrown", + "hashbrown 0.12.3", "regex", ] @@ -4541,49 +4659,82 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "usvg" -version = "0.18.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4058e0bd091a56f905e6963e40776ce6880b271275f0b493bff951433e303071" +checksum = "8b5b7c2b30845b3348c067ca3d09e20cc6e327c288f0ca4c48698712abf432e9" dependencies = [ - "base64", - "data-url 0.1.1", + "base64 0.13.1", + "data-url", "flate2", - "float-cmp 0.9.0", - "fontdb 0.6.2", - "kurbo", + "imagesize 0.10.1", + "kurbo 0.8.3", "log", - "pico-args 0.4.2", - "rctree 0.4.0", - "roxmltree 0.14.1", - "rustybuzz 0.4.0", + "rctree", + "roxmltree 0.15.1", "simplecss", "siphasher", - "svgtypes", - "ttf-parser 0.12.3", - "unicode-bidi", - "unicode-script", - "unicode-vo", - "xmlwriter", + "strict-num", + "svgtypes 0.8.2", ] [[package]] name = "usvg" -version = "0.28.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5b7c2b30845b3348c067ca3d09e20cc6e327c288f0ca4c48698712abf432e9" +checksum = "4b44e14b7678bcc5947b397991432d0c4e02a103958a0ed5e1b9b961ddd08b21" +dependencies = [ + "base64 0.21.2", + "log", + "pico-args", + "usvg-parser", + "usvg-text-layout", + "usvg-tree", + "xmlwriter", +] + +[[package]] +name = "usvg-parser" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90c8251d965c2882a636ffcc054340b1f13a6bce68779cb5b2084d8ffc2535be" dependencies = [ - "base64", - "data-url 0.2.0", + "data-url", "flate2", - "imagesize", - "kurbo", + "imagesize 0.11.0", + "kurbo 0.9.5", "log", - "rctree 0.5.0", - "roxmltree 0.15.1", - "simplecss", - "siphasher", + "rosvgtree", + "strict-num", + "svgtypes 0.11.0", + "usvg-tree", +] + +[[package]] +name = "usvg-text-layout" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c4fed019d1af07bfe0f3bac13d120d7b51bc65b38cb24809cf4ed0b8b631138" +dependencies = [ + "fontdb", + "kurbo 0.9.5", + "log", + "rustybuzz", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "usvg-tree", +] + +[[package]] +name = "usvg-tree" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7371265c467cdae0ccc3655e2e3f310c695fb9f717c0d25187bf3b333f7b5159" +dependencies = [ + "kurbo 0.9.5", + "rctree", "strict-num", - "svgtypes", + "svgtypes 0.11.0", ] [[package]] @@ -4619,6 +4770,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -4646,7 +4807,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", "wasm-bindgen-shared", ] @@ -4680,7 +4841,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.18", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4739,9 +4900,9 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.30.1" +version = "0.30.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bde68449abab1a808e5227b6e295f4ae3680911eb7711b4a2cb90141edb780" +checksum = "489c9654770f674fc7e266b3c579f4053d7551df0ceb392f153adb1f9ed06ac8" dependencies = [ "bitflags 1.3.2", "nix 0.26.2", @@ -4856,9 +5017,9 @@ dependencies = [ [[package]] name = "wayland-server" -version = "0.30.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9062def387c1b1d80e366d8243c2b3bd6d9e4f343032a3e5da8d4aa03866cf89" +checksum = "9c43c28096fe1d49fff7d1079404fdd0f669cd1a5b00c615bdfe71bb1884d23a" dependencies = [ "bitflags 1.3.2", "downcast-rs", @@ -4911,37 +5072,39 @@ checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" [[package]] name = "wgpu" -version = "0.14.2" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f643110d228fd62a60c5ed2ab56c4d5b3704520bd50561174ec4ec74932937" +checksum = "d745a1b6d91d85c33defbb29f0eee0450e1d2614d987e14bf6baf26009d132d7" dependencies = [ "arrayvec 0.7.2", + "cfg-if", "js-sys", "log", - "naga 0.10.0", + "naga 0.11.1", "parking_lot 0.12.1", + "profiling", "raw-window-handle 0.5.2", "smallvec", "static_assertions", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "wgpu-core 0.14.2", - "wgpu-hal 0.14.1", - "wgpu-types 0.14.1", + "wgpu-core 0.15.1", + "wgpu-hal 0.15.4", + "wgpu-types 0.15.2", ] [[package]] name = "wgpu" -version = "0.15.1" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d745a1b6d91d85c33defbb29f0eee0450e1d2614d987e14bf6baf26009d132d7" +checksum = "3059ea4ddec41ca14f356833e2af65e7e38c0a8f91273867ed526fb9bafcca95" dependencies = [ "arrayvec 0.7.2", "cfg-if", "js-sys", "log", - "naga 0.11.1", + "naga 0.12.2", "parking_lot 0.12.1", "profiling", "raw-window-handle 0.5.2", @@ -4950,63 +5113,62 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "wgpu-core 0.15.1", - "wgpu-hal 0.15.4", - "wgpu-types 0.15.2", + "wgpu-core 0.16.1", + "wgpu-hal 0.16.0", + "wgpu-types 0.16.0", ] [[package]] name = "wgpu-core" -version = "0.14.2" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6000d1284ef8eec6076fd5544a73125fd7eb9b635f18dceeb829d826f41724ca" +checksum = "7131408d940e335792645a98f03639573b0480e9e2e7cddbbab74f7c6d9f3fff" dependencies = [ "arrayvec 0.7.2", "bit-vec", "bitflags 1.3.2", - "cfg_aliases", "codespan-reporting", "fxhash", "log", - "naga 0.10.0", + "naga 0.11.1", "parking_lot 0.12.1", "profiling", "raw-window-handle 0.5.2", "smallvec", "thiserror", "web-sys", - "wgpu-hal 0.14.1", - "wgpu-types 0.14.1", + "wgpu-hal 0.15.4", + "wgpu-types 0.15.2", ] [[package]] name = "wgpu-core" -version = "0.15.1" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7131408d940e335792645a98f03639573b0480e9e2e7cddbbab74f7c6d9f3fff" +checksum = "8f478237b4bf0d5b70a39898a66fa67ca3a007d79f2520485b8b0c3dfc46f8c2" dependencies = [ "arrayvec 0.7.2", "bit-vec", - "bitflags 1.3.2", + "bitflags 2.3.1", "codespan-reporting", - "fxhash", "log", - "naga 0.11.1", + "naga 0.12.2", "parking_lot 0.12.1", "profiling", "raw-window-handle 0.5.2", + "rustc-hash", "smallvec", "thiserror", "web-sys", - "wgpu-hal 0.15.4", - "wgpu-types 0.15.2", + "wgpu-hal 0.16.0", + "wgpu-types 0.16.0", ] [[package]] name = "wgpu-hal" -version = "0.14.1" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc320a61acb26be4f549c9b1b53405c10a223fbfea363ec39474c32c348d12f" +checksum = "bdcf61a283adc744bb5453dd88ea91f3f86d5ca6b027661c6c73c7734ae0288b" dependencies = [ "android_system_properties", "arrayvec 0.7.2", @@ -5015,83 +5177,77 @@ dependencies = [ "bitflags 1.3.2", "block", "core-graphics-types", - "d3d12 0.5.0", + "d3d12", "foreign-types 0.3.2", "fxhash", - "glow 0.11.2", + "glow 0.12.2", "gpu-alloc", + "gpu-allocator", "gpu-descriptor", + "hassle-rs 0.9.0", "js-sys", "khronos-egl", + "libc", "libloading 0.7.4", "log", "metal", - "naga 0.10.0", + "naga 0.11.1", "objc", "parking_lot 0.12.1", "profiling", "range-alloc", "raw-window-handle 0.5.2", - "renderdoc-sys", + "renderdoc-sys 0.7.1", "smallvec", "thiserror", "wasm-bindgen", "web-sys", - "wgpu-types 0.14.1", + "wgpu-types 0.15.2", "winapi", ] [[package]] name = "wgpu-hal" -version = "0.15.4" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdcf61a283adc744bb5453dd88ea91f3f86d5ca6b027661c6c73c7734ae0288b" +checksum = "41af2ea7d87bd41ad0a37146252d5f7c26490209f47f544b2ee3b3ff34c7732e" dependencies = [ "android_system_properties", "arrayvec 0.7.2", "ash", "bit-set", - "bitflags 1.3.2", + "bitflags 2.3.1", "block", "core-graphics-types", - "d3d12 0.6.0", + "d3d12", "foreign-types 0.3.2", - "fxhash", - "glow 0.12.1", + "glow 0.12.2", "gpu-alloc", "gpu-allocator", "gpu-descriptor", - "hassle-rs", + "hassle-rs 0.10.0", "js-sys", "khronos-egl", "libc", - "libloading 0.7.4", + "libloading 0.8.0", "log", "metal", - "naga 0.11.1", + "naga 0.12.2", "objc", "parking_lot 0.12.1", "profiling", "range-alloc", "raw-window-handle 0.5.2", - "renderdoc-sys", + "renderdoc-sys 1.0.0", + "rustc-hash", "smallvec", "thiserror", "wasm-bindgen", "web-sys", - "wgpu-types 0.15.2", + "wgpu-types 0.16.0", "winapi", ] -[[package]] -name = "wgpu-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb6b28ef22cac17b9109b25b3bf8c9a103eeb293d7c5f78653979b09140375f6" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "wgpu-types" version = "0.15.2" @@ -5104,15 +5260,14 @@ dependencies = [ ] [[package]] -name = "wgpu_glyph" -version = "0.18.0" +name = "wgpu-types" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cafb82773e0f124a33674dab5de4dff73175aeb921949047ab014efb58fb446" +checksum = "5bd33a976130f03dcdcd39b3810c0c3fc05daf86f0aaf867db14bfb7c4a9a32b" dependencies = [ - "bytemuck", - "glyph_brush", - "log", - "wgpu 0.14.2", + "bitflags 2.3.1", + "js-sys", + "web-sys", ] [[package]] @@ -5133,6 +5288,12 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + [[package]] name = "winapi" version = "0.3.9" @@ -5559,7 +5720,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbee136714379ab22da0280207fdb7f47e0bb940adea97731b65598b8c7a92e" dependencies = [ "libc", - "memmap2 0.5.10", + "memmap2", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 05f1b269..02900343 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,8 +30,11 @@ libsystemd = { version = "0.5", optional = true } wayland-backend = "0.1.0" wayland-scanner = "0.30.0" cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] } -libcosmic = { git = "https://github.com/pop-os/libcosmic", rev = "24709e9c3b", default-features = false, features = ["softbuffer"] } -iced_softbuffer = { git = "https://github.com/pop-os/libcosmic", rev = "24709e9c3b" } +libcosmic = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b", default-features = false, features = ["tiny_skia"] } +iced_core = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b" } +iced_renderer = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b" } +iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b" } +tiny-skia = "0.9" ordered-float = "3.0" glow = "0.11.2" tracing-subscriber = { version = "0.3.16", features = ["env-filter", "tracing-log"] } diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 5dd470b9..5e0bd728 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -60,6 +60,7 @@ pub struct CosmicStackInternal { pointer_entered: Option>, previous_pointer: Arc, last_location: Arc, Serial, u32)>>>, + mask: Arc>>, } impl CosmicStackInternal { @@ -110,6 +111,7 @@ impl CosmicStack { pointer_entered: None, previous_pointer: Arc::new(AtomicUsize::new(0)), last_location: Arc::new(Mutex::new(None)), + mask: Arc::new(Mutex::new(None)), }, (width, TAB_HEIGHT), handle, @@ -273,6 +275,50 @@ impl Program for CosmicStackInternal { fn view(&self) -> Element<'_, Self::Message> { cosmic::iced::widget::text("TODO").into() } + + fn clip_mask(&self, size: Size, scale: f32) -> tiny_skia::Mask { + let mut mask = self.mask.lock().unwrap(); + if mask.is_none() { + let mut new_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap(); + + let mut pb = tiny_skia::PathBuilder::new(); + let radius = 8. * scale; + let (w, h) = (size.w as f32, size.h as f32); + + pb.move_to(0., h); // lower-left + + // upper-left rounded corner + pb.line_to(0., radius); + pb.quad_to(0., 0., radius, 0.); + + // upper-right rounded corner + pb.line_to(w - radius, 0.); + pb.quad_to(w, 0., w, radius); + + pb.line_to(w, h); // lower-right + + let path = pb.finish().unwrap(); + new_mask.fill_path( + &path, + tiny_skia::FillRule::EvenOdd, + true, + Default::default(), + ); + + *mask = Some(new_mask); + } + + mask.clone().unwrap() + } + + fn background_color(&self) -> iced_core::Color { + iced_core::Color { + r: 0.1176, + g: 0.1176, + b: 0.1176, + a: 1.0, + } + } } impl IsAlive for CosmicStack { diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index c611be88..e25f76fd 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -12,9 +12,8 @@ use crate::{ wayland::handlers::screencopy::ScreencopySessions, }; use calloop::LoopHandle; -use cosmic::iced_native::Command; +use cosmic::iced::Command; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; -use iced_softbuffer::native::raqote::{DrawOptions, DrawTarget, PathBuilder, SolidSource, Source}; use smithay::{ backend::{ input::KeyState, @@ -35,7 +34,10 @@ use smithay::{ Seat, }, output::Output, - utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform}, + utils::{ + Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, + Transform, + }, wayland::seat::WaylandFocus, }; use std::{ @@ -65,6 +67,7 @@ impl fmt::Debug for CosmicWindow { #[derive(Clone)] pub struct CosmicWindowInternal { pub(super) window: CosmicSurface, + mask: Arc>>, /// TODO: This needs to be per seat pointer_entered: Arc, last_seat: Arc, Serial)>>>, @@ -119,6 +122,7 @@ impl CosmicWindow { CosmicWindow(IcedElement::new( CosmicWindowInternal { window, + mask: Arc::new(Mutex::new(None)), pointer_entered: Arc::new(AtomicU8::new(Focus::None as u8)), last_seat: Arc::new(Mutex::new(None)), last_title: Arc::new(Mutex::new(last_title)), @@ -141,6 +145,7 @@ impl CosmicWindow { p.window .set_geometry(Rectangle::from_loc_and_size(loc, size)); }); + self.0.with_program(|p| p.mask.lock().unwrap().take()); self.0.resize(Size::from((geo.size.w, SSD_HEIGHT))); } @@ -218,12 +223,15 @@ impl Program for CosmicWindowInternal { Command::none() } - fn background(&self, target: &mut DrawTarget<&mut [u32]>) { - let radius = 8.; - let (w, h) = (target.width() as f32, target.height() as f32); + fn clip_mask(&self, size: Size, scale: f32) -> tiny_skia::Mask { + let mut mask = self.mask.lock().unwrap(); + if mask.is_none() { + let mut new_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap(); + + let mut pb = tiny_skia::PathBuilder::new(); + let radius = 8. * scale; + let (w, h) = (size.w as f32, size.h as f32); - if !(self.window.is_maximized() || self.window.is_fullscreen()) { - let mut pb = PathBuilder::new(); pb.move_to(0., h); // lower-left // upper-left rounded corner @@ -236,17 +244,63 @@ impl Program for CosmicWindowInternal { pb.line_to(w, h); // lower-right - let path = pb.finish(); - target.push_clip(&path); + let path = pb.finish().unwrap(); + new_mask.fill_path( + &path, + tiny_skia::FillRule::EvenOdd, + true, + Default::default(), + ); + + *mask = Some(new_mask); } + mask.clone().unwrap() + } + + fn background_color(&self) -> iced_core::Color { if self.window.is_activated() { - target.clear(SolidSource::from_unpremultiplied_argb(u8::MAX, 30, 30, 30)); + iced_core::Color { + r: 0.1176, + g: 0.1176, + b: 0.1176, + a: 1.0, + } } else { - target.clear(SolidSource::from_unpremultiplied_argb(u8::MAX, 39, 39, 39)); + iced_core::Color { + r: 0.153, + g: 0.153, + b: 0.153, + a: 1.0, + } } + } - target.pop_clip(); + fn foreground( + &self, + pixels: &mut tiny_skia::PixmapMut<'_>, + damage: &[Rectangle], + ) { + if !self.window.is_activated() { + let mask = self.mask.lock().unwrap(); + let mut paint = tiny_skia::Paint::default(); + paint.set_color_rgba8(0, 0, 0, 102); + + for rect in damage { + pixels.fill_rect( + tiny_skia::Rect::from_xywh( + rect.loc.x as f32, + rect.loc.y as f32, + rect.size.w as f32, + rect.size.h as f32, + ) + .unwrap(), + &paint, + Default::default(), + mask.as_ref(), + ); + } + } } fn view(&self) -> cosmic::Element<'_, Self::Message> { @@ -257,42 +311,6 @@ impl Program for CosmicWindowInternal { .on_close(Message::Close) .into_element() } - - fn foreground(&self, target: &mut DrawTarget<&mut [u32]>) { - if !self.window.is_activated() { - let radius = 8.; - let (w, h) = (target.width() as f32, target.height() as f32); - - if !(self.window.is_maximized() || self.window.is_fullscreen()) { - let mut pb = PathBuilder::new(); - pb.move_to(0., h); // lower-left - - // upper-left rounded corner - pb.line_to(0., radius); - pb.quad_to(0., 0., radius, 0.); - - // upper-right rounded corner - pb.line_to(w - radius, 0.); - pb.quad_to(w, 0., w, radius); - - pb.line_to(w, h); // lower-right - - let path = pb.finish(); - target.push_clip(&path); - } - - let mut options = DrawOptions::new(); - options.alpha = 0.4; - target.fill_rect( - 0., - 0., - w, - h, - &Source::Solid(SolidSource::from_unpremultiplied_argb(u8::MAX, 0, 0, 0)), - &options, - ); - } - } } impl IsAlive for CosmicWindow { @@ -329,6 +347,7 @@ impl SpaceElement for CosmicWindow { } fn set_activate(&self, activated: bool) { SpaceElement::set_activate(&self.0, activated); + self.0.force_redraw(); self.0 .with_program(|p| SpaceElement::set_activate(&p.window, activated)); } diff --git a/src/utils/iced.rs b/src/utils/iced.rs index b23dc201..93266f44 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -5,25 +5,28 @@ use std::{ sync::{mpsc::Receiver, Arc, Mutex}, }; -pub use cosmic::Renderer as IcedRenderer; -use cosmic::Theme; use cosmic::{ - iced_native::{ - command::Action, + iced::{ event::Event, keyboard::{Event as KeyboardEvent, Modifiers as IcedModifiers}, mouse::{Button as MouseButton, Event as MouseEvent, ScrollDelta}, - program::{Program as IcedProgram, State}, - renderer::Style, window::{Event as WindowEvent, Id}, - Command, Debug, Point as IcedPoint, Size as IcedSize, + Command, Point as IcedPoint, Rectangle as IcedRectangle, Size as IcedSize, + }, + iced_runtime::{ + command::Action, + program::{Program as IcedProgram, State}, + Debug, }, - Element, + Renderer as IcedRenderer, Theme, }; -use iced_softbuffer::{ - native::{raqote::DrawTarget, *}, +use iced_core::{renderer::Style, Color}; +use iced_renderer::Backend as BackendWrapper; +use iced_tiny_skia::{ + graphics::{damage, Primitive, Viewport}, Backend, }; +pub type Element<'a, Message> = cosmic::iced::Element<'a, Message, IcedRenderer>; use ordered_float::OrderedFloat; use smithay::{ @@ -47,7 +50,10 @@ use smithay::{ output::Output, reexports::calloop::RegistrationToken, reexports::calloop::{self, futures::Scheduler, LoopHandle}, - utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform}, + utils::{ + Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, + Transform, + }, }; #[derive(Debug)] @@ -88,11 +94,15 @@ pub trait Program { } fn view(&self) -> Element<'_, Self::Message>; - fn background(&self, target: &mut DrawTarget<&mut [u32]>) { - let _ = target; - } - fn foreground(&self, target: &mut DrawTarget<&mut [u32]>) { - let _ = target; + fn clip_mask(&self, size: Size, scale: f32) -> tiny_skia::Mask; + fn background_color(&self) -> Color; + + fn foreground( + &self, + pixels: &mut tiny_skia::PixmapMut<'_>, + damage: &[Rectangle], + ) { + let _ = (pixels, damage); } } @@ -105,7 +115,7 @@ impl IcedProgram for ProgramWrapper

{ self.0.update(message, &self.1) } - fn view(&self) -> Element<'_, Self::Message> { + fn view(&self, _id: Id) -> Element<'_, Self::Message> { self.0.view() } } @@ -113,7 +123,7 @@ impl IcedProgram for ProgramWrapper

{ struct IcedElementInternal { // draw buffer outputs: Vec, - buffers: HashMap, (MemoryRenderBuffer, bool)>, + buffers: HashMap, (MemoryRenderBuffer, Option<(Vec, Color)>)>, // state size: Size, @@ -163,10 +173,12 @@ impl IcedElement

{ handle: LoopHandle<'static, crate::state::Data>, ) -> IcedElement

{ let size = size.into(); - let mut renderer = IcedRenderer::new(Backend::new()); + let mut renderer = + IcedRenderer::new(BackendWrapper::TinySkia(Backend::new(Default::default()))); let mut debug = Debug::new(); let state = State::new( + Id(0), ProgramWrapper(program, handle.clone()), IcedSize::new(size.w as f32, size.h as f32), &mut renderer, @@ -217,7 +229,7 @@ impl IcedElement

{ } internal_ref.size = size; - for (scale, (buffer, needs_redraw)) in internal_ref.buffers.iter_mut() { + for (scale, (buffer, old_primitives)) in internal_ref.buffers.iter_mut() { let buffer_size = internal_ref .size .to_f64() @@ -225,15 +237,19 @@ impl IcedElement

{ .to_i32_round(); *buffer = MemoryRenderBuffer::new(Fourcc::Argb8888, buffer_size, 1, Transform::Normal, None); - *needs_redraw = true; + *old_primitives = None; } internal_ref.update(true); } pub fn force_update(&self) { + self.0.lock().unwrap().update(true); + } + + pub fn force_redraw(&self) { let mut internal = self.0.lock().unwrap(); - for (_buffer, ref mut needs_redraw) in internal.buffers.values_mut() { - *needs_redraw = true; + for (_buffer, ref mut old_primitives) in internal.buffers.values_mut() { + *old_primitives = None; } internal.update(true); } @@ -255,6 +271,7 @@ impl IcedElementInternal

{ let actions = self .state .update( + Id(0), IcedSize::new(self.size.w as f32, self.size.h as f32), IcedPoint::new(cursor_pos.x as f32, cursor_pos.y as f32), &mut self.renderer, @@ -262,17 +279,12 @@ impl IcedElementInternal

{ &Style { text_color: self.theme.cosmic().on_bg_color().into(), }, - &mut cosmic::iced_native::clipboard::Null, + &mut iced_core::clipboard::Null, &mut self.debug, ) .1 .map(|command| command.actions()); - if actions.is_some() { - for (_buffer, ref mut needs_redraw) in self.buffers.values_mut() { - *needs_redraw = true; - } - } let actions = actions.unwrap_or_default(); actions .into_iter() @@ -468,7 +480,7 @@ impl SpaceElement for IcedElement

{ fn set_activate(&self, activated: bool) { let mut internal = self.0.lock().unwrap(); internal.state.queue_event(Event::Window( - Id::MAIN, + Id(0), if activated { WindowEvent::Focused } else { @@ -497,7 +509,7 @@ impl SpaceElement for IcedElement

{ Transform::Normal, None, ), - true, + None, ), ); } @@ -547,7 +559,7 @@ impl SpaceElement for IcedElement

{ Transform::Normal, None, ), - true, + None, ), ); } @@ -570,64 +582,80 @@ where alpha: f32, ) -> Vec { let mut internal = self.0.lock().unwrap(); - - let _ = internal.update(false); // TODO + let _ = internal.update(false); // makes partial borrows easier let internal_ref = &mut *internal; - if let Some((buffer, ref mut needs_redraw)) = + if let Some((buffer, ref mut old_primitives)) = internal_ref.buffers.get_mut(&OrderedFloat(scale.x)) { - let size = internal_ref + let size: Size = internal_ref .size .to_f64() .to_buffer(scale.x, Transform::Normal) .to_i32_round(); - if *needs_redraw && size.w > 0 && size.h > 0 { + if size.w > 0 && size.h > 0 { let renderer = &mut internal_ref.renderer; let state_ref = &internal_ref.state; + let mut clip_mask = state_ref.program().0.clip_mask(size, scale.x as f32); + let overlay = internal_ref.debug.overlay(); + buffer .render() .draw(move |buf| { - let mut target = raqote::DrawTarget::from_backing( - size.w, - size.h, - bytemuck::cast_slice_mut::<_, u32>(buf), - ); - - target.clear(raqote::SolidSource::from_unpremultiplied_argb(0, 0, 0, 0)); - state_ref.program().0.background(&mut target); - - let draw_options = raqote::DrawOptions { - // Default to antialiasing off for now - antialias: raqote::AntialiasMode::None, - ..Default::default() - }; - - // Having at least one clip fixes some font rendering issues - target.push_clip_rect(raqote::IntRect::new( - raqote::IntPoint::new(0, 0), - raqote::IntPoint::new(size.w, size.h), - )); + let mut pixels = + tiny_skia::PixmapMut::from_bytes(buf, size.w as u32, size.h as u32) + .expect("Failed to create pixel map"); renderer.with_primitives(|backend, primitives| { - for primitive in primitives.iter() { - draw_primitive( - &mut target, - &draw_options, - backend, - scale.x as f32, - primitive, + let BackendWrapper::TinySkia(ref mut backend) = backend; + let background_color = state_ref.program().0.background_color(); + let bounds = IcedSize::new(size.w as u32, size.h as u32); + let viewport = Viewport::with_physical_size(bounds, scale.x); + + let mut damage = old_primitives + .as_ref() + .and_then(|(last_primitives, last_color)| { + (last_color == &background_color) + .then(|| damage::list(last_primitives, primitives)) + }) + .unwrap_or_else(|| { + vec![IcedRectangle::with_size(viewport.logical_size())] + }); + damage = damage::group(damage, scale.x as f32, bounds); + + if !damage.is_empty() { + backend.draw( + &mut pixels, + &mut clip_mask, + primitives, + &viewport, + &damage, + background_color, + &overlay, ); + + *old_primitives = Some((primitives.to_vec(), background_color)); } - }); - state_ref.program().0.foreground(&mut target); - Result::<_, ()>::Ok(vec![Rectangle::from_loc_and_size((0, 0), size)]) + let damage = damage + .into_iter() + .map(|x| x.snap()) + .map(|damage_rect| { + Rectangle::from_loc_and_size( + (damage_rect.x as i32, damage_rect.y as i32), + (damage_rect.width as i32, damage_rect.height as i32), + ) + }) + .collect::>(); + + state_ref.program().0.foreground(&mut pixels, &damage); + + Result::<_, ()>::Ok(damage) + }) }) .unwrap(); - *needs_redraw = false; } if let Ok(buffer) = MemoryRenderBufferRenderElement::from_buffer( From 24d3b794fe3b1dee46dc0944781d9a924ea03534 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 30 May 2023 13:20:46 +0200 Subject: [PATCH 039/264] tiling: highlight backgrounds --- src/backend/render/mod.rs | 19 ++- src/shell/layout/floating/grabs/moving.rs | 5 +- src/shell/layout/floating/mod.rs | 3 +- src/shell/layout/tiling/mod.rs | 163 +++++++++++++--------- 4 files changed, 116 insertions(+), 74 deletions(-) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 8a383cd0..370427c0 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -82,8 +82,7 @@ pub type GlMultiFrame<'a, 'b, 'frame> = pub type GlMultiError = MultiError, GbmGlesBackend>; pub static CLEAR_COLOR: [f32; 4] = [0.153, 0.161, 0.165, 1.0]; -pub static ACTIVE_GROUP_COLOR: [f32; 3] = [0.678, 0.635, 0.619]; -pub static GROUP_COLOR: [f32; 3] = [0.431, 0.404, 0.396]; +pub static GROUP_COLOR: [f32; 3] = [0.788, 0.788, 0.788]; pub static FOCUS_INDICATOR_COLOR: [f32; 3] = [0.580, 0.921, 0.921]; pub static OUTLINE_SHADER: &str = include_str!("./shaders/rounded_outline.frag"); @@ -136,6 +135,7 @@ impl From for Key { #[derive(PartialEq)] struct IndicatorSettings { thickness: u8, + radius: u8, alpha: f32, color: [f32; 3], } @@ -158,13 +158,20 @@ impl IndicatorShader { mut element_geo: Rectangle, thickness: u8, alpha: f32, - color: [f32; 3], ) -> PixelShaderElement { let t = thickness as i32; element_geo.loc -= (t, t).into(); element_geo.size += (t * 2, t * 2).into(); - IndicatorShader::element(renderer, key, element_geo, thickness, alpha, color) + IndicatorShader::element( + renderer, + key, + element_geo, + thickness, + thickness * 2, + alpha, + FOCUS_INDICATOR_COLOR, + ) } pub fn element( @@ -172,11 +179,13 @@ impl IndicatorShader { key: impl Into, geo: Rectangle, thickness: u8, + radius: u8, alpha: f32, color: [f32; 3], ) -> PixelShaderElement { let settings = IndicatorSettings { thickness, + radius, alpha, color, }; @@ -210,7 +219,7 @@ impl IndicatorShader { vec![ Uniform::new("color", color), Uniform::new("thickness", thickness), - Uniform::new("radius", thickness * 2.0), + Uniform::new("radius", radius as f32), ], ); cache.insert(key.clone(), (settings, elem)); diff --git a/src/shell/layout/floating/grabs/moving.rs b/src/shell/layout/floating/grabs/moving.rs index 3f5587cf..42a83a81 100644 --- a/src/shell/layout/floating/grabs/moving.rs +++ b/src/shell/layout/floating/grabs/moving.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - backend::render::{element::AsGlowRenderer, IndicatorShader, FOCUS_INDICATOR_COLOR}, + backend::render::{element::AsGlowRenderer, IndicatorShader}, shell::{ element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, focus::target::{KeyboardFocusTarget, PointerFocusTarget}, @@ -64,13 +64,12 @@ impl MoveGrabState { let mut elements: Vec = Vec::new(); if self.indicator_thickness > 0 { elements.push( - CosmicMappedRenderElement::from(IndicatorShader::element( + CosmicMappedRenderElement::from(IndicatorShader::focus_element( renderer, self.window.clone(), Rectangle::from_loc_and_size(render_location, self.window.geometry().size), self.indicator_thickness, 1.0, - FOCUS_INDICATOR_COLOR, )) .into(), ); diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 8e88bb60..15f7b6c4 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -13,7 +13,7 @@ use smithay::{ use std::collections::HashMap; use crate::{ - backend::render::{element::AsGlowRenderer, IndicatorShader, FOCUS_INDICATOR_COLOR}, + backend::render::{element::AsGlowRenderer, IndicatorShader}, shell::{ element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, grabs::ResizeEdge, @@ -388,7 +388,6 @@ impl FloatingLayout { ), indicator_thickness, alpha, - FOCUS_INDICATOR_COLOR, ); elements.insert(0, element.into()); } diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index fe3566a7..e793ba4d 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -2,8 +2,8 @@ use crate::{ backend::render::{ - element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, ACTIVE_GROUP_COLOR, - FOCUS_INDICATOR_COLOR, GROUP_COLOR, + element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, FOCUS_INDICATOR_COLOR, + GROUP_COLOR, }, shell::{ element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, @@ -1651,7 +1651,7 @@ impl TilingLayout { non_exclusive_zone, seat, // TODO: Would be better to be an old focus, // but for that we have to associate focus with a tree (and animate focus changes properly) - 1.0 - percentage, + 1.0 - transition, transition, ) } else { @@ -1680,7 +1680,7 @@ impl TilingLayout { renderer, non_exclusive_zone, seat, - percentage, + transition, transition, ) } else { @@ -1699,7 +1699,7 @@ impl TilingLayout { output_scale, percentage, if let Some(transition) = draw_groups { - let diff = (3u8.abs_diff(indicator_thickness) as f32 * transition).round() as u8; + let diff = (4u8.abs_diff(indicator_thickness) as f32 * transition).round() as u8; if 3 > indicator_thickness { indicator_thickness + diff } else { @@ -1738,63 +1738,76 @@ where { // we need to recalculate geometry for all elements, if we are drawing groups if let Some(root) = tree.root_node_id() { - let mut stack = vec![non_exclusive_zone]; + const OUTER_GAP: i32 = 8; + let outer_gap: i32 = (OUTER_GAP as f32 * transition).round() as i32; + const INNER_GAP: i32 = 16; + let inner_gap: i32 = (INNER_GAP as f32 * transition).round() as i32; + + let mut stack = vec![Rectangle::from_loc_and_size( + non_exclusive_zone.loc + Point::from((outer_gap, outer_gap)), + (non_exclusive_zone.size.to_point() - Point::from((outer_gap * 2, outer_gap * 2))) + .to_size(), + )]; let mut elements = Vec::new(); let mut geometries = HashMap::new(); - - const GAP: i32 = 16; - let gap: i32 = (GAP as f32 * transition).round() as i32; let alpha = alpha * transition; let focused = seat .and_then(|seat| TilingLayout::currently_focused_node(&tree, seat)) .map(|(id, _)| id); + let has_potential_groups = if let Some(focused_id) = focused.as_ref() { + let focused_node = tree.get(focused_id).unwrap(); + if let Some(parent) = focused_node.parent() { + let parent_node = tree.get(parent).unwrap(); + parent_node.children().len() > 2 + || parent_node.children().iter().any(|id| { + let data = tree.get(id).unwrap().data(); + data.is_group() && data.orientation() == parent_node.data().orientation() + }) + } else { + false + } + } else { + false + }; + for node_id in tree.traverse_pre_order_ids(root).unwrap() { if let Some(mut geo) = stack.pop() { - // zoom in windows - geo.loc += (gap, gap).into(); - geo.size -= (gap * 2, gap * 2).into(); - let node: &Node = tree.get(&node_id).unwrap(); let data = node.data(); - let is_potential_group = if let Some(focused_id) = focused.as_ref() { - // 1. focused can move into us directly - if let Some(parent) = node.parent() { - let parent_data = tree.get(parent).unwrap().data(); + let render_potential_group = has_potential_groups + && (if let Some(focused_id) = focused.as_ref() { + // `focused` can move into us directly + if let Some(parent) = node.parent() { + let parent_data = tree.get(parent).unwrap().data(); - let idx = tree - .children_ids(parent) - .unwrap() - .position(|id| id == &node_id) - .unwrap(); - if let Some(focused_idx) = tree - .children_ids(parent) - .unwrap() - .position(|id| id == focused_id) - { - // only direct neighbors - focused_idx.abs_diff(idx) == 1 + let idx = tree + .children_ids(parent) + .unwrap() + .position(|id| id == &node_id) + .unwrap(); + if let Some(focused_idx) = tree + .children_ids(parent) + .unwrap() + .position(|id| id == focused_id) + { + // only direct neighbors + focused_idx.abs_diff(idx) == 1 // skip neighbors, if this is a group of two windows && !(parent_data.len() == 2 && data.is_mapped(None)) // skip groups of two in opposite orientation to indicate move between && !(parent_data.len() == 2 && if data.is_group() { parent_data.orientation() != data.orientation() } else { false } ) + } else { + false + } } else { false } - } - // 2. focused can move out into us - else { - tree.children_ids(&node_id).unwrap().any(|child_id| { - tree.children_ids(child_id) - .unwrap() - .any(|child_id| child_id == focused_id) - }) - } - } else { - false - }; + } else { + false + }); match data { Data::Group { @@ -1803,30 +1816,29 @@ where sizes, alive, } => { - let has_active_child = if let Some(focused_id) = focused.as_ref() { - tree.children_ids(&node_id) - .unwrap() - .any(|child_id| child_id == focused_id) + let render_active_child = if let Some(focused_id) = focused.as_ref() { + !has_potential_groups + && tree + .children_ids(&node_id) + .unwrap() + .any(|child_id| child_id == focused_id) } else { false }; - if (is_potential_group || has_active_child) && &node_id != root { + if (render_potential_group || render_active_child) && &node_id != root { elements.push( IndicatorShader::element( renderer, Key::Group(Arc::downgrade(&alive)), geo, - 3, - alpha, - if has_active_child { - ACTIVE_GROUP_COLOR - } else { - GROUP_COLOR - }, + 4, + if render_active_child { 16 } else { 8 }, + alpha * if render_potential_group { 0.14 } else { 1.0 }, + GROUP_COLOR, ) .into(), - ) + ); } geometries.insert(node_id.clone(), geo); @@ -1876,27 +1888,51 @@ where } } Data::Mapped { mapped, .. } => { - if is_potential_group { + geo.loc += (outer_gap, outer_gap).into(); + geo.size -= (outer_gap * 2, outer_gap * 2).into(); + + if render_potential_group { elements.push( IndicatorShader::element( renderer, mapped.clone(), geo, - 3, - alpha, + 4, + 8, + alpha * if render_potential_group { 0.4 } else { 1.0 }, GROUP_COLOR, ) .into(), ); - } - if is_potential_group - || node.parent().map(|parent| parent == root).unwrap_or(false) - { - geo.loc += (gap, gap).into(); - geo.size -= (gap * 2, gap * 2).into(); + geo.loc += (outer_gap, outer_gap).into(); + geo.size -= (outer_gap * 2, outer_gap * 2).into(); } + elements.push( + BackdropShader::element( + renderer, + mapped.clone(), + geo, + 8., + alpha + * if focused + .as_ref() + .map(|focused_id| focused_id == &node_id) + .unwrap_or(false) + { + 0.4 + } else { + 0.15 + }, + GROUP_COLOR, + ) + .into(), + ); + + geo.loc += (inner_gap, inner_gap).into(); + geo.size -= (inner_gap * 2, inner_gap * 2).into(); + geometries.insert(node_id.clone(), geo); } } @@ -2157,7 +2193,6 @@ where geo, indicator_thickness, 1.0, - FOCUS_INDICATOR_COLOR, ); elements.push(element.into()); } From 53c6af5b2113ca2b1fa45d2e4ecb9f705325af93 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 1 Jun 2023 17:03:55 +0200 Subject: [PATCH 040/264] shaders: Premultiply alpha --- src/backend/render/mod.rs | 13 +++++++++++-- src/shell/workspace.rs | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 370427c0..129d33c3 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -217,7 +217,10 @@ impl IndicatorShader { None, //TODO alpha, vec![ - Uniform::new("color", color), + Uniform::new( + "color", + [color[0] * alpha, color[1] * alpha, color[2] * alpha], + ), Uniform::new("thickness", thickness), Uniform::new("radius", radius as f32), ], @@ -293,7 +296,13 @@ impl BackdropShader { geo, None, // TODO alpha, - vec![Uniform::new("color", color), Uniform::new("radius", radius)], + vec![ + Uniform::new( + "color", + [color[0] * alpha, color[1] * alpha, color[2] * alpha], + ), + Uniform::new("radius", radius), + ], ); cache.insert(key.clone(), (settings, elem)); } diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index 84d5ee15..dc54b3d8 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -634,7 +634,7 @@ impl Workspace { self.backdrop_id.clone(), zone, 0., - alpha * 0.65, + alpha * 0.85, [0.0, 0.0, 0.0], )) .into(), From 359cf70b492a92aae4e3dc035ebcf9040e5420f5 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 2 Jun 2023 13:11:06 +0200 Subject: [PATCH 041/264] deps: Unify iced version used by cosmic-comp and cosmic-time --- Cargo.lock | 977 +++--------------------------------- Cargo.toml | 8 +- src/shell/element/stack.rs | 6 +- src/shell/element/window.rs | 8 +- src/utils/iced.rs | 6 +- 5 files changed, 94 insertions(+), 911 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b411ed33..60bae03e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,12 +154,6 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "arrayvec" version = "0.7.2" @@ -378,56 +372,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "clipboard-win" -version = "4.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" -dependencies = [ - "error-code", - "str-buf", - "winapi", -] - -[[package]] -name = "clipboard_macos" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145a7f9e9b89453bc0a5e32d166456405d389cea5b578f57f1274b1397588a95" -dependencies = [ - "objc", - "objc-foundation", - "objc_id", -] - -[[package]] -name = "clipboard_wayland" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f6364a9f7a66f2ac1a1a098aa1c7f6b686f2496c6ac5e5c0d773445df912747" -dependencies = [ - "smithay-clipboard", -] - -[[package]] -name = "clipboard_x11" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "983a7010836ecd04dde2c6d27a0cb56ec5d21572177e782bdcb24a600124e921" -dependencies = [ - "thiserror", - "x11rb 0.9.0", -] - -[[package]] -name = "cmake" -version = "0.1.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" -dependencies = [ - "cc", -] - [[package]] name = "cocoa" version = "0.24.1" @@ -439,7 +383,7 @@ dependencies = [ "cocoa-foundation", "core-foundation", "core-graphics", - "foreign-types 0.3.2", + "foreign-types", "libc", "objc", ] @@ -454,7 +398,7 @@ dependencies = [ "block", "core-foundation", "core-graphics-types", - "foreign-types 0.3.2", + "foreign-types", "libc", "objc", ] @@ -512,7 +456,7 @@ dependencies = [ "bitflags 1.3.2", "core-foundation", "core-graphics-types", - "foreign-types 0.3.2", + "foreign-types", "libc", ] @@ -524,19 +468,7 @@ checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ "bitflags 1.3.2", "core-foundation", - "foreign-types 0.3.2", - "libc", -] - -[[package]] -name = "core-text" -version = "19.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" -dependencies = [ - "core-foundation", - "core-graphics", - "foreign-types 0.3.2", + "foreign-types", "libc", ] @@ -553,8 +485,6 @@ dependencies = [ "edid-rs", "egui", "glow 0.11.2", - "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", - "iced_renderer", "iced_tiny_skia", "id_tree", "indexmap", @@ -589,12 +519,12 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ "atomicwrites", "cosmic-config-derive", "dirs 5.0.1", - "iced_futures 0.6.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_futures", "notify", "ron 0.8.0", "serde", @@ -603,7 +533,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ "quote", "syn 1.0.109", @@ -643,7 +573,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ "anyhow", "cosmic-config", @@ -658,14 +588,9 @@ dependencies = [ [[package]] name = "cosmic-time" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269b94889f152389ed39fde8a69a6083ff4ca73993360d2850d5c281e3488c11" +source = "git+https://github.com/pop-os/cosmic-time?rev=35dd0b8#35dd0b8d2c399994b16fe512f4b85d882c13ebdd" dependencies = [ - "iced 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_futures 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_native", - "iced_style 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libcosmic", ] [[package]] @@ -729,29 +654,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossfont" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21fd3add36ea31aba1520aa5288714dd63be506106753226d0eb387a93bc9c45" -dependencies = [ - "cocoa", - "core-foundation", - "core-foundation-sys", - "core-graphics", - "core-text", - "dwrote", - "foreign-types 0.5.0", - "freetype-rs", - "libc", - "log", - "objc", - "once_cell", - "pkg-config", - "servo-fontconfig", - "winapi", -] - [[package]] name = "crunchy" version = "0.2.2" @@ -778,12 +680,6 @@ dependencies = [ "serde", ] -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - [[package]] name = "d3d12" version = "0.6.0" @@ -795,38 +691,14 @@ dependencies = [ "winapi", ] -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core 0.13.4", - "darling_macro 0.13.4", -] - [[package]] name = "darling" version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" dependencies = [ - "darling_core 0.20.1", - "darling_macro 0.20.1", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.109", + "darling_core", + "darling_macro", ] [[package]] @@ -843,24 +715,13 @@ dependencies = [ "syn 2.0.18", ] -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core 0.13.4", - "quote", - "syn 1.0.109", -] - [[package]] name = "darling_macro" version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ - "darling_core 0.20.1", + "darling_core", "quote", "syn 2.0.18", ] @@ -877,7 +738,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" dependencies = [ - "darling 0.20.1", + "darling", "proc-macro2", "quote", "syn 2.0.18", @@ -1009,20 +870,6 @@ dependencies = [ "libc", ] -[[package]] -name = "dwrote" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" -dependencies = [ - "lazy_static", - "libc", - "serde", - "serde_derive", - "winapi", - "wio", -] - [[package]] name = "ecolor" version = "0.21.0" @@ -1236,16 +1083,6 @@ dependencies = [ "libc", ] -[[package]] -name = "error-code" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" -dependencies = [ - "libc", - "str-buf", -] - [[package]] name = "etagere" version = "0.2.7" @@ -1265,16 +1102,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "expat-sys" -version = "2.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" -dependencies = [ - "cmake", - "pkg-config", -] - [[package]] name = "exr" version = "1.6.3" @@ -1402,28 +1229,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "foreign-types-shared 0.1.1", -] - -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared 0.3.1", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", + "foreign-types-shared", ] [[package]] @@ -1432,12 +1238,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - [[package]] name = "fraction" version = "0.13.1" @@ -1461,28 +1261,6 @@ dependencies = [ "xdg", ] -[[package]] -name = "freetype-rs" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb" -dependencies = [ - "bitflags 1.3.2", - "freetype-sys", - "libc", -] - -[[package]] -name = "freetype-sys" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" -dependencies = [ - "cmake", - "libc", - "pkg-config", -] - [[package]] name = "fsevent-sys" version = "4.1.0" @@ -1582,15 +1360,6 @@ dependencies = [ "slab", ] -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "gbm" version = "0.12.0" @@ -1705,44 +1474,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "glyph_brush" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edefd123f28a0b1d41ec4a489c2b43020b369180800977801611084f342978d" -dependencies = [ - "glyph_brush_draw_cache", - "glyph_brush_layout", - "ordered-float", - "rustc-hash", - "twox-hash", -] - -[[package]] -name = "glyph_brush_draw_cache" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6010675390f6889e09a21e2c8b575b3ee25667ea8237a8d59423f73cb8c28610" -dependencies = [ - "ab_glyph", - "crossbeam-channel", - "crossbeam-deque", - "linked-hash-map", - "rayon", - "rustc-hash", -] - -[[package]] -name = "glyph_brush_layout" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc32c2334f00ca5ac3695c5009ae35da21da8c62d255b5b96d56e2597a637a38" -dependencies = [ - "ab_glyph", - "approx 0.5.1", - "xi-unicode", -] - [[package]] name = "glyphon" version = "0.2.0" @@ -1751,7 +1482,7 @@ dependencies = [ "cosmic-text", "etagere", "lru", - "wgpu 0.16.1", + "wgpu", ] [[package]] @@ -1843,21 +1574,6 @@ dependencies = [ "ahash 0.8.3", ] -[[package]] -name = "hassle-rs" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90601c6189668c7345fc53842cb3f3a3d872203d523be1b3cb44a36a3e62fb85" -dependencies = [ - "bitflags 1.3.2", - "com-rs", - "libc", - "libloading 0.7.4", - "thiserror", - "widestring 0.5.1", - "winapi", -] - [[package]] name = "hassle-rs" version = "0.10.0" @@ -1869,7 +1585,7 @@ dependencies = [ "libc", "libloading 0.7.4", "thiserror", - "widestring 1.0.2", + "widestring", "winapi", ] @@ -1915,25 +1631,10 @@ dependencies = [ [[package]] name = "iced" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbddf356d01e9d41cd394a9d04d62bfd89650a30f12fda5839cabb8c4591c88" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ - "iced_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_futures 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_graphics 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_native", - "iced_wgpu 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_winit", - "thiserror", -] - -[[package]] -name = "iced" -version = "0.9.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" -dependencies = [ - "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", - "iced_futures 0.6.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_core", + "iced_futures", "iced_renderer", "iced_widget", "image", @@ -1943,18 +1644,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11e1942e28dedee756cc27e67e7a838cdc1e59fb6bf9627ec9f709ab3b135782" -dependencies = [ - "bitflags 1.3.2", - "instant", - "palette", -] - -[[package]] -name = "iced_core" -version = "0.9.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ "bitflags 1.3.2", "instant", @@ -1967,115 +1657,61 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "215d51fa4f70dbb63775d7141243c4d98d4d525d8949695601f8fbac7dcbc04e" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ "futures", + "iced_core", "log", "tokio", "wasm-bindgen-futures", "wasm-timer", ] -[[package]] -name = "iced_futures" -version = "0.6.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" -dependencies = [ - "futures", - "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", - "log", - "wasm-bindgen-futures", - "wasm-timer", -] - -[[package]] -name = "iced_graphics" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "338a6aff7db906537074ad0fe8b720cfdb9512cdfea43c628c76bd1cf50fdcc0" -dependencies = [ - "bitflags 1.3.2", - "bytemuck", - "glam", - "iced_native", - "iced_style 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log", - "raw-window-handle 0.5.2", - "thiserror", -] - [[package]] name = "iced_graphics" version = "0.8.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ "bitflags 1.3.2", "bytemuck", "glam", - "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_core", "image", "kamadak-exif", "log", - "raw-window-handle 0.5.2", + "raw-window-handle", "thiserror", "tiny-skia 0.9.1", ] -[[package]] -name = "iced_native" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d012eb06da490fe46a695b39721c20da9643f35cf2ecb9d30618fdeb96170616" -dependencies = [ - "iced_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_futures 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_style 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits", - "thiserror", - "twox-hash", - "unicode-segmentation", -] - [[package]] name = "iced_renderer" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ - "iced_graphics 0.8.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_graphics", "iced_tiny_skia", - "iced_wgpu 0.10.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", - "raw-window-handle 0.5.2", + "iced_wgpu", + "raw-window-handle", "thiserror", ] [[package]] name = "iced_runtime" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ - "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", - "iced_futures 0.6.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_core", + "iced_futures", "thiserror", ] [[package]] name = "iced_style" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e37333dc2991201140302cd0d4cea051bd37ca3671d5008ec85df86d232ff30" -dependencies = [ - "iced_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell", - "palette", -] - -[[package]] -name = "iced_style" -version = "0.8.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ - "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_core", "once_cell", "palette", ] @@ -2083,14 +1719,14 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ "bytemuck", "cosmic-text", - "iced_graphics 0.8.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_graphics", "kurbo 0.9.5", "log", - "raw-window-handle 0.5.2", + "raw-window-handle", "resvg 0.32.0", "rustc-hash", "softbuffer", @@ -2101,28 +1737,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478803c56061f567ce5ddf223b20d11d3c118cc46bb0d0552370dc65cdc4cb9c" -dependencies = [ - "bitflags 1.3.2", - "bytemuck", - "encase", - "futures", - "glam", - "glyph_brush", - "guillotiere", - "iced_graphics 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_native", - "log", - "raw-window-handle 0.5.2", - "wgpu 0.15.1", - "wgpu_glyph", -] - -[[package]] -name = "iced_wgpu" -version = "0.10.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -2131,47 +1746,30 @@ dependencies = [ "glam", "glyphon", "guillotiere", - "iced_graphics 0.8.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_graphics", "log", "once_cell", - "raw-window-handle 0.5.2", + "raw-window-handle", "resvg 0.32.0", "rustc-hash", "twox-hash", - "wgpu 0.16.1", + "wgpu", ] [[package]] name = "iced_widget" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ "iced_renderer", "iced_runtime", - "iced_style 0.8.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_style", "num-traits", "ouroboros 0.13.0", "thiserror", "unicode-segmentation", ] -[[package]] -name = "iced_winit" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a59ea3a85149a6a1f9e92b6c740ce90f04e5c7d848cfd05742336863fceb955" -dependencies = [ - "iced_futures 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_graphics 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "iced_native", - "log", - "thiserror", - "web-sys", - "winapi", - "window_clipboard", - "winit 0.27.5", -] - [[package]] name = "id_tree" version = "1.8.0" @@ -2384,7 +1982,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a53776d271cfb873b17c618af0298445c88afc52837f3e948fa3fafd131f449" dependencies = [ - "arrayvec 0.7.2", + "arrayvec", ] [[package]] @@ -2393,7 +1991,7 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd85a5776cd9500c2e2059c8c76c3b01528566b7fcbaf8098b55a33fc298849b" dependencies = [ - "arrayvec 0.7.2", + "arrayvec", ] [[package]] @@ -2417,7 +2015,7 @@ checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b#31f7e97d5bf4860be5afd406209eed733f736f04" +source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" dependencies = [ "apply", "cosmic-config", @@ -2425,15 +2023,18 @@ dependencies = [ "derive_setters", "fraction", "freedesktop-icons", - "iced 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", - "iced_core 0.9.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced", + "iced_core", + "iced_futures", + "iced_renderer", "iced_runtime", - "iced_style 0.8.0 (git+https://github.com/pop-os/libcosmic?rev=31f7e97d5b)", + "iced_style", "iced_tiny_skia", "iced_widget", "lazy_static", "palette", "slotmap", + "tokio", ] [[package]] @@ -2510,12 +2111,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -2626,7 +2221,7 @@ dependencies = [ "bitflags 1.3.2", "block", "core-graphics-types", - "foreign-types 0.3.2", + "foreign-types", "log", "objc", ] @@ -2674,26 +2269,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" -[[package]] -name = "naga" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c3d4269bcb7d50121097702fde1afb75f4ea8083aeb7a55688dcf289a853271" -dependencies = [ - "bit-set", - "bitflags 1.3.2", - "codespan-reporting", - "hexf-parse", - "indexmap", - "log", - "num-traits", - "rustc-hash", - "spirv", - "termcolor", - "thiserror", - "unicode-xid", -] - [[package]] name = "naga" version = "0.12.2" @@ -2739,7 +2314,7 @@ dependencies = [ "jni-sys", "ndk-sys", "num_enum", - "raw-window-handle 0.5.2", + "raw-window-handle", "thiserror", ] @@ -2749,55 +2324,13 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" -[[package]] -name = "ndk-glue" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0434fabdd2c15e0aab768ca31d5b7b333717f03cf02037d5a0a3ff3c278ed67f" -dependencies = [ - "libc", - "log", - "ndk", - "ndk-context", - "ndk-macro", - "ndk-sys", - "once_cell", - "parking_lot 0.12.1", -] - -[[package]] -name = "ndk-macro" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" -dependencies = [ - "darling 0.13.4", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "ndk-sys" version = "0.4.1+23.1.7779620" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" dependencies = [ - "jni-sys", -] - -[[package]] -name = "nix" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" -dependencies = [ - "bitflags 1.3.2", - "cc", - "cfg-if", - "libc", - "memoffset 0.6.5", + "jni-sys", ] [[package]] @@ -3013,17 +2546,6 @@ dependencies = [ "objc_exception", ] -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - [[package]] name = "objc-sys" version = "0.2.0-beta.2" @@ -3059,15 +2581,6 @@ dependencies = [ "cc", ] -[[package]] -name = "objc_id" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] - [[package]] name = "object" version = "0.30.3" @@ -3525,25 +3038,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b9283c6b06096b47afc7109834fdedab891175bb5241ee5d4f7d2546549f263" -[[package]] -name = "raw-window-handle" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28f55143d0548dad60bb4fbdc835a3d7ac6acc3324506450c5fdd6e42903a76" -dependencies = [ - "libc", - "raw-window-handle 0.4.3", -] - -[[package]] -name = "raw-window-handle" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" -dependencies = [ - "cty", -] - [[package]] name = "raw-window-handle" version = "0.5.2" @@ -3830,15 +3324,6 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" -[[package]] -name = "safe_arch" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ff3d6d9696af502cc3110dacce942840fb06ff4514cad92236ecc455f2ce05" -dependencies = [ - "bytemuck", -] - [[package]] name = "same-file" version = "1.0.6" @@ -3866,18 +3351,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "sctk-adwaita" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61270629cc6b4d77ec1907db1033d5c2e1a404c412743621981a871dc9c12339" -dependencies = [ - "crossfont", - "log", - "smithay-client-toolkit", - "tiny-skia 0.7.0", -] - [[package]] name = "sendfd" version = "0.4.3" @@ -3918,27 +3391,6 @@ dependencies = [ "serde", ] -[[package]] -name = "servo-fontconfig" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c" -dependencies = [ - "libc", - "servo-fontconfig-sys", -] - -[[package]] -name = "servo-fontconfig-sys" -version = "5.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388" -dependencies = [ - "expat-sys", - "freetype-sys", - "pkg-config", -] - [[package]] name = "sha2" version = "0.10.6" @@ -4052,8 +3504,8 @@ dependencies = [ "wayland-protocols-wlr", "wayland-server", "wayland-sys 0.30.1", - "winit 0.28.6", - "x11rb 0.11.1", + "winit", + "x11rb", "xkbcommon 0.5.0", ] @@ -4076,16 +3528,6 @@ dependencies = [ "wayland-protocols 0.29.5", ] -[[package]] -name = "smithay-clipboard" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" -dependencies = [ - "smithay-client-toolkit", - "wayland-client 0.29.5", -] - [[package]] name = "smithay-egui" version = "0.1.0" @@ -4118,11 +3560,11 @@ dependencies = [ "cocoa", "core-graphics", "fastrand", - "foreign-types 0.3.2", + "foreign-types", "log", "nix 0.26.2", "objc", - "raw-window-handle 0.5.2", + "raw-window-handle", "redox_syscall 0.3.5", "thiserror", "wasm-bindgen", @@ -4132,7 +3574,7 @@ dependencies = [ "web-sys", "windows-sys 0.42.0", "x11-dl", - "x11rb 0.11.1", + "x11rb", ] [[package]] @@ -4166,12 +3608,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "str-buf" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" - [[package]] name = "strict-num" version = "0.1.1" @@ -4360,21 +3796,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny-skia" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642680569bb895b16e4b9d181c60be1ed136fa0c9c7f11d004daf053ba89bf82" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "bytemuck", - "cfg-if", - "png", - "safe_arch", - "tiny-skia-path 0.7.0", -] - [[package]] name = "tiny-skia" version = "0.8.4" @@ -4382,7 +3803,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" dependencies = [ "arrayref", - "arrayvec 0.7.2", + "arrayvec", "bytemuck", "cfg-if", "png", @@ -4396,7 +3817,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce2986c82f77818c7b9144c70818fdde98db15308e329ae2f7204d767808fd3c" dependencies = [ "arrayref", - "arrayvec 0.7.2", + "arrayvec", "bytemuck", "cfg-if", "log", @@ -4404,16 +3825,6 @@ dependencies = [ "tiny-skia-path 0.9.0", ] -[[package]] -name = "tiny-skia-path" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c114d32f0c2ee43d585367cb013dfaba967ab9f62b90d9af0d696e955e70fa6c" -dependencies = [ - "arrayref", - "bytemuck", -] - [[package]] name = "tiny-skia-path" version = "0.8.4" @@ -5070,75 +4481,28 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" -[[package]] -name = "wgpu" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d745a1b6d91d85c33defbb29f0eee0450e1d2614d987e14bf6baf26009d132d7" -dependencies = [ - "arrayvec 0.7.2", - "cfg-if", - "js-sys", - "log", - "naga 0.11.1", - "parking_lot 0.12.1", - "profiling", - "raw-window-handle 0.5.2", - "smallvec", - "static_assertions", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "wgpu-core 0.15.1", - "wgpu-hal 0.15.4", - "wgpu-types 0.15.2", -] - [[package]] name = "wgpu" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3059ea4ddec41ca14f356833e2af65e7e38c0a8f91273867ed526fb9bafcca95" dependencies = [ - "arrayvec 0.7.2", + "arrayvec", "cfg-if", "js-sys", "log", - "naga 0.12.2", + "naga", "parking_lot 0.12.1", "profiling", - "raw-window-handle 0.5.2", + "raw-window-handle", "smallvec", "static_assertions", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "wgpu-core 0.16.1", - "wgpu-hal 0.16.0", - "wgpu-types 0.16.0", -] - -[[package]] -name = "wgpu-core" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7131408d940e335792645a98f03639573b0480e9e2e7cddbbab74f7c6d9f3fff" -dependencies = [ - "arrayvec 0.7.2", - "bit-vec", - "bitflags 1.3.2", - "codespan-reporting", - "fxhash", - "log", - "naga 0.11.1", - "parking_lot 0.12.1", - "profiling", - "raw-window-handle 0.5.2", - "smallvec", - "thiserror", - "web-sys", - "wgpu-hal 0.15.4", - "wgpu-types 0.15.2", + "wgpu-core", + "wgpu-hal", + "wgpu-types", ] [[package]] @@ -5147,63 +4511,21 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f478237b4bf0d5b70a39898a66fa67ca3a007d79f2520485b8b0c3dfc46f8c2" dependencies = [ - "arrayvec 0.7.2", + "arrayvec", "bit-vec", "bitflags 2.3.1", "codespan-reporting", "log", - "naga 0.12.2", + "naga", "parking_lot 0.12.1", "profiling", - "raw-window-handle 0.5.2", + "raw-window-handle", "rustc-hash", "smallvec", "thiserror", "web-sys", - "wgpu-hal 0.16.0", - "wgpu-types 0.16.0", -] - -[[package]] -name = "wgpu-hal" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdcf61a283adc744bb5453dd88ea91f3f86d5ca6b027661c6c73c7734ae0288b" -dependencies = [ - "android_system_properties", - "arrayvec 0.7.2", - "ash", - "bit-set", - "bitflags 1.3.2", - "block", - "core-graphics-types", - "d3d12", - "foreign-types 0.3.2", - "fxhash", - "glow 0.12.2", - "gpu-alloc", - "gpu-allocator", - "gpu-descriptor", - "hassle-rs 0.9.0", - "js-sys", - "khronos-egl", - "libc", - "libloading 0.7.4", - "log", - "metal", - "naga 0.11.1", - "objc", - "parking_lot 0.12.1", - "profiling", - "range-alloc", - "raw-window-handle 0.5.2", - "renderdoc-sys 0.7.1", - "smallvec", - "thiserror", - "wasm-bindgen", - "web-sys", - "wgpu-types 0.15.2", - "winapi", + "wgpu-hal", + "wgpu-types", ] [[package]] @@ -5213,52 +4535,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41af2ea7d87bd41ad0a37146252d5f7c26490209f47f544b2ee3b3ff34c7732e" dependencies = [ "android_system_properties", - "arrayvec 0.7.2", + "arrayvec", "ash", "bit-set", "bitflags 2.3.1", "block", "core-graphics-types", "d3d12", - "foreign-types 0.3.2", + "foreign-types", "glow 0.12.2", "gpu-alloc", "gpu-allocator", "gpu-descriptor", - "hassle-rs 0.10.0", + "hassle-rs", "js-sys", "khronos-egl", "libc", "libloading 0.8.0", "log", "metal", - "naga 0.12.2", + "naga", "objc", "parking_lot 0.12.1", "profiling", "range-alloc", - "raw-window-handle 0.5.2", + "raw-window-handle", "renderdoc-sys 1.0.0", "rustc-hash", "smallvec", "thiserror", "wasm-bindgen", "web-sys", - "wgpu-types 0.16.0", + "wgpu-types", "winapi", ] -[[package]] -name = "wgpu-types" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32444e121b0bd00cb02c0de32fde457a9491bd44e03e7a5db6df9b1da2f6f110" -dependencies = [ - "bitflags 1.3.2", - "js-sys", - "web-sys", -] - [[package]] name = "wgpu-types" version = "0.16.0" @@ -5270,24 +4581,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wgpu_glyph" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25440d5f32ec39de49c57c15c2d3f9133a7939b069b5ad07e5afd8b78fb8adc" -dependencies = [ - "bytemuck", - "glyph_brush", - "log", - "wgpu 0.15.1", -] - -[[package]] -name = "widestring" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" - [[package]] name = "widestring" version = "1.0.2" @@ -5334,20 +4627,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "window_clipboard" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015dd4474dc6aa96fe19aae3a24587a088bd90331dba5a5cc60fb3a180234c4d" -dependencies = [ - "clipboard-win", - "clipboard_macos", - "clipboard_wayland", - "clipboard_x11", - "raw-window-handle 0.3.4", - "thiserror", -] - [[package]] name = "windows" version = "0.44.0" @@ -5357,19 +4636,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - [[package]] name = "windows-sys" version = "0.42.0" @@ -5445,12 +4711,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -5463,12 +4723,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -5481,12 +4735,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -5499,12 +4747,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -5529,12 +4771,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -5547,39 +4783,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "winit" -version = "0.27.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c" -dependencies = [ - "bitflags 1.3.2", - "cocoa", - "core-foundation", - "core-graphics", - "dispatch", - "instant", - "libc", - "log", - "mio", - "ndk", - "ndk-glue", - "objc", - "once_cell", - "parking_lot 0.12.1", - "percent-encoding", - "raw-window-handle 0.4.3", - "raw-window-handle 0.5.2", - "sctk-adwaita", - "smithay-client-toolkit", - "wasm-bindgen", - "wayland-client 0.29.5", - "wayland-protocols 0.29.5", - "web-sys", - "windows-sys 0.36.1", - "x11-dl", -] - [[package]] name = "winit" version = "0.28.6" @@ -5601,7 +4804,7 @@ dependencies = [ "once_cell", "orbclient", "percent-encoding", - "raw-window-handle 0.5.2", + "raw-window-handle", "redox_syscall 0.3.5", "smithay-client-toolkit", "wasm-bindgen", @@ -5643,18 +4846,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "x11rb" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e99be55648b3ae2a52342f9a870c0e138709a3493261ce9b469afe6e4df6d8a" -dependencies = [ - "gethostname", - "nix 0.22.3", - "winapi", - "winapi-wsapoll", -] - [[package]] name = "x11rb" version = "0.11.1" @@ -5698,12 +4889,6 @@ dependencies = [ "home", ] -[[package]] -name = "xi-unicode" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" - [[package]] name = "xkbcommon" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index 02900343..73a1ba88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,10 +30,8 @@ libsystemd = { version = "0.5", optional = true } wayland-backend = "0.1.0" wayland-scanner = "0.30.0" cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] } -libcosmic = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b", default-features = false, features = ["tiny_skia"] } -iced_core = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b" } -iced_renderer = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b" } -iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic", rev = "31f7e97d5b" } +libcosmic = { git = "https://github.com/pop-os/libcosmic", rev = "5765053", default-features = false, features = ["tiny_skia"] } +iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic", rev = "5765053" } tiny-skia = "0.9" ordered-float = "3.0" glow = "0.11.2" @@ -42,7 +40,7 @@ tracing-journald = "0.3.0" tracing = { version = "0.1.37", features = ["max_level_debug", "release_max_level_info"] } puffin = { version = "0.14.3", optional = true } puffin_egui = { version = "0.21.0", optional = true } -cosmic-time = "0.2.0" +cosmic-time = { git = "https://github.com/pop-os/cosmic-time", rev = "35dd0b8", default-features = false, features = ["libcosmic"] } [dependencies.id_tree] git = "https://github.com/Drakulix/id-tree.git" diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 5e0bd728..615743f6 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -5,7 +5,7 @@ use crate::{ wayland::handlers::screencopy::ScreencopySessions, }; use calloop::LoopHandle; -use cosmic::Element; +use cosmic::{iced_core::Color, Element}; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; use smithay::{ backend::{ @@ -311,8 +311,8 @@ impl Program for CosmicStackInternal { mask.clone().unwrap() } - fn background_color(&self) -> iced_core::Color { - iced_core::Color { + fn background_color(&self) -> Color { + Color { r: 0.1176, g: 0.1176, b: 0.1176, diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index e25f76fd..2047efc8 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -12,7 +12,7 @@ use crate::{ wayland::handlers::screencopy::ScreencopySessions, }; use calloop::LoopHandle; -use cosmic::iced::Command; +use cosmic::{iced::Command, iced_core::Color}; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; use smithay::{ backend::{ @@ -258,16 +258,16 @@ impl Program for CosmicWindowInternal { mask.clone().unwrap() } - fn background_color(&self) -> iced_core::Color { + fn background_color(&self) -> Color { if self.window.is_activated() { - iced_core::Color { + Color { r: 0.1176, g: 0.1176, b: 0.1176, a: 1.0, } } else { - iced_core::Color { + Color { r: 0.153, g: 0.153, b: 0.153, diff --git a/src/utils/iced.rs b/src/utils/iced.rs index 93266f44..9698c759 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -13,6 +13,8 @@ use cosmic::{ window::{Event as WindowEvent, Id}, Command, Point as IcedPoint, Rectangle as IcedRectangle, Size as IcedSize, }, + iced_core::{clipboard::Null as NullClipboard, renderer::Style, Color}, + iced_renderer::Backend as BackendWrapper, iced_runtime::{ command::Action, program::{Program as IcedProgram, State}, @@ -20,8 +22,6 @@ use cosmic::{ }, Renderer as IcedRenderer, Theme, }; -use iced_core::{renderer::Style, Color}; -use iced_renderer::Backend as BackendWrapper; use iced_tiny_skia::{ graphics::{damage, Primitive, Viewport}, Backend, @@ -279,7 +279,7 @@ impl IcedElementInternal

{ &Style { text_color: self.theme.cosmic().on_bg_color().into(), }, - &mut iced_core::clipboard::Null, + &mut NullClipboard, &mut self.debug, ) .1 From 90e1eab7a856a180aaef7c95fc1a8ff52055ee3b Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 5 Jun 2023 18:16:32 +0200 Subject: [PATCH 042/264] tiling: Fix lateral movement #129 --- src/shell/layout/tiling/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index e793ba4d..68c09483 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -632,7 +632,7 @@ impl TilingLayout { | (Orientation::Vertical, Direction::Up) | (Orientation::Vertical, Direction::Down) ) { - if parent_data.len() == 2 { + if len == 2 { if let Some(sibling) = tree .children_ids(&parent) .unwrap() @@ -648,7 +648,8 @@ impl TilingLayout { | (Orientation::Vertical, Direction::Left) | (Orientation::Horizontal, Direction::Up) | (Orientation::Horizontal, Direction::Down) - ) { + ) && child_id == node_id + { // ..lets move into our sibling group instead let idx = From 8f20cf5ececb48a5ef51981d9cbc1c66ad686f85 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 5 Jun 2023 18:32:37 +0200 Subject: [PATCH 043/264] tiling: Fix potential group border color --- src/shell/layout/tiling/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 68c09483..fcded726 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1819,9 +1819,9 @@ where } => { let render_active_child = if let Some(focused_id) = focused.as_ref() { !has_potential_groups - && tree - .children_ids(&node_id) - .unwrap() + && node + .children() + .iter() .any(|child_id| child_id == focused_id) } else { false @@ -1835,7 +1835,7 @@ where geo, 4, if render_active_child { 16 } else { 8 }, - alpha * if render_potential_group { 0.14 } else { 1.0 }, + alpha * if render_potential_group { 0.40 } else { 1.0 }, GROUP_COLOR, ) .into(), @@ -1900,7 +1900,7 @@ where geo, 4, 8, - alpha * if render_potential_group { 0.4 } else { 1.0 }, + alpha * if render_potential_group { 0.40 } else { 1.0 }, GROUP_COLOR, ) .into(), From be1b4ceb10f690febc9449969d4f6cc3f520d265 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 9 Jun 2023 16:26:13 +0200 Subject: [PATCH 044/264] shell: Allow querying current vs pending state --- src/shell/element/mod.rs | 20 ++-- src/shell/element/surface.rs | 132 ++++++++++++++-------- src/shell/element/window.rs | 6 +- src/shell/layout/floating/grabs/resize.rs | 2 +- src/shell/layout/floating/mod.rs | 2 +- src/shell/layout/tiling/mod.rs | 6 +- src/shell/workspace.rs | 6 +- src/wayland/handlers/toplevel_info.rs | 6 +- 8 files changed, 111 insertions(+), 69 deletions(-) diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index dd4d1a72..60ea63c3 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -247,14 +247,14 @@ impl CosmicMapped { } } - pub fn is_resizing(&self) -> Option { + pub fn is_resizing(&self, pending: bool) -> Option { let window = match &self.element { CosmicMappedInternal::Stack(s) => s.active(), CosmicMappedInternal::Window(w) => w.surface(), _ => unreachable!(), }; - window.is_resizing() + window.is_resizing(pending) } pub fn set_tiled(&self, tiled: bool) { @@ -268,14 +268,14 @@ impl CosmicMapped { } } - pub fn is_tiled(&self) -> Option { + pub fn is_tiled(&self, pending: bool) -> Option { let window = match &self.element { CosmicMappedInternal::Stack(s) => s.active(), CosmicMappedInternal::Window(w) => w.surface(), _ => unreachable!(), }; - window.is_tiled() + window.is_tiled(pending) } pub fn set_fullscreen(&self, fullscreen: bool) { @@ -290,14 +290,14 @@ impl CosmicMapped { } } - pub fn is_fullscreen(&self) -> bool { + pub fn is_fullscreen(&self, pending: bool) -> bool { let window = match &self.element { CosmicMappedInternal::Stack(s) => s.active(), CosmicMappedInternal::Window(w) => w.surface(), _ => unreachable!(), }; - window.is_fullscreen() + window.is_fullscreen(pending) } pub fn set_maximized(&self, maximized: bool) { @@ -312,14 +312,14 @@ impl CosmicMapped { } } - pub fn is_maximized(&self) -> bool { + pub fn is_maximized(&self, pending: bool) -> bool { let window = match &self.element { CosmicMappedInternal::Stack(s) => s.active(), CosmicMappedInternal::Window(w) => w.surface(), _ => unreachable!(), }; - window.is_maximized() + window.is_maximized(pending) } pub fn set_activated(&self, activated: bool) { @@ -334,14 +334,14 @@ impl CosmicMapped { } } - pub fn is_activated(&self) -> bool { + pub fn is_activated(&self, pending: bool) -> bool { let window = match &self.element { CosmicMappedInternal::Stack(s) => s.active(), CosmicMappedInternal::Window(w) => w.surface(), _ => unreachable!(), }; - window.is_activated() + window.is_activated(pending) } pub fn set_geometry(&self, geo: Rectangle) { diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index d02c4083..6b034837 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -129,13 +129,21 @@ impl CosmicSurface { } } - pub fn is_activated(&self) -> bool { + pub fn is_activated(&self, pending: bool) -> bool { match self { - CosmicSurface::Wayland(window) => window - .toplevel() - .current_state() - .states - .contains(ToplevelState::Activated), + CosmicSurface::Wayland(window) => { + if pending { + window.toplevel().with_pending_state(|pending| { + pending.states.contains(ToplevelState::Activated) + }) + } else { + window + .toplevel() + .current_state() + .states + .contains(ToplevelState::Activated) + } + } CosmicSurface::X11(surface) => surface.is_activated(), _ => unreachable!(), } @@ -157,29 +165,46 @@ impl CosmicSurface { } } - pub fn is_decorated(&self) -> bool { + pub fn is_decorated(&self, pending: bool) -> bool { match self { - CosmicSurface::Wayland(window) => window - .toplevel() - .current_state() - .decoration_mode - .map(|mode| mode == DecorationMode::ClientSide) - .unwrap_or(true), + CosmicSurface::Wayland(window) => { + if pending { + window.toplevel().with_pending_state(|pending| { + pending + .decoration_mode + .map(|mode| mode == DecorationMode::ClientSide) + .unwrap_or(true) + }) + } else { + window + .toplevel() + .current_state() + .decoration_mode + .map(|mode| mode == DecorationMode::ClientSide) + .unwrap_or(true) + } + } CosmicSurface::X11(surface) => surface.is_decorated(), _ => unreachable!(), } } - pub fn is_resizing(&self) -> Option { + pub fn is_resizing(&self, pending: bool) -> Option { match self { CosmicSurface::Wayland(window) => { - let xdg = window.toplevel(); - Some( - xdg.current_state().states.contains(ToplevelState::Resizing) - || xdg.with_pending_state(|states| { - states.states.contains(ToplevelState::Resizing) - }), - ) + if pending { + Some(window.toplevel().with_pending_state(|pending| { + pending.states.contains(ToplevelState::Resizing) + })) + } else { + Some( + window + .toplevel() + .current_state() + .states + .contains(ToplevelState::Resizing), + ) + } } _ => None, } @@ -198,15 +223,23 @@ impl CosmicSurface { } } - pub fn is_tiled(&self) -> Option { + pub fn is_tiled(&self, pending: bool) -> Option { match self { - CosmicSurface::Wayland(window) => Some( - window - .toplevel() - .current_state() - .states - .contains(ToplevelState::TiledLeft), - ), + CosmicSurface::Wayland(window) => { + if pending { + Some(window.toplevel().with_pending_state(|pending| { + pending.states.contains(ToplevelState::TiledLeft) + })) + } else { + Some( + window + .toplevel() + .current_state() + .states + .contains(ToplevelState::TiledLeft), + ) + } + } _ => None, } } @@ -230,16 +263,20 @@ impl CosmicSurface { } } - pub fn is_fullscreen(&self) -> bool { + pub fn is_fullscreen(&self, pending: bool) -> bool { match self { CosmicSurface::Wayland(window) => { - let xdg = window.toplevel(); - xdg.current_state() - .states - .contains(ToplevelState::Fullscreen) - || xdg.with_pending_state(|state| { - state.states.contains(ToplevelState::Fullscreen) + if pending { + window.toplevel().with_pending_state(|pending| { + pending.states.contains(ToplevelState::Fullscreen) }) + } else { + window + .toplevel() + .current_state() + .states + .contains(ToplevelState::Fullscreen) + } } CosmicSurface::X11(surface) => surface.is_fullscreen(), _ => unreachable!(), @@ -262,15 +299,20 @@ impl CosmicSurface { } } - pub fn is_maximized(&self) -> bool { + pub fn is_maximized(&self, pending: bool) -> bool { match self { CosmicSurface::Wayland(window) => { - let xdg = window.toplevel(); - xdg.current_state() - .states - .contains(ToplevelState::Maximized) - || xdg - .with_pending_state(|state| state.states.contains(ToplevelState::Maximized)) + if pending { + window.toplevel().with_pending_state(|pending| { + pending.states.contains(ToplevelState::Maximized) + }) + } else { + window + .toplevel() + .current_state() + .states + .contains(ToplevelState::Maximized) + } } CosmicSurface::X11(surface) => surface.is_maximized(), _ => unreachable!(), @@ -311,7 +353,7 @@ impl CosmicSurface { _ => unreachable!(), } .map(|size| { - if self.is_decorated() { + if self.is_decorated(false) { size + (0, SSD_HEIGHT).into() } else { size @@ -337,7 +379,7 @@ impl CosmicSurface { _ => unreachable!(), } .map(|size| { - if self.is_decorated() { + if self.is_decorated(false) { size + (0, SSD_HEIGHT).into() } else { size diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 2047efc8..797f65ad 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -107,7 +107,7 @@ impl CosmicWindowInternal { } pub fn has_ssd(&self) -> bool { - !self.window.is_decorated() + !self.window.is_decorated(false) } } @@ -259,7 +259,7 @@ impl Program for CosmicWindowInternal { } fn background_color(&self) -> Color { - if self.window.is_activated() { + if self.window.is_activated(false) { Color { r: 0.1176, g: 0.1176, @@ -281,7 +281,7 @@ impl Program for CosmicWindowInternal { pixels: &mut tiny_skia::PixmapMut<'_>, damage: &[Rectangle], ) { - if !self.window.is_activated() { + if !self.window.is_activated(false) { let mask = self.mask.lock().unwrap(); let mut paint = tiny_skia::Paint::default(); paint.set_color_rgba8(0, 0, 0, 102); diff --git a/src/shell/layout/floating/grabs/resize.rs b/src/shell/layout/floating/grabs/resize.rs index 9654f173..b9acd24b 100644 --- a/src/shell/layout/floating/grabs/resize.rs +++ b/src/shell/layout/floating/grabs/resize.rs @@ -226,7 +226,7 @@ impl ResizeSurfaceGrab { // Finish resizing. if let Some(ResizeState::WaitingForCommit(_)) = *resize_state { - if !window.is_resizing().unwrap_or(false) { + if !window.is_resizing(false).unwrap_or(false) { *resize_state = None; } } diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 15f7b6c4..e00d6fe7 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -158,7 +158,7 @@ impl FloatingLayout { pub fn unmap(&mut self, window: &CosmicMapped) -> bool { #[allow(irrefutable_let_patterns)] - let is_maximized = window.is_maximized(); + let is_maximized = window.is_maximized(true); if !is_maximized { if let Some(location) = self.space.element_location(window) { diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index fcded726..884d8321 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1415,7 +1415,7 @@ impl TilingLayout { } }, Data::Mapped { mapped, .. } => { - if !(mapped.is_fullscreen() || mapped.is_maximized()) { + if !(mapped.is_fullscreen(true) || mapped.is_maximized(true)) { mapped.set_tiled(true); let internal_geometry = Rectangle::from_loc_and_size( geo.loc + output.geometry().loc, @@ -1460,7 +1460,7 @@ impl TilingLayout { .unwrap() .filter(|node| node.data().is_mapped(None)) .filter(|node| match node.data() { - Data::Mapped { mapped, .. } => mapped.is_activated(), + Data::Mapped { mapped, .. } => mapped.is_activated(false), _ => unreachable!(), }) .map(|node| match node.data() { @@ -1480,7 +1480,7 @@ impl TilingLayout { .unwrap() .filter(|node| node.data().is_mapped(None)) .filter(|node| match node.data() { - Data::Mapped { mapped, .. } => !mapped.is_activated(), + Data::Mapped { mapped, .. } => !mapped.is_activated(false), _ => unreachable!(), }) .map(|node| match node.data() { diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index dc54b3d8..e00504f0 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -143,7 +143,7 @@ impl Workspace { assert!(was_floating != was_tiling); } - if mapped.is_maximized() || mapped.is_fullscreen() { + if mapped.is_maximized(true) || mapped.is_fullscreen(true) { self.unmaximize_request(&mapped.active_window()); } @@ -324,7 +324,7 @@ impl Workspace { start_data: PointerGrabStartData, edges: ResizeEdge, ) -> Option { - if mapped.is_fullscreen() || mapped.is_maximized() { + if mapped.is_fullscreen(true) || mapped.is_maximized(true) { return None; } @@ -355,7 +355,7 @@ impl Workspace { let mapped = self.element_for_surface(&window)?.clone(); let mut initial_window_location = self.element_geometry(&mapped).unwrap().loc; - if mapped.is_fullscreen() || mapped.is_maximized() { + if mapped.is_fullscreen(true) || mapped.is_maximized(true) { // If surface is maximized then unmaximize it let new_size = self.unmaximize_request(window); let ratio = pos.x / output.geometry().size.w as f64; diff --git a/src/wayland/handlers/toplevel_info.rs b/src/wayland/handlers/toplevel_info.rs index 40905c66..273fec7b 100644 --- a/src/wayland/handlers/toplevel_info.rs +++ b/src/wayland/handlers/toplevel_info.rs @@ -31,15 +31,15 @@ impl Window for CosmicSurface { } fn is_activated(&self) -> bool { - CosmicSurface::is_activated(self) + CosmicSurface::is_activated(self, false) } fn is_maximized(&self) -> bool { - CosmicSurface::is_maximized(self) + CosmicSurface::is_maximized(self, false) } fn is_fullscreen(&self) -> bool { - CosmicSurface::is_fullscreen(self) + CosmicSurface::is_fullscreen(self, false) } fn is_minimized(&self) -> bool { From 19c0fad00c7f85e34d56d29a510a751333e1a76d Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 9 Jun 2023 17:14:01 +0200 Subject: [PATCH 045/264] Revert: "tiling: Move window into sibling group, if orientation matches " --- src/shell/layout/tiling/mod.rs | 47 +--------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 884d8321..de796a15 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -632,52 +632,7 @@ impl TilingLayout { | (Orientation::Vertical, Direction::Up) | (Orientation::Vertical, Direction::Down) ) { - if len == 2 { - if let Some(sibling) = tree - .children_ids(&parent) - .unwrap() - .find(|id| *id != &child_id) - .cloned() - { - let sibling_data = tree.get(&sibling).unwrap().data(); - if sibling_data.is_group() { - let sibling_orientation = sibling_data.orientation(); - if matches!( - (sibling_orientation, direction), - (Orientation::Vertical, Direction::Right) - | (Orientation::Vertical, Direction::Left) - | (Orientation::Horizontal, Direction::Up) - | (Orientation::Horizontal, Direction::Down) - ) && child_id == node_id - { - // ..lets move into our sibling group instead - - let idx = - if direction == Direction::Left || direction == Direction::Up { - 0 - } else { - sibling_data.len() - }; - tree.move_node(&node_id, MoveBehavior::ToParent(&sibling)) - .unwrap(); - tree.make_nth_sibling(&node_id, idx).unwrap(); - - tree.get_mut(&sibling).unwrap().data_mut().add_window(idx); - tree.get_mut(&og_parent) - .unwrap() - .data_mut() - .remove_window(og_idx); - - let blocker = - TilingLayout::update_positions(&output, &mut tree, self.gaps); - queue.push_tree(tree, blocker); - return None; - } - } - } - } - - // or create a new group with our parent (cleanup will remove any one-child-groups afterwards) + // ...create a new group with our parent (cleanup will remove any one-child-groups afterwards) TilingLayout::new_group( &mut tree, &parent, From 331fc9c22be624c8a8aab0d5bf8b723c895b91e1 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 9 Jun 2023 17:44:52 +0200 Subject: [PATCH 046/264] tiling: All groups of two with focused child get active border --- src/shell/layout/tiling/mod.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index de796a15..13e68665 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1717,10 +1717,6 @@ where if let Some(parent) = focused_node.parent() { let parent_node = tree.get(parent).unwrap(); parent_node.children().len() > 2 - || parent_node.children().iter().any(|id| { - let data = tree.get(id).unwrap().data(); - data.is_group() && data.orientation() == parent_node.data().orientation() - }) } else { false } @@ -1751,10 +1747,8 @@ where { // only direct neighbors focused_idx.abs_diff(idx) == 1 - // skip neighbors, if this is a group of two windows - && !(parent_data.len() == 2 && data.is_mapped(None)) - // skip groups of two in opposite orientation to indicate move between - && !(parent_data.len() == 2 && if data.is_group() { parent_data.orientation() != data.orientation() } else { false } ) + // skip neighbors, if this is a group of two + && parent_data.len() > 2 } else { false } From a04bcdd2b0958990fd8997c2a0d7b254fde4eeef Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 9 Jun 2023 19:37:26 +0200 Subject: [PATCH 047/264] tiling: Fixup group selection visuals --- src/shell/layout/tiling/mod.rs | 118 ++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 46 deletions(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 13e68665..4f6dadce 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1,10 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::{ - backend::render::{ - element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, FOCUS_INDICATOR_COLOR, - GROUP_COLOR, - }, + backend::render::{element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, GROUP_COLOR}, shell::{ element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, focus::{ @@ -1675,6 +1672,9 @@ impl TilingLayout { } } +const OUTER_GAP: i32 = 8; +const INNER_GAP: i32 = 16; + fn geometries_for_groupview( tree: &Tree, renderer: &mut R, @@ -1694,9 +1694,7 @@ where { // we need to recalculate geometry for all elements, if we are drawing groups if let Some(root) = tree.root_node_id() { - const OUTER_GAP: i32 = 8; let outer_gap: i32 = (OUTER_GAP as f32 * transition).round() as i32; - const INNER_GAP: i32 = 16; let inner_gap: i32 = (INNER_GAP as f32 * transition).round() as i32; let mut stack = vec![Rectangle::from_loc_and_size( @@ -1780,7 +1778,7 @@ where elements.push( IndicatorShader::element( renderer, - Key::Group(Arc::downgrade(&alive)), + Key::Group(Arc::downgrade(alive)), geo, 4, if render_active_child { 16 } else { 8 }, @@ -1859,26 +1857,37 @@ where geo.size -= (outer_gap * 2, outer_gap * 2).into(); } - elements.push( - BackdropShader::element( - renderer, - mapped.clone(), - geo, - 8., - alpha - * if focused - .as_ref() - .map(|focused_id| focused_id == &node_id) - .unwrap_or(false) - { - 0.4 - } else { - 0.15 - }, - GROUP_COLOR, - ) - .into(), - ); + if focused + .as_ref() + .map(|focused_id| { + !tree + .ancestor_ids(&node_id) + .unwrap() + .any(|id| id == focused_id) + }) + .unwrap_or(false) + { + elements.push( + BackdropShader::element( + renderer, + mapped.clone(), + geo, + 8., + alpha + * if focused + .as_ref() + .map(|focused_id| focused_id == &node_id) + .unwrap_or(false) + { + 0.4 + } else { + 0.15 + }, + GROUP_COLOR, + ) + .into(), + ); + } geo.loc += (inner_gap, inner_gap).into(); geo.size -= (inner_gap * 2, inner_gap * 2).into(); @@ -2039,10 +2048,12 @@ where .and_then(|seat| TilingLayout::currently_focused_node(&target_tree, seat)) .map(|(id, _)| id); + let mut group_backdrop = None; + if let Some(root) = target_tree.root_node_id() { let old_geometries = old_geometries.unwrap_or_default(); let geometries = geometries.unwrap_or_default(); - target_tree + let mut elements: Vec> = target_tree .traverse_pre_order_ids(root) .unwrap() .flat_map(|node_id| { @@ -2133,7 +2144,31 @@ where let mut elements = Vec::new(); if focused == Some(node_id) { - if indicator_thickness > 0 { + if indicator_thickness > 0 || data.is_group() { + let mut geo = geo.clone(); + if data.is_group() { + let outer_gap: i32 = (OUTER_GAP as f32 * percentage).round() as i32; + geo.loc += (outer_gap, outer_gap).into(); + geo.size -= (outer_gap * 2, outer_gap * 2).into(); + + group_backdrop = Some( + BackdropShader::element( + renderer, + match data { + Data::Group { alive, .. } => { + Key::Group(Arc::downgrade(alive)) + } + _ => unreachable!(), + }, + geo, + 8., + 0.4, + GROUP_COLOR, + ) + .into(), + ); + } + let element = IndicatorShader::focus_element( renderer, match data { @@ -2141,23 +2176,12 @@ where Data::Group { alive, .. } => Key::Group(Arc::downgrade(alive)), }, geo, - indicator_thickness, - 1.0, - ); - elements.push(element.into()); - } - - if data.is_group() { - let element = BackdropShader::element( - renderer, - match data { - Data::Mapped { mapped, .. } => mapped.clone().into(), - Data::Group { alive, .. } => Key::Group(Arc::downgrade(alive)), + if data.is_group() { + 4 + } else { + indicator_thickness }, - geo, - (indicator_thickness * 2) as f32, - 0.25, - FOCUS_INDICATOR_COLOR, + 1.0, ); elements.push(element.into()); } @@ -2226,7 +2250,9 @@ where elements }) - .collect() + .collect(); + elements.extend(group_backdrop); + elements } else { Vec::new() } From c282c5c08e6030c25cbbfd769ac10f09ce950890 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 9 Jun 2023 19:47:41 +0200 Subject: [PATCH 048/264] shell: Don't activate windows, if groups are selected --- src/shell/focus/mod.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/shell/focus/mod.rs b/src/shell/focus/mod.rs index 60eabcde..d67ea768 100644 --- a/src/shell/focus/mod.rs +++ b/src/shell/focus/mod.rs @@ -136,12 +136,20 @@ impl Shell { // update activate status let focused_windows = seats .flat_map(|seat| { - self.outputs.iter().flat_map(|o| { + if matches!( + seat.get_keyboard().unwrap().current_focus(), + Some(KeyboardFocusTarget::Group(_)) + ) { + return None; + } + + Some(self.outputs.iter().flat_map(|o| { let space = self.active_space(o); let stack = space.focus_stack.get(seat); stack.last().cloned() - }) + })) }) + .flatten() .collect::>(); for output in self.outputs.iter() { From 8dbdd4a13e734a514e071048466143c996a13c2e Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 14 Jun 2023 14:44:36 +0200 Subject: [PATCH 049/264] wayland: Wire up wp_fractional_scale --- src/state.rs | 28 +++++++++-- src/wayland/handlers/fractional_scale.rs | 60 ++++++++++++++++++++++++ src/wayland/handlers/mod.rs | 1 + 3 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 src/wayland/handlers/fractional_scale.rs diff --git a/src/state.rs b/src/state.rs index 39772323..2492ff5e 100644 --- a/src/state.rs +++ b/src/state.rs @@ -53,6 +53,7 @@ use smithay::{ compositor::{CompositorClientState, CompositorState}, data_device::DataDeviceState, dmabuf::{DmabufFeedback, DmabufState}, + fractional_scale::{with_fractional_scale, FractionalScaleManagerState}, keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitState, output::OutputManagerState, presentation::PresentationState, @@ -113,6 +114,7 @@ pub struct Common { pub compositor_state: CompositorState, pub data_device_state: DataDeviceState, pub dmabuf_state: DmabufState, + pub fractional_scale_state: FractionalScaleManagerState, pub keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState, pub output_state: OutputManagerState, pub output_configuration_state: OutputConfigurationState, @@ -244,6 +246,7 @@ impl State { let compositor_state = CompositorState::new::(dh); let data_device_state = DataDeviceState::new::(dh); let dmabuf_state = DmabufState::new(); + let fractional_scale_state = FractionalScaleManagerState::new::(dh); let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::(dh); let output_state = OutputManagerState::new_with_xdg_output::(dh); let output_configuration_state = OutputConfigurationState::new(dh, |_| true); @@ -292,6 +295,7 @@ impl State { compositor_state, data_device_state, dmabuf_state, + fractional_scale_state, screencopy_state, shm_state, seat_state, @@ -450,7 +454,7 @@ impl Common { if outputs_for_element.contains(&output) { let window = mapped.active_window(); window.with_surfaces(|surface, states| { - update_surface_primary_scanout_output( + let primary_scanout_output = update_surface_primary_scanout_output( surface, output, states, @@ -468,6 +472,12 @@ impl Common { } }, ); + if let Some(output) = primary_scanout_output { + with_fractional_scale(states, |fraction_scale| { + fraction_scale + .set_preferred_scale(output.current_scale().fractional_scale()); + }); + } }); window.send_frame(output, time, throttle, surface_primary_scanout_output); if let Some(feedback) = window @@ -504,13 +514,19 @@ impl Common { self.shell.override_redirect_windows.iter().for_each(|or| { if let Some(wl_surface) = or.wl_surface() { with_surfaces_surface_tree(&wl_surface, |surface, states| { - update_surface_primary_scanout_output( + let primary_scanout_output = update_surface_primary_scanout_output( surface, output, states, render_element_states, default_primary_scanout_output_compare, ); + if let Some(output) = primary_scanout_output { + with_fractional_scale(states, |fraction_scale| { + fraction_scale + .set_preferred_scale(output.current_scale().fractional_scale()); + }); + } }); send_frames_surface_tree( &wl_surface, @@ -542,13 +558,19 @@ impl Common { let map = smithay::desktop::layer_map_for_output(output); for layer_surface in map.layers() { layer_surface.with_surfaces(|surface, states| { - update_surface_primary_scanout_output( + let primary_scanout_output = update_surface_primary_scanout_output( surface, output, states, render_element_states, default_primary_scanout_output_compare, ); + if let Some(output) = primary_scanout_output { + with_fractional_scale(states, |fraction_scale| { + fraction_scale + .set_preferred_scale(output.current_scale().fractional_scale()); + }); + } }); layer_surface.send_frame(output, time, throttle, surface_primary_scanout_output); if let Some(feedback) = diff --git a/src/wayland/handlers/fractional_scale.rs b/src/wayland/handlers/fractional_scale.rs new file mode 100644 index 00000000..54b1eaf7 --- /dev/null +++ b/src/wayland/handlers/fractional_scale.rs @@ -0,0 +1,60 @@ +use crate::{state::State, utils::prelude::SeatExt}; +use smithay::{ + delegate_fractional_scale, + desktop::utils::surface_primary_scanout_output, + reexports::wayland_server::protocol::wl_surface::WlSurface, + wayland::{ + compositor::{get_parent, with_states}, + fractional_scale::{with_fractional_scale, FractionalScaleHandler}, + }, +}; + +impl FractionalScaleHandler for State { + fn new_fractional_scale(&mut self, surface: WlSurface) { + // Here we can set the initial fractional scale + // + // First we look if the surface already has a primary scan-out output, if not + // we test if the surface is a subsurface and try to use the primary scan-out output + // of the root surface. If the root also has no primary scan-out output we just try + // to use the first output of the toplevel. + // If the surface is the root we also try to use the first output of the toplevel. + // + // If all the above tests do not lead to a output we just use the active output + // of the last active seat (which will also be the output a toplevel will + // initially be placed on) + let mut root = surface.clone(); + while let Some(parent) = get_parent(&root) { + root = parent; + } + + with_states(&surface, |states| { + let output = surface_primary_scanout_output(&surface, states) + .or_else(|| { + if root != surface { + with_states(&root, |states| { + surface_primary_scanout_output(&root, states).or_else(|| { + self.common + .shell + .visible_outputs_for_surface(&surface) + .next() + }) + }) + } else { + self.common + .shell + .visible_outputs_for_surface(&surface) + .next() + } + }) + .unwrap_or_else(|| { + let seat = self.common.last_active_seat(); + seat.active_output() + }); + with_fractional_scale(states, |fractional_scale| { + fractional_scale.set_preferred_scale(output.current_scale().fractional_scale()); + }); + }); + } +} + +delegate_fractional_scale!(State); diff --git a/src/wayland/handlers/mod.rs b/src/wayland/handlers/mod.rs index 56e4a9be..098b6e4b 100644 --- a/src/wayland/handlers/mod.rs +++ b/src/wayland/handlers/mod.rs @@ -5,6 +5,7 @@ pub mod compositor; pub mod data_device; pub mod decoration; pub mod dmabuf; +pub mod fractional_scale; pub mod keyboard_shortcuts_inhibit; pub mod layer_shell; pub mod output; From cf5b4017ba090648a2e1f6fa4da46116ef83829a Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 15 Jun 2023 12:43:52 +0200 Subject: [PATCH 050/264] wayland/fractional: Avoid deadlock --- src/wayland/handlers/fractional_scale.rs | 51 ++++++++++++------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/wayland/handlers/fractional_scale.rs b/src/wayland/handlers/fractional_scale.rs index 54b1eaf7..a5b54224 100644 --- a/src/wayland/handlers/fractional_scale.rs +++ b/src/wayland/handlers/fractional_scale.rs @@ -22,34 +22,35 @@ impl FractionalScaleHandler for State { // If all the above tests do not lead to a output we just use the active output // of the last active seat (which will also be the output a toplevel will // initially be placed on) - let mut root = surface.clone(); - while let Some(parent) = get_parent(&root) { - root = parent; - } + let output = with_states(&surface, |states| { + surface_primary_scanout_output(&surface, states) + }) + .or_else(|| { + let mut root = surface.clone(); + while let Some(parent) = get_parent(&root) { + root = parent; + } - with_states(&surface, |states| { - let output = surface_primary_scanout_output(&surface, states) + (root != surface) + .then(|| { + with_states(&root, |states| { + surface_primary_scanout_output(&root, states) + }) + }) + .flatten() .or_else(|| { - if root != surface { - with_states(&root, |states| { - surface_primary_scanout_output(&root, states).or_else(|| { - self.common - .shell - .visible_outputs_for_surface(&surface) - .next() - }) - }) - } else { - self.common - .shell - .visible_outputs_for_surface(&surface) - .next() - } + self.common + .shell + .visible_outputs_for_surface(&surface) + .next() }) - .unwrap_or_else(|| { - let seat = self.common.last_active_seat(); - seat.active_output() - }); + }) + .unwrap_or_else(|| { + let seat = self.common.last_active_seat(); + seat.active_output() + }); + + with_states(&surface, |states| { with_fractional_scale(states, |fractional_scale| { fractional_scale.set_preferred_scale(output.current_scale().fractional_scale()); }); From b1985b0052c26576492b343076562ba318c680af Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 22 Jun 2023 21:30:45 +0200 Subject: [PATCH 051/264] shell: Consider pending_layers for visible outputs --- src/shell/mod.rs | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/shell/mod.rs b/src/shell/mod.rs index c8b81d6e..bacada6f 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -1,6 +1,11 @@ use calloop::LoopHandle; use serde::{Deserialize, Serialize}; -use std::{cell::RefCell, collections::HashMap, time::Instant}; +use std::{ + cell::RefCell, + collections::HashMap, + sync::atomic::{AtomicBool, Ordering}, + time::Instant, +}; use tracing::warn; use cosmic_protocols::workspace::v1::server::zcosmic_workspace_handle_v1::State as WState; @@ -954,11 +959,23 @@ impl Shell { &'a self, surface: &'a WlSurface, ) -> impl Iterator + 'a { - match self.outputs.iter().find(|o| { - let map = layer_map_for_output(o); - map.layer_for_surface(surface, WindowSurfaceType::ALL) - .is_some() - }) { + match self + .outputs + .iter() + .find(|o| { + let map = layer_map_for_output(o); + map.layer_for_surface(surface, WindowSurfaceType::ALL) + .is_some() + }) + .or_else(|| { + self.pending_layers.iter().find_map(|(l, output, _)| { + let found = AtomicBool::new(false); + l.with_surfaces(|s, _| { + found.fetch_or(s == surface, Ordering::SeqCst); + }); + found.load(Ordering::SeqCst).then_some(output) + }) + }) { Some(output) => { Box::new(std::iter::once(output.clone())) as Box> } From 89a5d6adae42be1bbe9d328443ec126c3af071f1 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Wed, 28 Jun 2023 17:33:54 -0700 Subject: [PATCH 052/264] Ignore caps/num lock in key bindings I noticed https://github.com/pop-os/cosmic-comp/issues/17 again, but this time I realized num lock was on. Hopefully this is the only cause of that issue (and caps lock, but that is easier to notice). I don't think we would event want either of these states to be part of a key binding. And `KeyModifiers` doesn't seem to be used anywhere else this would be relevant. So they can be ignored. This should be more similar to how keybindings are handled elsewhere. --- src/config/mod.rs | 10 ---------- src/config/types.rs | 2 -- 2 files changed, 12 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 45143d5d..8a692c98 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -903,8 +903,6 @@ pub enum KeyModifier { Alt, Shift, Super, - CapsLock, - NumLock, } #[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] @@ -913,8 +911,6 @@ pub struct KeyModifiers { pub alt: bool, pub shift: bool, pub logo: bool, - pub caps_lock: bool, - pub num_lock: bool, } impl PartialEq for KeyModifiers { @@ -923,8 +919,6 @@ impl PartialEq for KeyModifiers { && self.alt == other.alt && self.shift == other.shift && self.logo == other.logo - && self.caps_lock == other.caps_lock - && self.num_lock == other.num_lock } } @@ -935,8 +929,6 @@ impl std::ops::AddAssign for KeyModifiers { KeyModifier::Alt => self.alt = true, KeyModifier::Shift => self.shift = true, KeyModifier::Super => self.logo = true, - KeyModifier::CapsLock => self.caps_lock = true, - KeyModifier::NumLock => self.num_lock = true, }; } } @@ -957,9 +949,7 @@ impl Into for KeyModifier { ctrl: false, alt: false, shift: false, - caps_lock: false, logo: false, - num_lock: false, }; modifiers += self; modifiers diff --git a/src/config/types.rs b/src/config/types.rs index 584dd51c..d9f2577c 100644 --- a/src/config/types.rs +++ b/src/config/types.rs @@ -212,9 +212,7 @@ impl From for KeyModifiers { ctrl: false, alt: false, shift: false, - caps_lock: false, logo: false, - num_lock: false, }, |mut modis, modi: KeyModifier| { modis += modi; From b3401eb18a621df81a5aa554b99e13fcd7ea0064 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 5 Jun 2023 17:52:47 +0200 Subject: [PATCH 053/264] shell/tiling: semi-working stacking --- config.ron | 1 + src/config/mod.rs | 2 + src/input/mod.rs | 6 ++ src/shell/element/mod.rs | 60 ++++++++++++++- src/shell/element/stack.rs | 53 +++++++++++-- src/shell/element/window.rs | 4 + src/shell/layout/tiling/mod.rs | 137 +++++++++++++++++++++++++++++++-- 7 files changed, 251 insertions(+), 12 deletions(-) diff --git a/config.ron b/config.ron index 8b8acdf6..2700cc54 100644 --- a/config.ron +++ b/config.ron @@ -54,6 +54,7 @@ (modifiers: [Super, Shift], key: "l"): Move(Right), (modifiers: [Super], key: "o"): ToggleOrientation, + (modifiers: [Super], key: "s"): ToggleStacking, (modifiers: [Super], key: "y"): ToggleTiling, (modifiers: [Super], key: "g"): ToggleWindowFloating, diff --git a/src/config/mod.rs b/src/config/mod.rs index 8a692c98..87e82348 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1010,6 +1010,8 @@ pub enum Action { ToggleOrientation, Orientation(crate::shell::layout::Orientation), + ToggleStacking, + ToggleTiling, ToggleWindowFloating, diff --git a/src/input/mod.rs b/src/input/mod.rs index b942297e..03e68dd3 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1120,6 +1120,12 @@ impl State { .tiling_layer .update_orientation(Some(orientation), &seat); } + Action::ToggleStacking => { + let output = seat.active_output(); + let workspace = self.common.shell.active_space_mut(&output); + let focus_stack = workspace.focus_stack.get_mut(seat); + workspace.tiling_layer.toggle_stacking(seat, focus_stack); + } Action::ToggleTiling => { let output = seat.active_output(); let workspace = self.common.shell.active_space_mut(&output); diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 60ea63c3..18807eb8 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -6,6 +6,7 @@ use crate::{ state::State, utils::prelude::SeatExt, }; +use calloop::LoopHandle; use id_tree::NodeId; use smithay::{ backend::{ @@ -228,8 +229,7 @@ impl CosmicMapped { pub fn handle_focus(&self, direction: FocusDirection) -> bool { if let CosmicMappedInternal::Stack(stack) = &self.element { - //TODO: stack.handle_focus(direction) - false + stack.handle_focus(direction) } else { false } @@ -458,6 +458,62 @@ impl CosmicMapped { } } + pub fn convert_to_stack<'a>( + &mut self, + outputs: impl Iterator)>, + ) { + match &self.element { + CosmicMappedInternal::Window(window) => { + let surface = window.surface(); + let activated = surface.is_activated(); + let handle = window.loop_handle(); + + let stack = CosmicStack::new(std::iter::once(surface), handle); + if let Some(geo) = self.last_geometry.lock().unwrap().clone() { + stack.set_geometry(geo); + } + for (output, overlap) in outputs { + stack.output_enter(output, overlap); + } + stack.set_activate(activated); + stack.active().send_configure(); + stack.refresh(); + + self.element = CosmicMappedInternal::Stack(stack); + } + _ => {} + } + } + + pub fn convert_to_surface<'a>( + &mut self, + surface: CosmicSurface, + outputs: impl Iterator)>, + ) { + let handle = self.loop_handle(); + let window = CosmicWindow::new(surface, handle); + + if let Some(geo) = self.last_geometry.lock().unwrap().clone() { + window.set_geometry(geo); + } + for (output, overlap) in outputs { + window.output_enter(output, overlap); + } + window.set_activate(self.is_activated()); + window.surface().send_configure(); + window.refresh(); + + self.element = CosmicMappedInternal::Window(window); + } + + pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> { + match &self.element { + CosmicMappedInternal::Stack(stack) => stack.loop_handle(), + CosmicMappedInternal::Window(window) => window.loop_handle(), + _ => unreachable!(), + } + } + #[cfg(feature = "debug")] pub fn set_debug(&self, flag: bool) { let mut debug = self.debug.lock().unwrap(); diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 615743f6..1c0e9964 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -1,4 +1,5 @@ use crate::{ + shell::focus::FocusDirection, state::State, utils::iced::{IcedElement, Program}, utils::prelude::SeatExt, @@ -126,6 +127,10 @@ impl CosmicStack { pub fn remove_window(&self, window: &CosmicSurface) { self.0.with_program(|p| { let mut windows = p.windows.lock().unwrap(); + if windows.len() == 1 { + return; + } + let Some(idx) = windows.iter().position(|w| w == window) else { return }; windows.remove(idx); p.active.fetch_min(windows.len() - 1, Ordering::SeqCst); @@ -135,11 +140,14 @@ impl CosmicStack { pub fn remove_idx(&self, idx: usize) { self.0.with_program(|p| { let mut windows = p.windows.lock().unwrap(); + if windows.len() == 1 { + return; + } if windows.len() >= idx { return; } windows.remove(idx); - p.active.fetch_min(windows.len(), Ordering::SeqCst); + p.active.fetch_min(windows.len() - 1, Ordering::SeqCst); }) } @@ -147,6 +155,32 @@ impl CosmicStack { self.0.with_program(|p| p.windows.lock().unwrap().len()) } + pub fn handle_focus(&self, direction: FocusDirection) -> bool { + self.0.with_program(|p| { + match direction { + FocusDirection::Left => p + .active + .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |val| val.checked_sub(1)) + .is_ok(), + FocusDirection::Right => { + let max = p.windows.lock().unwrap().len(); + p.active + .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |val| { + if val < max - 1 { + Some(val + 1) + } else { + None + } + }) + .is_ok() + } + FocusDirection::Out => false, //TODO + FocusDirection::In => false, //TODO + _ => false, + } + }) + } + pub fn active(&self) -> CosmicSurface { self.0 .with_program(|p| p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)].clone()) @@ -267,6 +301,10 @@ impl CosmicStack { active }) } + + pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> { + self.0.loop_handle() + } } impl Program for CosmicStackInternal { @@ -396,12 +434,19 @@ impl SpaceElement for CosmicStack { fn refresh(&self) { self.0.with_program(|p| { let mut windows = p.windows.lock().unwrap(); - windows.retain(IsAlive::alive); // TODO: We don't handle empty stacks properly + + // don't let the stack become empty + let active = windows[p.active.load(Ordering::SeqCst)].clone(); + windows.retain(IsAlive::alive); + if windows.is_empty() { + windows.push(active); + } + let len = windows.len(); let _ = p .active .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |active| { - (active > len).then_some(len - 1) + (active >= len).then_some(len - 1) }); windows.iter().for_each(|w| SpaceElement::refresh(w)) }) @@ -490,11 +535,9 @@ impl PointerTarget for CosmicStack { if event.location.y < TAB_HEIGHT as f64 { let focus = p.swap_focus(Focus::Header); - assert_eq!(focus, Focus::None); true } else { let focus = p.swap_focus(Focus::Window); - assert_eq!(focus, Focus::None); *p.last_location.lock().unwrap() = Some((event.location, event.serial, event.time)); let active = p.active.load(Ordering::SeqCst); diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 797f65ad..36ce7fe8 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -165,6 +165,10 @@ impl CosmicWindow { Point::from((0, 0)) } } + + pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> { + self.0.loop_handle() + } } #[derive(Debug, Clone, Copy)] diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 4f6dadce..8e6279a7 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -3,10 +3,13 @@ use crate::{ backend::render::{element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, GROUP_COLOR}, shell::{ - element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, + element::{ + window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement, + CosmicStack, CosmicWindow, + }, focus::{ target::{KeyboardFocusTarget, WindowGroup}, - FocusDirection, + FocusDirection, FocusStackMut, }, grabs::ResizeEdge, layout::Orientation, @@ -393,6 +396,19 @@ impl TilingLayout { let queue = self.queues.get_mut(output).expect("Output not mapped?"); let mut tree = queue.trees.back().unwrap().0.copy_clone(); + TilingLayout::map_to_tree(&mut tree, window, output, focus_stack, direction); + + let blocker = TilingLayout::update_positions(output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); + } + + fn map_to_tree<'a>( + mut tree: &mut Tree, + window: impl Into, + output: &Output, + focus_stack: Option + 'a>, + direction: Option, + ) { let window = window.into(); let new_window = Node::new(Data::Mapped { mapped: window.clone(), @@ -457,9 +473,6 @@ impl TilingLayout { }; *window.tiling_node_id.lock().unwrap() = Some(window_id); - - let blocker = TilingLayout::update_positions(output, &mut tree, self.gaps); - queue.push_tree(tree, blocker); } pub fn unmap(&mut self, window: &CosmicMapped) -> Option { @@ -1052,6 +1065,120 @@ impl TilingLayout { } } + pub fn toggle_stacking<'a>(&mut self, seat: &Seat, mut focus_stack: FocusStackMut) { + let output = seat.active_output(); + let Some(queue) = self.queues.get_mut(&output) else { return }; + let mut tree = queue.trees.back().unwrap().0.copy_clone(); + + if let Some((last_active, last_active_data)) = + TilingLayout::currently_focused_node(&tree, seat) + { + match last_active_data { + FocusedNodeData::Window(mapped) => { + if mapped.is_window() { + // if it is just a window + match tree.get_mut(&last_active).unwrap().data_mut() { + Data::Mapped { mapped, .. } => { + mapped.convert_to_stack(std::iter::once((&output, mapped.bbox()))); + focus_stack.append(&mapped); + } + _ => unreachable!(), + }; + } else { + // if we have a stack + let mut surfaces = mapped.windows().map(|(s, _)| s); + let first = surfaces.next().expect("Stack without a window?"); + + let handle = match tree.get_mut(&last_active).unwrap().data_mut() { + Data::Mapped { mapped, .. } => { + let handle = mapped.loop_handle(); + mapped.convert_to_surface( + first, + std::iter::once((&output, mapped.bbox())), + ); + focus_stack.append(&mapped); + handle + } + _ => unreachable!(), + }; + + // map the rest + for other in surfaces { + let window = + CosmicMapped::from(CosmicWindow::new(other, handle.clone())); + window.output_enter(&output, window.bbox()); + window.set_bounds(output.geometry().size); + + TilingLayout::map_to_tree( + &mut tree, + window, + &output, + Some(focus_stack.iter()), + None, + ) + } + + // TODO: Focus the new group + } + } + FocusedNodeData::Group(_, _) => { + let mut handle = None; + let surfaces = tree + .traverse_pre_order(&last_active) + .unwrap() + .flat_map(|node| match node.data() { + Data::Mapped { mapped, .. } => { + if handle.is_none() { + handle = Some(mapped.loop_handle()); + } + Some(mapped.windows().map(|(s, _)| s)) + } + Data::Group { .. } => None, + }) + .flatten() + .collect::>(); + + if surfaces.is_empty() { + return; + } + let handle = handle.unwrap(); + let stack = CosmicStack::new(surfaces.into_iter(), handle); + + for child in tree + .children_ids(&last_active) + .unwrap() + .cloned() + .collect::>() + .into_iter() + { + tree.remove_node(child, RemoveBehavior::DropChildren) + .unwrap(); + } + let data = tree.get_mut(&last_active).unwrap().data_mut(); + + let geo = *data.geometry(); + stack.set_geometry(geo); + stack.output_enter(&output, stack.bbox()); + stack.set_activate(true); + stack.active().send_configure(); + stack.refresh(); + + let mapped = CosmicMapped::from(stack); + *mapped.last_geometry.lock().unwrap() = Some(geo); + *mapped.tiling_node_id.lock().unwrap() = Some(last_active); + focus_stack.append(&mapped); + *data = Data::Mapped { + mapped, + last_geometry: geo, + }; + } + } + + let blocker = TilingLayout::update_positions(&output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); + } + } + pub fn recalculate(&mut self, output: &Output) { let Some(queue) = self.queues.get_mut(output) else { return }; let mut tree = queue.trees.back().unwrap().0.copy_clone(); From e73ebd4413873714e94ce47440d0eff2ec0b4eed Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 8 Jun 2023 13:19:30 +0200 Subject: [PATCH 054/264] stacking: header --- Cargo.lock | 1 + Cargo.toml | 1 + src/backend/render/mod.rs | 6 +- src/shell/element/mod.rs | 13 +- src/shell/element/stack.rs | 726 +++++++++++++++++++--- src/shell/element/surface.rs | 13 + src/shell/element/window.rs | 8 +- src/shell/layout/floating/grabs/moving.rs | 6 +- src/shell/layout/floating/mod.rs | 6 +- src/shell/layout/tiling/mod.rs | 7 +- src/shell/workspace.rs | 3 +- src/utils/iced.rs | 9 +- src/wayland/handlers/screencopy.rs | 6 +- 13 files changed, 684 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60bae03e..a634231c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -477,6 +477,7 @@ name = "cosmic-comp" version = "0.1.0" dependencies = [ "anyhow", + "apply", "bitflags 1.3.2", "bytemuck", "calloop", diff --git a/Cargo.toml b/Cargo.toml index 73a1ba88..167b854a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ license = "GPL-3.0-only" authors = ["Victoria Brekenfeld"] [dependencies] +apply = "0.3.0" anyhow = { version = "1.0.51", features = ["backtrace"] } bitflags = "1.3.2" bytemuck = "1.12" diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 129d33c3..7931ad39 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -11,7 +11,7 @@ use std::{ use crate::{ config::WorkspaceLayout, shell::{ - element::window::CosmicWindowRenderElement, + element::{stack::CosmicStackRenderElement, window::CosmicWindowRenderElement}, focus::target::WindowGroup, layout::{floating::SeatMoveGrabState, tiling::ANIMATION_DURATION}, CosmicMapped, CosmicMappedRenderElement, WorkspaceRenderElement, @@ -364,6 +364,7 @@ where ::TextureId: Clone + 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, E: From> + From>, { #[cfg(feature = "debug")] @@ -434,6 +435,7 @@ where ::Error: From, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { #[cfg(feature = "debug")] @@ -740,6 +742,7 @@ where CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, Source: Clone, { @@ -799,6 +802,7 @@ where CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, Source: Clone, { diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 18807eb8..39ba4c7c 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -53,7 +53,7 @@ pub mod stack; pub use self::stack::CosmicStack; pub mod window; pub use self::window::CosmicWindow; -use self::window::CosmicWindowRenderElement; +use self::{stack::CosmicStackRenderElement, window::CosmicWindowRenderElement}; #[cfg(feature = "debug")] use egui::plot::{Corner, Legend, Plot, PlotPoints, Polygon}; @@ -323,14 +323,10 @@ impl CosmicMapped { } pub fn set_activated(&self, activated: bool) { - for window in match &self.element { - CosmicMappedInternal::Stack(s) => { - Box::new(s.surfaces()) as Box> - } - CosmicMappedInternal::Window(w) => Box::new(std::iter::once(w.surface())), + match &self.element { + CosmicMappedInternal::Stack(s) => s.set_activate(activated), + CosmicMappedInternal::Window(w) => w.set_activate(activated), _ => unreachable!(), - } { - window.set_activated(activated) } } @@ -1009,6 +1005,7 @@ where ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, { type RenderElement = CosmicMappedRenderElement; fn render_elements>( diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 1c0e9964..cc962992 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -1,12 +1,22 @@ use crate::{ + backend::render::{ + element::{AsGlowFrame, AsGlowRenderer}, + GlMultiError, GlMultiFrame, GlMultiRenderer, + }, shell::focus::FocusDirection, state::State, utils::iced::{IcedElement, Program}, utils::prelude::SeatExt, wayland::handlers::screencopy::ScreencopySessions, }; +use apply::Apply; use calloop::LoopHandle; -use cosmic::{iced_core::Color, Element}; +use cosmic::{ + iced::widget as iced_widget, + iced_core::{alignment, Color, Length}, + iced_widget::rule::FillMode, + theme, widget as cosmic_widget, Element as CosmicElement, +}; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; use smithay::{ backend::{ @@ -14,8 +24,10 @@ use smithay::{ renderer::{ element::{ memory::MemoryRenderBufferRenderElement, surface::WaylandSurfaceRenderElement, - AsRenderElements, + AsRenderElements, Element, Id, RenderElement, }, + glow::GlowRenderer, + utils::CommitCounter, ImportAll, ImportMem, Renderer, }, }, @@ -26,14 +38,13 @@ use smithay::{ Seat, }, output::Output, - render_elements, - utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size}, + utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform}, }; use std::{ fmt, hash::Hash, sync::{ - atomic::{AtomicU8, AtomicUsize, Ordering}, + atomic::{AtomicBool, AtomicU8, AtomicUsize, Ordering}, Arc, Mutex, }, }; @@ -57,10 +68,13 @@ impl fmt::Debug for CosmicStack { pub struct CosmicStackInternal { windows: Arc>>, active: Arc, + activated: Arc, + group_focused: Arc, previous_keyboard: Arc, pointer_entered: Option>, previous_pointer: Arc, last_location: Arc, Serial, u32)>>>, + geometry: Arc>>>, mask: Arc>>, } @@ -103,15 +117,24 @@ impl CosmicStack { ) -> CosmicStack { let windows = windows.map(Into::into).collect::>(); assert!(!windows.is_empty()); + + for window in &windows { + window.try_force_undecorated(true); + window.set_tiled(true); + } + let width = windows[0].geometry().size.w; CosmicStack(IcedElement::new( CosmicStackInternal { windows: Arc::new(Mutex::new(windows)), active: Arc::new(AtomicUsize::new(0)), + activated: Arc::new(AtomicBool::new(false)), + group_focused: Arc::new(AtomicBool::new(false)), previous_keyboard: Arc::new(AtomicUsize::new(0)), pointer_entered: None, previous_pointer: Arc::new(AtomicUsize::new(0)), last_location: Arc::new(Mutex::new(None)), + geometry: Arc::new(Mutex::new(None)), mask: Arc::new(Mutex::new(None)), }, (width, TAB_HEIGHT), @@ -119,9 +142,13 @@ impl CosmicStack { )) } - pub fn add_window(&self, window: CosmicSurface) { + pub fn add_window(&self, window: impl Into) { + let window = window.into(); + window.try_force_undecorated(true); + window.set_tiled(true); self.0 .with_program(|p| p.windows.lock().unwrap().push(window)); + self.0.force_redraw() } pub fn remove_window(&self, window: &CosmicSurface) { @@ -132,9 +159,13 @@ impl CosmicStack { } let Some(idx) = windows.iter().position(|w| w == window) else { return }; - windows.remove(idx); + let window = windows.remove(idx); + window.try_force_undecorated(false); + window.set_tiled(false); + p.active.fetch_min(windows.len() - 1, Ordering::SeqCst); - }) + }); + self.0.force_redraw() } pub fn remove_idx(&self, idx: usize) { @@ -146,9 +177,13 @@ impl CosmicStack { if windows.len() >= idx { return; } - windows.remove(idx); + let window = windows.remove(idx); + window.try_force_undecorated(false); + window.set_tiled(false); + p.active.fetch_min(windows.len() - 1, Ordering::SeqCst); - }) + }); + self.0.force_redraw() } pub fn len(&self) -> usize { @@ -156,13 +191,18 @@ impl CosmicStack { } pub fn handle_focus(&self, direction: FocusDirection) -> bool { - self.0.with_program(|p| { - match direction { - FocusDirection::Left => p - .active - .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |val| val.checked_sub(1)) - .is_ok(), - FocusDirection::Right => { + let result = self.0.with_program(|p| match direction { + FocusDirection::Left => { + if !p.group_focused.load(Ordering::SeqCst) { + p.active + .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |val| val.checked_sub(1)) + .is_ok() + } else { + false + } + } + FocusDirection::Right => { + if !p.group_focused.load(Ordering::SeqCst) { let max = p.windows.lock().unwrap().len(); p.active .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |val| { @@ -173,12 +213,40 @@ impl CosmicStack { } }) .is_ok() + } else { + false } - FocusDirection::Out => false, //TODO - FocusDirection::In => false, //TODO - _ => false, } - }) + FocusDirection::Out => { + if !p.group_focused.swap(true, Ordering::SeqCst) { + p.windows.lock().unwrap().iter().for_each(|w| { + w.set_activated(false); + w.send_configure(); + }); + true + } else { + false + } + } + FocusDirection::In => { + if !p.group_focused.swap(false, Ordering::SeqCst) { + p.windows.lock().unwrap().iter().for_each(|w| { + w.set_activated(true); + w.send_configure(); + }); + true + } else { + false + } + } + _ => false, + }); + + if result { + self.0.force_update(); + } + + result } pub fn active(&self) -> CosmicSurface { @@ -198,7 +266,8 @@ impl CosmicStack { p.previous_keyboard.store(old, Ordering::SeqCst); p.previous_pointer.store(old, Ordering::SeqCst); } - }) + }); + self.0.force_redraw() } pub fn surfaces(&self) -> impl Iterator { @@ -222,9 +291,13 @@ impl CosmicStack { let loc = (geo.loc.x, geo.loc.y + TAB_HEIGHT); let size = (geo.size.w, geo.size.h - TAB_HEIGHT); + let win_geo = Rectangle::from_loc_and_size(loc, size); for window in p.windows.lock().unwrap().iter() { - window.set_geometry(Rectangle::from_loc_and_size(loc, size)); + window.set_geometry(win_geo); } + + *p.geometry.lock().unwrap() = Some(geo); + p.mask.lock().unwrap().take(); }); self.0.resize(Size::from((geo.size.w, TAB_HEIGHT))); } @@ -239,14 +312,13 @@ impl CosmicStack { let active = p.active.load(Ordering::SeqCst); let previous = p.previous_keyboard.swap(active, Ordering::SeqCst); if previous != active { - KeyboardTarget::leave(&p.windows.lock().unwrap()[previous], seat, data, serial); - KeyboardTarget::enter( - &p.windows.lock().unwrap()[active], - seat, - data, - Vec::new(), //seat.keys(), - serial, - ) + let windows = p.windows.lock().unwrap(); + if let Some(previous) = windows.get(previous) { + KeyboardTarget::leave(previous, seat, data, serial); + } + seat.get_keyboard().unwrap().with_pressed_keysyms(|syms| { + KeyboardTarget::enter(&windows[active], seat, data, syms, serial) + }) } active }) @@ -264,31 +336,23 @@ impl CosmicStack { let active = p.active.load(Ordering::SeqCst); let previous = p.previous_pointer.swap(active, Ordering::SeqCst); if previous != active { - if let Some(sessions) = p.windows.lock().unwrap()[previous] - .user_data() - .get::() - { - for session in &*sessions.0.borrow() { - session.cursor_leave(seat, InputType::Pointer) + let windows = p.windows.lock().unwrap(); + if let Some(previous) = windows.get(previous) { + if let Some(sessions) = previous.user_data().get::() { + for session in &*sessions.0.borrow() { + session.cursor_leave(seat, InputType::Pointer) + } } + PointerTarget::leave(previous, seat, data, serial, time); } - PointerTarget::leave( - &p.windows.lock().unwrap()[previous], - seat, - data, - serial, - time, - ); - if let Some(sessions) = p.windows.lock().unwrap()[active] - .user_data() - .get::() - { + + if let Some(sessions) = windows[active].user_data().get::() { for session in &*sessions.0.borrow() { session.cursor_enter(seat, InputType::Pointer) } } PointerTarget::enter( - &p.windows.lock().unwrap()[active], + &windows[active], seat, data, &MotionEvent { @@ -310,8 +374,240 @@ impl CosmicStack { impl Program for CosmicStackInternal { type Message = (); - fn view(&self) -> Element<'_, Self::Message> { - cosmic::iced::widget::text("TODO").into() + fn view(&self) -> CosmicElement<'_, Self::Message> { + let windows = self.windows.lock().unwrap(); + let Some(width) = self + .geometry + .lock() + .unwrap() + .as_ref() + .map(|r| r.size.w) + else { + return iced_widget::row(Vec::new()).into(); + }; + let tab_region = width - 128 - 8; // 64 left, 64 right + last rule with padding + let active = self.active.load(Ordering::SeqCst); + let activated = self.activated.load(Ordering::SeqCst); + let group_focused = self.group_focused.load(Ordering::SeqCst); + + let mut elements = vec![cosmic_widget::icon("view-paged-symbolic", 16) + .force_svg(true) + .style(if group_focused { + theme::Svg::custom(|theme| iced_widget::svg::Appearance { + color: Some(if theme.cosmic().is_dark { + Color::BLACK + } else { + Color::WHITE + }), + }) + } else { + theme::Svg::Symbolic + }) + .apply(iced_widget::container) + .padding([4, 24]) + .center_y() + .into()]; + + const ACTIVE_TAB_WIDTH: i32 = 140; + const MIN_TAB_WIDTH: i32 = 36; + let tab_width = if windows.len() == 1 { + tab_region + } else { + let potential_width = tab_region / windows.len() as i32; + if potential_width < ACTIVE_TAB_WIDTH { + (tab_region - ACTIVE_TAB_WIDTH) / (windows.len() - 1) as i32 + } else { + potential_width + } + }; + let scrolling = tab_width < MIN_TAB_WIDTH; + + let mut tabs = Vec::new(); + for (i, window) in windows.iter().enumerate() { + let mut tab_elements = Vec::new(); + + let app_id = window.app_id(); + let title = window.title(); + let is_active = i == active; + let was_previous_active = i.checked_sub(1).map(|i| i == active).unwrap_or(false); + let tab_width = tab_width.max(if is_active { + ACTIVE_TAB_WIDTH + } else { + MIN_TAB_WIDTH + }); + + tabs.push( + iced_widget::vertical_rule(4) + .style( + if is_active || was_previous_active || (i == 0 && group_focused) { + if activated { + theme::Rule::custom(|theme| iced_widget::rule::Appearance { + color: theme.cosmic().accent_color().into(), + width: 4, + radius: 0., + fill_mode: FillMode::Full, + }) + } else { + theme::Rule::custom(|theme| iced_widget::rule::Appearance { + color: theme.cosmic().palette.neutral_5.into(), + width: 4, + radius: 0., + fill_mode: FillMode::Full, + }) + } + } else { + theme::Rule::custom(|theme| iced_widget::rule::Appearance { + color: theme.cosmic().palette.neutral_5.into(), + width: 4, + radius: 8., + fill_mode: FillMode::Padded(4), + }) + }, + ) + .into(), + ); + + tab_elements.push( + cosmic_widget::icon(app_id, 12) + .apply(iced_widget::container) + .height(Length::Fill) + .center_y() + .into(), + ); + + let text_width = tab_width - if tab_width > 125 { 64 } else { 40 }; + if text_width > 0 { + tab_elements.push( + cosmic_widget::text(title) + .size(14) + .font(if is_active && self.activated.load(Ordering::SeqCst) { + cosmic::font::FONT_SEMIBOLD + } else { + cosmic::font::FONT + }) + .horizontal_alignment(alignment::Horizontal::Left) + .vertical_alignment(alignment::Vertical::Center) + .height(Length::Fill) + .width(text_width as u16) + .into(), + ); + } + + if tab_width > 125 { + tab_elements.push( + cosmic_widget::icon("window-close-symbolic", 16) + .force_svg(true) + .style(theme::Svg::Symbolic) + .apply(iced_widget::container) + .height(Length::Fill) + .center_y() + .into(), + ); + } + + tabs.push( + iced_widget::row(tab_elements) + .height(Length::Fill) + .width(tab_width as u16 - 22) + .spacing(8) + .apply(iced_widget::container) + .padding([2, 10]) + .center_y() + .style(if is_active { + if activated { + theme::Container::custom(|theme| iced_widget::container::Appearance { + text_color: Some(Color::from(theme.cosmic().accent_text_color())), + background: Some(cosmic::iced::Background::Color( + Color::from_rgba(1.0, 1.0, 1.0, 0.1), + )), + border_radius: 0.0.into(), + border_width: 0.0, + border_color: Color::TRANSPARENT, + }) + } else { + theme::Container::custom(|_theme| iced_widget::container::Appearance { + text_color: None, + background: Some(cosmic::iced::Background::Color( + Color::from_rgba(1.0, 1.0, 1.0, 0.1), + )), + border_radius: 0.0.into(), + border_width: 0.0, + border_color: Color::TRANSPARENT, + }) + } + } else { + theme::Container::Transparent + }) + .into(), + ) + } + + let last_was_active = active == windows.len() - 1; + let group_focused_clone = self.group_focused.clone(); + tabs.push( + iced_widget::vertical_rule(4) + .style( + if last_was_active || group_focused_clone.load(Ordering::SeqCst) { + if activated { + theme::Rule::custom(|theme| iced_widget::rule::Appearance { + color: theme.cosmic().accent_color().into(), + width: 4, + radius: 0., + fill_mode: FillMode::Full, + }) + } else { + theme::Rule::custom(|theme| iced_widget::rule::Appearance { + color: theme.cosmic().palette.neutral_5.into(), + width: 4, + radius: 0., + fill_mode: FillMode::Full, + }) + } + } else { + theme::Rule::custom(|theme| iced_widget::rule::Appearance { + color: theme.cosmic().palette.neutral_5.into(), + width: 4, + radius: 8., + fill_mode: FillMode::Padded(4), + }) + }, + ) + .into(), + ); + + let tabs = + iced_widget::row(tabs) + .apply(iced_widget::container) + .style(theme::Container::custom(|theme| { + iced_widget::container::Appearance { + text_color: None, + background: Some(cosmic::iced::Background::Color(Color::from( + theme.cosmic().palette.neutral_3, + ))), + border_radius: 0.0.into(), + border_width: 0.0, + border_color: Color::TRANSPARENT, + } + })); + if scrolling { + elements.push( + iced_widget::Scrollable::new(tabs) + .height(Length::Fill) + .width(tab_region as u16) + .into(), + ) + } else { + elements.push(tabs.into()); + } + + elements.push(iced_widget::horizontal_space(64).into()); + + iced_widget::row(elements) + .height(TAB_HEIGHT as u16) + .width(width as u16) + .apply(iced_widget::container) + .center_y() + .into() } fn clip_mask(&self, size: Size, scale: f32) -> tiny_skia::Mask { @@ -350,11 +646,46 @@ impl Program for CosmicStackInternal { } fn background_color(&self) -> Color { - Color { - r: 0.1176, - g: 0.1176, - b: 0.1176, - a: 1.0, + if self.group_focused.load(Ordering::SeqCst) { + Color::from(cosmic::theme::COSMIC_DARK.accent_color()) + } else { + Color::from(cosmic::theme::COSMIC_DARK.palette.neutral_3) + } + } + + fn foreground( + &self, + pixels: &mut tiny_skia::PixmapMut<'_>, + damage: &[Rectangle], + scale: f32, + ) { + if self.group_focused.load(Ordering::SeqCst) { + let border = Rectangle::from_loc_and_size( + (0, TAB_HEIGHT - scale as i32), + (pixels.width() as i32, scale as i32), + ); + let mask = self.mask.lock().unwrap(); + + let mut paint = tiny_skia::Paint::default(); + let (b, g, r, a) = theme::COSMIC_DARK.accent_color().into_components(); + paint.set_color(tiny_skia::Color::from_rgba(r, g, b, a).unwrap()); + + for rect in damage { + if let Some(overlap) = rect.intersection(border) { + pixels.fill_rect( + tiny_skia::Rect::from_xywh( + overlap.loc.x as f32, + overlap.loc.y as f32, + overlap.size.w as f32, + overlap.size.h as f32, + ) + .unwrap(), + &paint, + Default::default(), + mask.as_ref(), + ) + } + } } } } @@ -390,13 +721,17 @@ impl SpaceElement for CosmicStack { } fn set_activate(&self, activated: bool) { SpaceElement::set_activate(&self.0, activated); + self.0.force_redraw(); self.0.with_program(|p| { - p.windows - .lock() - .unwrap() - .iter() - .for_each(|w| SpaceElement::set_activate(w, activated)) - }) + p.activated.store(activated, Ordering::SeqCst); + if !p.group_focused.load(Ordering::SeqCst) { + p.windows + .lock() + .unwrap() + .iter() + .for_each(|w| SpaceElement::set_activate(w, activated)) + } + }); } fn output_enter(&self, output: &Output, overlap: Rectangle) { SpaceElement::output_enter(&self.0, output, overlap); @@ -432,6 +767,7 @@ impl SpaceElement for CosmicStack { }) } fn refresh(&self) { + SpaceElement::refresh(&self.0); self.0.with_program(|p| { let mut windows = p.windows.lock().unwrap(); @@ -448,8 +784,8 @@ impl SpaceElement for CosmicStack { .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |active| { (active >= len).then_some(len - 1) }); - windows.iter().for_each(|w| SpaceElement::refresh(w)) - }) + windows.iter().for_each(|w| SpaceElement::refresh(w)); + }); } } @@ -475,7 +811,9 @@ impl KeyboardTarget for CosmicStack { } fn leave(&self, seat: &Seat, data: &mut State, serial: Serial) { let active = self.keyboard_leave_if_previous(seat, data, serial); + self.0.force_redraw(); self.0.with_program(|p| { + p.group_focused.store(false, Ordering::SeqCst); KeyboardTarget::leave(&p.windows.lock().unwrap()[active], seat, data, serial) }) } @@ -490,15 +828,17 @@ impl KeyboardTarget for CosmicStack { ) { let active = self.keyboard_leave_if_previous(seat, data, serial); self.0.with_program(|p| { - KeyboardTarget::key( - &p.windows.lock().unwrap()[active], - seat, - data, - key, - state, - serial, - time, - ) + if !p.group_focused.load(Ordering::SeqCst) { + KeyboardTarget::key( + &p.windows.lock().unwrap()[active], + seat, + data, + key, + state, + serial, + time, + ) + } }) } fn modifiers( @@ -510,13 +850,15 @@ impl KeyboardTarget for CosmicStack { ) { let active = self.keyboard_leave_if_previous(seat, data, serial); self.0.with_program(|p| { - KeyboardTarget::modifiers( - &p.windows.lock().unwrap()[active], - seat, - data, - modifiers, - serial, - ) + if !p.group_focused.load(Ordering::SeqCst) { + KeyboardTarget::modifiers( + &p.windows.lock().unwrap()[active], + seat, + data, + modifiers, + serial, + ) + } }) } } @@ -630,14 +972,27 @@ impl PointerTarget for CosmicStack { match self.0.with_program(|p| p.current_focus()) { Focus::Header => PointerTarget::button(&self.0, seat, data, event), - Focus::Window => self.0.with_program(|p| { - PointerTarget::button( - &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)], - seat, - data, - event, - ) - }), + Focus::Window => { + if self.0.with_program(|p| { + PointerTarget::button( + &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)], + seat, + data, + event, + ); + if p.group_focused.swap(false, Ordering::SeqCst) { + p.windows.lock().unwrap().iter().for_each(|w| { + SpaceElement::set_activate(w, true); + w.send_configure(); + }); + true + } else { + false + } + }) { + self.0.force_redraw(); + } + } _ => {} } } @@ -702,39 +1057,206 @@ impl PointerTarget for CosmicStack { } } -render_elements! { - pub CosmicStackRenderElement where R: ImportAll + ImportMem; - Header=MemoryRenderBufferRenderElement, - Window=WaylandSurfaceRenderElement, +pub enum CosmicStackRenderElement +where + R: ImportAll + ImportMem + AsGlowRenderer + Renderer, + ::TextureId: 'static, +{ + Header(MemoryRenderBufferRenderElement), + Window(WaylandSurfaceRenderElement), +} + +impl From> for CosmicStackRenderElement +where + R: ImportAll + ImportMem + AsGlowRenderer + Renderer, + ::TextureId: 'static, +{ + fn from(elem: WaylandSurfaceRenderElement) -> Self { + CosmicStackRenderElement::Window(elem) + } +} + +impl From> for CosmicStackRenderElement +where + R: ImportAll + ImportMem + AsGlowRenderer + Renderer, + ::TextureId: 'static, +{ + fn from(elem: MemoryRenderBufferRenderElement) -> Self { + CosmicStackRenderElement::Header(elem) + } +} + +impl Element for CosmicStackRenderElement +where + R: AsGlowRenderer + Renderer + ImportAll + ImportMem, + ::TextureId: 'static, +{ + fn id(&self) -> &Id { + match self { + CosmicStackRenderElement::Header(h) => h.id(), + CosmicStackRenderElement::Window(w) => w.id(), + } + } + + fn current_commit(&self) -> CommitCounter { + match self { + CosmicStackRenderElement::Header(h) => h.current_commit(), + CosmicStackRenderElement::Window(w) => w.current_commit(), + } + } + + fn src(&self) -> Rectangle { + match self { + CosmicStackRenderElement::Header(h) => h.src(), + CosmicStackRenderElement::Window(w) => w.src(), + } + } + + fn geometry(&self, scale: Scale) -> Rectangle { + match self { + CosmicStackRenderElement::Header(h) => h.geometry(scale), + CosmicStackRenderElement::Window(w) => w.geometry(scale), + } + } + + fn location(&self, scale: Scale) -> Point { + match self { + CosmicStackRenderElement::Header(h) => h.location(scale), + CosmicStackRenderElement::Window(w) => w.location(scale), + } + } + + fn transform(&self) -> Transform { + match self { + CosmicStackRenderElement::Header(h) => h.transform(), + CosmicStackRenderElement::Window(w) => w.transform(), + } + } + + fn damage_since( + &self, + scale: Scale, + commit: Option, + ) -> Vec> { + match self { + CosmicStackRenderElement::Header(h) => h.damage_since(scale, commit), + CosmicStackRenderElement::Window(w) => w.damage_since(scale, commit), + } + } + + fn opaque_regions(&self, scale: Scale) -> Vec> { + match self { + CosmicStackRenderElement::Header(h) => h.opaque_regions(scale), + CosmicStackRenderElement::Window(w) => w.opaque_regions(scale), + } + } + + fn alpha(&self) -> f32 { + match self { + CosmicStackRenderElement::Header(h) => h.alpha(), + CosmicStackRenderElement::Window(w) => w.alpha(), + } + } +} + +impl RenderElement for CosmicStackRenderElement { + fn draw<'a>( + &self, + frame: &mut ::Frame<'a>, + src: Rectangle, + dst: Rectangle, + damage: &[Rectangle], + ) -> Result<(), ::Error> { + match self { + CosmicStackRenderElement::Header(h) => h.draw(frame, src, dst, damage), + CosmicStackRenderElement::Window(w) => w.draw(frame, src, dst, damage), + } + } + + fn underlying_storage( + &self, + renderer: &mut GlowRenderer, + ) -> Option { + match self { + CosmicStackRenderElement::Header(h) => h.underlying_storage(renderer), + CosmicStackRenderElement::Window(w) => w.underlying_storage(renderer), + } + } +} + +impl<'a, 'b> RenderElement> + for CosmicStackRenderElement> +{ + fn draw<'c>( + &self, + frame: &mut GlMultiFrame<'a, 'b, 'c>, + src: Rectangle, + dst: Rectangle, + damage: &[Rectangle], + ) -> Result<(), GlMultiError> { + match self { + CosmicStackRenderElement::Header(h) => h + .draw(frame.glow_frame_mut(), src, dst, damage) + .map_err(|err| GlMultiError::Render(err)), + CosmicStackRenderElement::Window(w) => w.draw(frame, src, dst, damage), + } + } + + fn underlying_storage( + &self, + renderer: &mut GlMultiRenderer<'a, 'b>, + ) -> Option { + match self { + CosmicStackRenderElement::Header(h) => { + h.underlying_storage(renderer.glow_renderer_mut()) + } + CosmicStackRenderElement::Window(w) => w.underlying_storage(renderer), + } + } } impl AsRenderElements for CosmicStack where - R: Renderer + ImportAll + ImportMem, + R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: 'static, + CosmicStackRenderElement: RenderElement, { type RenderElement = CosmicStackRenderElement; fn render_elements>( &self, renderer: &mut R, - mut location: Point, + location: Point, scale: Scale, alpha: f32, ) -> Vec { - let mut elements = AsRenderElements::::render_elements::>( - &self.0, renderer, location, scale, alpha, - ); - location.y += TAB_HEIGHT; + let stack_loc = location + + self + .0 + .with_program(|p| { + p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)] + .geometry() + .loc + }) + .to_physical_precise_round(scale); + let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32)); + + let mut elements = + AsRenderElements::::render_elements::>( + &self.0, + renderer.glow_renderer_mut(), + stack_loc, + scale, + alpha, + ); elements.extend(self.0.with_program(|p| { - let elements = AsRenderElements::::render_elements::>( + AsRenderElements::::render_elements::>( &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)], renderer, - location, + window_loc, scale, alpha, - ); - elements + ) })); elements.into_iter().map(C::from).collect() diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index 6b034837..fedaec1c 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -189,6 +189,19 @@ impl CosmicSurface { } } + pub fn try_force_undecorated(&self, enable: bool) { + match self { + CosmicSurface::Wayland(window) => window.toplevel().with_pending_state(|pending| { + pending.decoration_mode = if enable { + Some(DecorationMode::ServerSide) + } else { + None + }; + }), + _ => {} + } + } + pub fn is_resizing(&self, pending: bool) -> Option { match self { CosmicSurface::Wayland(window) => { diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 36ce7fe8..81518b28 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -284,6 +284,7 @@ impl Program for CosmicWindowInternal { &self, pixels: &mut tiny_skia::PixmapMut<'_>, damage: &[Rectangle], + _scale: f32, ) { if !self.window.is_activated(false) { let mask = self.mask.lock().unwrap(); @@ -755,12 +756,17 @@ where ) }); if has_ssd { + let ssd_loc = location + + self + .0 + .with_program(|p| p.window.geometry().loc) + .to_physical_precise_round(scale); elements.extend(AsRenderElements::::render_elements::< CosmicWindowRenderElement, >( &self.0, renderer.glow_renderer_mut(), - location, + ssd_loc, scale, alpha, )) diff --git a/src/shell/layout/floating/grabs/moving.rs b/src/shell/layout/floating/grabs/moving.rs index 42a83a81..d5f40656 100644 --- a/src/shell/layout/floating/grabs/moving.rs +++ b/src/shell/layout/floating/grabs/moving.rs @@ -3,7 +3,10 @@ use crate::{ backend::render::{element::AsGlowRenderer, IndicatorShader}, shell::{ - element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, + element::{ + stack::CosmicStackRenderElement, window::CosmicWindowRenderElement, CosmicMapped, + CosmicMappedRenderElement, + }, focus::target::{KeyboardFocusTarget, PointerFocusTarget}, CosmicSurface, }, @@ -45,6 +48,7 @@ impl MoveGrabState { ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, I: From>, { #[cfg(feature = "debug")] diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index e00d6fe7..a8d05921 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -15,7 +15,10 @@ use std::collections::HashMap; use crate::{ backend::render::{element::AsGlowRenderer, IndicatorShader}, shell::{ - element::{window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement}, + element::{ + stack::CosmicStackRenderElement, window::CosmicWindowRenderElement, CosmicMapped, + CosmicMappedRenderElement, + }, grabs::ResizeEdge, CosmicSurface, }, @@ -358,6 +361,7 @@ impl FloatingLayout { ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, { #[cfg(feature = "debug")] puffin::profile_function!(); diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 8e6279a7..ac741955 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -4,8 +4,8 @@ use crate::{ backend::render::{element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, GROUP_COLOR}, shell::{ element::{ - window::CosmicWindowRenderElement, CosmicMapped, CosmicMappedRenderElement, - CosmicStack, CosmicWindow, + stack::CosmicStackRenderElement, window::CosmicWindowRenderElement, CosmicMapped, + CosmicMappedRenderElement, CosmicStack, CosmicWindow, }, focus::{ target::{KeyboardFocusTarget, WindowGroup}, @@ -1668,6 +1668,7 @@ impl TilingLayout { ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, { #[cfg(feature = "debug")] puffin::profile_function!(); @@ -2044,6 +2045,7 @@ where ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, { if let Some(root) = reference_tree.root_node_id() { let geometries = geometries.unwrap_or_default(); @@ -2170,6 +2172,7 @@ where ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, { let focused = seat .and_then(|seat| TilingLayout::currently_focused_node(&target_tree, seat)) diff --git a/src/shell/workspace.rs b/src/shell/workspace.rs index e00504f0..d23edefa 100644 --- a/src/shell/workspace.rs +++ b/src/shell/workspace.rs @@ -47,7 +47,7 @@ use std::{collections::HashMap, time::Instant}; use tracing::warn; use super::{ - element::{window::CosmicWindowRenderElement, CosmicMapped}, + element::{stack::CosmicStackRenderElement, window::CosmicWindowRenderElement, CosmicMapped}, focus::{FocusStack, FocusStackMut}, grabs::{ResizeEdge, ResizeGrab}, CosmicMappedRenderElement, CosmicSurface, @@ -483,6 +483,7 @@ impl Workspace { ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { #[cfg(feature = "debug")] diff --git a/src/utils/iced.rs b/src/utils/iced.rs index 9698c759..4f41825f 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -101,8 +101,9 @@ pub trait Program { &self, pixels: &mut tiny_skia::PixmapMut<'_>, damage: &[Rectangle], + scale: f32, ) { - let _ = (pixels, damage); + let _ = (pixels, damage, scale); } } @@ -563,6 +564,7 @@ impl SpaceElement for IcedElement

{ ), ); } + internal.update(true); } } @@ -650,7 +652,10 @@ where }) .collect::>(); - state_ref.program().0.foreground(&mut pixels, &damage); + state_ref + .program() + .0 + .foreground(&mut pixels, &damage, scale.x as f32); Result::<_, ()>::Ok(damage) }) diff --git a/src/wayland/handlers/screencopy.rs b/src/wayland/handlers/screencopy.rs index cc920b65..08c62492 100644 --- a/src/wayland/handlers/screencopy.rs +++ b/src/wayland/handlers/screencopy.rs @@ -49,8 +49,8 @@ use crate::{ render_output, render_workspace, CursorMode, CLEAR_COLOR, }, shell::{ - element::window::CosmicWindowRenderElement, CosmicMappedRenderElement, CosmicSurface, - WorkspaceRenderElement, + element::{stack::CosmicStackRenderElement, window::CosmicWindowRenderElement}, + CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement, }, state::{BackendData, ClientState, Common, Data, State}, utils::prelude::OutputExt, @@ -672,6 +672,7 @@ pub fn render_output_to_buffer( CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { let cursor_mode = match session.cursor_mode() { @@ -805,6 +806,7 @@ pub fn render_workspace_to_buffer( CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, CosmicWindowRenderElement: RenderElement, + CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { let cursor_mode = match session.cursor_mode() { From 7e3a96eb53f07654b31d59d2acf40bd65f968f9a Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 8 Jun 2023 21:50:16 +0200 Subject: [PATCH 055/264] shell: refactor unnecessary bounds --- src/backend/render/mod.rs | 11 -- src/shell/element/mod.rs | 7 +- src/shell/element/stack.rs | 188 ++-------------------- src/shell/element/window.rs | 183 ++------------------- src/shell/layout/floating/grabs/moving.rs | 9 +- src/wayland/handlers/screencopy.rs | 9 +- 6 files changed, 27 insertions(+), 380 deletions(-) diff --git a/src/backend/render/mod.rs b/src/backend/render/mod.rs index 7931ad39..a530e4bf 100644 --- a/src/backend/render/mod.rs +++ b/src/backend/render/mod.rs @@ -11,7 +11,6 @@ use std::{ use crate::{ config::WorkspaceLayout, shell::{ - element::{stack::CosmicStackRenderElement, window::CosmicWindowRenderElement}, focus::target::WindowGroup, layout::{floating::SeatMoveGrabState, tiling::ANIMATION_DURATION}, CosmicMapped, CosmicMappedRenderElement, WorkspaceRenderElement, @@ -363,8 +362,6 @@ where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: Clone + 'static, CosmicMappedRenderElement: RenderElement, - CosmicWindowRenderElement: RenderElement, - CosmicStackRenderElement: RenderElement, E: From> + From>, { #[cfg(feature = "debug")] @@ -434,8 +431,6 @@ where ::TextureId: Clone + 'static, ::Error: From, CosmicMappedRenderElement: RenderElement, - CosmicWindowRenderElement: RenderElement, - CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { #[cfg(feature = "debug")] @@ -642,7 +637,6 @@ where ::TextureId: Clone + 'static, ::Error: From, CosmicMappedRenderElement: RenderElement, - CosmicWindowRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { let layer_map = layer_map_for_output(output); @@ -687,7 +681,6 @@ where ::TextureId: Clone + 'static, ::Error: From, CosmicMappedRenderElement: RenderElement, - CosmicWindowRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { let layer_map = layer_map_for_output(output); @@ -741,8 +734,6 @@ where ::Error: From, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, - CosmicWindowRenderElement: RenderElement, - CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, Source: Clone, { @@ -801,8 +792,6 @@ where ::Error: From, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, - CosmicWindowRenderElement: RenderElement, - CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, Source: Clone, { diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 39ba4c7c..38d42ce4 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -53,7 +53,6 @@ pub mod stack; pub use self::stack::CosmicStack; pub mod window; pub use self::window::CosmicWindow; -use self::{stack::CosmicStackRenderElement, window::CosmicWindowRenderElement}; #[cfg(feature = "debug")] use egui::plot::{Corner, Legend, Plot, PlotPoints, Polygon}; @@ -727,7 +726,7 @@ impl From for CosmicMapped { pub enum CosmicMappedRenderElement where - R: AsGlowRenderer + Renderer + ImportAll + ImportMem, + R: Renderer + ImportAll + ImportMem, ::TextureId: 'static, { Stack(self::stack::CosmicStackRenderElement), @@ -749,7 +748,7 @@ where impl Element for CosmicMappedRenderElement where - R: AsGlowRenderer + Renderer + ImportAll + ImportMem, + R: Renderer + ImportAll + ImportMem, ::TextureId: 'static, { fn id(&self) -> &smithay::backend::renderer::element::Id { @@ -1004,8 +1003,6 @@ where R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, - CosmicWindowRenderElement: RenderElement, - CosmicStackRenderElement: RenderElement, { type RenderElement = CosmicMappedRenderElement; fn render_elements>( diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index cc962992..b115e2b0 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -1,9 +1,5 @@ use crate::{ - backend::render::{ - element::{AsGlowFrame, AsGlowRenderer}, - GlMultiError, GlMultiFrame, GlMultiRenderer, - }, - shell::focus::FocusDirection, + shell::{focus::FocusDirection, Shell}, state::State, utils::iced::{IcedElement, Program}, utils::prelude::SeatExt, @@ -24,10 +20,8 @@ use smithay::{ renderer::{ element::{ memory::MemoryRenderBufferRenderElement, surface::WaylandSurfaceRenderElement, - AsRenderElements, Element, Id, RenderElement, + AsRenderElements, }, - glow::GlowRenderer, - utils::CommitCounter, ImportAll, ImportMem, Renderer, }, }, @@ -38,7 +32,9 @@ use smithay::{ Seat, }, output::Output, - utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, Transform}, + render_elements, + utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size}, + wayland::seat::WaylandFocus, }; use std::{ fmt, @@ -1057,169 +1053,16 @@ impl PointerTarget for CosmicStack { } } -pub enum CosmicStackRenderElement -where - R: ImportAll + ImportMem + AsGlowRenderer + Renderer, - ::TextureId: 'static, -{ - Header(MemoryRenderBufferRenderElement), - Window(WaylandSurfaceRenderElement), -} - -impl From> for CosmicStackRenderElement -where - R: ImportAll + ImportMem + AsGlowRenderer + Renderer, - ::TextureId: 'static, -{ - fn from(elem: WaylandSurfaceRenderElement) -> Self { - CosmicStackRenderElement::Window(elem) - } -} - -impl From> for CosmicStackRenderElement -where - R: ImportAll + ImportMem + AsGlowRenderer + Renderer, - ::TextureId: 'static, -{ - fn from(elem: MemoryRenderBufferRenderElement) -> Self { - CosmicStackRenderElement::Header(elem) - } -} - -impl Element for CosmicStackRenderElement -where - R: AsGlowRenderer + Renderer + ImportAll + ImportMem, - ::TextureId: 'static, -{ - fn id(&self) -> &Id { - match self { - CosmicStackRenderElement::Header(h) => h.id(), - CosmicStackRenderElement::Window(w) => w.id(), - } - } - - fn current_commit(&self) -> CommitCounter { - match self { - CosmicStackRenderElement::Header(h) => h.current_commit(), - CosmicStackRenderElement::Window(w) => w.current_commit(), - } - } - - fn src(&self) -> Rectangle { - match self { - CosmicStackRenderElement::Header(h) => h.src(), - CosmicStackRenderElement::Window(w) => w.src(), - } - } - - fn geometry(&self, scale: Scale) -> Rectangle { - match self { - CosmicStackRenderElement::Header(h) => h.geometry(scale), - CosmicStackRenderElement::Window(w) => w.geometry(scale), - } - } - - fn location(&self, scale: Scale) -> Point { - match self { - CosmicStackRenderElement::Header(h) => h.location(scale), - CosmicStackRenderElement::Window(w) => w.location(scale), - } - } - - fn transform(&self) -> Transform { - match self { - CosmicStackRenderElement::Header(h) => h.transform(), - CosmicStackRenderElement::Window(w) => w.transform(), - } - } - - fn damage_since( - &self, - scale: Scale, - commit: Option, - ) -> Vec> { - match self { - CosmicStackRenderElement::Header(h) => h.damage_since(scale, commit), - CosmicStackRenderElement::Window(w) => w.damage_since(scale, commit), - } - } - - fn opaque_regions(&self, scale: Scale) -> Vec> { - match self { - CosmicStackRenderElement::Header(h) => h.opaque_regions(scale), - CosmicStackRenderElement::Window(w) => w.opaque_regions(scale), - } - } - - fn alpha(&self) -> f32 { - match self { - CosmicStackRenderElement::Header(h) => h.alpha(), - CosmicStackRenderElement::Window(w) => w.alpha(), - } - } -} - -impl RenderElement for CosmicStackRenderElement { - fn draw<'a>( - &self, - frame: &mut ::Frame<'a>, - src: Rectangle, - dst: Rectangle, - damage: &[Rectangle], - ) -> Result<(), ::Error> { - match self { - CosmicStackRenderElement::Header(h) => h.draw(frame, src, dst, damage), - CosmicStackRenderElement::Window(w) => w.draw(frame, src, dst, damage), - } - } - - fn underlying_storage( - &self, - renderer: &mut GlowRenderer, - ) -> Option { - match self { - CosmicStackRenderElement::Header(h) => h.underlying_storage(renderer), - CosmicStackRenderElement::Window(w) => w.underlying_storage(renderer), - } - } -} - -impl<'a, 'b> RenderElement> - for CosmicStackRenderElement> -{ - fn draw<'c>( - &self, - frame: &mut GlMultiFrame<'a, 'b, 'c>, - src: Rectangle, - dst: Rectangle, - damage: &[Rectangle], - ) -> Result<(), GlMultiError> { - match self { - CosmicStackRenderElement::Header(h) => h - .draw(frame.glow_frame_mut(), src, dst, damage) - .map_err(|err| GlMultiError::Render(err)), - CosmicStackRenderElement::Window(w) => w.draw(frame, src, dst, damage), - } - } - - fn underlying_storage( - &self, - renderer: &mut GlMultiRenderer<'a, 'b>, - ) -> Option { - match self { - CosmicStackRenderElement::Header(h) => { - h.underlying_storage(renderer.glow_renderer_mut()) - } - CosmicStackRenderElement::Window(w) => w.underlying_storage(renderer), - } - } +render_elements! { + pub CosmicStackRenderElement where R: ImportAll + ImportMem; + Header = MemoryRenderBufferRenderElement, + Window = WaylandSurfaceRenderElement, } impl AsRenderElements for CosmicStack where - R: Renderer + ImportAll + ImportMem + AsGlowRenderer, + R: Renderer + ImportAll + ImportMem, ::TextureId: 'static, - CosmicStackRenderElement: RenderElement, { type RenderElement = CosmicStackRenderElement; fn render_elements>( @@ -1240,14 +1083,9 @@ where .to_physical_precise_round(scale); let window_loc = location + Point::from((0, (TAB_HEIGHT as f64 * scale.y) as i32)); - let mut elements = - AsRenderElements::::render_elements::>( - &self.0, - renderer.glow_renderer_mut(), - stack_loc, - scale, - alpha, - ); + let mut elements = AsRenderElements::::render_elements::>( + &self.0, renderer, stack_loc, scale, alpha, + ); elements.extend(self.0.with_program(|p| { AsRenderElements::::render_elements::>( diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 81518b28..79eaa116 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -1,8 +1,4 @@ use crate::{ - backend::render::{ - element::{AsGlowFrame, AsGlowRenderer}, - GlMultiError, GlMultiFrame, GlMultiRenderer, - }, shell::Shell, state::State, utils::{ @@ -20,10 +16,8 @@ use smithay::{ renderer::{ element::{ memory::MemoryRenderBufferRenderElement, surface::WaylandSurfaceRenderElement, - AsRenderElements, Element, Id, RenderElement, + AsRenderElements, }, - glow::GlowRenderer, - utils::CommitCounter, ImportAll, ImportMem, Renderer, }, }, @@ -34,9 +28,9 @@ use smithay::{ Seat, }, output::Output, + render_elements, utils::{ Buffer as BufferCoords, IsAlive, Logical, Physical, Point, Rectangle, Scale, Serial, Size, - Transform, }, wayland::seat::WaylandFocus, }; @@ -570,169 +564,16 @@ impl PointerTarget for CosmicWindow { } } -pub enum CosmicWindowRenderElement -where - R: ImportAll + ImportMem + AsGlowRenderer + Renderer, - ::TextureId: 'static, -{ - Header(MemoryRenderBufferRenderElement), - Window(WaylandSurfaceRenderElement), -} - -impl From> for CosmicWindowRenderElement -where - R: ImportAll + ImportMem + AsGlowRenderer + Renderer, - ::TextureId: 'static, -{ - fn from(elem: WaylandSurfaceRenderElement) -> Self { - CosmicWindowRenderElement::Window(elem) - } -} - -impl From> for CosmicWindowRenderElement -where - R: ImportAll + ImportMem + AsGlowRenderer + Renderer, - ::TextureId: 'static, -{ - fn from(elem: MemoryRenderBufferRenderElement) -> Self { - CosmicWindowRenderElement::Header(elem) - } -} - -impl Element for CosmicWindowRenderElement -where - R: AsGlowRenderer + Renderer + ImportAll + ImportMem, - ::TextureId: 'static, -{ - fn id(&self) -> &Id { - match self { - CosmicWindowRenderElement::Header(h) => h.id(), - CosmicWindowRenderElement::Window(w) => w.id(), - } - } - - fn current_commit(&self) -> CommitCounter { - match self { - CosmicWindowRenderElement::Header(h) => h.current_commit(), - CosmicWindowRenderElement::Window(w) => w.current_commit(), - } - } - - fn src(&self) -> Rectangle { - match self { - CosmicWindowRenderElement::Header(h) => h.src(), - CosmicWindowRenderElement::Window(w) => w.src(), - } - } - - fn geometry(&self, scale: Scale) -> Rectangle { - match self { - CosmicWindowRenderElement::Header(h) => h.geometry(scale), - CosmicWindowRenderElement::Window(w) => w.geometry(scale), - } - } - - fn location(&self, scale: Scale) -> Point { - match self { - CosmicWindowRenderElement::Header(h) => h.location(scale), - CosmicWindowRenderElement::Window(w) => w.location(scale), - } - } - - fn transform(&self) -> Transform { - match self { - CosmicWindowRenderElement::Header(h) => h.transform(), - CosmicWindowRenderElement::Window(w) => w.transform(), - } - } - - fn damage_since( - &self, - scale: Scale, - commit: Option, - ) -> Vec> { - match self { - CosmicWindowRenderElement::Header(h) => h.damage_since(scale, commit), - CosmicWindowRenderElement::Window(w) => w.damage_since(scale, commit), - } - } - - fn opaque_regions(&self, scale: Scale) -> Vec> { - match self { - CosmicWindowRenderElement::Header(h) => h.opaque_regions(scale), - CosmicWindowRenderElement::Window(w) => w.opaque_regions(scale), - } - } - - fn alpha(&self) -> f32 { - match self { - CosmicWindowRenderElement::Header(h) => h.alpha(), - CosmicWindowRenderElement::Window(w) => w.alpha(), - } - } -} - -impl RenderElement for CosmicWindowRenderElement { - fn draw<'a>( - &self, - frame: &mut ::Frame<'a>, - src: Rectangle, - dst: Rectangle, - damage: &[Rectangle], - ) -> Result<(), ::Error> { - match self { - CosmicWindowRenderElement::Header(h) => h.draw(frame, src, dst, damage), - CosmicWindowRenderElement::Window(w) => w.draw(frame, src, dst, damage), - } - } - - fn underlying_storage( - &self, - renderer: &mut GlowRenderer, - ) -> Option { - match self { - CosmicWindowRenderElement::Header(h) => h.underlying_storage(renderer), - CosmicWindowRenderElement::Window(w) => w.underlying_storage(renderer), - } - } -} - -impl<'a, 'b> RenderElement> - for CosmicWindowRenderElement> -{ - fn draw<'c>( - &self, - frame: &mut GlMultiFrame<'a, 'b, 'c>, - src: Rectangle, - dst: Rectangle, - damage: &[Rectangle], - ) -> Result<(), GlMultiError> { - match self { - CosmicWindowRenderElement::Header(h) => h - .draw(frame.glow_frame_mut(), src, dst, damage) - .map_err(|err| GlMultiError::Render(err)), - CosmicWindowRenderElement::Window(w) => w.draw(frame, src, dst, damage), - } - } - - fn underlying_storage( - &self, - renderer: &mut GlMultiRenderer<'a, 'b>, - ) -> Option { - match self { - CosmicWindowRenderElement::Header(h) => { - h.underlying_storage(renderer.glow_renderer_mut()) - } - CosmicWindowRenderElement::Window(w) => w.underlying_storage(renderer), - } - } +render_elements! { + pub CosmicWindowRenderElement where R: ImportAll + ImportMem; + Header = MemoryRenderBufferRenderElement, + Window = WaylandSurfaceRenderElement, } impl AsRenderElements for CosmicWindow where - R: Renderer + ImportAll + ImportMem + AsGlowRenderer, + R: Renderer + ImportAll + ImportMem, ::TextureId: 'static, - CosmicWindowRenderElement: RenderElement, { type RenderElement = CosmicWindowRenderElement; fn render_elements>( @@ -761,15 +602,9 @@ where .0 .with_program(|p| p.window.geometry().loc) .to_physical_precise_round(scale); - elements.extend(AsRenderElements::::render_elements::< + elements.extend(AsRenderElements::::render_elements::< CosmicWindowRenderElement, - >( - &self.0, - renderer.glow_renderer_mut(), - ssd_loc, - scale, - alpha, - )) + >(&self.0, renderer, ssd_loc, scale, alpha)) } elements.into_iter().map(C::from).collect() diff --git a/src/shell/layout/floating/grabs/moving.rs b/src/shell/layout/floating/grabs/moving.rs index d5f40656..a0e76164 100644 --- a/src/shell/layout/floating/grabs/moving.rs +++ b/src/shell/layout/floating/grabs/moving.rs @@ -3,12 +3,9 @@ use crate::{ backend::render::{element::AsGlowRenderer, IndicatorShader}, shell::{ - element::{ - stack::CosmicStackRenderElement, window::CosmicWindowRenderElement, CosmicMapped, - CosmicMappedRenderElement, - }, + element::CosmicMappedRenderElement, focus::target::{KeyboardFocusTarget, PointerFocusTarget}, - CosmicSurface, + CosmicMapped, CosmicSurface, }, utils::prelude::*, }; @@ -47,8 +44,6 @@ impl MoveGrabState { R: Renderer + ImportAll + ImportMem + AsGlowRenderer, ::TextureId: 'static, CosmicMappedRenderElement: RenderElement, - CosmicWindowRenderElement: RenderElement, - CosmicStackRenderElement: RenderElement, I: From>, { #[cfg(feature = "debug")] diff --git a/src/wayland/handlers/screencopy.rs b/src/wayland/handlers/screencopy.rs index 08c62492..b7c6ae66 100644 --- a/src/wayland/handlers/screencopy.rs +++ b/src/wayland/handlers/screencopy.rs @@ -48,10 +48,7 @@ use crate::{ element::{AsGlowRenderer, CosmicElement}, render_output, render_workspace, CursorMode, CLEAR_COLOR, }, - shell::{ - element::{stack::CosmicStackRenderElement, window::CosmicWindowRenderElement}, - CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement, - }, + shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement}, state::{BackendData, ClientState, Common, Data, State}, utils::prelude::OutputExt, wayland::protocols::{ @@ -671,8 +668,6 @@ pub fn render_output_to_buffer( ::Error: From, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, - CosmicWindowRenderElement: RenderElement, - CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { let cursor_mode = match session.cursor_mode() { @@ -805,8 +800,6 @@ pub fn render_workspace_to_buffer( ::Error: From, CosmicElement: RenderElement, CosmicMappedRenderElement: RenderElement, - CosmicWindowRenderElement: RenderElement, - CosmicStackRenderElement: RenderElement, WorkspaceRenderElement: RenderElement, { let cursor_mode = match session.cursor_mode() { From f00753071edee7acaae78ad8fb6fb7ada4905d25 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 8 Jun 2023 21:50:25 +0200 Subject: [PATCH 056/264] stacking: Wire up mouse input --- src/shell/element/stack.rs | 210 +++++++++++++++++++++++++------------ 1 file changed, 143 insertions(+), 67 deletions(-) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index b115e2b0..2b67f61f 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -10,6 +10,7 @@ use calloop::LoopHandle; use cosmic::{ iced::widget as iced_widget, iced_core::{alignment, Color, Length}, + iced_runtime::Command, iced_widget::rule::FillMode, theme, widget as cosmic_widget, Element as CosmicElement, }; @@ -67,8 +68,9 @@ pub struct CosmicStackInternal { activated: Arc, group_focused: Arc, previous_keyboard: Arc, - pointer_entered: Option>, + pointer_entered: Arc, previous_pointer: Arc, + last_seat: Arc, Serial)>>>, last_location: Arc, Serial, u32)>>>, geometry: Arc>>>, mask: Arc>>, @@ -76,23 +78,15 @@ pub struct CosmicStackInternal { impl CosmicStackInternal { pub fn swap_focus(&self, focus: Focus) -> Focus { - if let Some(pointer_entered) = self.pointer_entered.as_ref() { - unsafe { - std::mem::transmute::( - pointer_entered.swap(focus as u8, Ordering::SeqCst), - ) - } - } else { - Focus::Window + unsafe { + std::mem::transmute::( + self.pointer_entered.swap(focus as u8, Ordering::SeqCst), + ) } } pub fn current_focus(&self) -> Focus { - if let Some(pointer_entered) = self.pointer_entered.as_ref() { - unsafe { std::mem::transmute::(pointer_entered.load(Ordering::SeqCst)) } - } else { - Focus::Window - } + unsafe { std::mem::transmute::(self.pointer_entered.load(Ordering::SeqCst)) } } } @@ -127,8 +121,9 @@ impl CosmicStack { activated: Arc::new(AtomicBool::new(false)), group_focused: Arc::new(AtomicBool::new(false)), previous_keyboard: Arc::new(AtomicUsize::new(0)), - pointer_entered: None, + pointer_entered: Arc::new(AtomicU8::new(Focus::None as u8)), previous_pointer: Arc::new(AtomicUsize::new(0)), + last_seat: Arc::new(Mutex::new(None)), last_location: Arc::new(Mutex::new(None)), geometry: Arc::new(Mutex::new(None)), mask: Arc::new(Mutex::new(None)), @@ -190,9 +185,18 @@ impl CosmicStack { let result = self.0.with_program(|p| match direction { FocusDirection::Left => { if !p.group_focused.load(Ordering::SeqCst) { - p.active - .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |val| val.checked_sub(1)) - .is_ok() + if let Ok(old) = + p.active + .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |val| { + val.checked_sub(1) + }) + { + p.previous_keyboard.store(old, Ordering::SeqCst); + p.previous_pointer.store(old, Ordering::SeqCst); + true + } else { + false + } } else { false } @@ -200,15 +204,22 @@ impl CosmicStack { FocusDirection::Right => { if !p.group_focused.load(Ordering::SeqCst) { let max = p.windows.lock().unwrap().len(); - p.active - .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |val| { - if val < max - 1 { - Some(val + 1) - } else { - None - } - }) - .is_ok() + if let Ok(old) = + p.active + .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |val| { + if val < max - 1 { + Some(val + 1) + } else { + None + } + }) + { + p.previous_keyboard.store(old, Ordering::SeqCst); + p.previous_pointer.store(old, Ordering::SeqCst); + true + } else { + false + } } else { false } @@ -312,9 +323,13 @@ impl CosmicStack { if let Some(previous) = windows.get(previous) { KeyboardTarget::leave(previous, seat, data, serial); } - seat.get_keyboard().unwrap().with_pressed_keysyms(|syms| { - KeyboardTarget::enter(&windows[active], seat, data, syms, serial) - }) + KeyboardTarget::enter( + &windows[active], + seat, + data, + Vec::new(), /* TODO */ + serial, + ) } active }) @@ -367,8 +382,49 @@ impl CosmicStack { } } +#[derive(Debug, Clone, Copy)] +pub enum Message { + DragStart, + Activate(usize), + Close(usize), +} + impl Program for CosmicStackInternal { - type Message = (); + type Message = Message; + + fn update( + &mut self, + message: Self::Message, + loop_handle: &LoopHandle<'static, crate::state::Data>, + ) -> Command { + match message { + Message::DragStart => { + if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() { + if let Some(surface) = self.windows.lock().unwrap() + [self.active.load(Ordering::SeqCst)] + .wl_surface() + { + loop_handle.insert_idle(move |data| { + Shell::move_request(&mut data.state, &surface, &seat, serial); + }); + } + } + } + Message::Activate(idx) => { + if self.windows.lock().unwrap().get(idx).is_some() { + let old = self.active.swap(idx, Ordering::SeqCst); + self.previous_keyboard.store(old, Ordering::SeqCst); + self.previous_pointer.store(old, Ordering::SeqCst); + } + } + Message::Close(idx) => { + if let Some(val) = self.windows.lock().unwrap().get(idx) { + val.close() + } + } + } + Command::none() + } fn view(&self) -> CosmicElement<'_, Self::Message> { let windows = self.windows.lock().unwrap(); @@ -402,6 +458,8 @@ impl Program for CosmicStackInternal { .apply(iced_widget::container) .padding([4, 24]) .center_y() + .apply(iced_widget::mouse_area) + .on_press(Message::DragStart) .into()]; const ACTIVE_TAB_WIDTH: i32 = 140; @@ -471,7 +529,7 @@ impl Program for CosmicStackInternal { .into(), ); - let text_width = tab_width - if tab_width > 125 { 64 } else { 40 }; + let text_width = tab_width - if tab_width > 125 { 72 } else { 40 }; if text_width > 0 { tab_elements.push( cosmic_widget::text(title) @@ -494,6 +552,9 @@ impl Program for CosmicStackInternal { cosmic_widget::icon("window-close-symbolic", 16) .force_svg(true) .style(theme::Svg::Symbolic) + .apply(iced_widget::button) + .style(theme::Button::Text) + .on_press(Message::Close(i)) .apply(iced_widget::container) .height(Length::Fill) .center_y() @@ -534,6 +595,8 @@ impl Program for CosmicStackInternal { } else { theme::Container::Transparent }) + .apply(iced_widget::mouse_area) + .on_press(Message::Activate(i)) .into(), ) } @@ -596,7 +659,12 @@ impl Program for CosmicStackInternal { elements.push(tabs.into()); } - elements.push(iced_widget::horizontal_space(64).into()); + elements.push( + iced_widget::horizontal_space(64) + .apply(iced_widget::mouse_area) + .on_press(Message::DragStart) + .into(), + ); iced_widget::row(elements) .height(TAB_HEIGHT as u16) @@ -861,47 +929,52 @@ impl KeyboardTarget for CosmicStack { impl PointerTarget for CosmicStack { fn enter(&self, seat: &Seat, data: &mut State, event: &MotionEvent) { + let mut event = event.clone(); + event.location.y -= TAB_HEIGHT as f64; if self.0.with_program(|p| { - if let Some(sessions) = p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)] - .user_data() - .get::() - { + let active_window = &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)]; + if let Some(sessions) = active_window.user_data().get::() { for session in &*sessions.0.borrow() { session.cursor_enter(seat, InputType::Pointer) } } - if event.location.y < TAB_HEIGHT as f64 { - let focus = p.swap_focus(Focus::Header); + if (event.location.y - active_window.geometry().loc.y as f64) < 0. { + let previous = p.swap_focus(Focus::Header); + if previous == Focus::Window { + PointerTarget::leave(active_window, seat, data, event.serial, event.time); + } true } else { - let focus = p.swap_focus(Focus::Window); + p.swap_focus(Focus::Window); *p.last_location.lock().unwrap() = Some((event.location, event.serial, event.time)); let active = p.active.load(Ordering::SeqCst); p.previous_pointer.store(active, Ordering::SeqCst); - PointerTarget::enter( - &p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)], - seat, - data, - event, - ); + PointerTarget::enter(active_window, seat, data, &event); false } }) { - PointerTarget::enter(&self.0, seat, data, event) + event.location.y += TAB_HEIGHT as f64; + event.location -= self.0.with_program(|p| { + p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)] + .geometry() + .loc + .to_f64() + }); + PointerTarget::enter(&self.0, seat, data, &event) } } fn motion(&self, seat: &Seat, data: &mut State, event: &MotionEvent) { + let mut event = event.clone(); + event.location.y -= TAB_HEIGHT as f64; let active = self.pointer_leave_if_previous(seat, data, event.serial, event.time, event.location); if let Some((previous, next)) = self.0.with_program(|p| { - if let Some(sessions) = p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)] - .user_data() - .get::() - { + let active_window = &p.windows.lock().unwrap()[active]; + if let Some(sessions) = active_window.user_data().get::() { for session in &*sessions.0.borrow() { let buffer_loc = (event.location.x, event.location.y); // we always screencast windows at 1x1 scale if let Some((geo, hotspot)) = @@ -912,35 +985,34 @@ impl PointerTarget for CosmicStack { } } - if event.location.y < TAB_HEIGHT as f64 { + if (event.location.y - active_window.geometry().loc.y as f64) < 0. { let previous = p.swap_focus(Focus::Header); if previous == Focus::Window { - PointerTarget::leave( - &p.windows.lock().unwrap()[active], - seat, - data, - event.serial, - event.time, - ); + PointerTarget::leave(active_window, seat, data, event.serial, event.time); } Some((previous, Focus::Header)) } else { - let mut event = event.clone(); - event.location.y -= TAB_HEIGHT as f64; + *p.last_location.lock().unwrap() = Some((event.location, event.serial, event.time)); let previous = p.swap_focus(Focus::Window); if previous != Focus::Window { - PointerTarget::enter(&p.windows.lock().unwrap()[active], seat, data, &event); + PointerTarget::enter(active_window, seat, data, &event); } else { - PointerTarget::motion(&p.windows.lock().unwrap()[active], seat, data, &event); + PointerTarget::motion(active_window, seat, data, &event); } Some((previous, Focus::Window)) } }) { + event.location.y += TAB_HEIGHT as f64; + event.location -= self + .0 + .with_program(|p| p.windows.lock().unwrap()[active].geometry().loc.to_f64()); match (previous, next) { - (Focus::Header, Focus::Header) => PointerTarget::motion(&self.0, seat, data, event), - (_, Focus::Header) => PointerTarget::enter(&self.0, seat, data, event), + (Focus::Header, Focus::Header) => { + PointerTarget::motion(&self.0, seat, data, &event) + } + (_, Focus::Header) => PointerTarget::enter(&self.0, seat, data, &event), (Focus::Header, _) => { PointerTarget::leave(&self.0, seat, data, event.serial, event.time) } @@ -967,7 +1039,12 @@ impl PointerTarget for CosmicStack { } match self.0.with_program(|p| p.current_focus()) { - Focus::Header => PointerTarget::button(&self.0, seat, data, event), + Focus::Header => { + self.0.with_program(|p| { + *p.last_seat.lock().unwrap() = Some((seat.clone(), event.serial)); + }); + PointerTarget::button(&self.0, seat, data, event) + } Focus::Window => { if self.0.with_program(|p| { PointerTarget::button( @@ -1035,7 +1112,6 @@ impl PointerTarget for CosmicStack { p.swap_focus(Focus::None) }); - assert!(previous != Focus::None); match previous { Focus::Header => PointerTarget::leave(&self.0, seat, data, serial, time), From b400939dd976d44f45e780ad5bc14ce212b0f410 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 12 Jun 2023 17:23:54 +0200 Subject: [PATCH 057/264] shell: Introduce MoveResult to implement stacking --- src/input/mod.rs | 96 ++++++++++++++------------- src/shell/element/mod.rs | 25 ++++++- src/shell/layout/tiling/mod.rs | 117 +++++++++++++++++++++++++++++---- 3 files changed, 175 insertions(+), 63 deletions(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index 03e68dd3..89de945f 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -6,7 +6,7 @@ use crate::{ focus::{target::PointerFocusTarget, FocusDirection}, layout::{ floating::SeatMoveGrabState, - tiling::{Direction, FocusResult}, + tiling::{Direction, FocusResult, MoveResult}, }, OverviewMode, Workspace, }, // shell::grabs::SeatMoveGrabState @@ -1048,53 +1048,55 @@ impl State { return; // TODO, is this what we want? How do we indicate the switch? } - if let Some(_move_further) = - workspace.tiling_layer.move_current_node(direction, seat) - { - // TODO: Being able to move Groups (move_further should be KeyboardFocusTarget instead) - match (direction, self.common.config.static_conf.workspace_layout) { - (Direction::Left, WorkspaceLayout::Horizontal) - | (Direction::Up, WorkspaceLayout::Vertical) => self.handle_action( - Action::MoveToPreviousWorkspace, - seat, - serial, - time, - mods, - Some(direction), - ), - (Direction::Right, WorkspaceLayout::Horizontal) - | (Direction::Down, WorkspaceLayout::Vertical) => self.handle_action( - Action::MoveToNextWorkspace, - seat, - serial, - time, - mods, - Some(direction), - ), - (Direction::Left, WorkspaceLayout::Vertical) - | (Direction::Up, WorkspaceLayout::Horizontal) => self.handle_action( - Action::MoveToPreviousOutput, - seat, - serial, - time, - mods, - Some(direction), - ), - (Direction::Right, WorkspaceLayout::Vertical) - | (Direction::Down, WorkspaceLayout::Horizontal) => self.handle_action( - Action::MoveToNextOutput, - seat, - serial, - time, - mods, - Some(direction), - ), + match workspace.tiling_layer.move_current_node(direction, seat) { + MoveResult::MoveFurther(_move_further) => { + match (direction, self.common.config.static_conf.workspace_layout) { + (Direction::Left, WorkspaceLayout::Horizontal) + | (Direction::Up, WorkspaceLayout::Vertical) => self.handle_action( + Action::MoveToPreviousWorkspace, + seat, + serial, + time, + mods, + Some(direction), + ), + (Direction::Right, WorkspaceLayout::Horizontal) + | (Direction::Down, WorkspaceLayout::Vertical) => self.handle_action( + Action::MoveToNextWorkspace, + seat, + serial, + time, + mods, + Some(direction), + ), + (Direction::Left, WorkspaceLayout::Vertical) + | (Direction::Up, WorkspaceLayout::Horizontal) => self.handle_action( + Action::MoveToPreviousOutput, + seat, + serial, + time, + mods, + Some(direction), + ), + (Direction::Right, WorkspaceLayout::Vertical) + | (Direction::Down, WorkspaceLayout::Horizontal) => self.handle_action( + Action::MoveToNextOutput, + seat, + serial, + time, + mods, + Some(direction), + ), + } + } + MoveResult::ShiftFocus(shift) => { + Common::set_focus(self, Some(&shift), seat, None); } - } else { - let focus_stack = workspace.focus_stack.get(seat); - if let Some(focused_window) = focus_stack.last() { - if workspace.is_tiled(focused_window) { - self.common.shell.set_overview_mode(Some(mods)); + MoveResult::Done => { + if let Some(focused_window) = workspace.focus_stack.get(seat).last() { + if workspace.is_tiled(focused_window) { + self.common.shell.set_overview_mode(Some(mods)); + } } } } diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 38d42ce4..02aaf2c4 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -48,6 +48,7 @@ use std::{ }; pub mod surface; +use self::stack::MoveResult; pub use self::surface::CosmicSurface; pub mod stack; pub use self::stack::CosmicStack; @@ -61,7 +62,10 @@ use smithay::backend::renderer::{element::texture::TextureRenderElement, gles::G #[cfg(feature = "debug")] use tracing::debug; -use super::{focus::FocusDirection, layout::floating::ResizeState}; +use super::{ + focus::FocusDirection, + layout::{floating::ResizeState, tiling::Direction}, +}; space_elements! { #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -226,6 +230,14 @@ impl CosmicMapped { }) } + pub fn handle_move(&self, direction: Direction) -> MoveResult { + if let CosmicMappedInternal::Stack(stack) = &self.element { + stack.handle_move(direction) + } else { + MoveResult::Default + } + } + pub fn handle_focus(&self, direction: FocusDirection) -> bool { if let CosmicMappedInternal::Stack(stack) = &self.element { stack.handle_focus(direction) @@ -453,6 +465,13 @@ impl CosmicMapped { } } + pub fn stack_ref_mut(&mut self) -> Option<&mut CosmicStack> { + match &mut self.element { + CosmicMappedInternal::Stack(stack) => Some(stack), + _ => None, + } + } + pub fn convert_to_stack<'a>( &mut self, outputs: impl Iterator)>, @@ -460,7 +479,7 @@ impl CosmicMapped { match &self.element { CosmicMappedInternal::Window(window) => { let surface = window.surface(); - let activated = surface.is_activated(); + let activated = surface.is_activated(true); let handle = window.loop_handle(); let stack = CosmicStack::new(std::iter::once(surface), handle); @@ -494,7 +513,7 @@ impl CosmicMapped { for (output, overlap) in outputs { window.output_enter(output, overlap); } - window.set_activate(self.is_activated()); + window.set_activate(self.is_activated(true)); window.surface().send_configure(); window.refresh(); diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index ac741955..824fe7e7 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -4,8 +4,9 @@ use crate::{ backend::render::{element::AsGlowRenderer, BackdropShader, IndicatorShader, Key, GROUP_COLOR}, shell::{ element::{ - stack::CosmicStackRenderElement, window::CosmicWindowRenderElement, CosmicMapped, - CosmicMappedRenderElement, CosmicStack, CosmicWindow, + stack::{CosmicStackRenderElement, MoveResult as StackMoveResult}, + window::CosmicWindowRenderElement, + CosmicMapped, CosmicMappedRenderElement, CosmicStack, CosmicWindow, }, focus::{ target::{KeyboardFocusTarget, WindowGroup}, @@ -101,6 +102,13 @@ pub enum FocusResult { Some(KeyboardFocusTarget), } +#[derive(Debug, Clone, PartialEq)] +pub enum MoveResult { + Done, + MoveFurther(KeyboardFocusTarget), + ShiftFocus(KeyboardFocusTarget), +} + #[derive(Debug, Clone, Default)] struct TreeQueue { trees: VecDeque<(Tree, Option)>, @@ -160,6 +168,12 @@ impl Data { None => matches!(self, Data::Mapped { .. }), } } + fn is_stack(&self) -> bool { + match self { + Data::Mapped { mapped, .. } => mapped.is_stack(), + _ => false, + } + } fn orientation(&self) -> Orientation { match self { @@ -595,19 +609,57 @@ impl TilingLayout { &mut self, direction: Direction, seat: &Seat, - ) -> Option { + ) -> MoveResult { let output = seat.active_output(); let queue = self.queues.get_mut(&output).unwrap(); let mut tree = queue.trees.back().unwrap().0.copy_clone(); - let (node_id, data) = TilingLayout::currently_focused_node(&mut tree, seat)?; + let Some((node_id, data)) = TilingLayout::currently_focused_node(&mut tree, seat) else { + return MoveResult::Done + }; + + // stacks may handle movement internally + if let FocusedNodeData::Window(window) = data.clone() { + match window.handle_move(direction) { + StackMoveResult::Handled => return MoveResult::Done, + StackMoveResult::MoveOut(surface, loop_handle) => { + let mapped: CosmicMapped = CosmicWindow::new(surface, loop_handle).into(); + mapped.output_enter(&output, mapped.bbox()); + let orientation = match direction { + Direction::Left | Direction::Right => Orientation::Vertical, + Direction::Up | Direction::Down => Orientation::Horizontal, + }; + + let new_node = Node::new(Data::Mapped { + mapped: mapped.clone(), + last_geometry: Rectangle::from_loc_and_size((0, 0), (100, 100)), + }); + let new_id = tree.insert(new_node, InsertBehavior::AsRoot).unwrap(); + TilingLayout::new_group(&mut tree, &node_id, &new_id, orientation).unwrap(); + tree.make_nth_sibling( + &new_id, + match direction { + Direction::Left | Direction::Up => 0, + Direction::Right | Direction::Down => 1, + }, + ) + .unwrap(); + *mapped.tiling_node_id.lock().unwrap() = Some(new_id); + + let blocker = TilingLayout::update_positions(&output, &mut tree, self.gaps); + queue.push_tree(tree, blocker); + return MoveResult::ShiftFocus(mapped.into()); + } + StackMoveResult::Default => {} // continue normally + } + } let mut child_id = node_id.clone(); // Without a parent to start with, just return let Some(og_parent) = tree.get(&node_id).unwrap().parent().cloned() else { return match data { - FocusedNodeData::Window(window) => Some(window.into()), - FocusedNodeData::Group(focus_stack, alive) => Some(WindowGroup { + FocusedNodeData::Window(window) => MoveResult::MoveFurther(window.into()), + FocusedNodeData::Group(focus_stack, alive) => MoveResult::MoveFurther(WindowGroup { node: node_id, output: output.downgrade(), alive, @@ -670,7 +722,7 @@ impl TilingLayout { let blocker = TilingLayout::update_positions(&output, &mut tree, self.gaps); queue.push_tree(tree, blocker); - return None; + return MoveResult::Done; } // now if the orientation matches @@ -696,7 +748,7 @@ impl TilingLayout { let blocker = TilingLayout::update_positions(&output, &mut tree, self.gaps); queue.push_tree(tree, blocker); - return None; + return MoveResult::Done; } // we can maybe move inside the group, if we don't run out of elements @@ -722,7 +774,40 @@ impl TilingLayout { .nth(next_idx) .unwrap() .clone(); - if tree.get(&next_child_id).unwrap().data().is_group() && len == 2 { + + let result = if tree.get(&next_child_id).unwrap().data().is_stack() + && tree.get(&node_id).unwrap().data().is_mapped(None) + && !tree.get(&node_id).unwrap().data().is_stack() + { + let node = tree + .remove_node(node_id, RemoveBehavior::DropChildren) + .unwrap(); + + let stack_data = tree.get_mut(&next_child_id).unwrap().data_mut(); + let mut mapped = match stack_data { + Data::Mapped { mapped, .. } => mapped.clone(), + _ => unreachable!(), + }; + let stack = mapped.stack_ref_mut().unwrap(); + + let surface = match node.data() { + Data::Mapped { mapped, .. } => mapped.active_window(), + _ => unreachable!(), + }; + stack.add_window( + surface, + match direction { + Direction::Right => Some(0), + _ => None, + }, + ); + tree.get_mut(&og_parent) + .unwrap() + .data_mut() + .remove_window(og_idx); + + MoveResult::ShiftFocus(mapped.into()) + } else if tree.get(&next_child_id).unwrap().data().is_group() && len == 2 { // if it is a group, we want to move into the group tree.move_node(&node_id, MoveBehavior::ToParent(&next_child_id)) .unwrap(); @@ -783,6 +868,8 @@ impl TilingLayout { .unwrap() .data_mut() .remove_window(og_idx); + + MoveResult::Done } else if len == 2 && child_id == node_id { // if we are just us two in the group, lets swap tree.make_nth_sibling(&node_id, next_idx).unwrap(); @@ -791,6 +878,8 @@ impl TilingLayout { .unwrap() .data_mut() .swap_windows(idx, next_idx); + + MoveResult::Done } else { // else we make a new fork TilingLayout::new_group(&mut tree, &next_child_id, &node_id, orientation) @@ -808,11 +897,13 @@ impl TilingLayout { .unwrap() .data_mut() .remove_window(og_idx); - } + + MoveResult::Done + }; let blocker = TilingLayout::update_positions(&output, &mut tree, self.gaps); queue.push_tree(tree, blocker); - return None; + return result; } // We have reached the end of our parent group, try to move out even higher. @@ -821,8 +912,8 @@ impl TilingLayout { } match data { - FocusedNodeData::Window(window) => Some(window.into()), - FocusedNodeData::Group(focus_stack, alive) => Some( + FocusedNodeData::Window(window) => MoveResult::MoveFurther(window.into()), + FocusedNodeData::Group(focus_stack, alive) => MoveResult::MoveFurther( WindowGroup { node: node_id, output: output.downgrade(), From ab1c2df2154e039e01e80b06ebb97a8aaab24abf Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 12 Jun 2023 17:24:36 +0200 Subject: [PATCH 058/264] stack: Be able to handle moves internally --- src/shell/element/stack.rs | 58 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 2b67f61f..d80d3362 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -100,6 +100,12 @@ pub enum Focus { Window, } +pub enum MoveResult { + Handled, + MoveOut(CosmicSurface, LoopHandle<'static, crate::state::Data>), + Default, +} + impl CosmicStack { pub fn new>( windows: impl Iterator, @@ -133,12 +139,20 @@ impl CosmicStack { )) } - pub fn add_window(&self, window: impl Into) { + pub fn add_window(&self, window: impl Into, idx: Option) { let window = window.into(); window.try_force_undecorated(true); window.set_tiled(true); - self.0 - .with_program(|p| p.windows.lock().unwrap().push(window)); + self.0.with_program(|p| { + if let Some(idx) = idx { + p.windows.lock().unwrap().insert(idx, window); + p.active.store(idx, Ordering::SeqCst); + } else { + let mut windows = p.windows.lock().unwrap(); + windows.push(window); + p.active.store(windows.len() - 1, Ordering::SeqCst); + } + }); self.0.force_redraw() } @@ -256,6 +270,44 @@ impl CosmicStack { result } + pub fn handle_move(&self, direction: Direction) -> MoveResult { + let loop_handle = self.0.loop_handle(); + self.0.with_program(|p| { + if p.group_focused.load(Ordering::SeqCst) { + return MoveResult::Default; + } + + let active = p.active.load(Ordering::SeqCst); + let mut windows = p.windows.lock().unwrap(); + + let next = match direction { + Direction::Left => active.checked_sub(1), + Direction::Right => (active + 1 < windows.len()).then_some(active + 1), + Direction::Down | Direction::Up => None, + }; + + if let Some(val) = next { + let old = p.active.swap(val, Ordering::SeqCst); + windows.swap(old, val); + p.previous_keyboard.store(old, Ordering::SeqCst); + p.previous_pointer.store(old, Ordering::SeqCst); + MoveResult::Handled + } else { + if windows.len() == 1 { + return MoveResult::Default; + } + let window = windows.remove(active); + if active == windows.len() { + p.active.store(active - 1, Ordering::SeqCst); + } + window.try_force_undecorated(false); + window.set_tiled(false); + + MoveResult::MoveOut(window, loop_handle) + } + }) + } + pub fn active(&self) -> CosmicSurface { self.0 .with_program(|p| p.windows.lock().unwrap()[p.active.load(Ordering::SeqCst)].clone()) From 8e4fa6bfc60d2fd013571a9fee496b5949353160 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 12 Jun 2023 17:25:28 +0200 Subject: [PATCH 059/264] iced: Get rid of unused clip_mask logic --- src/shell/element/stack.rs | 67 +++++++++-------------------- src/shell/element/window.rs | 86 ++++++++++++++----------------------- src/utils/iced.rs | 7 +-- 3 files changed, 56 insertions(+), 104 deletions(-) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index d80d3362..dd8226b4 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -1,5 +1,5 @@ use crate::{ - shell::{focus::FocusDirection, Shell}, + shell::{focus::FocusDirection, layout::tiling::Direction, Shell}, state::State, utils::iced::{IcedElement, Program}, utils::prelude::SeatExt, @@ -9,7 +9,7 @@ use apply::Apply; use calloop::LoopHandle; use cosmic::{ iced::widget as iced_widget, - iced_core::{alignment, Color, Length}, + iced_core::{alignment, renderer::BorderRadius, Background, Color, Length}, iced_runtime::Command, iced_widget::rule::FillMode, theme, widget as cosmic_widget, Element as CosmicElement, @@ -723,52 +723,26 @@ impl Program for CosmicStackInternal { .width(width as u16) .apply(iced_widget::container) .center_y() + .style(if self.group_focused.load(Ordering::SeqCst) { + theme::Container::custom(|theme| iced_widget::container::Appearance { + text_color: Some(Color::from(theme.cosmic().background.on)), + background: Some(Background::Color(theme.cosmic().accent_color().into())), + border_radius: BorderRadius::from([8.0, 8.0, 0.0, 0.0]), + border_width: 0.0, + border_color: Color::TRANSPARENT, + }) + } else { + theme::Container::custom(|theme| iced_widget::container::Appearance { + text_color: Some(Color::from(theme.cosmic().background.on)), + background: Some(Background::Color(theme.cosmic().palette.neutral_3.into())), + border_radius: BorderRadius::from([8.0, 8.0, 0.0, 0.0]), + border_width: 0.0, + border_color: Color::TRANSPARENT, + }) + }) .into() } - fn clip_mask(&self, size: Size, scale: f32) -> tiny_skia::Mask { - let mut mask = self.mask.lock().unwrap(); - if mask.is_none() { - let mut new_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap(); - - let mut pb = tiny_skia::PathBuilder::new(); - let radius = 8. * scale; - let (w, h) = (size.w as f32, size.h as f32); - - pb.move_to(0., h); // lower-left - - // upper-left rounded corner - pb.line_to(0., radius); - pb.quad_to(0., 0., radius, 0.); - - // upper-right rounded corner - pb.line_to(w - radius, 0.); - pb.quad_to(w, 0., w, radius); - - pb.line_to(w, h); // lower-right - - let path = pb.finish().unwrap(); - new_mask.fill_path( - &path, - tiny_skia::FillRule::EvenOdd, - true, - Default::default(), - ); - - *mask = Some(new_mask); - } - - mask.clone().unwrap() - } - - fn background_color(&self) -> Color { - if self.group_focused.load(Ordering::SeqCst) { - Color::from(cosmic::theme::COSMIC_DARK.accent_color()) - } else { - Color::from(cosmic::theme::COSMIC_DARK.palette.neutral_3) - } - } - fn foreground( &self, pixels: &mut tiny_skia::PixmapMut<'_>, @@ -780,7 +754,6 @@ impl Program for CosmicStackInternal { (0, TAB_HEIGHT - scale as i32), (pixels.width() as i32, scale as i32), ); - let mask = self.mask.lock().unwrap(); let mut paint = tiny_skia::Paint::default(); let (b, g, r, a) = theme::COSMIC_DARK.accent_color().into_components(); @@ -798,7 +771,7 @@ impl Program for CosmicStackInternal { .unwrap(), &paint, Default::default(), - mask.as_ref(), + None, ) } } diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 79eaa116..253e9603 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -8,7 +8,7 @@ use crate::{ wayland::handlers::screencopy::ScreencopySessions, }; use calloop::LoopHandle; -use cosmic::{iced::Command, iced_core::Color}; +use cosmic::iced::Command; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; use smithay::{ backend::{ @@ -138,8 +138,8 @@ impl CosmicWindow { ); p.window .set_geometry(Rectangle::from_loc_and_size(loc, size)); + p.mask.lock().unwrap().take(); }); - self.0.with_program(|p| p.mask.lock().unwrap().take()); self.0.resize(Size::from((geo.size.w, SSD_HEIGHT))); } @@ -221,67 +221,45 @@ impl Program for CosmicWindowInternal { Command::none() } - fn clip_mask(&self, size: Size, scale: f32) -> tiny_skia::Mask { - let mut mask = self.mask.lock().unwrap(); - if mask.is_none() { - let mut new_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap(); - - let mut pb = tiny_skia::PathBuilder::new(); - let radius = 8. * scale; - let (w, h) = (size.w as f32, size.h as f32); - - pb.move_to(0., h); // lower-left + fn foreground( + &self, + pixels: &mut tiny_skia::PixmapMut<'_>, + damage: &[Rectangle], + scale: f32, + ) { + if !self.window.is_activated(false) { + let mut mask = self.mask.lock().unwrap(); + if mask.is_none() { + let (w, h) = (pixels.width(), pixels.height()); + let mut new_mask = tiny_skia::Mask::new(w, h).unwrap(); - // upper-left rounded corner - pb.line_to(0., radius); - pb.quad_to(0., 0., radius, 0.); + let mut pb = tiny_skia::PathBuilder::new(); + let radius = 8. * scale; + let (w, h) = (w as f32, h as f32); - // upper-right rounded corner - pb.line_to(w - radius, 0.); - pb.quad_to(w, 0., w, radius); + pb.move_to(0., h); // lower-left - pb.line_to(w, h); // lower-right + // upper-left rounded corner + pb.line_to(0., radius); + pb.quad_to(0., 0., radius, 0.); - let path = pb.finish().unwrap(); - new_mask.fill_path( - &path, - tiny_skia::FillRule::EvenOdd, - true, - Default::default(), - ); + // upper-right rounded corner + pb.line_to(w - radius, 0.); + pb.quad_to(w, 0., w, radius); - *mask = Some(new_mask); - } + pb.line_to(w, h); // lower-right - mask.clone().unwrap() - } + let path = pb.finish().unwrap(); + new_mask.fill_path( + &path, + tiny_skia::FillRule::EvenOdd, + true, + Default::default(), + ); - fn background_color(&self) -> Color { - if self.window.is_activated(false) { - Color { - r: 0.1176, - g: 0.1176, - b: 0.1176, - a: 1.0, - } - } else { - Color { - r: 0.153, - g: 0.153, - b: 0.153, - a: 1.0, + *mask = Some(new_mask); } - } - } - fn foreground( - &self, - pixels: &mut tiny_skia::PixmapMut<'_>, - damage: &[Rectangle], - _scale: f32, - ) { - if !self.window.is_activated(false) { - let mask = self.mask.lock().unwrap(); let mut paint = tiny_skia::Paint::default(); paint.set_color_rgba8(0, 0, 0, 102); diff --git a/src/utils/iced.rs b/src/utils/iced.rs index 4f41825f..fabf8663 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced.rs @@ -94,8 +94,9 @@ pub trait Program { } fn view(&self) -> Element<'_, Self::Message>; - fn clip_mask(&self, size: Size, scale: f32) -> tiny_skia::Mask; - fn background_color(&self) -> Color; + fn background_color(&self) -> Color { + Color::TRANSPARENT + } fn foreground( &self, @@ -600,7 +601,7 @@ where if size.w > 0 && size.h > 0 { let renderer = &mut internal_ref.renderer; let state_ref = &internal_ref.state; - let mut clip_mask = state_ref.program().0.clip_mask(size, scale.x as f32); + let mut clip_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap(); let overlay = internal_ref.debug.overlay(); buffer From 5dda8cfef59820fbb67126d8cd1557a89cc613f9 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 12 Jun 2023 17:25:43 +0200 Subject: [PATCH 060/264] surface: Restore previous decoration mode --- src/shell/element/surface.rs | 32 +++++++++++++++++++++++------- src/wayland/handlers/decoration.rs | 2 +- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index fedaec1c..d9d1df60 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -1,4 +1,4 @@ -use std::time::Duration; +use std::{cell::RefCell, time::Duration}; use smithay::{ backend::renderer::{ @@ -191,13 +191,31 @@ impl CosmicSurface { pub fn try_force_undecorated(&self, enable: bool) { match self { - CosmicSurface::Wayland(window) => window.toplevel().with_pending_state(|pending| { - pending.decoration_mode = if enable { - Some(DecorationMode::ServerSide) + CosmicSurface::Wayland(window) => { + if enable { + let previous_decoration_state = + window.toplevel().current_state().decoration_mode.clone(); + window + .user_data() + .insert_if_missing(|| RefCell::new(Option::::None)); + *window + .user_data() + .get::>>() + .unwrap() + .borrow_mut() = previous_decoration_state; + window.toplevel().with_pending_state(|pending| { + pending.decoration_mode = Some(DecorationMode::ServerSide); + }); } else { - None - }; - }), + let previous_mode = window + .user_data() + .get::>>() + .and_then(|m| m.borrow().clone()); + window.toplevel().with_pending_state(|pending| { + pending.decoration_mode = previous_mode; + }); + } + } _ => {} } } diff --git a/src/wayland/handlers/decoration.rs b/src/wayland/handlers/decoration.rs index 94c8f8be..d637dfa2 100644 --- a/src/wayland/handlers/decoration.rs +++ b/src/wayland/handlers/decoration.rs @@ -55,7 +55,7 @@ impl State { .find(|(window, _)| window.wl_surface().as_ref() == Some(surface)) { window.toplevel().with_pending_state(|state| { - state.decoration_mode = dbg!(Some(mode)); + state.decoration_mode = Some(mode); }); window.toplevel().send_configure(); } From be95fb90708bc7016bbf3dc28e5bfa68a77153a6 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 12 Jun 2023 17:25:54 +0200 Subject: [PATCH 061/264] tiling: Allow direction to be reversed --- src/shell/layout/tiling/mod.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 824fe7e7..8e37a8ac 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -95,6 +95,18 @@ pub enum Direction { Down, } +impl std::ops::Not for Direction { + type Output = Self; + fn not(self) -> Self::Output { + match self { + Direction::Left => Direction::Right, + Direction::Right => Direction::Left, + Direction::Up => Direction::Down, + Direction::Down => Direction::Up, + } + } +} + #[derive(Debug, Clone, PartialEq)] pub enum FocusResult { None, From 1dd0c3ecb72dbcdbb8979b19f000380fec53817b Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 12 Jun 2023 17:43:11 +0200 Subject: [PATCH 062/264] stack: Fix initial geometry of moved out windows --- src/shell/element/window.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 253e9603..27e5849d 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -100,8 +100,8 @@ impl CosmicWindowInternal { unsafe { std::mem::transmute::(self.pointer_entered.load(Ordering::SeqCst)) } } - pub fn has_ssd(&self) -> bool { - !self.window.is_decorated(false) + pub fn has_ssd(&self, pending: bool) -> bool { + !self.window.is_decorated(pending) } } @@ -130,11 +130,11 @@ impl CosmicWindow { self.0.with_program(|p| { let loc = ( geo.loc.x, - geo.loc.y + if p.has_ssd() { SSD_HEIGHT } else { 0 }, + geo.loc.y + if p.has_ssd(true) { SSD_HEIGHT } else { 0 }, ); let size = ( geo.size.w, - std::cmp::max(geo.size.h - if p.has_ssd() { SSD_HEIGHT } else { 0 }, 0), + std::cmp::max(geo.size.h - if p.has_ssd(true) { SSD_HEIGHT } else { 0 }, 0), ); p.window .set_geometry(Rectangle::from_loc_and_size(loc, size)); @@ -152,7 +152,7 @@ impl CosmicWindow { } pub fn offset(&self) -> Point { - let has_ssd = self.0.with_program(|p| p.has_ssd()); + let has_ssd = self.0.with_program(|p| p.has_ssd(false)); if has_ssd { Point::from((0, SSD_HEIGHT)) } else { @@ -300,7 +300,7 @@ impl SpaceElement for CosmicWindow { fn bbox(&self) -> Rectangle { self.0.with_program(|p| { let mut bbox = SpaceElement::bbox(&p.window); - if p.has_ssd() { + if p.has_ssd(false) { bbox.size.h += SSD_HEIGHT; } bbox @@ -312,7 +312,7 @@ impl SpaceElement for CosmicWindow { return false; } self.0.with_program(|p| { - if p.has_ssd() { + if p.has_ssd(false) { if point.y < SSD_HEIGHT as f64 { return true; } else { @@ -341,7 +341,7 @@ impl SpaceElement for CosmicWindow { fn geometry(&self) -> Rectangle { self.0.with_program(|p| { let mut geo = SpaceElement::geometry(&p.window); - if p.has_ssd() { + if p.has_ssd(false) { geo.size.h += SSD_HEIGHT; } geo @@ -416,7 +416,7 @@ impl PointerTarget for CosmicWindow { } } - if p.has_ssd() { + if p.has_ssd(false) { if event.location.y < SSD_HEIGHT as f64 { let focus = p.swap_focus(Focus::Header); assert_eq!(focus, Focus::None); @@ -452,7 +452,7 @@ impl PointerTarget for CosmicWindow { } } - if p.has_ssd() { + if p.has_ssd(false) { if event.location.y < SSD_HEIGHT as f64 { let previous = p.swap_focus(Focus::Header); if previous == Focus::Window { @@ -491,7 +491,7 @@ impl PointerTarget for CosmicWindow { fn relative_motion(&self, seat: &Seat, data: &mut State, event: &RelativeMotionEvent) { self.0.with_program(|p| { - if !p.has_ssd() || p.current_focus() == Focus::Window { + if !p.has_ssd(false) || p.current_focus() == Focus::Window { PointerTarget::relative_motion(&p.window, seat, data, event) } }) @@ -561,7 +561,7 @@ where scale: Scale, alpha: f32, ) -> Vec { - let has_ssd = self.0.with_program(|p| p.has_ssd()); + let has_ssd = self.0.with_program(|p| p.has_ssd(false)); let window_loc = if has_ssd { location + Point::from((0, (SSD_HEIGHT as f64 * scale.y) as i32)) From f5f58b0663b1724ee5d74619a45596cc0474121d Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 12 Jun 2023 17:43:24 +0200 Subject: [PATCH 063/264] tiling: Fix too eager moving into stack --- src/shell/layout/tiling/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 8e37a8ac..48f3a1b5 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -790,6 +790,7 @@ impl TilingLayout { let result = if tree.get(&next_child_id).unwrap().data().is_stack() && tree.get(&node_id).unwrap().data().is_mapped(None) && !tree.get(&node_id).unwrap().data().is_stack() + && len == 2 { let node = tree .remove_node(node_id, RemoveBehavior::DropChildren) From 73d7f3779f3c8f71922394efb2d6af534438bddc Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 13 Jun 2023 18:32:04 +0200 Subject: [PATCH 064/264] stack: Handle scrolling properly --- src/shell/element/stack.rs | 209 ++++++++++++++++++++++++++++++------ src/shell/element/window.rs | 8 +- 2 files changed, 179 insertions(+), 38 deletions(-) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index dd8226b4..87b8d5b8 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -1,20 +1,25 @@ +use super::CosmicSurface; use crate::{ shell::{focus::FocusDirection, layout::tiling::Direction, Shell}, state::State, - utils::iced::{IcedElement, Program}, + utils::iced::{tab_text::tab_text, IcedElement, Program}, utils::prelude::SeatExt, wayland::handlers::screencopy::ScreencopySessions, }; use apply::Apply; use calloop::LoopHandle; use cosmic::{ - iced::widget as iced_widget, - iced_core::{alignment, renderer::BorderRadius, Background, Color, Length}, + iced::{id::Id, widget as iced_widget}, + iced_core::{alignment, renderer::BorderRadius, Background, Color, Length, Size as IcedSize}, iced_runtime::Command, - iced_widget::rule::FillMode, + iced_widget::{ + rule::FillMode, + scrollable::{AbsoluteOffset, Viewport}, + }, theme, widget as cosmic_widget, Element as CosmicElement, }; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; +use once_cell::sync::Lazy; use smithay::{ backend::{ input::KeyState, @@ -46,18 +51,16 @@ use std::{ }, }; -use super::CosmicSurface; +static SCROLLABLE_ID: Lazy = Lazy::new(|| Id::new("scrollable")); #[derive(Clone, PartialEq, Eq, Hash)] pub struct CosmicStack(IcedElement); impl fmt::Debug for CosmicStack { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.with_program(|stack| { - f.debug_struct("CosmicStack") - .field("internal", stack) - .finish_non_exhaustive() - }) + f.debug_struct("CosmicStack") + .field("internal", &self.0) + .finish_non_exhaustive() } } @@ -74,6 +77,7 @@ pub struct CosmicStackInternal { last_location: Arc, Serial, u32)>>>, geometry: Arc>>>, mask: Arc>>, + scrollable_offset: Arc>>, } impl CosmicStackInternal { @@ -88,6 +92,8 @@ impl CosmicStackInternal { pub fn current_focus(&self) -> Focus { unsafe { std::mem::transmute::(self.pointer_entered.load(Ordering::SeqCst)) } } + + //pub fn offsets_for_tabs(&self) -> Vec< } const TAB_HEIGHT: i32 = 24; @@ -133,6 +139,7 @@ impl CosmicStack { last_location: Arc::new(Mutex::new(None)), geometry: Arc::new(Mutex::new(None)), mask: Arc::new(Mutex::new(None)), + scrollable_offset: Arc::new(Mutex::new(None)), }, (width, TAB_HEIGHT), handle, @@ -437,8 +444,11 @@ impl CosmicStack { #[derive(Debug, Clone, Copy)] pub enum Message { DragStart, - Activate(usize), + Activate(usize, Option<(f32, f32, f32)>), Close(usize), + ScrollForward(IcedSize), + ScrollBack, + Scrolled(Viewport), } impl Program for CosmicStackInternal { @@ -462,18 +472,83 @@ impl Program for CosmicStackInternal { } } } - Message::Activate(idx) => { + Message::Activate(idx, offsets) => { if self.windows.lock().unwrap().get(idx).is_some() { let old = self.active.swap(idx, Ordering::SeqCst); self.previous_keyboard.store(old, Ordering::SeqCst); self.previous_pointer.store(old, Ordering::SeqCst); } + if let Some((left_offset, right_offset, scroll_width)) = offsets { + let current_offset = self + .scrollable_offset + .lock() + .unwrap() + .unwrap_or(AbsoluteOffset::default()); + let current_start = current_offset.x; + let current_end = current_start + scroll_width; + assert!((right_offset - left_offset) <= (current_end - current_start)); + if (left_offset - current_start).is_sign_negative() + || (current_end - right_offset).is_sign_negative() + { + if (left_offset - current_start).abs() < (right_offset - current_end).abs() + { + let offset = AbsoluteOffset { + x: left_offset, + y: current_offset.y, + }; + *self.scrollable_offset.lock().unwrap() = Some(offset); + return iced_widget::scrollable::scroll_to::( + SCROLLABLE_ID.clone(), + offset, + ); + } else { + let offset = AbsoluteOffset { + x: right_offset - scroll_width, + y: current_offset.y, + }; + *self.scrollable_offset.lock().unwrap() = Some(offset); + return iced_widget::scrollable::scroll_to::( + SCROLLABLE_ID.clone(), + offset, + ); + } + } + } } Message::Close(idx) => { if let Some(val) = self.windows.lock().unwrap().get(idx) { val.close() } } + Message::Scrolled(viewport) => { + *self.scrollable_offset.lock().unwrap() = Some(viewport.absolute_offset()); + } + Message::ScrollForward(bounds) => { + let mut offset = self + .scrollable_offset + .lock() + .unwrap() + .unwrap_or(AbsoluteOffset::default()); + offset.x = (offset.x + 10.).min(bounds.width); + *self.scrollable_offset.lock().unwrap() = Some(offset); + return iced_widget::scrollable::scroll_to::( + SCROLLABLE_ID.clone(), + offset, + ); + } + Message::ScrollBack => { + let mut offset = self + .scrollable_offset + .lock() + .unwrap() + .unwrap_or(AbsoluteOffset::default()); + offset.x = (offset.x - 10.).max(0.0); + *self.scrollable_offset.lock().unwrap() = Some(offset); + return iced_widget::scrollable::scroll_to::( + SCROLLABLE_ID.clone(), + offset, + ); + } } Command::none() } @@ -489,7 +564,7 @@ impl Program for CosmicStackInternal { else { return iced_widget::row(Vec::new()).into(); }; - let tab_region = width - 128 - 8; // 64 left, 64 right + last rule with padding + let tab_region = width - 128 - 4; // 64 left, 64 right + last rule let active = self.active.load(Ordering::SeqCst); let activated = self.activated.load(Ordering::SeqCst); let group_focused = self.group_focused.load(Ordering::SeqCst); @@ -515,7 +590,7 @@ impl Program for CosmicStackInternal { .into()]; const ACTIVE_TAB_WIDTH: i32 = 140; - const MIN_TAB_WIDTH: i32 = 36; + const MIN_TAB_WIDTH: i32 = 38; let tab_width = if windows.len() == 1 { tab_region } else { @@ -527,8 +602,11 @@ impl Program for CosmicStackInternal { } }; let scrolling = tab_width < MIN_TAB_WIDTH; + let full_width = ACTIVE_TAB_WIDTH + (windows.len() as i32 - 1) * MIN_TAB_WIDTH; + let scroll_region = tab_region - 40; let mut tabs = Vec::new(); + let mut offset = 0; for (i, window) in windows.iter().enumerate() { let mut tab_elements = Vec::new(); @@ -593,6 +671,7 @@ impl Program for CosmicStackInternal { }) .horizontal_alignment(alignment::Horizontal::Left) .vertical_alignment(alignment::Vertical::Center) + .apply(tab_text) .height(Length::Fill) .width(text_width as u16) .into(), @@ -648,9 +727,18 @@ impl Program for CosmicStackInternal { theme::Container::Transparent }) .apply(iced_widget::mouse_area) - .on_press(Message::Activate(i)) + .on_press(Message::Activate( + i, + scrolling.then_some(( + offset as f32, + (offset + tab_width + 4) as f32, + scroll_region as f32, + )), + )) .into(), - ) + ); + + offset += tab_width; } let last_was_active = active == windows.len() - 1; @@ -686,29 +774,84 @@ impl Program for CosmicStackInternal { .into(), ); - let tabs = - iced_widget::row(tabs) - .apply(iced_widget::container) - .style(theme::Container::custom(|theme| { - iced_widget::container::Appearance { - text_color: None, - background: Some(cosmic::iced::Background::Color(Color::from( - theme.cosmic().palette.neutral_3, - ))), - border_radius: 0.0.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, - } - })); + let tabs = iced_widget::row(tabs) + .apply(iced_widget::container) + .style(theme::Container::custom(|theme| { + iced_widget::container::Appearance { + text_color: None, + background: Some(cosmic::iced::Background::Color(Color::from( + theme.cosmic().palette.neutral_3, + ))), + border_radius: 0.0.into(), + border_width: 0.0, + border_color: Color::TRANSPARENT, + } + })) + .height((TAB_HEIGHT - 1) as u16); if scrolling { + elements.push( + iced_widget::vertical_rule(4) + .style(theme::Rule::custom(|theme| iced_widget::rule::Appearance { + color: theme.cosmic().palette.neutral_5.into(), + width: 4, + radius: 8., + fill_mode: FillMode::Padded(4), + })) + .into(), + ); + elements.push( + cosmic_widget::icon("go-previous-symbolic", 16) + .force_svg(true) + .style(theme::Svg::Symbolic) + .apply(iced_widget::button) + .style(theme::Button::Text) + .on_press(Message::ScrollBack) + .apply(iced_widget::container) + .height(Length::Fill) + .center_y() + .into(), + ); elements.push( iced_widget::Scrollable::new(tabs) + .horizontal_scroll( + iced_widget::scrollable::Properties::new() + .margin(0.0) + .scroller_width(1.0) + .width(1.0), + ) .height(Length::Fill) - .width(tab_region as u16) + .width(Length::Fill) + .id(SCROLLABLE_ID.clone()) + .on_scroll(Message::Scrolled) .into(), - ) + ); + elements.push( + cosmic_widget::icon("go-next-symbolic", 16) + .force_svg(true) + .style(theme::Svg::Symbolic) + .apply(iced_widget::button) + .style(theme::Button::Text) + .on_press(Message::ScrollForward(IcedSize { + width: full_width as f32, + height: TAB_HEIGHT as f32, + })) + .apply(iced_widget::container) + .height(Length::Fill) + .center_y() + .into(), + ); + elements.push( + iced_widget::vertical_rule(4) + .style(theme::Rule::custom(|theme| iced_widget::rule::Appearance { + color: theme.cosmic().palette.neutral_5.into(), + width: 4, + radius: 8., + fill_mode: FillMode::Padded(4), + })) + .into(), + ); } else { - elements.push(tabs.into()); + elements.push(tabs.width(tab_region as u16).into()); } elements.push( diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 27e5849d..930079f7 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -50,11 +50,9 @@ pub struct CosmicWindow(IcedElement); impl fmt::Debug for CosmicWindow { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.with_program(|window| { - f.debug_struct("CosmicWindow") - .field("internal", window) - .finish_non_exhaustive() - }) + f.debug_struct("CosmicWindow") + .field("internal", &self.0) + .finish_non_exhaustive() } } From d07a4de80539182ee3849655fcbf28c5cc52379a Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 13 Jun 2023 18:32:38 +0200 Subject: [PATCH 065/264] iced: Add tab_text helper widget --- src/utils/{iced.rs => iced/mod.rs} | 6 +- src/utils/iced/tab_text.rs | 126 +++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 3 deletions(-) rename src/utils/{iced.rs => iced/mod.rs} (99%) create mode 100644 src/utils/iced/tab_text.rs diff --git a/src/utils/iced.rs b/src/utils/iced/mod.rs similarity index 99% rename from src/utils/iced.rs rename to src/utils/iced/mod.rs index fabf8663..16882109 100644 --- a/src/utils/iced.rs +++ b/src/utils/iced/mod.rs @@ -28,6 +28,8 @@ use iced_tiny_skia::{ }; pub type Element<'a, Message> = cosmic::iced::Element<'a, Message, IcedRenderer>; +pub mod tab_text; + use ordered_float::OrderedFloat; use smithay::{ backend::{ @@ -284,10 +286,8 @@ impl IcedElementInternal

{ &mut NullClipboard, &mut self.debug, ) - .1 - .map(|command| command.actions()); + .1; - let actions = actions.unwrap_or_default(); actions .into_iter() .filter_map(|action| { diff --git a/src/utils/iced/tab_text.rs b/src/utils/iced/tab_text.rs new file mode 100644 index 00000000..da31b59e --- /dev/null +++ b/src/utils/iced/tab_text.rs @@ -0,0 +1,126 @@ +use cosmic::{ + iced::Element, + iced_core::{ + layout::{Layout, Limits, Node}, + renderer, + widget::{Tree, Widget}, + Length, Point, Rectangle, Size, + }, + iced_widget::text::StyleSheet as TextStyleSheet, +}; + +pub struct TabText<'a, Message, Renderer> +where + Renderer: cosmic::iced_core::Renderer, + Renderer::Theme: TextStyleSheet, +{ + text: Element<'a, Message, Renderer>, + height: Length, + width: Length, +} + +pub fn tab_text<'a, Message, Renderer>( + text: impl Into>, +) -> TabText<'a, Message, Renderer> +where + Renderer: cosmic::iced_core::Renderer, + Renderer::Theme: TextStyleSheet, +{ + TabText::new(text) +} + +impl<'a, Message, Renderer> TabText<'a, Message, Renderer> +where + Renderer: cosmic::iced_core::Renderer, + Renderer::Theme: TextStyleSheet, +{ + pub fn new(text: impl Into>) -> Self { + TabText { + width: Length::Shrink, + height: Length::Shrink, + text: text.into(), + } + } + + pub fn width(mut self, width: impl Into) -> Self { + let width = width.into(); + self.width = width; + self + } + + pub fn height(mut self, height: impl Into) -> Self { + let height = height.into(); + self.height = height; + self + } +} + +impl<'a, Message, Renderer> Widget for TabText<'a, Message, Renderer> +where + Renderer: cosmic::iced_core::Renderer, + Renderer::Theme: TextStyleSheet, +{ + fn width(&self) -> Length { + self.width + } + fn height(&self) -> Length { + self.height + } + + fn children(&self) -> Vec { + vec![Tree::new(&self.text)] + } + + fn diff(&mut self, tree: &mut Tree) { + tree.diff_children(std::slice::from_mut(&mut self.text)) + } + + fn layout(&self, renderer: &Renderer, limits: &Limits) -> Node { + let limits = limits.width(self.width).height(self.height); + let child_limits = Limits::new( + Size::new(limits.min().width, limits.min().height), + Size::new(limits.max().width * 2., limits.max().height), + ); + let content = self.text.as_widget().layout(renderer, &child_limits); + let size = limits.resolve(content.size()); + + Node::with_children(size, vec![content]) + } + + fn draw( + &self, + tree: &Tree, + renderer: &mut Renderer, + theme: &Renderer::Theme, + style: &renderer::Style, + layout: Layout<'_>, + cursor_position: Point, + _viewport: &Rectangle, + ) { + let bounds = layout.bounds(); + let content_layout = layout.children().next().unwrap(); + + renderer.with_layer(bounds, |renderer| { + self.text.as_widget().draw( + &tree.children[0], + renderer, + theme, + style, + content_layout, + cursor_position, + &bounds, + ); + }); + } +} + +impl<'a, Message, Renderer> Into> for TabText<'a, Message, Renderer> +where + Renderer: cosmic::iced_core::Renderer + 'a, + Renderer::Theme: TextStyleSheet, + Message: 'a, +{ + fn into(self) -> Element<'a, Message, Renderer> { + Element::new(self) + } +} From fb7768aee12ac11d9203835862ef8a22ab7cff79 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 13 Jun 2023 18:33:19 +0200 Subject: [PATCH 066/264] tiling: Spawn new windows inside focused stacks --- src/shell/layout/tiling/mod.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 48f3a1b5..1c07ba03 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -466,7 +466,16 @@ impl TilingLayout { let last_active = focus_stack .and_then(|focus_stack| TilingLayout::last_active_window(&mut tree, focus_stack)); - if let Some((ref node_id, _last_active_window)) = last_active { + if let Some((ref node_id, mut last_active_window)) = last_active { + if window.is_window() && last_active_window.is_stack() { + let surface = window.active_window(); + last_active_window + .stack_ref_mut() + .unwrap() + .add_window(surface, None); + return; + } + let orientation = { let window_size = tree.get(node_id).unwrap().data().geometry().size; if window_size.w > window_size.h { From b7a9a318c34fa7472b274b6dfbabb295fa9d5d01 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 13 Jun 2023 18:43:29 +0200 Subject: [PATCH 067/264] deps: Temporarily use iced-branch --- Cargo.lock | 40 ++++++++++++++++++++++++++++------------ Cargo.toml | 16 ++++++++++++++++ 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a634231c..2745462a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -493,6 +493,7 @@ dependencies = [ "libcosmic", "libsystemd", "log-panics", + "once_cell", "ordered-float", "png", "puffin 0.14.3", @@ -1632,7 +1633,7 @@ dependencies = [ [[package]] name = "iced" version = "0.9.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" dependencies = [ "iced_core", "iced_futures", @@ -1645,7 +1646,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.9.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" dependencies = [ "bitflags 1.3.2", "instant", @@ -1658,7 +1659,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.6.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" dependencies = [ "futures", "iced_core", @@ -1671,7 +1672,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.8.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -1688,7 +1689,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -1700,7 +1701,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" dependencies = [ "iced_core", "iced_futures", @@ -1710,7 +1711,7 @@ dependencies = [ [[package]] name = "iced_style" version = "0.8.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" dependencies = [ "iced_core", "once_cell", @@ -1720,7 +1721,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" dependencies = [ "bytemuck", "cosmic-text", @@ -1738,7 +1739,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.10.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -1760,7 +1761,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" dependencies = [ "iced_renderer", "iced_runtime", @@ -2593,9 +2594,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.2" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "option-ext" @@ -4977,3 +4978,18 @@ checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" dependencies = [ "simd-adler32", ] + +[[patch.unused]] +name = "iced_accessibility" +version = "0.1.0" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" + +[[patch.unused]] +name = "iced_sctk" +version = "0.1.0" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" + +[[patch.unused]] +name = "iced_winit" +version = "0.9.1" +source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" diff --git a/Cargo.toml b/Cargo.toml index 167b854a..d99da2e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ tracing = { version = "0.1.37", features = ["max_level_debug", "release_max_leve puffin = { version = "0.14.3", optional = true } puffin_egui = { version = "0.21.0", optional = true } cosmic-time = { git = "https://github.com/pop-os/cosmic-time", rev = "35dd0b8", default-features = false, features = ["libcosmic"] } +once_cell = "1.18.0" [dependencies.id_tree] git = "https://github.com/Drakulix/id-tree.git" @@ -77,3 +78,18 @@ lto = "fat" [patch."https://github.com/Smithay/smithay.git"] smithay = { git = "https://github.com/smithay//smithay", rev = "43ce6b4372" } + +[patch."https://github.com/pop-os/libcosmic.git"] +iced = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_accessibility = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_core = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_futures = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_graphics = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_renderer = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_runtime = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_sctk = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_style = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_tiny_skia = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_wgpu = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_widget = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } +iced_winit = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } From c9114fe54b0fe1782f14bac802a25677b7f4d164 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 13 Jun 2023 18:44:01 +0200 Subject: [PATCH 068/264] config: Add stacking shortcut --- config.ron | 1 + 1 file changed, 1 insertion(+) diff --git a/config.ron b/config.ron index 2700cc54..3147cf71 100644 --- a/config.ron +++ b/config.ron @@ -58,6 +58,7 @@ (modifiers: [Super], key: "y"): ToggleTiling, (modifiers: [Super], key: "g"): ToggleWindowFloating, + (modifiers: [Super], key: "s"): ToggleStacking, (modifiers: [Super], key: "m"): Maximize, From 0d4320745edd9c044987d24a209e0e304fde9d31 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 13 Jun 2023 19:33:32 +0200 Subject: [PATCH 069/264] deps: Use updated libcosmic --- Cargo.lock | 211 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 20 +---- 2 files changed, 107 insertions(+), 124 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2745462a..e946eddf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] @@ -156,9 +156,9 @@ checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c" [[package]] name = "ash" @@ -257,9 +257,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" +checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded" [[package]] name = "block" @@ -329,10 +329,11 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "calloop" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a59225be45a478d772ce015d9743e49e92798ece9e34eda9a6aa2a6a7f40192" +checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" dependencies = [ + "bitflags 1.3.2", "futures-util", "log", "nix 0.25.1", @@ -521,7 +522,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -535,7 +536,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "quote", "syn 1.0.109", @@ -575,7 +576,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "anyhow", "cosmic-config", @@ -590,7 +591,7 @@ dependencies = [ [[package]] name = "cosmic-time" version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-time?rev=35dd0b8#35dd0b8d2c399994b16fe512f4b85d882c13ebdd" +source = "git+https://github.com/pop-os/cosmic-time?rev=da8217a#da8217adcac559147eed13287d70e458d68670e0" dependencies = [ "libcosmic", ] @@ -636,22 +637,22 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.8.0", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if", ] @@ -815,11 +816,11 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] name = "dlib" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.7.4", + "libloading 0.8.0", ] [[package]] @@ -1106,15 +1107,15 @@ dependencies = [ [[package]] name = "exr" -version = "1.6.3" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd2162b720141a91a054640662d3edce3d50a944a50ffca5313cd951abb35b4" +checksum = "279d3efcc55e19917fff7ab3ddd6c14afb6a90881a0078465196fe2f99d08c56" dependencies = [ "bit_field", "flume", "half", "lebe", - "miniz_oxide 0.6.2", + "miniz_oxide 0.7.1", "rayon-core", "smallvec", "zune-inflate", @@ -1408,9 +1409,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "js-sys", @@ -1633,7 +1634,7 @@ dependencies = [ [[package]] name = "iced" version = "0.9.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "iced_core", "iced_futures", @@ -1646,7 +1647,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.9.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "bitflags 1.3.2", "instant", @@ -1659,7 +1660,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.6.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "futures", "iced_core", @@ -1672,7 +1673,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.8.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -1689,7 +1690,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.1.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -1701,7 +1702,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.1.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "iced_core", "iced_futures", @@ -1711,7 +1712,7 @@ dependencies = [ [[package]] name = "iced_style" version = "0.8.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "iced_core", "once_cell", @@ -1721,7 +1722,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.1.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "bytemuck", "cosmic-text", @@ -1739,7 +1740,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.10.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -1761,7 +1762,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.1.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "iced_renderer", "iced_runtime", @@ -1925,9 +1926,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -2010,14 +2011,14 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.144" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?rev=5765053#5765053ad70d7b0fded56fe9e9c73649509a03ae" +source = "git+https://github.com/pop-os/libcosmic?rev=804b183#804b183492eb8d270b62ade3e6863638ec4f3814" dependencies = [ "apply", "cosmic-config", @@ -2037,6 +2038,7 @@ dependencies = [ "palette", "slotmap", "tokio", + "tracing", ] [[package]] @@ -2121,9 +2123,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -2131,9 +2133,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.18" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "log-panics" @@ -2214,6 +2216,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + [[package]] name = "metal" version = "0.24.0" @@ -2585,9 +2596,9 @@ dependencies = [ [[package]] name = "object" -version = "0.30.3" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" dependencies = [ "memchr", ] @@ -2737,7 +2748,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.7", + "parking_lot_core 0.9.8", ] [[package]] @@ -2756,22 +2767,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.2.16", + "redox_syscall 0.3.5", "smallvec", - "windows-sys 0.45.0", + "windows-targets 0.48.0", ] [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "phf" @@ -2861,9 +2872,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "png" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaeebc51f9e7d2c150d3f3bfeb667f2aa985db5ef1e3d212847bdedb488beeaa" +checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -2914,9 +2925,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] @@ -3105,9 +3116,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.3" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "aho-corasick", "memchr", @@ -3280,9 +3291,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.37.19" +version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ "bitflags 1.3.2", "errno 0.3.1", @@ -3364,18 +3375,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", @@ -3471,7 +3482,7 @@ source = "git+https://github.com/smithay//smithay?rev=43ce6b4372#43ce6b437257151 dependencies = [ "appendlist", "ash", - "bitflags 2.3.1", + "bitflags 2.3.2", "calloop", "cc", "cgmath", @@ -3710,15 +3721,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", "fastrand", "redox_syscall 0.3.5", "rustix", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -3773,9 +3785,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" dependencies = [ "itoa", "serde", @@ -4201,9 +4213,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4211,9 +4223,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", @@ -4226,9 +4238,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.36" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -4238,9 +4250,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4248,9 +4260,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", @@ -4261,9 +4273,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-timer" @@ -4469,9 +4481,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -4515,7 +4527,7 @@ checksum = "8f478237b4bf0d5b70a39898a66fa67ca3a007d79f2520485b8b0c3dfc46f8c2" dependencies = [ "arrayvec", "bit-vec", - "bitflags 2.3.1", + "bitflags 2.3.2", "codespan-reporting", "log", "naga", @@ -4532,15 +4544,15 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41af2ea7d87bd41ad0a37146252d5f7c26490209f47f544b2ee3b3ff34c7732e" +checksum = "74851c2c8e5d97652e74c241d41b0656b31c924a45dcdecde83975717362cfa4" dependencies = [ "android_system_properties", "arrayvec", "ash", "bit-set", - "bitflags 2.3.1", + "bitflags 2.3.2", "block", "core-graphics-types", "d3d12", @@ -4578,7 +4590,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bd33a976130f03dcdcd39b3810c0c3fc05daf86f0aaf867db14bfb7c4a9a32b" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.3.2", "js-sys", "web-sys", ] @@ -4912,9 +4924,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d8f380ae16a37b30e6a2cf67040608071384b1450c189e61bea3ff57cde922d" +checksum = "52839dc911083a8ef63efa4d039d1f58b5e409f923e44c80828f206f66e5541c" [[package]] name = "xmlparser" @@ -4978,18 +4990,3 @@ checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" dependencies = [ "simd-adler32", ] - -[[patch.unused]] -name = "iced_accessibility" -version = "0.1.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" - -[[patch.unused]] -name = "iced_sctk" -version = "0.1.0" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" - -[[patch.unused]] -name = "iced_winit" -version = "0.9.1" -source = "git+https://github.com/pop-os/iced.git?branch=runtime-state-operate#c43f0c4794c8199c2b15cd1dc3c98ae72777a994" diff --git a/Cargo.toml b/Cargo.toml index d99da2e4..fad31a08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,8 +31,8 @@ libsystemd = { version = "0.5", optional = true } wayland-backend = "0.1.0" wayland-scanner = "0.30.0" cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] } -libcosmic = { git = "https://github.com/pop-os/libcosmic", rev = "5765053", default-features = false, features = ["tiny_skia"] } -iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic", rev = "5765053" } +libcosmic = { git = "https://github.com/pop-os/libcosmic", rev = "804b183", default-features = false, features = ["tiny_skia"] } +iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic", rev = "804b183" } tiny-skia = "0.9" ordered-float = "3.0" glow = "0.11.2" @@ -41,7 +41,7 @@ tracing-journald = "0.3.0" tracing = { version = "0.1.37", features = ["max_level_debug", "release_max_level_info"] } puffin = { version = "0.14.3", optional = true } puffin_egui = { version = "0.21.0", optional = true } -cosmic-time = { git = "https://github.com/pop-os/cosmic-time", rev = "35dd0b8", default-features = false, features = ["libcosmic"] } +cosmic-time = { git = "https://github.com/pop-os/cosmic-time", rev = "da8217a", default-features = false, features = ["libcosmic"] } once_cell = "1.18.0" [dependencies.id_tree] @@ -79,17 +79,3 @@ lto = "fat" [patch."https://github.com/Smithay/smithay.git"] smithay = { git = "https://github.com/smithay//smithay", rev = "43ce6b4372" } -[patch."https://github.com/pop-os/libcosmic.git"] -iced = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_accessibility = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_core = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_futures = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_graphics = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_renderer = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_runtime = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_sctk = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_style = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_tiny_skia = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_wgpu = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_widget = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } -iced_winit = { git = "https://github.com/pop-os/iced.git", branch = "runtime-state-operate" } From 5cdf6146921774f10187dffc36d329ada810c49f Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Tue, 13 Jun 2023 19:58:14 +0200 Subject: [PATCH 070/264] config: Add shortcuts for group selections --- config.ron | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.ron b/config.ron index 3147cf71..e6810579 100644 --- a/config.ron +++ b/config.ron @@ -43,6 +43,8 @@ (modifiers: [Super], key: "j"): Focus(Down), (modifiers: [Super], key: "k"): Focus(Up), (modifiers: [Super], key: "l"): Focus(Right), + (modifiers: [Super], key: "u"): Focus(Out), + (modifiers: [Super], key: "i"): Focus(In), (modifiers: [Super, Shift], key: "Left"): Move(Left), (modifiers: [Super, Shift], key: "Right"): Move(Right), From 5884e287a5f99d7d5836fd8328c76078fd17852f Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 14 Jun 2023 16:43:13 +0200 Subject: [PATCH 071/264] stacking: Correctly restore decoration state --- src/shell/element/mod.rs | 2 ++ src/shell/element/surface.rs | 20 +++++----------- src/shell/layout/tiling/mod.rs | 2 ++ src/wayland/handlers/decoration.rs | 37 ++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 02aaf2c4..64e33588 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -505,6 +505,8 @@ impl CosmicMapped { outputs: impl Iterator)>, ) { let handle = self.loop_handle(); + surface.try_force_undecorated(false); + surface.set_tiled(false); let window = CosmicWindow::new(surface, handle); if let Some(geo) = self.last_geometry.lock().unwrap().clone() { diff --git a/src/shell/element/surface.rs b/src/shell/element/surface.rs index d9d1df60..ec29685c 100644 --- a/src/shell/element/surface.rs +++ b/src/shell/element/surface.rs @@ -1,4 +1,4 @@ -use std::{cell::RefCell, time::Duration}; +use std::time::Duration; use smithay::{ backend::renderer::{ @@ -38,7 +38,7 @@ use smithay::{ xwayland::{xwm::X11Relatable, X11Surface}, }; -use crate::state::SurfaceDmabufFeedback; +use crate::{state::SurfaceDmabufFeedback, wayland::handlers::decoration::PreferredDecorationMode}; space_elements! { #[derive(Debug, Clone, PartialEq)] @@ -195,22 +195,14 @@ impl CosmicSurface { if enable { let previous_decoration_state = window.toplevel().current_state().decoration_mode.clone(); - window - .user_data() - .insert_if_missing(|| RefCell::new(Option::::None)); - *window - .user_data() - .get::>>() - .unwrap() - .borrow_mut() = previous_decoration_state; + if PreferredDecorationMode::is_unset(window) { + PreferredDecorationMode::update(window, previous_decoration_state); + } window.toplevel().with_pending_state(|pending| { pending.decoration_mode = Some(DecorationMode::ServerSide); }); } else { - let previous_mode = window - .user_data() - .get::>>() - .and_then(|m| m.borrow().clone()); + let previous_mode = PreferredDecorationMode::mode(window); window.toplevel().with_pending_state(|pending| { pending.decoration_mode = previous_mode; }); diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 1c07ba03..608c0e02 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -1217,6 +1217,8 @@ impl TilingLayout { // map the rest for other in surfaces { + other.try_force_undecorated(false); + other.set_tiled(false); let window = CosmicMapped::from(CosmicWindow::new(other, handle.clone())); window.output_enter(&output, window.bbox()); diff --git a/src/wayland/handlers/decoration.rs b/src/wayland/handlers/decoration.rs index d637dfa2..151e0890 100644 --- a/src/wayland/handlers/decoration.rs +++ b/src/wayland/handlers/decoration.rs @@ -1,5 +1,8 @@ +use std::cell::RefCell; + use smithay::{ delegate_kde_decoration, delegate_xdg_decoration, + desktop::Window, reexports::{ wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode as XdgMode, wayland_protocols_misc::server_decoration::server::org_kde_kwin_server_decoration::{ @@ -22,6 +25,38 @@ use crate::{ state::State, }; +pub struct PreferredDecorationMode(RefCell>); + +impl PreferredDecorationMode { + pub fn is_unset(window: &Window) -> bool { + window + .user_data() + .get::() + .is_none() + } + + pub fn mode(window: &Window) -> Option { + let user_data = window.user_data(); + user_data.insert_if_missing(|| PreferredDecorationMode(RefCell::new(None))); + user_data + .get::() + .unwrap() + .0 + .borrow() + .clone() + } + + pub fn update(window: &Window, update: Option) { + let user_data = window.user_data(); + user_data.insert_if_missing(|| PreferredDecorationMode(RefCell::new(None))); + *user_data + .get::() + .unwrap() + .0 + .borrow_mut() = update; + } +} + impl State { pub fn new_decoration(mapped: &CosmicMapped, surface: &WlSurface) -> KdeMode { if mapped.is_stack() { @@ -54,6 +89,7 @@ impl State { .windows() .find(|(window, _)| window.wl_surface().as_ref() == Some(surface)) { + PreferredDecorationMode::update(&window, Some(mode)); window.toplevel().with_pending_state(|state| { state.decoration_mode = Some(mode); }); @@ -66,6 +102,7 @@ impl State { .windows() .find(|(window, _)| window.wl_surface().as_ref() == Some(surface)) { + PreferredDecorationMode::update(&window, None); window.toplevel().with_pending_state(|state| { state.decoration_mode = None; }); From 1452281fa7bf40ff976542ff682073f55aa2d2fc Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 14 Jun 2023 17:29:08 +0200 Subject: [PATCH 072/264] tiling: Focus whole stack on Focus::In --- src/shell/element/mod.rs | 7 +++++++ src/shell/element/stack.rs | 5 +++++ src/shell/layout/tiling/mod.rs | 7 ++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/shell/element/mod.rs b/src/shell/element/mod.rs index 64e33588..b230d67f 100644 --- a/src/shell/element/mod.rs +++ b/src/shell/element/mod.rs @@ -465,6 +465,13 @@ impl CosmicMapped { } } + pub fn stack_ref(&self) -> Option<&CosmicStack> { + match &self.element { + CosmicMappedInternal::Stack(stack) => Some(stack), + _ => None, + } + } + pub fn stack_ref_mut(&mut self) -> Option<&mut CosmicStack> { match &mut self.element { CosmicMappedInternal::Stack(stack) => Some(stack), diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index 87b8d5b8..fca06ab0 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -436,6 +436,11 @@ impl CosmicStack { }) } + pub(in super::super) fn focus_stack(&self) { + self.0 + .with_program(|p| p.group_focused.store(true, Ordering::SeqCst)); + } + pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> { self.0.loop_handle() } diff --git a/src/shell/layout/tiling/mod.rs b/src/shell/layout/tiling/mod.rs index 608c0e02..20dd2c8a 100644 --- a/src/shell/layout/tiling/mod.rs +++ b/src/shell/layout/tiling/mod.rs @@ -984,7 +984,12 @@ impl TilingLayout { if let Some(id) = id { return match tree.get(&id).unwrap().data() { - Data::Mapped { mapped, .. } => FocusResult::Some(mapped.clone().into()), + Data::Mapped { mapped, .. } => { + if mapped.is_stack() { + mapped.stack_ref().unwrap().focus_stack(); + } + FocusResult::Some(mapped.clone().into()) + } Data::Group { alive, .. } => FocusResult::Some( WindowGroup { node: id, From 7037d44226a98512a1c68d91f23b7a84d4738ec2 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Wed, 14 Jun 2023 17:56:35 +0200 Subject: [PATCH 073/264] stack: Bigger icons --- src/shell/element/stack.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index fca06ab0..d1692cf0 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -657,14 +657,14 @@ impl Program for CosmicStackInternal { ); tab_elements.push( - cosmic_widget::icon(app_id, 12) + cosmic_widget::icon(app_id, 16) .apply(iced_widget::container) .height(Length::Fill) .center_y() .into(), ); - let text_width = tab_width - if tab_width > 125 { 72 } else { 40 }; + let text_width = tab_width - if tab_width > 125 { 76 } else { 44 }; if text_width > 0 { tab_elements.push( cosmic_widget::text(title) @@ -690,6 +690,7 @@ impl Program for CosmicStackInternal { .style(theme::Svg::Symbolic) .apply(iced_widget::button) .style(theme::Button::Text) + .padding(0) .on_press(Message::Close(i)) .apply(iced_widget::container) .height(Length::Fill) From 64845186f51ab1cfe287d607cba9e29f3be36c99 Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 22 Jun 2023 20:58:39 +0200 Subject: [PATCH 074/264] stacking: Refactored view code into widgets --- src/shell/element/stack.rs | 466 +++-------- src/shell/element/stack/tab.rs | 429 ++++++++++ .../iced => shell/element/stack}/tab_text.rs | 7 +- src/shell/element/stack/tabs.rs | 778 ++++++++++++++++++ src/utils/{iced/mod.rs => iced.rs} | 2 - 5 files changed, 1314 insertions(+), 368 deletions(-) create mode 100644 src/shell/element/stack/tab.rs rename src/{utils/iced => shell/element/stack}/tab_text.rs (93%) create mode 100644 src/shell/element/stack/tabs.rs rename src/utils/{iced/mod.rs => iced.rs} (99%) diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index d1692cf0..3102c139 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -2,7 +2,7 @@ use super::CosmicSurface; use crate::{ shell::{focus::FocusDirection, layout::tiling::Direction, Shell}, state::State, - utils::iced::{tab_text::tab_text, IcedElement, Program}, + utils::iced::{IcedElement, Program}, utils::prelude::SeatExt, wayland::handlers::screencopy::ScreencopySessions, }; @@ -10,12 +10,9 @@ use apply::Apply; use calloop::LoopHandle; use cosmic::{ iced::{id::Id, widget as iced_widget}, - iced_core::{alignment, renderer::BorderRadius, Background, Color, Length, Size as IcedSize}, + iced_core::{renderer::BorderRadius, Background, Color, Length}, iced_runtime::Command, - iced_widget::{ - rule::FillMode, - scrollable::{AbsoluteOffset, Viewport}, - }, + iced_widget::scrollable::AbsoluteOffset, theme, widget as cosmic_widget, Element as CosmicElement, }; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; @@ -51,6 +48,15 @@ use std::{ }, }; +mod tab; +mod tab_text; +mod tabs; + +use self::{ + tab::{Tab, TabMessage}, + tabs::Tabs, +}; + static SCROLLABLE_ID: Lazy = Lazy::new(|| Id::new("scrollable")); #[derive(Clone, PartialEq, Eq, Hash)] @@ -70,6 +76,7 @@ pub struct CosmicStackInternal { active: Arc, activated: Arc, group_focused: Arc, + scroll_to_focus: Arc, previous_keyboard: Arc, pointer_entered: Arc, previous_pointer: Arc, @@ -77,7 +84,6 @@ pub struct CosmicStackInternal { last_location: Arc, Serial, u32)>>>, geometry: Arc>>>, mask: Arc>>, - scrollable_offset: Arc>>, } impl CosmicStackInternal { @@ -132,6 +138,7 @@ impl CosmicStack { active: Arc::new(AtomicUsize::new(0)), activated: Arc::new(AtomicBool::new(false)), group_focused: Arc::new(AtomicBool::new(false)), + scroll_to_focus: Arc::new(AtomicBool::new(false)), previous_keyboard: Arc::new(AtomicUsize::new(0)), pointer_entered: Arc::new(AtomicU8::new(Focus::None as u8)), previous_pointer: Arc::new(AtomicUsize::new(0)), @@ -139,7 +146,6 @@ impl CosmicStack { last_location: Arc::new(Mutex::new(None)), geometry: Arc::new(Mutex::new(None)), mask: Arc::new(Mutex::new(None)), - scrollable_offset: Arc::new(Mutex::new(None)), }, (width, TAB_HEIGHT), handle, @@ -159,6 +165,7 @@ impl CosmicStack { windows.push(window); p.active.store(windows.len() - 1, Ordering::SeqCst); } + p.scroll_to_focus.store(true, Ordering::SeqCst); }); self.0.force_redraw() } @@ -214,6 +221,7 @@ impl CosmicStack { { p.previous_keyboard.store(old, Ordering::SeqCst); p.previous_pointer.store(old, Ordering::SeqCst); + p.scroll_to_focus.store(true, Ordering::SeqCst); true } else { false @@ -237,6 +245,7 @@ impl CosmicStack { { p.previous_keyboard.store(old, Ordering::SeqCst); p.previous_pointer.store(old, Ordering::SeqCst); + p.scroll_to_focus.store(true, Ordering::SeqCst); true } else { false @@ -298,6 +307,7 @@ impl CosmicStack { windows.swap(old, val); p.previous_keyboard.store(old, Ordering::SeqCst); p.previous_pointer.store(old, Ordering::SeqCst); + p.scroll_to_focus.store(true, Ordering::SeqCst); MoveResult::Handled } else { if windows.len() == 1 { @@ -306,6 +316,7 @@ impl CosmicStack { let window = windows.remove(active); if active == windows.len() { p.active.store(active - 1, Ordering::SeqCst); + p.scroll_to_focus.store(true, Ordering::SeqCst); } window.try_force_undecorated(false); window.set_tiled(false); @@ -449,11 +460,50 @@ impl CosmicStack { #[derive(Debug, Clone, Copy)] pub enum Message { DragStart, - Activate(usize, Option<(f32, f32, f32)>), + Activate(usize), Close(usize), - ScrollForward(IcedSize), + ScrollForward, ScrollBack, - Scrolled(Viewport), + Scrolled, +} + +impl TabMessage for Message { + fn activate(idx: usize) -> Self { + Message::Activate(idx) + } + + fn is_activate(&self) -> Option { + match self { + Message::Activate(idx) => Some(*idx), + _ => None, + } + } + + fn scroll_back() -> Self { + Message::ScrollBack + } + + fn scroll_further() -> Self { + Message::ScrollForward + } + + fn populate_scroll(&mut self, mut current_offset: AbsoluteOffset) -> Option { + match self { + Message::ScrollBack => Some({ + current_offset.x -= 10.; + current_offset + }), + Message::ScrollForward => Some({ + current_offset.x += 10.; + current_offset + }), + _ => None, + } + } + + fn scrolled() -> Self { + Message::Scrolled + } } impl Program for CosmicStackInternal { @@ -477,47 +527,12 @@ impl Program for CosmicStackInternal { } } } - Message::Activate(idx, offsets) => { + Message::Activate(idx) => { if self.windows.lock().unwrap().get(idx).is_some() { let old = self.active.swap(idx, Ordering::SeqCst); self.previous_keyboard.store(old, Ordering::SeqCst); self.previous_pointer.store(old, Ordering::SeqCst); - } - if let Some((left_offset, right_offset, scroll_width)) = offsets { - let current_offset = self - .scrollable_offset - .lock() - .unwrap() - .unwrap_or(AbsoluteOffset::default()); - let current_start = current_offset.x; - let current_end = current_start + scroll_width; - assert!((right_offset - left_offset) <= (current_end - current_start)); - if (left_offset - current_start).is_sign_negative() - || (current_end - right_offset).is_sign_negative() - { - if (left_offset - current_start).abs() < (right_offset - current_end).abs() - { - let offset = AbsoluteOffset { - x: left_offset, - y: current_offset.y, - }; - *self.scrollable_offset.lock().unwrap() = Some(offset); - return iced_widget::scrollable::scroll_to::( - SCROLLABLE_ID.clone(), - offset, - ); - } else { - let offset = AbsoluteOffset { - x: right_offset - scroll_width, - y: current_offset.y, - }; - *self.scrollable_offset.lock().unwrap() = Some(offset); - return iced_widget::scrollable::scroll_to::( - SCROLLABLE_ID.clone(), - offset, - ); - } - } + self.scroll_to_focus.store(true, Ordering::SeqCst); } } Message::Close(idx) => { @@ -525,35 +540,10 @@ impl Program for CosmicStackInternal { val.close() } } - Message::Scrolled(viewport) => { - *self.scrollable_offset.lock().unwrap() = Some(viewport.absolute_offset()); - } - Message::ScrollForward(bounds) => { - let mut offset = self - .scrollable_offset - .lock() - .unwrap() - .unwrap_or(AbsoluteOffset::default()); - offset.x = (offset.x + 10.).min(bounds.width); - *self.scrollable_offset.lock().unwrap() = Some(offset); - return iced_widget::scrollable::scroll_to::( - SCROLLABLE_ID.clone(), - offset, - ); - } - Message::ScrollBack => { - let mut offset = self - .scrollable_offset - .lock() - .unwrap() - .unwrap_or(AbsoluteOffset::default()); - offset.x = (offset.x - 10.).max(0.0); - *self.scrollable_offset.lock().unwrap() = Some(offset); - return iced_widget::scrollable::scroll_to::( - SCROLLABLE_ID.clone(), - offset, - ); + Message::Scrolled => { + self.scroll_to_focus.store(false, Ordering::SeqCst); } + _ => unreachable!(), } Command::none() } @@ -569,303 +559,53 @@ impl Program for CosmicStackInternal { else { return iced_widget::row(Vec::new()).into(); }; - let tab_region = width - 128 - 4; // 64 left, 64 right + last rule let active = self.active.load(Ordering::SeqCst); - let activated = self.activated.load(Ordering::SeqCst); let group_focused = self.group_focused.load(Ordering::SeqCst); - let mut elements = vec![cosmic_widget::icon("view-paged-symbolic", 16) - .force_svg(true) - .style(if group_focused { - theme::Svg::custom(|theme| iced_widget::svg::Appearance { - color: Some(if theme.cosmic().is_dark { - Color::BLACK - } else { - Color::WHITE - }), - }) - } else { - theme::Svg::Symbolic - }) - .apply(iced_widget::container) - .padding([4, 24]) - .center_y() - .apply(iced_widget::mouse_area) - .on_press(Message::DragStart) - .into()]; - - const ACTIVE_TAB_WIDTH: i32 = 140; - const MIN_TAB_WIDTH: i32 = 38; - let tab_width = if windows.len() == 1 { - tab_region - } else { - let potential_width = tab_region / windows.len() as i32; - if potential_width < ACTIVE_TAB_WIDTH { - (tab_region - ACTIVE_TAB_WIDTH) / (windows.len() - 1) as i32 - } else { - potential_width - } - }; - let scrolling = tab_width < MIN_TAB_WIDTH; - let full_width = ACTIVE_TAB_WIDTH + (windows.len() as i32 - 1) * MIN_TAB_WIDTH; - let scroll_region = tab_region - 40; - - let mut tabs = Vec::new(); - let mut offset = 0; - for (i, window) in windows.iter().enumerate() { - let mut tab_elements = Vec::new(); - - let app_id = window.app_id(); - let title = window.title(); - let is_active = i == active; - let was_previous_active = i.checked_sub(1).map(|i| i == active).unwrap_or(false); - let tab_width = tab_width.max(if is_active { - ACTIVE_TAB_WIDTH - } else { - MIN_TAB_WIDTH - }); - - tabs.push( - iced_widget::vertical_rule(4) - .style( - if is_active || was_previous_active || (i == 0 && group_focused) { - if activated { - theme::Rule::custom(|theme| iced_widget::rule::Appearance { - color: theme.cosmic().accent_color().into(), - width: 4, - radius: 0., - fill_mode: FillMode::Full, - }) - } else { - theme::Rule::custom(|theme| iced_widget::rule::Appearance { - color: theme.cosmic().palette.neutral_5.into(), - width: 4, - radius: 0., - fill_mode: FillMode::Full, - }) - } - } else { - theme::Rule::custom(|theme| iced_widget::rule::Appearance { - color: theme.cosmic().palette.neutral_5.into(), - width: 4, - radius: 8., - fill_mode: FillMode::Padded(4), - }) - }, - ) - .into(), - ); - - tab_elements.push( - cosmic_widget::icon(app_id, 16) - .apply(iced_widget::container) - .height(Length::Fill) - .center_y() - .into(), - ); - - let text_width = tab_width - if tab_width > 125 { 76 } else { 44 }; - if text_width > 0 { - tab_elements.push( - cosmic_widget::text(title) - .size(14) - .font(if is_active && self.activated.load(Ordering::SeqCst) { - cosmic::font::FONT_SEMIBOLD - } else { - cosmic::font::FONT - }) - .horizontal_alignment(alignment::Horizontal::Left) - .vertical_alignment(alignment::Vertical::Center) - .apply(tab_text) - .height(Length::Fill) - .width(text_width as u16) - .into(), - ); - } - - if tab_width > 125 { - tab_elements.push( - cosmic_widget::icon("window-close-symbolic", 16) - .force_svg(true) - .style(theme::Svg::Symbolic) - .apply(iced_widget::button) - .style(theme::Button::Text) - .padding(0) - .on_press(Message::Close(i)) - .apply(iced_widget::container) - .height(Length::Fill) - .center_y() - .into(), - ); - } - - tabs.push( - iced_widget::row(tab_elements) - .height(Length::Fill) - .width(tab_width as u16 - 22) - .spacing(8) - .apply(iced_widget::container) - .padding([2, 10]) - .center_y() - .style(if is_active { - if activated { - theme::Container::custom(|theme| iced_widget::container::Appearance { - text_color: Some(Color::from(theme.cosmic().accent_text_color())), - background: Some(cosmic::iced::Background::Color( - Color::from_rgba(1.0, 1.0, 1.0, 0.1), - )), - border_radius: 0.0.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, - }) + let elements = vec![ + cosmic_widget::icon("window-stack-symbolic", 16) + .force_svg(true) + .style(if group_focused { + theme::Svg::custom(|theme| iced_widget::svg::Appearance { + color: Some(if theme.cosmic().is_dark { + Color::BLACK } else { - theme::Container::custom(|_theme| iced_widget::container::Appearance { - text_color: None, - background: Some(cosmic::iced::Background::Color( - Color::from_rgba(1.0, 1.0, 1.0, 0.1), - )), - border_radius: 0.0.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, - }) - } - } else { - theme::Container::Transparent + Color::WHITE + }), }) - .apply(iced_widget::mouse_area) - .on_press(Message::Activate( - i, - scrolling.then_some(( - offset as f32, - (offset + tab_width + 4) as f32, - scroll_region as f32, - )), - )) - .into(), - ); - - offset += tab_width; - } - - let last_was_active = active == windows.len() - 1; - let group_focused_clone = self.group_focused.clone(); - tabs.push( - iced_widget::vertical_rule(4) - .style( - if last_was_active || group_focused_clone.load(Ordering::SeqCst) { - if activated { - theme::Rule::custom(|theme| iced_widget::rule::Appearance { - color: theme.cosmic().accent_color().into(), - width: 4, - radius: 0., - fill_mode: FillMode::Full, - }) - } else { - theme::Rule::custom(|theme| iced_widget::rule::Appearance { - color: theme.cosmic().palette.neutral_5.into(), - width: 4, - radius: 0., - fill_mode: FillMode::Full, - }) - } - } else { - theme::Rule::custom(|theme| iced_widget::rule::Appearance { - color: theme.cosmic().palette.neutral_5.into(), - width: 4, - radius: 8., - fill_mode: FillMode::Padded(4), - }) - }, - ) + } else { + theme::Svg::Symbolic + }) + .apply(iced_widget::container) + .padding([4, 24]) + .center_y() + .apply(iced_widget::mouse_area) + .on_press(Message::DragStart) .into(), - ); - - let tabs = iced_widget::row(tabs) - .apply(iced_widget::container) - .style(theme::Container::custom(|theme| { - iced_widget::container::Appearance { - text_color: None, - background: Some(cosmic::iced::Background::Color(Color::from( - theme.cosmic().palette.neutral_3, - ))), - border_radius: 0.0.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, - } - })) - .height((TAB_HEIGHT - 1) as u16); - if scrolling { - elements.push( - iced_widget::vertical_rule(4) - .style(theme::Rule::custom(|theme| iced_widget::rule::Appearance { - color: theme.cosmic().palette.neutral_5.into(), - width: 4, - radius: 8., - fill_mode: FillMode::Padded(4), - })) - .into(), - ); - elements.push( - cosmic_widget::icon("go-previous-symbolic", 16) - .force_svg(true) - .style(theme::Svg::Symbolic) - .apply(iced_widget::button) - .style(theme::Button::Text) - .on_press(Message::ScrollBack) - .apply(iced_widget::container) - .height(Length::Fill) - .center_y() - .into(), - ); - elements.push( - iced_widget::Scrollable::new(tabs) - .horizontal_scroll( - iced_widget::scrollable::Properties::new() - .margin(0.0) - .scroller_width(1.0) - .width(1.0), - ) - .height(Length::Fill) - .width(Length::Fill) - .id(SCROLLABLE_ID.clone()) - .on_scroll(Message::Scrolled) - .into(), - ); - elements.push( - cosmic_widget::icon("go-next-symbolic", 16) - .force_svg(true) - .style(theme::Svg::Symbolic) - .apply(iced_widget::button) - .style(theme::Button::Text) - .on_press(Message::ScrollForward(IcedSize { - width: full_width as f32, - height: TAB_HEIGHT as f32, - })) - .apply(iced_widget::container) - .height(Length::Fill) - .center_y() - .into(), - ); - elements.push( - iced_widget::vertical_rule(4) - .style(theme::Rule::custom(|theme| iced_widget::rule::Appearance { - color: theme.cosmic().palette.neutral_5.into(), - width: 4, - radius: 8., - fill_mode: FillMode::Padded(4), - })) - .into(), - ); - } else { - elements.push(tabs.width(tab_region as u16).into()); - } - - elements.push( + CosmicElement::new( + Tabs::new( + windows + .iter() + .enumerate() + .map(|(i, w)| Tab::new(w.title(), w.app_id()).on_close(Message::Close(i))), + active, + windows[active].is_activated(false), + group_focused, + ) + .id(SCROLLABLE_ID.clone()) + .force_visible( + self.scroll_to_focus + .load(Ordering::SeqCst) + .then_some(active), + ) + .height(Length::Fill) + .width(Length::Fill), + ), iced_widget::horizontal_space(64) .apply(iced_widget::mouse_area) .on_press(Message::DragStart) .into(), - ); + ]; iced_widget::row(elements) .height(TAB_HEIGHT as u16) diff --git a/src/shell/element/stack/tab.rs b/src/shell/element/stack/tab.rs new file mode 100644 index 00000000..193f14a6 --- /dev/null +++ b/src/shell/element/stack/tab.rs @@ -0,0 +1,429 @@ +use apply::Apply; +use cosmic::{ + font::Font, + iced::{ + widget::{ + self, container::draw_background, rule::FillMode, text::StyleSheet as TextStyleSheet, + }, + Element, + }, + iced_core::{ + alignment, event, + layout::{Layout, Limits, Node}, + mouse, overlay, renderer, + widget::{ + operation::{Operation, OperationOutputWrapper}, + tree::Tree, + Widget, + }, + Clipboard, Color, Length, Point, Rectangle, Shell, Size, + }, + iced_style::{ + button::StyleSheet as ButtonStyleSheet, container::StyleSheet as ContainerStyleSheet, + rule::StyleSheet as RuleStyleSheet, + }, + iced_widget::scrollable::AbsoluteOffset, + theme, + widget::{icon, text, Icon}, +}; + +use super::tab_text::tab_text; + +pub(super) enum TabRuleTheme { + ActiveActivated, + ActiveDeactivated, + Default, +} + +impl Into for TabRuleTheme { + fn into(self) -> theme::Rule { + match self { + Self::ActiveActivated => theme::Rule::custom(|theme| widget::rule::Appearance { + color: theme.cosmic().accent_color().into(), + width: 4, + radius: 0., + fill_mode: FillMode::Full, + }), + Self::ActiveDeactivated => theme::Rule::custom(|theme| widget::rule::Appearance { + color: theme.cosmic().palette.neutral_5.into(), + width: 4, + radius: 0., + fill_mode: FillMode::Full, + }), + Self::Default => theme::Rule::custom(|theme| widget::rule::Appearance { + color: theme.cosmic().palette.neutral_5.into(), + width: 4, + radius: 8., + fill_mode: FillMode::Padded(4), + }), + } + } +} + +pub(super) enum TabBackgroundTheme { + ActiveActivated, + ActiveDeactivated, + Default, +} + +impl Into for TabBackgroundTheme { + fn into(self) -> theme::Container { + match self { + Self::ActiveActivated => { + theme::Container::custom(|theme| widget::container::Appearance { + text_color: Some(Color::from(theme.cosmic().accent_text_color())), + background: Some(cosmic::iced::Background::Color(Color::from_rgba( + 1.0, 1.0, 1.0, 0.1, + ))), + border_radius: 0.0.into(), + border_width: 0.0, + border_color: Color::TRANSPARENT, + }) + } + Self::ActiveDeactivated => { + theme::Container::custom(|_theme| widget::container::Appearance { + text_color: None, + background: Some(cosmic::iced::Background::Color(Color::from_rgba( + 1.0, 1.0, 1.0, 0.1, + ))), + border_radius: 0.0.into(), + border_width: 0.0, + border_color: Color::TRANSPARENT, + }) + } + Self::Default => theme::Container::Transparent, + } + } +} + +pub trait TabMessage { + fn activate(idx: usize) -> Self; + fn is_activate(&self) -> Option; + + fn scroll_further() -> Self; + fn scroll_back() -> Self; + fn populate_scroll(&mut self, current_offset: AbsoluteOffset) -> Option; + fn scrolled() -> Self; +} + +pub struct Tab<'a, Message: TabMessage> { + app_icon: Icon<'a>, + title: String, + font: Font, + close_message: Option, + rule_theme: TabRuleTheme, + background_theme: TabBackgroundTheme, + active: bool, +} + +impl<'a, Message: TabMessage> Tab<'a, Message> { + pub fn new(title: impl Into, app_id: impl Into) -> Self { + Tab { + app_icon: icon(app_id.into(), 16), + title: title.into(), + font: cosmic::font::FONT, + close_message: None, + rule_theme: TabRuleTheme::Default, + background_theme: TabBackgroundTheme::Default, + active: false, + } + } + + pub fn on_close(mut self, message: Message) -> Self { + self.close_message = Some(message); + self + } + + pub(super) fn font(mut self, font: Font) -> Self { + self.font = font; + self + } + + pub(super) fn rule_style(mut self, theme: TabRuleTheme) -> Self { + self.rule_theme = theme; + self + } + + pub(super) fn background_style(mut self, theme: TabBackgroundTheme) -> Self { + self.background_theme = theme; + self + } + + pub(super) fn non_active(mut self) -> Self { + self.active = false; + self + } + + pub(super) fn active(mut self) -> Self { + self.active = true; + self + } + + pub(super) fn internal(self, idx: usize) -> TabInternal<'a, Message, Renderer> + where + Renderer: cosmic::iced_core::Renderer + 'a, + Renderer: cosmic::iced_core::text::Renderer, + Renderer::Theme: ButtonStyleSheet