diff --git a/Cargo.lock b/Cargo.lock index 2f07822..c6dfa9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,9 +58,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", "once_cell", @@ -106,9 +106,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "628a8f9bd1e24b4e0db2b4bc2d000b001e7dd032d54afa60a68836aeec5aa54a" dependencies = [ "anstyle", "anstyle-parse", @@ -154,9 +154,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "apply" @@ -193,9 +193,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "as-raw-xcb-connection" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5f312b0a56c5cdf967c0aeb67f6289603354951683bc97ddc595ab974ba9aa" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" [[package]] name = "ash" @@ -208,9 +208,9 @@ dependencies = [ [[package]] name = "ashpd" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c018490e423efb6f032ef575f873ea57b61d44bec763cfe027b8e8852a027cf" +checksum = "4ac22eda5891cc086690cb6fa10121c0390de0e3b04eb269f2d766b00d3f2d81" dependencies = [ "enumflags2", "futures-channel", @@ -255,7 +255,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" dependencies = [ "concurrent-queue", - "event-listener 4.0.0", + "event-listener 4.0.3", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -267,11 +267,11 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" dependencies = [ - "async-lock 3.2.0", + "async-lock 3.3.0", "async-task", "concurrent-queue", "fastrand 2.0.1", - "futures-lite 2.1.0", + "futures-lite 2.2.0", "slab", ] @@ -309,18 +309,18 @@ dependencies = [ [[package]] name = "async-io" -version = "2.2.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +checksum = "fb41eb19024a91746eba0773aa5e16036045bbf45733766661099e182ea6a744" dependencies = [ - "async-lock 3.2.0", + "async-lock 3.3.0", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.1.0", + "futures-lite 2.2.0", "parking", - "polling 3.3.1", - "rustix 0.38.28", + "polling 3.3.2", + "rustix 0.38.30", "slab", "tracing", "windows-sys 0.52.0", @@ -337,11 +337,11 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ - "event-listener 4.0.0", + "event-listener 4.0.3", "event-listener-strategy", "pin-project-lite", ] @@ -359,7 +359,7 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.28", + "rustix 0.38.30", "windows-sys 0.48.0", ] @@ -371,7 +371,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -380,13 +380,13 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" dependencies = [ - "async-io 2.2.2", + "async-io 2.3.0", "async-lock 2.8.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.28", + "rustix 0.38.30", "signal-hook-registry", "slab", "windows-sys 0.48.0", @@ -394,19 +394,19 @@ dependencies = [ [[package]] name = "async-task" -version = "4.5.0" +version = "4.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -420,7 +420,7 @@ name = "atomicwrites" version = "0.4.2" source = "git+https://github.com/jackpot51/rust-atomicwrites#043ab4859d53ffd3d55334685303d8df39c9f768" dependencies = [ - "rustix 0.38.28", + "rustix 0.38.30", "tempfile", "windows-sys 0.48.0", ] @@ -475,9 +475,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bit-set" @@ -508,9 +508,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" dependencies = [ "serde", ] @@ -537,11 +537,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ "async-channel 2.1.1", - "async-lock 3.2.0", + "async-lock 3.3.0", "async-task", "fastrand 2.0.1", "futures-io", - "futures-lite 2.1.0", + "futures-lite 2.2.0", "piper", "tracing", ] @@ -578,7 +578,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -605,14 +605,14 @@ dependencies = [ [[package]] name = "calloop" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b50b5a44d59a98c55a9eeb518f39bf7499ba19fd98ee7d22618687f3f10adbf" +checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "log", - "polling 3.3.1", - "rustix 0.38.28", + "polling 3.3.2", + "rustix 0.38.30", "slab", "thiserror", ] @@ -624,7 +624,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" dependencies = [ "calloop", - "rustix 0.38.28", + "rustix 0.38.30", "wayland-backend 0.3.2", "wayland-client 0.31.1", ] @@ -663,9 +663,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "clap" -version = "4.4.11" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -673,9 +673,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -692,7 +692,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -896,18 +896,19 @@ dependencies = [ [[package]] name = "cosmic-client-toolkit" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=c1b6516#c1b651630c2b71cd8dfd2eb4ab47ede9dbd63840" +source = "git+https://github.com/pop-os/cosmic-protocols?rev=e65fa5e#e65fa5e2bb47e51656221657049bd3f88ae9dae5" dependencies = [ "cosmic-protocols", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit 0.18.0 (git+https://github.com/smithay/client-toolkit?rev=2e9bf9f)", "wayland-client 0.31.1", ] [[package]] name = "cosmic-comp-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-comp#a8b401b11df3b05336358f1bc7b4ee06f9ef53b5" +source = "git+https://github.com/pop-os/cosmic-comp#44bf1c316f3ca417c76fb45ec3f5e7efb6388e25" dependencies = [ + "cosmic-config", "input", "serde", ] @@ -915,7 +916,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "atomicwrites", "calloop", @@ -923,6 +924,7 @@ dependencies = [ "dirs 5.0.1", "iced_futures", "notify", + "once_cell", "ron", "serde", ] @@ -930,7 +932,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "quote", "syn 1.0.109", @@ -939,7 +941,7 @@ dependencies = [ [[package]] name = "cosmic-panel-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel#7c9c9245bce034beefc8efb71fc086ca14337517" +source = "git+https://github.com/pop-os/cosmic-panel#0b9dcfe06ff5642420278ce097bb65874ffdeff4" dependencies = [ "anyhow", "cosmic-config", @@ -953,9 +955,9 @@ dependencies = [ [[package]] name = "cosmic-protocols" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=c1b6516#c1b651630c2b71cd8dfd2eb4ab47ede9dbd63840" +source = "git+https://github.com/pop-os/cosmic-protocols?rev=e65fa5e#e65fa5e2bb47e51656221657049bd3f88ae9dae5" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "wayland-backend 0.3.2", "wayland-client 0.31.1", "wayland-protocols 0.31.0", @@ -963,6 +965,17 @@ dependencies = [ "wayland-server", ] +[[package]] +name = "cosmic-randr-shell" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-randr?rev=c35172c#c35172c637865d498ac509848a9194ba345d1350" +dependencies = [ + "kdl", + "slotmap", + "thiserror", + "tokio", +] + [[package]] name = "cosmic-settings" version = "0.1.0" @@ -975,6 +988,7 @@ dependencies = [ "color-eyre", "cosmic-comp-config", "cosmic-panel-config", + "cosmic-randr-shell", "cosmic-settings-desktop", "cosmic-settings-page", "cosmic-settings-system", @@ -984,11 +998,13 @@ dependencies = [ "dirs 5.0.1", "downcast-rs", "freedesktop-desktop-entry", + "futures-lite 2.2.0", "generator", "i18n-embed", "i18n-embed-fl", "image", "itertools 0.11.0", + "itoa", "libcosmic", "log", "notify", @@ -1017,7 +1033,7 @@ dependencies = [ "image", "infer", "rayon", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit 0.18.0 (git+https://github.com/smithay/client-toolkit/?rev=e63ab5f)", "tokio", "tracing", "wayland-client 0.31.1", @@ -1062,18 +1078,19 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75acbfb314aeb4f5210d379af45ed1ec2c98c7f1790bf57b8a4c562ac0c51b71" +source = "git+https://github.com/pop-os/cosmic-text.git#8457e68d984c465f7c5306424a73aa162aff32f2" dependencies = [ + "bitflags 2.4.2", "fontdb", "libm", "log", "rangemap", "rustc-hash", - "rustybuzz 0.11.0", - "self_cell 1.0.2", + "rustybuzz", + "self_cell 1.0.3", "swash", "sys-locale", + "ttf-parser", "unicode-bidi", "unicode-linebreak", "unicode-script", @@ -1083,7 +1100,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "almost", "cosmic-config", @@ -1096,9 +1113,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -1114,45 +1131,37 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.16" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset 0.9.0", ] [[package]] name = "crossbeam-utils" -version = "0.8.17" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crunchy" @@ -1193,7 +1202,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e" dependencies = [ "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1208,7 +1217,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16e44ab292b1dddfdaf7be62cfd8877df52f2f3fde5858d95bab606be259f20" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libloading 0.8.1", "winapi", ] @@ -1234,7 +1243,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1245,7 +1254,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1287,7 +1296,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1358,7 +1367,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1388,7 +1397,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb1b703ffbc7ebd216eba7900008049a56ace55580ecb2ee7fa801e8d8be87" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "bytemuck", "drm-ffi", "drm-fourcc", @@ -1452,7 +1461,7 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1509,9 +1518,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "4.0.0" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" dependencies = [ "concurrent-queue", "parking", @@ -1524,7 +1533,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" dependencies = [ - "event-listener 4.0.0", + "event-listener 4.0.3", "pin-project-lite", ] @@ -1577,9 +1586,9 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fdeflate" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" dependencies = [ "simd-adler32", ] @@ -1711,21 +1720,21 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "674e258f4b5d2dcd63888c01c68413c51f565e8af99d2f7701c7b81d79ef41c4" dependencies = [ - "roxmltree", + "roxmltree 0.18.1", ] [[package]] name = "fontdb" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020e203f177c0fb250fb19455a252e838d2bbbce1f80f25ecc42402aafa8cd38" +checksum = "98b88c54a38407f7352dd2c4238830115a6377741098ffd1f997c813d0e088a6" dependencies = [ "fontconfig-parser", "log", - "memmap2 0.8.0", + "memmap2 0.9.3", "slotmap", "tinyvec", - "ttf-parser 0.19.2", + "ttf-parser", ] [[package]] @@ -1746,7 +1755,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1811,9 +1820,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1826,9 +1835,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -1836,15 +1845,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1854,9 +1863,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -1875,9 +1884,9 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" +checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" dependencies = [ "fastrand 2.0.1", "futures-core", @@ -1888,32 +1897,32 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -1962,9 +1971,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", @@ -2028,9 +2037,9 @@ checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945" [[package]] name = "glow" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "886c2a30b160c4c6fec8f987430c26b526b7988ca71f664e6a699ddf6f9601e4" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" dependencies = [ "js-sys", "slotmap", @@ -2049,8 +2058,8 @@ dependencies = [ [[package]] name = "glyphon" -version = "0.3.0" -source = "git+https://github.com/grovesNL/glyphon.git?rev=2caa9fc5e5923c1d827d177c3619cab7e9885b85#2caa9fc5e5923c1d827d177c3619cab7e9885b85" +version = "0.4.1" +source = "git+https://github.com/jackpot51/glyphon.git#abb70c0fda8cf1a5dfc314c1c778103d7ba951e6" dependencies = [ "cosmic-text", "etagere", @@ -2064,7 +2073,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "gpu-alloc-types", ] @@ -2074,7 +2083,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", ] [[package]] @@ -2097,7 +2106,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "gpu-descriptor-types", "hashbrown 0.14.3", ] @@ -2108,7 +2117,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", ] [[package]] @@ -2152,7 +2161,7 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.7", "allocator-api2", ] @@ -2179,9 +2188,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" [[package]] name = "hex" @@ -2248,7 +2257,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.41", + "syn 2.0.48", "unic-langid", ] @@ -2262,13 +2271,13 @@ dependencies = [ "i18n-config", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "iced" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "iced_accessibility", "iced_core", @@ -2283,7 +2292,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "accesskit", "accesskit_unix", @@ -2292,7 +2301,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "bitflags 1.3.2", "iced_accessibility", @@ -2302,7 +2311,7 @@ dependencies = [ "palette", "raw-window-handle", "serde", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit 0.18.0 (git+https://github.com/smithay/client-toolkit?rev=2e9bf9f)", "thiserror", "xxhash-rust", ] @@ -2310,7 +2319,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "futures", "iced_core", @@ -2323,7 +2332,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -2346,7 +2355,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -2359,19 +2368,19 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "iced_accessibility", "iced_core", "iced_futures", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit 0.18.0 (git+https://github.com/smithay/client-toolkit?rev=2e9bf9f)", "thiserror", ] [[package]] name = "iced_sctk" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "enum-repr", "float-cmp", @@ -2383,7 +2392,7 @@ dependencies = [ "itertools 0.10.5", "lazy_static", "raw-window-handle", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit 0.18.0 (git+https://github.com/smithay/client-toolkit?rev=2e9bf9f)", "smithay-clipboard", "thiserror", "tracing", @@ -2395,7 +2404,7 @@ dependencies = [ [[package]] name = "iced_style" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "iced_core", "once_cell", @@ -2405,7 +2414,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "bytemuck", "cosmic-text", @@ -2423,7 +2432,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -2443,14 +2452,14 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.12.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "iced_renderer", "iced_runtime", "iced_style", "num-traits", "ouroboros", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit 0.18.0 (git+https://github.com/smithay/client-toolkit?rev=2e9bf9f)", "thiserror", "unicode-segmentation", ] @@ -2536,7 +2545,7 @@ checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -2579,9 +2588,9 @@ dependencies = [ [[package]] name = "image" -version = "0.24.7" +version = "0.24.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" dependencies = [ "bytemuck", "byteorder", @@ -2589,7 +2598,6 @@ dependencies = [ "exr", "gif", "jpeg-decoder", - "num-rational", "num-traits", "png", "qoi", @@ -2734,19 +2742,25 @@ dependencies = [ ] [[package]] -name = "jpeg-decoder" -version = "0.3.0" +name = "itoa" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" dependencies = [ "rayon", ] [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -2760,6 +2774,17 @@ dependencies = [ "mutate_once", ] +[[package]] +name = "kdl" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062c875482ccb676fd40c804a40e3824d4464c18c364547456d1c8e8e951ae47" +dependencies = [ + "miette", + "nom", + "thiserror", +] + [[package]] name = "khronos-egl" version = "6.0.0" @@ -2820,14 +2845,14 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#d53f693a3715fdd79481d75652cbf74286f4f387" +source = "git+https://github.com/pop-os/libcosmic#994e93d6d2f90f947d56376094eb19877d708063" dependencies = [ "apply", "ashpd", @@ -2846,6 +2871,7 @@ dependencies = [ "iced_sctk", "iced_style", "iced_tiny_skia", + "iced_wgpu", "iced_widget", "lazy_static", "palette", @@ -2893,7 +2919,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libc", "redox_syscall 0.4.1", ] @@ -2916,9 +2942,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "litemap" @@ -2957,9 +2983,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lru" -version = "0.11.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" dependencies = [ "hashbrown 0.14.3", ] @@ -2986,9 +3012,9 @@ dependencies = [ [[package]] name = "lyon_geom" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74df1ff0a0147282eb10699537a03baa7d31972b58984a1d44ce0624043fe8ad" +checksum = "edecfb8d234a2b0be031ab02ebcdd9f3b9ee418fb35e265f7a540a48d197bff9" dependencies = [ "arrayvec", "euclid", @@ -3007,13 +3033,13 @@ dependencies = [ [[package]] name = "lyon_tessellation" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f5bcf02928361d18e6edb8ad3bc5b93cba8aa57e2508deb072c2d2ade8bbd0d" +checksum = "8c7c67b5bc8123b352b2e7e742b47d1f236a13fe77619433be9568fbd888e9c0" dependencies = [ "float_next_after", "lyon_path", - "thiserror", + "num-traits", ] [[package]] @@ -3027,9 +3053,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memmap2" @@ -3051,9 +3077,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.0" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deaba38d7abf1d4cca21cc89e932e542ba2b9258664d2a9ef0e61512039c9375" +checksum = "45fd3a57831bf88bc63f8cebc0cf956116276e97fef3966103e96416209f7c92" dependencies = [ "libc", ] @@ -3091,7 +3117,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "block", "core-graphics-types", "foreign-types", @@ -3100,6 +3126,35 @@ dependencies = [ "paste", ] +[[package]] +name = "miette" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" +dependencies = [ + "miette-derive", + "once_cell", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -3135,7 +3190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae585df4b6514cf8842ac0f1ab4992edc975892704835b549cf818dc0191249e" dependencies = [ "bit-set", - "bitflags 2.4.1", + "bitflags 2.4.2", "codespan-reporting", "hexf-parse", "indexmap", @@ -3187,18 +3242,28 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "libc", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "notify" version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "crossbeam-channel", "filetime", "fsevent-sys", @@ -3358,9 +3423,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] @@ -3418,7 +3483,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -3454,7 +3519,7 @@ checksum = "b7db010ec5ff3d4385e4f133916faacd9dad0f6a09394c92d825b3aed310fa0a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -3553,7 +3618,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -3588,7 +3653,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -3616,15 +3681,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "png" -version = "0.17.10" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3651,14 +3716,14 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.1" +version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41" dependencies = [ "cfg-if", "concurrent-queue", "pin-project-lite", - "rustix 0.38.28", + "rustix 0.38.30", "tracing", "windows-sys 0.52.0", ] @@ -3711,18 +3776,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] [[package]] name = "profiling" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de09527cd2ea2c2d59fb6c2f8c1ab8c71709ed9d1b6d60b0e1c9fbb6fdcb33c" +checksum = "d135ede8821cf6376eb7a64148901e1690b788c11ae94dc297ae917dbc91dc0e" [[package]] name = "qoi" @@ -3753,9 +3818,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -3810,9 +3875,9 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -3820,9 +3885,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3900,9 +3965,9 @@ checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b" [[package]] name = "resvg" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7980f653f9a7db31acff916a262c3b78c562919263edea29bf41a056e20497" +checksum = "cadccb3d99a9efb8e5e00c16fbb732cbe400db2ec7fc004697ee7d97d86cf1f4" dependencies = [ "gif", "jpeg-decoder", @@ -3931,7 +3996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64", - "bitflags 2.4.1", + "bitflags 2.4.2", "serde", "serde_derive", ] @@ -3945,6 +4010,12 @@ dependencies = [ "xmlparser", ] +[[package]] +name = "roxmltree" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" + [[package]] name = "rust-embed" version = "6.8.1" @@ -3965,7 +4036,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.41", + "syn 2.0.48", "walkdir", ] @@ -4017,14 +4088,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", - "linux-raw-sys 0.4.12", + "linux-raw-sys 0.4.13", "windows-sys 0.52.0", ] @@ -4036,31 +4107,15 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "rustybuzz" -version = "0.10.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71cd15fef9112a1f94ac64b58d1e4628192631ad6af4dc69997f995459c874e7" +checksum = "f0ae5692c5beaad6a9e22830deeed7874eae8a4e3ba4076fb48e12c56856222c" dependencies = [ - "bitflags 1.3.2", - "bytemuck", - "smallvec", - "ttf-parser 0.19.2", - "unicode-bidi-mirroring", - "unicode-ccc", - "unicode-properties", - "unicode-script", -] - -[[package]] -name = "rustybuzz" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee8fe2a8461a0854a37101fe7a1b13998d0cfa987e43248e81d2a5f4570f6fa" -dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "bytemuck", "libm", "smallvec", - "ttf-parser 0.20.0", + "ttf-parser", "unicode-bidi-mirroring", "unicode-ccc", "unicode-properties", @@ -4094,51 +4149,51 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d" dependencies = [ - "self_cell 1.0.2", + "self_cell 1.0.3", ] [[package]] name = "self_cell" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e388332cd64eb80cd595a00941baf513caffae8dce9cfd0467fc9c66397dade6" +checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "serde_repr" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "serde_spanned" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -4224,9 +4279,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" [[package]] name = "smithay-client-toolkit" @@ -4249,18 +4304,45 @@ dependencies = [ [[package]] name = "smithay-client-toolkit" version = "0.18.0" -source = "git+https://github.com/smithay/client-toolkit//?rev=e63ab5f#e63ab5f01964bc48766fc4c3bf79cc05dc59874c" +source = "git+https://github.com/smithay/client-toolkit?rev=2e9bf9f#2e9bf9f31698851ca373e5f1e7ba3e6e804e4db1" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "bytemuck", "calloop", "calloop-wayland-source", "cursor-icon", "libc", "log", - "memmap2 0.9.0", + "memmap2 0.9.3", "pkg-config", - "rustix 0.38.28", + "rustix 0.38.30", + "thiserror", + "wayland-backend 0.3.2", + "wayland-client 0.31.1", + "wayland-csd-frame", + "wayland-cursor 0.31.0", + "wayland-protocols 0.31.0", + "wayland-protocols-wlr", + "wayland-scanner 0.31.0", + "xkbcommon", + "xkeysym", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.18.0" +source = "git+https://github.com/smithay/client-toolkit/?rev=e63ab5f#e63ab5f01964bc48766fc4c3bf79cc05dc59874c" +dependencies = [ + "bitflags 2.4.2", + "bytemuck", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2 0.9.3", + "pkg-config", + "rustix 0.38.30", "thiserror", "wayland-backend 0.3.2", "wayland-client 0.31.1", @@ -4318,11 +4400,11 @@ dependencies = [ "foreign-types", "js-sys", "log", - "memmap2 0.9.0", + "memmap2 0.9.3", "objc", "raw-window-handle", "redox_syscall 0.4.1", - "rustix 0.38.28", + "rustix 0.38.30", "tiny-xlib", "wasm-bindgen", "wayland-backend 0.3.2", @@ -4415,9 +4497,9 @@ checksum = "8fb1df15f412ee2e9dfc1c504260fa695c1c3f10fe9f4a6ee2d2184d7d6450e2" [[package]] name = "svgtypes" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71499ff2d42f59d26edb21369a308ede691421f79ebc0f001e2b1fd3a7c9e52" +checksum = "6e44e288cd960318917cbd540340968b90becc8bc81f171345d706e7a89d9d70" dependencies = [ "kurbo", "siphasher", @@ -4446,9 +4528,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.41" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -4463,7 +4545,7 @@ checksum = "285ba80e733fac80aa4270fbcdf83772a79b80aa35c97075320abfee4a915b06" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "unicode-xid", ] @@ -4504,50 +4586,50 @@ dependencies = [ [[package]] name = "temp-dir" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af547b166dd1ea4b472165569fc456cfb6818116f854690b0ff205e636523dab" +checksum = "dd16aa9ffe15fe021c6ee3766772132c6e98dfa395a167e16864f61a9cfb71d6" [[package]] name = "tempfile" -version = "3.8.1" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if", "fastrand 2.0.1", "redox_syscall 0.4.1", - "rustix 0.38.28", - "windows-sys 0.48.0", + "rustix 0.38.30", + "windows-sys 0.52.0", ] [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -4562,9 +4644,9 @@ dependencies = [ [[package]] name = "tiff" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" dependencies = [ "flate2", "jpeg-decoder", @@ -4645,9 +4727,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -4734,7 +4816,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -4782,12 +4864,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "ttf-parser" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49d64318d8311fc2668e48b63969f4343e0a85c4a109aa8460d6672e364b8bd1" - [[package]] name = "ttf-parser" version = "0.20.0" @@ -4822,10 +4898,11 @@ dependencies = [ [[package]] name = "uds_windows" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce65604324d3cce9b966701489fbd0cf318cb1f7bd9dd07ac9a4ee6fb791930d" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ + "memoffset 0.9.0", "tempfile", "winapi", ] @@ -4851,9 +4928,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-bidi-mirroring" @@ -4938,9 +5015,9 @@ dependencies = [ [[package]] name = "usvg" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51daa774fe9ee5efcf7b4fec13019b8119cda764d9a8b5b06df02bb1445c656" +checksum = "38b0a51b72ab80ca511d126b77feeeb4fb1e972764653e61feac30adc161a756" dependencies = [ "base64", "log", @@ -4953,16 +5030,16 @@ dependencies = [ [[package]] name = "usvg-parser" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c88a5ffaa338f0e978ecf3d4e00d8f9f493e29bed0752e1a808a1db16afc40" +checksum = "9bd4e3c291f45d152929a31f0f6c819245e2921bfd01e7bd91201a9af39a2bdc" dependencies = [ "data-url", "flate2", "imagesize", "kurbo", "log", - "roxmltree", + "roxmltree 0.19.0", "simplecss", "siphasher", "svgtypes", @@ -4971,14 +5048,14 @@ dependencies = [ [[package]] name = "usvg-text-layout" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2374378cb7a3fb8f33894e0fdb8625e1bbc4f25312db8d91f862130b541593" +checksum = "d383a3965de199d7f96d4e11a44dd859f46e86de7f3dca9a39bf82605da0a37c" dependencies = [ "fontdb", "kurbo", "log", - "rustybuzz 0.10.0", + "rustybuzz", "unicode-bidi", "unicode-script", "unicode-vo", @@ -4987,9 +5064,9 @@ dependencies = [ [[package]] name = "usvg-tree" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cacb0c5edeaf3e80e5afcf5b0d4004cc1d36318befc9a7c6606507e5d0f4062" +checksum = "8ee3d202ebdb97a6215604b8f5b4d6ef9024efd623cf2e373a6416ba976ec7d3" dependencies = [ "rctree", "strict-num", @@ -5051,9 +5128,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5061,24 +5138,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" dependencies = [ "cfg-if", "js-sys", @@ -5088,9 +5165,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5098,22 +5175,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-timer" @@ -5193,7 +5270,7 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ca7d52347346f5473bf2f56705f360e8440873052e575e55890c4fa57843ed3" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "nix 0.26.4", "wayland-backend 0.3.2", "wayland-scanner 0.31.0", @@ -5217,7 +5294,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cursor-icon", "wayland-backend 0.3.2", ] @@ -5274,7 +5351,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e253d7107ba913923dc253967f35e8561a3c65f914543e46843c88ddd729e21c" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "wayland-backend 0.3.2", "wayland-client 0.31.1", "wayland-scanner 0.31.0", @@ -5287,7 +5364,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "wayland-backend 0.3.2", "wayland-client 0.31.1", "wayland-protocols 0.31.0", @@ -5334,7 +5411,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f3f0c52a445936ca1184c98f1a69cf4ad9c9130788884531ef04428468cb1ce" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "downcast-rs", "io-lifetimes 2.0.3", "nix 0.26.4", @@ -5425,7 +5502,7 @@ checksum = "ef91c1d62d1e9e81c79e600131a258edf75c9531cbdbde09c44a011a47312726" dependencies = [ "arrayvec", "bit-vec", - "bitflags 2.4.1", + "bitflags 2.4.2", "codespan-reporting", "log", "naga", @@ -5450,7 +5527,7 @@ dependencies = [ "arrayvec", "ash", "bit-set", - "bitflags 2.4.1", + "bitflags 2.4.2", "block", "core-graphics-types", "d3d12", @@ -5489,7 +5566,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d5ed5f0edf0de351fe311c53304986315ce866f394a2e6df0c4b3c70774bcdd" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "js-sys", "web-sys", ] @@ -5702,9 +5779,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.28" +version = "0.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c830786f7720c2fd27a1a0e27a709dbd3c4d009b56d098fc742d4f4eab91fe2" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" dependencies = [ "memchr", ] @@ -5812,9 +5889,9 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" [[package]] name = "xxhash-rust" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9828b178da53440fa9c766a3d2f73f7cf5d0ac1fe3980c1e5018d899fd19e07b" +checksum = "53be06678ed9e83edb1745eb72efc0bbcd7b5c3c35711a860906aed827a13d61" [[package]] name = "yazi" @@ -5842,7 +5919,7 @@ checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "synstructure", ] @@ -5921,22 +5998,22 @@ checksum = "dd15f8e0dbb966fd9245e7498c7e9e5055d9e5c8b676b95bd67091cd11a1e697" [[package]] name = "zerocopy" -version = "0.7.30" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.30" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -5956,7 +6033,7 @@ checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "synstructure", ] @@ -5990,7 +6067,7 @@ checksum = "7b4e5997cbf58990550ef1f0e5124a05e47e1ebd33a84af25739be6031a62c20" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 890d919..d9b0281 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,12 +2,9 @@ members = ["app", "page", "pages/*"] default-members = ["app"] -[workspace.dependencies.iced_core] -git = "https://github.com/pop-os/libcosmic" - [workspace.dependencies.libcosmic] git = "https://github.com/pop-os/libcosmic" -features = ["single-instance", "tokio", "wayland", "xdg-portal"] +features = ["single-instance", "tokio", "wayland", "wgpu", "xdg-portal"] [workspace.dependencies.cosmic-config] git = "https://github.com/pop-os/libcosmic" @@ -22,17 +19,12 @@ git = "https://github.com/pop-os/cosmic-comp" [workspace.dependencies.cosmic-panel-config] git = "https://github.com/pop-os/cosmic-panel" -# [patch."https://github.com/pop-os/libcosmic"] -# libcosmic = { path = "../libcosmic" } -# cosmic-config = { path = "../libcosmic/cosmic-config" } - -# libcosmic = { git = "https://github.com/pop-os/libcosmic//", branch = "refactor-single-instance" } -# cosmic-config = { git = "https://github.com/pop-os/libcosmic//", branch = "refactor-single-instance"} - -[patch."https://github.com/Smithay/client-toolkit"] -sctk = { git = "https://github.com/smithay/client-toolkit//", package = "smithay-client-toolkit", rev = "e63ab5f"} +[workspace.dependencies.sctk] +git = "https://github.com/smithay/client-toolkit/" +package = "smithay-client-toolkit" +rev = "e63ab5f" [profile.release] opt-level = 3 -debug = true -lto = "thin" +# debug = true +# lto = "thin" diff --git a/app/Cargo.toml b/app/Cargo.toml index e9eac43..e7b6b11 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -7,8 +7,9 @@ rust-version = "1.65.0" [dependencies] apply = "0.3.0" -async-channel = "1.8.0" +async-channel = "1.9.0" color-eyre = "0.6.2" +cosmic-randr-shell = { git = "https://github.com/pop-os/cosmic-randr", rev = "c35172c" } cosmic-settings-desktop = { path = "../pages/desktop" } cosmic-settings-page = { path = "../page" } cosmic-settings-system = { path = "../pages/system" } @@ -16,33 +17,38 @@ cosmic-settings-time = { path = "../pages/time" } derivative = "2.2.0" derive_setters = "0.1.6" dirs = "5.0.1" -generator = "0.7.4" +generator = "0.7.5" i18n-embed-fl = "0.6.7" itertools = "0.11.0" libcosmic = {workspace = true} -once_cell = "1.17.2" -regex = "1.8.3" -rust-embed = "6.6.1" -slotmap = "1.0.6" -tokio = "1.28.2" +once_cell = "1.19.0" +regex = "1.10.2" +rust-embed = "6.8.1" +slotmap = "1.0.7" +tokio = "1.35.1" downcast-rs = "1.2.0" cosmic-comp-config = { workspace = true } # TODO: migrate this dependency to the pages/desktop crate. cosmic-panel-config = { workspace = true } -tracing = "0.1.37" -tracing-subscriber = "0.3.17" +tracing = "0.1.40" +tracing-subscriber = "0.3.18" log = "0.4" -url = "2.3.1" +url = "2.5.0" freedesktop-desktop-entry = "0.5.0" -notify = "6.0.0" +notify = "6.1.1" anyhow = "1.0" -image = "0.24.6" -serde = { version = "1.0.180", features = ["derive"] } -ashpd = { version = "0.6.2", default-features = false } +image = "0.24.7" +serde = { version = "1.0.195", features = ["derive"] } +ashpd = { version = "0.6.8", default-features = false } ron = "0.8" static_init = "1.0.3" -clap = {version = "4.4.8", features = ["derive"] } +clap = {version = "4.4.15", features = ["derive"] } +itoa = "1.0.10" +futures = { package = "futures-lite", version = "2.2.0" } [dependencies.i18n-embed] version = "0.13.9" features = ["fluent-system", "desktop-requester"] + +[features] +test = [] diff --git a/app/src/app.rs b/app/src/app.rs index 5a080ff..94ee38d 100644 --- a/app/src/app.rs +++ b/app/src/app.rs @@ -331,6 +331,12 @@ impl cosmic::Application for SettingsApp { page::update!(self.pages, message, desktop::workspaces::Page); } + crate::pages::Message::Displays(message) => { + if let Some(page) = self.pages.page_mut::() { + return page.update(message).map(cosmic::app::Message::App); + } + } + crate::pages::Message::Input(message) => { if let Some(page) = self.pages.page_mut::() { return page.update(message).map(cosmic::app::Message::App); diff --git a/app/src/main.rs b/app/src/main.rs index 771c16b..4cea97b 100644 --- a/app/src/main.rs +++ b/app/src/main.rs @@ -84,6 +84,8 @@ pub fn main() -> color_eyre::Result<()> { std::env::set_var("RUST_SPANTRACE", "0"); } + std::env::set_var("WGPU_POWER_PREF", "low"); + init_logger(); init_localizer(); @@ -133,7 +135,6 @@ fn init_logger() { tracing_subscriber::registry().with(log_filter).init(); } - #[macro_export] macro_rules! cache_dynamic_lazy { ( $( $visible:vis static $variable:ident: $type:ty = $expression:expr; )+ ) => { @@ -142,4 +143,4 @@ macro_rules! cache_dynamic_lazy { $visible static $variable: $type = $expression; )+ }; -} \ No newline at end of file +} diff --git a/app/src/pages/desktop/appearance.rs b/app/src/pages/desktop/appearance.rs index abe1ac2..fe4af7b 100644 --- a/app/src/pages/desktop/appearance.rs +++ b/app/src/pages/desktop/appearance.rs @@ -91,7 +91,7 @@ impl From<(Option, ThemeMode, Option, ThemeBuilder)> for Page { ThemeBuilder, ), ) -> Self { - let theme: Theme = if theme_mode.is_dark { + let theme = if theme_mode.is_dark { Theme::dark_default() } else { Theme::light_default() @@ -615,9 +615,9 @@ impl Page { }; let config = if self.theme_mode.is_dark { - Theme::::dark_config() + Theme::dark_config() } else { - Theme::::light_config() + Theme::light_config() }; let new_theme = self.theme_builder.clone().build(); if let Ok(config) = config { @@ -757,9 +757,9 @@ impl Page { }; let config = if self.theme_mode.is_dark { - Theme::::dark_config() + Theme::dark_config() } else { - Theme::::light_config() + Theme::light_config() }; let new_theme = self.theme_builder.clone().build(); if let Ok(config) = config { @@ -776,7 +776,7 @@ impl Page { Message::UseDefaultWindowHint(v) => { self.no_custom_window_hint = v; theme_builder_needs_update = true; - let theme: Theme = if self.theme_mode.is_dark { + let theme = if self.theme_mode.is_dark { Theme::dark_default() } else { Theme::light_default() @@ -840,9 +840,9 @@ impl Page { self.theme_builder = theme_builder; let config = if self.theme_mode.is_dark { - Theme::::dark_config() + Theme::dark_config() } else { - Theme::::light_config() + Theme::light_config() }; if let Ok(config) = config { let new_theme = self.theme_builder.clone().build(); diff --git a/app/src/pages/desktop/display/arrangement.rs b/app/src/pages/desktop/display/arrangement.rs new file mode 100644 index 0000000..ff8e9da --- /dev/null +++ b/app/src/pages/desktop/display/arrangement.rs @@ -0,0 +1,600 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: MPL-2.0 + +use cosmic::iced_core::renderer::Quad; +use cosmic::iced_core::widget::{tree, Tree}; +use cosmic::iced_core::{ + self as core, Clipboard, Element, Layout, Length, Rectangle, Renderer as IcedRenderer, Shell, + Size, Widget, +}; +use cosmic::iced_core::{alignment, event, text}; +use cosmic::iced_core::{layout, mouse, renderer, touch, Point}; +use cosmic::widget::segmented_button::{self, SingleSelectModel}; +use cosmic::Renderer; +use cosmic_randr_shell::{self as randr, OutputKey}; +use randr::Transform; + +const UNIT_PIXELS: f32 = 12.0; + +pub type OnPlacementFunc = Box Message>; +pub type OnSelectFunc = Box Message>; + +#[must_use] +#[derive(derive_setters::Setters)] +pub struct Arrangement<'a, Message> { + #[setters(skip)] + list: &'a randr::List, + #[setters(skip)] + tab_model: &'a SingleSelectModel, + #[setters(skip)] + on_placement: Option>, + #[setters(skip)] + on_select: Option>, + width: Length, + height: Length, +} + +impl<'a, Message> Arrangement<'a, Message> { + pub fn new(list: &'a randr::List, tab_model: &'a SingleSelectModel) -> Self { + Self { + list, + tab_model, + on_placement: None, + on_select: None, + width: Length::Shrink, + height: Length::Shrink, + } + } + + pub fn on_placement( + mut self, + on_placement: impl Fn(OutputKey, i32, i32) -> Message + 'static, + ) -> Self { + self.on_placement = Some(Box::new(on_placement)); + self + } + + pub fn on_select( + mut self, + on_select: impl Fn(segmented_button::Entity) -> Message + 'static, + ) -> Self { + self.on_select = Some(Box::new(on_select)); + self + } +} + +impl<'a, Message: Clone> Widget for Arrangement<'a, Message> { + fn tag(&self) -> tree::Tag { + tree::Tag::of::() + } + + fn state(&self) -> tree::State { + tree::State::new(State::default()) + } + + fn width(&self) -> Length { + self.width + } + + fn height(&self) -> Length { + self.height + } + + fn layout( + &self, + tree: &mut Tree, + _renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + // Determine the max display dimensions, and the total display area utilized. + let mut max_dimensions = (0, 0); + let mut display_area = (0, 0); + + for (_key, output) in self.list.outputs.iter() { + if !output.enabled { + continue; + } + + let Some(mode_key) = output.current else { + continue; + }; + + let Some(mode) = self.list.modes.get(mode_key) else { + continue; + }; + + let (width, height) = if output.transform.map_or(true, is_landscape) { + (mode.size.0, mode.size.1) + } else { + (mode.size.1, mode.size.0) + }; + + max_dimensions.0 = max_dimensions.0.max(width); + max_dimensions.1 = max_dimensions.1.max(height); + + display_area.0 = display_area.0.max(width as i32 + output.position.0); + display_area.1 = display_area.1.max(height as i32 + output.position.1); + } + + let width = (max_dimensions.0 as i32 * 3 + display_area.0) as f32 / UNIT_PIXELS; + let height = (max_dimensions.1 as i32 * 3 + display_area.1) as f32 / UNIT_PIXELS; + + let state = tree.state.downcast_mut::(); + state.max_dimensions = ( + max_dimensions.0 as f32 * 1.25 / UNIT_PIXELS, + max_dimensions.1 as f32 * 1.25 / UNIT_PIXELS, + ); + + let limits = limits + .width(Length::Fixed(width)) + .height(Length::Fixed(height)); + + let size = limits.resolve(Size::ZERO); + + layout::Node::new(size) + } + + fn on_event( + &mut self, + tree: &mut Tree, + event: cosmic::iced_core::Event, + layout: Layout<'_>, + cursor: mouse::Cursor, + _renderer: &Renderer, + _clipboard: &mut dyn Clipboard, + shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, + ) -> event::Status { + let bounds = layout.bounds(); + + match event { + core::Event::Mouse(mouse::Event::CursorMoved { .. }) + | core::Event::Touch(touch::Event::FingerMoved { .. }) => { + if let Some(position) = cursor.position() { + let state = tree.state.downcast_mut::(); + if let Some((output_key, region)) = state.dragging.as_mut() { + update_dragged_region( + self.tab_model, + self.list, + &bounds, + *output_key, + region, + state.max_dimensions, + (position.x - state.offset.0, position.y - state.offset.1), + ); + + return event::Status::Captured; + } + } + } + + core::Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) + | core::Event::Touch(touch::Event::FingerPressed { .. }) => { + if let Some(position) = cursor.position() { + let state = tree.state.downcast_mut::(); + if let Some((output_key, output_region)) = display_region_hovers( + self.tab_model, + self.list, + &bounds, + state.max_dimensions, + position, + ) { + state.drag_from = position; + state.offset = (position.x - output_region.x, position.y - output_region.y); + state.dragging = Some((output_key, output_region)); + return event::Status::Captured; + } + } + } + + core::Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) + | core::Event::Touch(touch::Event::FingerLifted { .. }) => { + let state = tree.state.downcast_mut::(); + if let Some((output_key, region)) = state.dragging.take() { + if let Some(position) = cursor.position() { + if position.distance(state.drag_from) < 4.0 { + if let Some(ref on_select) = self.on_select { + for id in self.tab_model.iter() { + if let Some(&key) = self.tab_model.data::(id) { + if key == output_key { + shell.publish(on_select(id)); + } + } + } + } + + return event::Status::Captured; + } + } + + if let Some(ref on_placement) = self.on_placement { + shell.publish(on_placement( + output_key, + ((region.x - state.max_dimensions.0 - bounds.x) * UNIT_PIXELS) as i32, + ((region.y - state.max_dimensions.1 - bounds.y) * UNIT_PIXELS) as i32, + )); + } + + return event::Status::Captured; + } + } + + _ => (), + } + + event::Status::Ignored + } + + fn mouse_interaction( + &self, + tree: &Tree, + layout: Layout<'_>, + cursor: mouse::Cursor, + _viewport: &Rectangle, + _renderer: &Renderer, + ) -> mouse::Interaction { + let state = tree.state.downcast_ref::(); + let bounds = layout.bounds(); + + for (_output_key, region) in + display_regions(self.tab_model, self.list, &bounds, state.max_dimensions) + { + if cursor.is_over(region) { + return mouse::Interaction::Grab; + } + } + + mouse::Interaction::Idle + } + + fn draw( + &self, + tree: &Tree, + renderer: &mut Renderer, + _theme: &cosmic::Theme, + _style: &renderer::Style, + layout: Layout<'_>, + _cursor: mouse::Cursor, + viewport: &Rectangle, + ) { + let state = tree.state.downcast_ref::(); + + let bounds = layout.bounds(); + let theme = cosmic::theme::active(); + let cosmic_theme = theme.cosmic(); + + let border_color = cosmic_theme.palette.neutral_7; + + let active_key = self.tab_model.active_data::(); + + for (id, (output_key, mut region)) in + display_regions(self.tab_model, self.list, &bounds, state.max_dimensions).enumerate() + { + // If the output is being dragged, show its dragged position instead. + if let Some((dragged_key, dragged_region)) = state.dragging { + if dragged_key == output_key { + region = dragged_region; + } + } + + let (background, border_color) = if Some(&output_key) == active_key { + let mut border_color = border_color; + border_color.alpha = 0.4; + + (cosmic_theme.accent_color(), border_color) + } else { + (cosmic_theme.palette.neutral_4, border_color) + }; + + renderer.fill_quad( + Quad { + bounds: region, + border_radius: 4.0.into(), + border_width: 3.0, + border_color: border_color.into(), + }, + core::Background::Color(background.into()), + ); + + let id_bounds = Rectangle { + x: region.x + (region.width / 2.0 - 36.0), + y: region.y + (region.height / 2.0 - 23.0), + width: 72.0, + height: 46.0, + }; + + renderer.fill_quad( + Quad { + bounds: id_bounds, + border_radius: 30.0.into(), + border_width: 0.0, + border_color: core::Color::TRANSPARENT, + }, + core::Background::Color(cosmic_theme.palette.neutral_1.into()), + ); + + core::text::Renderer::fill_text( + renderer, + core::Text { + content: itoa::Buffer::new().format(id), + size: core::Pixels(24.0), + line_height: core::text::LineHeight::Relative(1.2), + font: cosmic::font::FONT_BOLD, + bounds: id_bounds.size(), + horizontal_alignment: alignment::Horizontal::Center, + vertical_alignment: alignment::Vertical::Center, + shaping: text::Shaping::Basic, + }, + core::Point { + x: id_bounds.center_x(), + y: id_bounds.center_y(), + }, + cosmic_theme.palette.neutral_10.into(), + *viewport, + ); + } + } +} + +impl<'a, Message: 'static + Clone> From> for cosmic::Element<'a, Message> { + fn from(display_positioner: Arrangement<'a, Message>) -> Self { + Element::new(display_positioner) + } +} + +#[derive(Default)] +struct State { + drag_from: Point, + dragging: Option<(OutputKey, Rectangle)>, + offset: (f32, f32), + max_dimensions: (f32, f32), +} + +/// Iteratively calculate display regions for each display output in the list. +fn display_regions<'a>( + model: &'a SingleSelectModel, + list: &'a randr::List, + bounds: &'a Rectangle, + max_dimensions: (f32, f32), +) -> impl Iterator + 'a { + model + .iter() + .filter_map(move |id| model.data::(id)) + .filter_map(move |&key| { + let Some(output) = list.outputs.get(key) else { + return None; + }; + + if !output.enabled { + return None; + } + + let Some(mode_key) = output.current else { + return None; + }; + + let Some(mode) = list.modes.get(mode_key) else { + return None; + }; + + let (mut width, mut height) = ( + (mode.size.0 as f32) / UNIT_PIXELS, + (mode.size.1 as f32) / UNIT_PIXELS, + ); + + (width, height) = if output.transform.map_or(true, is_landscape) { + (width, height) + } else { + (height, width) + }; + + Some(( + key, + Rectangle { + width, + height, + x: max_dimensions.0 + bounds.x + (output.position.0 as f32) / UNIT_PIXELS, + y: max_dimensions.1 + bounds.y + (output.position.1 as f32) / UNIT_PIXELS, + }, + )) + }) +} + +fn display_region_hovers( + model: &SingleSelectModel, + list: &randr::List, + bounds: &Rectangle, + max_dimensions: (f32, f32), + point: Point, +) -> Option<(OutputKey, Rectangle)> { + for (output_key, region) in display_regions(model, list, bounds, max_dimensions) { + if region.contains(point) { + return Some((output_key, region)); + } + } + + None +} + +/// Updates a display's region, preventing coordinates from overlapping with existing displays. +fn update_dragged_region( + model: &SingleSelectModel, + list: &randr::List, + bounds: &Rectangle, + output: OutputKey, + region: &mut Rectangle, + max_dimensions: (f32, f32), + (x, y): (f32, f32), +) { + let mut dragged_region = Rectangle { x, y, ..*region }; + + // Prevent display from exceeding boundaries. + if !dragged_region.is_within_strict(bounds) { + return; + } + + let mut nearest = f32::MAX; + let mut nearest_region = Rectangle::default(); + let mut nearest_side = NearestSide::East; + + // Find the nearest adjacent display to the dragged display. + for (other_output, other_region) in display_regions(model, list, bounds, max_dimensions) { + if other_output == output { + continue; + } + + let center = dragged_region.center(); + + let eastward = distance(east_point(&other_region), center) * 1.5; + let westward = distance(west_point(&other_region), center) * 1.5; + let northward = distance(north_point(&other_region), center); + let southward = distance(south_point(&other_region), center); + + let mut nearer = false; + + if nearest > eastward { + (nearest, nearest_side, nearer) = (eastward, NearestSide::East, true); + } + + if nearest > westward { + (nearest, nearest_side, nearer) = (westward, NearestSide::West, true); + } + + if nearest > northward { + (nearest, nearest_side, nearer) = (northward, NearestSide::North, true); + } + + if nearest > southward { + (nearest, nearest_side, nearer) = (southward, NearestSide::South, true); + } + + if nearer { + nearest_region = other_region; + } + } + + // Attach dragged display to nearest adjacent display. + match nearest_side { + NearestSide::East => { + dragged_region.x = nearest_region.x - dragged_region.width; + dragged_region.y = dragged_region + .y + .max(nearest_region.y - dragged_region.height + 8.0) + .min(nearest_region.y + nearest_region.height - 8.0); + } + + NearestSide::North => { + dragged_region.y = nearest_region.y - dragged_region.height; + dragged_region.x = dragged_region + .x + .max(nearest_region.x - dragged_region.width + 8.0) + .min(nearest_region.x + nearest_region.width - 8.0); + } + + NearestSide::West => { + dragged_region.x = nearest_region.x + nearest_region.width; + dragged_region.y = dragged_region + .y + .max(nearest_region.y - dragged_region.height + 8.0) + .min(nearest_region.y + nearest_region.height - 8.0); + } + + NearestSide::South => { + dragged_region.y = nearest_region.y + nearest_region.height; + dragged_region.x = dragged_region + .x + .max(nearest_region.x - dragged_region.width + 8.0) + .min(nearest_region.x + nearest_region.width - 8.0); + } + } + + // Snap-align on x-axis when alignment is near. + if (dragged_region.x - nearest_region.x).abs() <= 8.0 { + dragged_region.x = nearest_region.x; + } + + // Snap-align on x-axis when alignment is near bottom edge. + if ((dragged_region.x + dragged_region.width) - (nearest_region.x + nearest_region.width)).abs() + <= 8.0 + { + dragged_region.x = nearest_region.x + nearest_region.width - dragged_region.width; + } + + // Snap-align on y-axis when alignment is near. + if (dragged_region.y - nearest_region.y).abs() <= 8.0 { + dragged_region.y = nearest_region.y; + } + + // Snap-align on y-axis when alignment is near bottom edge. + if ((dragged_region.y + dragged_region.height) - (nearest_region.y + nearest_region.height)) + .abs() + <= 8.0 + { + dragged_region.y = nearest_region.y + nearest_region.height - dragged_region.height; + } + + // Prevent display from exceeding boundaries. + if !dragged_region.is_within_strict(bounds) { + return; + } + + // Prevent display from overlapping with other displays. + for (other_output, other_region) in display_regions(model, list, bounds, max_dimensions) { + if other_output == output { + continue; + } + + if other_region.intersects(&dragged_region) { + return; + } + } + + *region = dragged_region; +} + +fn is_landscape(transform: Transform) -> bool { + matches!( + transform, + Transform::Normal | Transform::Rotate180 | Transform::Flipped | Transform::Flipped180 + ) +} + +#[derive(Debug)] +enum NearestSide { + East, + North, + South, + West, +} + +fn distance(a: Point, b: Point) -> f32 { + ((b.x - a.x).powf(2.0) + (b.y - a.y).powf(2.0)).sqrt() +} + +fn east_point(r: &Rectangle) -> Point { + Point { + x: r.x, + y: r.center_y(), + } +} + +fn north_point(r: &Rectangle) -> Point { + Point { + x: r.center_x(), + y: r.y, + } +} + +fn west_point(r: &Rectangle) -> Point { + Point { + x: r.x + r.width, + y: r.center_y(), + } +} + +fn south_point(r: &Rectangle) -> Point { + Point { + x: r.center_x(), + y: r.y + r.height, + } +} diff --git a/app/src/pages/desktop/display/graphics.rs b/app/src/pages/desktop/display/graphics.rs new file mode 100644 index 0000000..37dc6be --- /dev/null +++ b/app/src/pages/desktop/display/graphics.rs @@ -0,0 +1,246 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only + +use super::{Message, NightLight}; +use crate::pages; +use apply::Apply; +use cosmic::iced_core::{Alignment, Length, Padding}; +use cosmic::prelude::CollectionWidget; +use cosmic::widget::{button, column, icon, list_column, row, toggler}; +use cosmic::{Command, Element}; +use std::sync::Arc; + +pub const INTEGRATED: &str = "integrated"; +pub const NVIDIA: &str = "nvidia"; +pub const HYBRID: &str = "hybrid"; +pub const COMPUTE: &str = "compute"; + +pub async fn fetch() -> Option>> { + let switchable = tokio::process::Command::new("system76-power") + .args(["graphics", "switchable"]) + .output() + .await + .map(|output| { + std::str::from_utf8(&output.stdout).map_or(false, |text| text.trim() == "switchable") + }); + + match switchable { + Ok(false) => None, + + Ok(true) => Some(Arc::new( + tokio::process::Command::new("system76-power") + .arg("graphics") + .output() + .await + .and_then(|output| { + if let Ok(mut mode) = std::str::from_utf8(&output.stdout) { + mode = mode.trim(); + if mode == COMPUTE { + Ok(Mode::Compute) + } else if mode == HYBRID { + Ok(Mode::Hybrid) + } else if mode == INTEGRATED { + Ok(Mode::Integrated) + } else if mode == NVIDIA { + Ok(Mode::Nvidia) + } else { + Err(std::io::Error::new( + std::io::ErrorKind::InvalidData, + "unknown graphics mode", + )) + } + } else { + Err(std::io::Error::new( + std::io::ErrorKind::InvalidData, + "system76-power output was not UTF-8", + )) + } + }), + )), + + Err(why) => Some(Arc::new(Err(why))), + } +} + +pub fn view( + mode: &'static str, + description: &'static str, + button: Option<(&'static str, Message)>, +) -> Element<'static, Message> { + let theme = cosmic::theme::active(); + let theme = theme.cosmic(); + let has_checkmark = button.is_none(); + + let content = column::with_capacity(3) + .padding(Padding::from([theme.space_xxs(), theme.space_l()])) + .push(cosmic::widget::text::body(mode)) + .push(cosmic::widget::text::caption(description)) + .push(cosmic::widget::Space::new(Length::Fill, 12)) + .push_maybe(button.map(|(text, message)| { + button::text(text) + .style(cosmic::theme::Button::Link) + .trailing_icon(icon::from_name("go-next-symbolic").size(16)) + .padding(0) + .on_press(message) + })); + + if has_checkmark { + row::with_capacity(2) + .align_items(Alignment::Center) + .push(content) + .push(icon::from_name("object-select-symbolic").size(24)) + .apply(Element::from) + .apply(cosmic::widget::list::container) + .into() + } else { + cosmic::widget::list::container(content).into() + } +} + +/// Switchable graphics mode +#[derive(Clone, Copy, Debug)] +pub enum Mode { + Compute, + Hybrid, + Integrated, + Nvidia, +} + +impl Mode { + #[must_use] + pub fn argument_str(self) -> &'static str { + match self { + Self::Compute => COMPUTE, + Self::Hybrid => HYBRID, + Self::Integrated => INTEGRATED, + Self::Nvidia => NVIDIA, + } + } + + #[must_use] + pub fn localized_str(self) -> &'static str { + match self { + Self::Compute => &super::text::GRAPHICS_MODE_COMPUTE, + Self::Hybrid => &super::text::GRAPHICS_MODE_HYBRID, + Self::Integrated => &super::text::GRAPHICS_MODE_INTEGRATED, + Self::Nvidia => &super::text::GRAPHICS_MODE_NVIDIA, + } + } +} + +impl super::Page { + pub fn graphics_mode_view(&self) -> Element { + let mut container = list_column(); + + if let Some(graphics_mode) = self.config.graphics_mode { + // Displays the active graphics mode, and a button for configuring it. + container = container.add(cosmic::widget::settings::item( + &*super::text::GRAPHICS_MODE, + row() + .align_items(Alignment::Center) + .push(cosmic::widget::text::body(graphics_mode.localized_str())) + .push( + button::icon(icon::from_name("go-next-symbolic")) + .extra_small() + .on_press(Message::GraphicsModeContext), + ), + )); + } + + // Displays the night light status, and a button for configuring it. + container = container.add( + cosmic::widget::settings::item::builder(&*super::text::NIGHT_LIGHT) + .description(&*super::text::NIGHT_LIGHT_DESCRIPTION) + .control( + row() + .align_items(Alignment::Center) + .push(toggler(None, self.config.night_light_enabled, |enable| { + Message::NightLight(NightLight::Toggle(enable)) + })) + .push( + button::icon(icon::from_name("go-next-symbolic")) + .extra_small() + .on_press(Message::NightLightContext), + ), + ), + ); + + container + .apply(Element::from) + .map(crate::pages::Message::Displays) + } + + pub fn graphics_mode_context_view(&self) -> Element { + let theme = cosmic::theme::active(); + let theme = theme.cosmic(); + + column::with_capacity(4) + .spacing(theme.space_xs()) + .push(view( + &super::text::GRAPHICS_MODE_INTEGRATED, + &super::text::GRAPHICS_MODE_INTEGRATED_DESC, + if let Some(Mode::Integrated) = self.config.graphics_mode { + None + } else { + Some(( + &super::text::GRAPHICS_MODE_INTEGRATED_ENABLE, + Message::GraphicsMode(Mode::Integrated), + )) + }, + )) + .push(view( + &super::text::GRAPHICS_MODE_NVIDIA, + &super::text::GRAPHICS_MODE_NVIDIA_DESC, + if let Some(Mode::Nvidia) = self.config.graphics_mode { + None + } else { + Some(( + &super::text::GRAPHICS_MODE_NVIDIA_ENABLE, + Message::GraphicsMode(Mode::Nvidia), + )) + }, + )) + .push(view( + &super::text::GRAPHICS_MODE_HYBRID, + &super::text::GRAPHICS_MODE_HYBRID_DESC, + if let Some(Mode::Hybrid) = self.config.graphics_mode { + None + } else { + Some(( + &super::text::GRAPHICS_MODE_HYBRID_ENABLE, + Message::GraphicsMode(Mode::Hybrid), + )) + }, + )) + .push(view( + &super::text::GRAPHICS_MODE_COMPUTE, + &super::text::GRAPHICS_MODE_COMPUTE_DESC, + if let Some(Mode::Compute) = self.config.graphics_mode { + None + } else { + Some(( + &super::text::GRAPHICS_MODE_COMPUTE_ENABLE, + Message::GraphicsMode(Mode::Compute), + )) + }, + )) + .apply(Element::from) + .map(pages::Message::Displays) + } + + /// Change the graphics mode. + pub fn set_graphics_mode(&mut self, mode: Mode) -> Command { + self.config.graphics_mode = Some(mode); + + // Runs `system76-power graphics {{mode}}` + cosmic::command::future(async move { + let result = tokio::process::Command::new("system76-power") + .args(["graphics", mode.argument_str()]) + .status() + .await; + let page_message = + crate::pages::Message::Displays(Message::GraphicsModeResult(Arc::new(result))); + crate::app::Message::PageMessage(page_message) + }) + } +} diff --git a/app/src/pages/desktop/display/mod.rs b/app/src/pages/desktop/display/mod.rs new file mode 100644 index 0000000..a3a7bdd --- /dev/null +++ b/app/src/pages/desktop/display/mod.rs @@ -0,0 +1,790 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only + +pub mod arrangement; +pub mod graphics; +pub mod text; + +use crate::{app, pages}; +use apply::Apply; +use arrangement::Arrangement; +use cosmic::iced::Length; +use cosmic::iced_widget::scrollable::{Direction, Properties}; +use cosmic::widget::{ + column, container, dropdown, list_column, segmented_button, toggler, view_switcher, +}; +use cosmic::{command, Command, Element}; +use cosmic_randr_shell::{List, Output, OutputKey, Transform}; +use cosmic_settings_page::{self as page, section, Section}; +use slotmap::{Key, SlotMap}; +use std::collections::BTreeMap; +use std::{process::ExitStatus, sync::Arc}; + +/// Display color depth options +#[derive(Clone, Copy, Debug)] +pub struct ColorDepth(usize); + +/// Identifies the content to display in the context drawer +pub enum ContextDrawer { + GraphicsMode, + NightLight, +} + +/// Display mirroring options +#[derive(Clone, Copy, Debug)] +pub enum Mirroring { + Disable, + ProjectToAll, + Project(OutputKey), + Mirror(OutputKey), +} + +/// Night light preferences +#[derive(Clone, Copy, Debug)] +pub enum NightLight { + /// Toggles night light's automatic scheduling. + AutoSchedule(bool), + /// Sets the night light schedule. + ManualSchedule, + /// Changes the preferred night light temperature. + Temperature(f32), + /// Toggles night light mode + Toggle(bool), +} + +#[derive(Clone, Debug)] +pub enum Message { + /// Change placement of display + Position(OutputKey, i32, i32), + /// Changes the active display being configured. + Display(segmented_button::Entity), + /// Set the color depth of a display. + ColorDepth(ColorDepth), + /// Set the color profile of a display. + ColorProfile(usize), + /// Toggles display on or off. + DisplayToggle(bool), + /// Changes the hybrid graphics mode. + GraphicsMode(graphics::Mode), + /// Shows the graphics mode context drawer. + GraphicsModeContext, + /// Status of an applied graphics mode change + GraphicsModeResult(Arc>), + /// Configures mirroring status of a display. + Mirroring(Mirroring), + /// Handle night light preferences. + NightLight(NightLight), + /// Show the night light mode context drawer. + NightLightContext, + /// Set the orientation of a display. + Orientation(Transform), + /// Status of an applied display change. + RandrResult(Arc>), + /// Set the refresh rate of a display. + RefreshRate(usize), + /// Set the resolution of a display. + Resolution(usize), + /// Set the preferred scale for a display. + Scale(usize), + /// Refreshes display outputs. + Update { + /// The current graphics mode + graphics: Option>>, + + /// Available outputs from cosmic-randr. + randr: Arc>, + }, +} + +impl From for app::Message { + fn from(message: Message) -> Self { + let page_message = crate::pages::Message::Displays(message); + app::Message::PageMessage(page_message) + } +} + +#[derive(Clone, Copy)] +enum Randr { + Position(i32, i32), + RefreshRate(u32), + Resolution(u32, u32), + Scale(u32), + Transform(Transform), + Toggle(bool), +} + +/// The page struct for the display settings page. +#[derive(Default)] +pub struct Page { + list: List, + display_tabs: segmented_button::SingleSelectModel, + active_display: OutputKey, + config: Config, + cache: ViewCache, + context: Option, +} + +#[derive(Default)] +struct Config { + /// Whether night light is enabled. + night_light_enabled: bool, + graphics_mode: Option, + refresh_rate: Option, + resolution: Option<(u32, u32)>, + scale: u32, +} + +/// Cached view content for widgets. +#[derive(Default)] +struct ViewCache { + modes: BTreeMap<(u32, u32), Vec>, + orientations: [&'static str; 4], + refresh_rates: Vec, + resolutions: Vec, + orientation_selected: Option, + refresh_rate_selected: Option, + resolution_selected: Option, + scale_selected: Option, +} + +impl page::AutoBind for Page {} + +impl page::Page for Page { + fn content( + &self, + sections: &mut SlotMap>, + ) -> Option { + Some(vec![ + // Graphics switching and light mode + sections.insert( + Section::default() + .descriptions(vec![ + text::GRAPHICS_MODE.clone(), + text::GRAPHICS_MODE_COMPUTE_DESC.clone(), + text::GRAPHICS_MODE_HYBRID_DESC.clone(), + text::GRAPHICS_MODE_INTEGRATED_DESC.clone(), + text::GRAPHICS_MODE_NVIDIA_DESC.clone(), + text::NIGHT_LIGHT.clone(), + text::NIGHT_LIGHT_AUTO.clone(), + text::NIGHT_LIGHT_DESCRIPTION.clone(), + ]) + .view::(|_binder, page, _section| page.graphics_mode_view()), + ), + // Display arrangement + sections.insert( + Section::default() + .title(&*text::DISPLAY_ARRANGEMENT) + .descriptions(vec![ + text::DISPLAY_ARRANGEMENT.clone(), + text::DISPLAY_ARRANGEMENT_DESC.clone(), + ]) + .view::(|_binder, page, _section| page.display_arrangement_view()), + ), + // Display configuration + sections.insert( + Section::default() + .descriptions(vec![ + text::DISPLAY.clone(), + text::DISPLAY_REFRESH_RATE.clone(), + text::DISPLAY_SCALE.clone(), + text::ORIENTATION.clone(), + text::ORIENTATION_LANDSCAPE.clone(), + text::ORIENTATION_PORTRAIT.clone(), + ]) + .view::(|_binder, page, _section| page.display_view()), + ), + ]) + } + + fn info(&self) -> page::Info { + page::Info::new("display", "preferences-desktop-display-symbolic") + .title(fl!("display")) + .description(fl!("display", "desc")) + } + + #[cfg(not(feature = "test"))] + fn reload(&mut self, _page: page::Entity) -> Command { + command::future(reload()) + } + + #[cfg(feature = "test")] + fn reload(&mut self, _page: page::Entity) -> Command { + command::future(async move { + let mut randr = List::default(); + + let test_mode = randr.modes.insert(cosmic_randr_shell::Mode { + size: (1920, 1080), + refresh_rate: 144_000, + preferred: true, + }); + + randr.outputs.insert(cosmic_randr_shell::Output { + name: "Dummy-1".into(), + enabled: true, + make: None, + model: "Test 1".into(), + physical: (1, 1), + position: (0, 0), + scale: 1.0, + transform: Some(Transform::Normal), + modes: vec![test_mode], + current: Some(test_mode), + }); + + randr.outputs.insert(cosmic_randr_shell::Output { + name: "Dummy-2".into(), + enabled: true, + make: None, + model: "Test 1".into(), + physical: (1, 1), + position: (1920, 0), + scale: 1.0, + transform: Some(Transform::Normal), + modes: vec![test_mode], + current: Some(test_mode), + }); + + crate::pages::Message::Displays(Message::Update { + graphics: graphics::fetch().await, + randr: Arc::new(Ok(randr)), + }) + }) + } + + fn context_drawer(&self) -> Option> { + Some(match self.context { + Some(ContextDrawer::GraphicsMode) => self.graphics_mode_context_view(), + + Some(ContextDrawer::NightLight) => self.night_light_context_view(), + + None => return None, + }) + } +} + +impl Page { + pub fn update(&mut self, message: Message) -> Command { + match message { + Message::RandrResult(result) => { + if let Some(Err(why)) = Arc::into_inner(result) { + tracing::error!(?why, "cosmic-randr error"); + } + + return cosmic::command::future(async { + crate::Message::PageMessage(reload().await) + }); + } + + Message::Display(display) => self.set_display(display), + + Message::ColorDepth(color_depth) => return self.set_color_depth(color_depth), + + Message::ColorProfile(profile) => return self.set_color_profile(profile), + + Message::DisplayToggle(enable) => return self.toggle_display(enable), + + Message::GraphicsMode(mode) => return self.set_graphics_mode(mode), + + Message::GraphicsModeContext => { + self.context = Some(ContextDrawer::GraphicsMode); + return cosmic::command::message(app::Message::OpenContextDrawer( + text::GRAPHICS_MODE.clone().into(), + )); + } + + Message::GraphicsModeResult(result) => { + if let Some(Err(why)) = Arc::into_inner(result) { + tracing::error!(?why, "system76-power error"); + } + } + + Message::Mirroring(mirroring) => match mirroring { + Mirroring::Disable => (), + Mirroring::Mirror(target_display) => (), + Mirroring::Project(target_display) => (), + Mirroring::ProjectToAll => (), + }, + + Message::NightLight(night_light) => {} + + Message::NightLightContext => { + self.context = Some(ContextDrawer::NightLight); + return cosmic::command::message(app::Message::OpenContextDrawer( + text::NIGHT_LIGHT.clone().into(), + )); + } + + Message::Orientation(orientation) => return self.set_orientation(orientation), + + Message::Position(display, x, y) => return self.set_position(display, x, y), + + Message::RefreshRate(rate) => return self.set_refresh_rate(rate), + + Message::Resolution(option) => return self.set_resolution(option), + + Message::Scale(scale) => return self.set_scale(scale), + + Message::Update { graphics, randr } => { + match graphics.and_then(Arc::into_inner) { + Some(Ok(mode)) => { + self.config.graphics_mode = Some(mode); + } + + Some(Err(why)) => { + tracing::error!(?why, "error fetching graphics switching mode"); + } + + None => (), + } + + match Arc::into_inner(randr) { + Some(Ok(outputs)) => self.update_displays(outputs), + + Some(Err(why)) => { + tracing::error!(?why, "error fetching displays"); + } + + None => (), + } + + self.cache.orientations = [ + text::ORIENTATION_LANDSCAPE.as_str(), + text::ORIENTATION_PORTRAIT.as_str(), + text::ORIENTATION_LANDSCAPE_FLIPPED.as_str(), + text::ORIENTATION_PORTRAIT_FLIPPED.as_str(), + ]; + } + } + + Command::none() + } + + /// View for the display arrangement section. + pub fn display_arrangement_view(&self) -> Element { + column() + .padding(cosmic::iced::Padding::from([16, 24])) + .spacing(10) + .push(cosmic::widget::text::body(&*text::DISPLAY_ARRANGEMENT_DESC)) + .push({ + Arrangement::new(&self.list, &self.display_tabs) + .on_select(|id| pages::Message::Displays(Message::Display(id))) + .on_placement(|id, x, y| pages::Message::Displays(Message::Position(id, x, y))) + .apply(cosmic::widget::scrollable) + .width(Length::Shrink) + .direction(Direction::Both { + horizontal: Properties::new(), + vertical: Properties::new(), + }) + .apply(container) + .center_x() + .width(Length::Fill) + }) + .apply(cosmic::widget::list::container) + .into() + } + + /// View for the display configuration section. + pub fn display_view(&self) -> Element { + let Some(&active_id) = self.display_tabs.active_data::() else { + return column().into() + }; + + let active_output = &self.list.outputs[active_id]; + + let display_meta = list_column().add(cosmic::widget::settings::item( + &*text::DISPLAY_ENABLE, + toggler(None, active_output.enabled, Message::DisplayToggle), + )); + + let display_options = list_column() + .add(cosmic::widget::settings::item( + &*text::DISPLAY_RESOLUTION, + dropdown( + &self.cache.resolutions, + self.cache.resolution_selected, + Message::Resolution, + ), + )) + .add(cosmic::widget::settings::item( + &*text::DISPLAY_REFRESH_RATE, + dropdown( + &self.cache.refresh_rates, + self.cache.refresh_rate_selected, + Message::RefreshRate, + ), + )) + .add(cosmic::widget::settings::item( + &*text::DISPLAY_SCALE, + dropdown( + &["50%", "75%", "100%", "125%", "150%", "175%", "200%"], + self.cache.scale_selected, + Message::Scale, + ), + )) + .add(cosmic::widget::settings::item( + &*text::ORIENTATION, + dropdown( + &self.cache.orientations, + self.cache.orientation_selected, + |id| { + Message::Orientation(match id { + 0 => Transform::Normal, + 1 => Transform::Rotate90, + 2 => Transform::Flipped, + _ => Transform::Flipped90, + }) + }, + ), + )); + + column() + .spacing(24) + .push(view_switcher::horizontal(&self.display_tabs).on_activate(Message::Display)) + .push(display_meta) + .push(cosmic::widget::text::heading(&*text::DISPLAY_OPTIONS)) + .push(display_options) + .apply(Element::from) + .map(pages::Message::Displays) + } + + /// Displays the night light context drawer. + pub fn night_light_context_view(&self) -> Element { + column().into() + } + + /// Reloads the display list, and all information relevant to the active display. + pub fn update_displays(&mut self, list: List) { + self.active_display = OutputKey::null(); + self.display_tabs.clear(); + self.list = list; + + let sorted_outputs = self + .list + .outputs + .iter() + .map(|(key, output)| (&*output.name, key)) + .collect::>(); + + for (name, id) in sorted_outputs { + let Some(output) = self.list.outputs.get(id) else { + continue + }; + + let inches = + ((output.physical.0.pow(2) + output.physical.1.pow(2)) as f32).sqrt() * 0.039_370_1; + + let inches_string = format!("{inches:.1}\""); + + self.display_tabs + .insert() + .text(match name { + "eDP-1" | "LVDS1" => { + fl!("display", "laptop", size = inches_string.as_str()) + } + output => fl!( + "display", + "external", + size = inches_string.as_str(), + output = output + ), + }) + .data::(id); + } + + self.display_tabs.activate_position(0); + + // Retrieve data for the first, activated display. + self.set_display(self.display_tabs.active()); + } + + /// Changes the color depth of the active display. + pub fn set_color_depth(&mut self, depth: ColorDepth) -> Command { + unimplemented!() + } + + /// Changes the color profile of the active display. + pub fn set_color_profile(&mut self, profile: usize) -> Command { + unimplemented!() + } + + /// Changes the active display, and regenerates available options for it. + pub fn set_display(&mut self, display: segmented_button::Entity) { + let Some(&output_id) = self.display_tabs.data::(display) else { + return; + }; + + let Some(output) = self.list.outputs.get_mut(output_id) else { + return; + }; + + self.display_tabs.activate(display); + self.active_display = output_id; + self.config.refresh_rate = None; + self.config.resolution = None; + self.config.scale = (output.scale * 100.0) as u32; + + self.cache.modes.clear(); + self.cache.refresh_rates.clear(); + self.cache.resolutions.clear(); + self.cache.orientation_selected = match output.transform { + Some(Transform::Normal) => Some(0), + Some(Transform::Rotate90) => Some(1), + Some(Transform::Flipped) => Some(2), + Some(Transform::Flipped90) => Some(3), + _ => None, + }; + self.cache.resolution_selected = None; + self.cache.refresh_rate_selected = None; + + self.cache.scale_selected = Some(if self.config.scale < 75 { + 0 + } else if self.config.scale < 100 { + 1 + } else if self.config.scale < 125 { + 2 + } else if self.config.scale < 150 { + 3 + } else if self.config.scale < 175 { + 4 + } else if self.config.scale < 200 { + 5 + } else { + 6 + }); + + if let Some(current_mode_id) = output.current { + for (mode_id, mode) in output + .modes + .iter() + .filter_map(|&id| self.list.modes.get(id).map(|m| (id, m))) + { + let refresh_rates = self.cache.modes.entry(mode.size).or_insert_with(Vec::new); + + refresh_rates.push(mode.refresh_rate); + + if current_mode_id == mode_id { + self.cache.refresh_rate_selected = Some(refresh_rates.len() - 1); + self.cache.resolution_selected = Some(self.cache.modes.len() - 1); + self.config.resolution = Some(mode.size); + self.config.refresh_rate = Some(mode.refresh_rate); + } + } + } + + for (&resolution, rates) in self.cache.modes.iter().rev() { + self.cache + .resolutions + .push(format!("{}x{}", resolution.0, resolution.1)); + if Some(resolution) == self.config.resolution { + cache_rates(&mut self.cache.refresh_rates, rates); + } + } + } + + /// Change display orientation. + pub fn set_orientation(&mut self, transform: Transform) -> Command { + let Some(output) = self.list.outputs.get(self.active_display) else { + return Command::none(); + }; + + self.cache.orientation_selected = match transform { + Transform::Normal => Some(0), + Transform::Rotate90 => Some(1), + Transform::Flipped => Some(2), + _ => Some(3), + }; + + self.exec_randr(output, Randr::Transform(transform)) + } + + /// Changes the position of the display. + pub fn set_position(&mut self, display: OutputKey, x: i32, y: i32) -> Command { + let Some(output) = self.list.outputs.get_mut(display) else { + return Command::none(); + }; + + output.position = (x, y); + + if cfg!(feature = "test") { + tracing::debug!("set position {x},{y}"); + return Command::none(); + } + + let output = &self.list.outputs[display]; + self.exec_randr(output, Randr::Position(x, y)) + } + + /// Changes the refresh rate of the active display. + pub fn set_refresh_rate(&mut self, option: usize) -> Command { + let Some(output) = self.list.outputs.get(self.active_display) else { + return Command::none(); + }; + + if let Some(ref resolution) = self.config.resolution { + if let Some(rates) = self.cache.modes.get(resolution) { + if let Some(&rate) = rates.get(option) { + self.cache.refresh_rate_selected = Some(option); + self.config.refresh_rate = Some(rate); + return self.exec_randr(output, Randr::RefreshRate(rate)); + } + } + } + + Command::none() + } + + /// Change the resolution of the active display. + pub fn set_resolution(&mut self, option: usize) -> Command { + let Some(output) = self.list.outputs.get(self.active_display) else { + return Command::none(); + }; + + let Some((&resolution, rates)) = self.cache.modes.iter().rev().nth(option) else { + return Command::none(); + }; + + self.cache.refresh_rates.clear(); + cache_rates(&mut self.cache.refresh_rates, rates); + + let Some(&rate) = rates.first() else { + return Command::none(); + }; + + self.config.refresh_rate = Some(rate); + self.config.resolution = Some(resolution); + self.cache.refresh_rate_selected = Some(0); + self.cache.resolution_selected = Some(option); + self.exec_randr(output, Randr::Resolution(resolution.0, resolution.1)) + } + + /// Set the scale of the active display. + pub fn set_scale(&mut self, option: usize) -> Command { + let Some(output) = self.list.outputs.get(self.active_display) else { + return Command::none(); + }; + + let scale = (option * 25 + 50) as u32; + + self.cache.scale_selected = Some(option); + self.config.scale = scale; + self.exec_randr(output, Randr::Scale(scale)) + } + + /// Enables or disables the active display. + pub fn toggle_display(&mut self, enable: bool) -> Command { + let Some(output) = self.list.outputs.get_mut(self.active_display) else { + return Command::none(); + }; + + output.enabled = enable; + + let output = &self.list.outputs[self.active_display]; + self.exec_randr(output, Randr::Toggle(output.enabled)) + } + + /// Applies a display configuration via `cosmic-randr`. + fn exec_randr(&self, output: &Output, request: Randr) -> Command { + let Some(current) = output.current.and_then(|id| self.list.modes.get(id)) else { + return Command::none(); + }; + + let name = &*output.name; + + let mut command = tokio::process::Command::new("cosmic-randr"); + + match request { + Randr::Position(x, y) => { + command + .arg("mode") + .arg("--pos-x") + .arg(itoa::Buffer::new().format(x)) + .arg("--pos-y") + .arg(itoa::Buffer::new().format(y)) + .arg(name) + .arg(itoa::Buffer::new().format(current.size.0)) + .arg(itoa::Buffer::new().format(current.size.1)); + } + + Randr::RefreshRate(rate) => { + command + .arg("mode") + .arg("--refresh") + .arg( + &[ + itoa::Buffer::new().format(rate / 1000), + ".", + itoa::Buffer::new().format(rate % 1000), + ] + .concat(), + ) + .arg(name) + .arg(itoa::Buffer::new().format(current.size.0)) + .arg(itoa::Buffer::new().format(current.size.1)); + } + + Randr::Resolution(width, height) => { + command + .arg("mode") + .arg(name) + .arg(itoa::Buffer::new().format(width)) + .arg(itoa::Buffer::new().format(height)); + } + + Randr::Scale(scale) => { + command + .arg("mode") + .arg("--scale") + .arg( + &[ + itoa::Buffer::new().format(scale / 100), + ".", + itoa::Buffer::new().format(scale % 100), + ] + .concat(), + ) + .arg(name) + .arg(itoa::Buffer::new().format(current.size.0)) + .arg(itoa::Buffer::new().format(current.size.1)); + } + + Randr::Toggle(enable) => { + command + .arg(if enable { "enable" } else { "disable" }) + .arg(name); + } + + Randr::Transform(transform) => { + command + .arg("mode") + .arg("--transform") + .arg(&*format!("{transform}")) + .arg(name) + .arg(itoa::Buffer::new().format(current.size.0)) + .arg(itoa::Buffer::new().format(current.size.1)); + } + } + + cosmic::command::future(async move { + tracing::debug!(?command, "executing"); + app::Message::from(Message::RandrResult(Arc::new(command.status().await))) + }) + } +} + +fn cache_rates(cached_rates: &mut Vec, rates: &[u32]) { + *cached_rates = rates + .iter() + .map(|&rate| format!("{:>3}.{:02} Hz", rate / 1000, rate % 1000)) + .collect(); +} + +pub async fn reload() -> crate::pages::Message { + let graphics_fut = graphics::fetch(); + let randr_fut = cosmic_randr_shell::list(); + let (graphics, randr) = futures::future::zip(graphics_fut, randr_fut).await; + + crate::pages::Message::Displays(Message::Update { + graphics, + randr: Arc::new(randr), + }) +} diff --git a/app/src/pages/desktop/display/text.rs b/app/src/pages/desktop/display/text.rs new file mode 100644 index 0000000..a1462e9 --- /dev/null +++ b/app/src/pages/desktop/display/text.rs @@ -0,0 +1,97 @@ +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only + +crate::cache_dynamic_lazy! { + pub static COLOR: String = fl!("color"); + + pub static COLOR_DEPTH: String = fl!("color", "depth"); + + pub static COLOR_PROFILE: String = fl!("color", "profile"); + + pub static COLOR_PROFILES: String = fl!("color", "sidebar"); + + pub static COLOR_TEMPERATURE: String = fl!("color", "temperature"); + + pub static DISPLAY: String = fl!("display"); + + pub static DISPLAY_ARRANGEMENT: String = fl!("display", "arrangement"); + + pub static DISPLAY_ARRANGEMENT_DESC: String = fl!("display", "arrangement-desc"); + + pub static DISPLAY_ENABLE: String = fl!("display", "enable"); + + pub static DISPLAY_EXTERNAL: String = fl!("display", "external"); + + pub static DISPLAY_LAPTOP: String = fl!("display", "laptop"); + + pub static DISPLAY_OPTIONS: String = fl!("display", "options"); + + pub static DISPLAY_REFRESH_RATE: String = fl!("display", "refresh-rate"); + + pub static DISPLAY_RESOLUTION: String = fl!("display", "resolution"); + + pub static DISPLAY_SCALE: String = fl!("display", "scale"); + + pub static GRAPHICS_MODE: String = fl!("graphics-mode"); + + pub static GRAPHICS_MODE_COMPUTE: String = + fl!("graphics-mode", "mode", mode = super::graphics::COMPUTE); + + pub static GRAPHICS_MODE_COMPUTE_ENABLE: String = + fl!("graphics-mode", "enable", mode = super::graphics::COMPUTE); + + pub static GRAPHICS_MODE_COMPUTE_DESC: String = + fl!("graphics-mode", "desc", mode = super::graphics::COMPUTE); + + pub static GRAPHICS_MODE_HYBRID: String = + fl!("graphics-mode", "mode", mode = super::graphics::HYBRID); + + pub static GRAPHICS_MODE_HYBRID_ENABLE: String = + fl!("graphics-mode", "enable", mode = super::graphics::HYBRID); + + pub static GRAPHICS_MODE_HYBRID_DESC: String = + fl!("graphics-mode", "desc", mode = super::graphics::HYBRID); + + pub static GRAPHICS_MODE_INTEGRATED: String = + fl!("graphics-mode", "mode", mode = super::graphics::INTEGRATED); + + pub static GRAPHICS_MODE_INTEGRATED_ENABLE: String = fl!( + "graphics-mode", + "enable", + mode = super::graphics::INTEGRATED + ); + + pub static GRAPHICS_MODE_INTEGRATED_DESC: String = + fl!("graphics-mode", "desc", mode = super::graphics::INTEGRATED); + + pub static GRAPHICS_MODE_NVIDIA: String = + fl!("graphics-mode", "mode", mode = super::graphics::NVIDIA); + + pub static GRAPHICS_MODE_NVIDIA_ENABLE: String = + fl!("graphics-mode", "enable", mode = super::graphics::NVIDIA); + + pub static GRAPHICS_MODE_NVIDIA_DESC: String = + fl!("graphics-mode", "desc", mode = super::graphics::NVIDIA); + + pub static MIRRORING: String = fl!("mirroring"); + + pub static NIGHT_LIGHT: String = fl!("night-light"); + + pub static NIGHT_LIGHT_AUTO: String = fl!("night-light", "auto"); + + pub static NIGHT_LIGHT_DESCRIPTION: String = fl!("night-light", "desc"); + + pub static ORIENTATION: String = fl!("orientation"); + + pub static ORIENTATION_LANDSCAPE: String = fl!("orientation", "landscape"); + + pub static ORIENTATION_LANDSCAPE_FLIPPED: String = fl!("orientation", "landscape-flipped"); + + pub static ORIENTATION_PORTRAIT: String = fl!("orientation", "portrait"); + + pub static ORIENTATION_PORTRAIT_FLIPPED: String = fl!("orientation", "portrait-flipped"); + + pub static SCHEDULING: String = fl!("scheduling"); + + pub static SCHEDULING_MANUAL: String = fl!("scheduling", "manual"); +} diff --git a/app/src/pages/desktop/mod.rs b/app/src/pages/desktop/mod.rs index 1daf743..5baa0db 100644 --- a/app/src/pages/desktop/mod.rs +++ b/app/src/pages/desktop/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only pub mod appearance; +pub mod display; pub mod dock; pub mod notifications; pub mod options; @@ -26,7 +27,8 @@ impl page::Page for Page { impl page::AutoBind for Page { fn sub_pages(page: page::Insert) -> page::Insert { - page.sub_page::() + page.sub_page::() + .sub_page::() .sub_page::() .sub_page::() .sub_page::() diff --git a/app/src/pages/mod.rs b/app/src/pages/mod.rs index fe3b9aa..79e82f6 100644 --- a/app/src/pages/mod.rs +++ b/app/src/pages/mod.rs @@ -13,16 +13,17 @@ pub mod time; #[derive(Clone, Debug)] pub enum Message { About(system::about::Message), + Appearance(desktop::appearance::Message), DateAndTime(time::date::Message), Desktop(desktop::Message), - Panel(desktop::panel::Message), - Dock(desktop::dock::Message), DesktopWallpaper(desktop::wallpaper::Message), - PanelApplet(desktop::panel::applets_inner::Message), - DockApplet(desktop::dock::applets::Message), - Appearance(desktop::appearance::Message), DesktopWorkspaces(desktop::workspaces::Message), - Input(input::Message), + Displays(desktop::display::Message), + Dock(desktop::dock::Message), + DockApplet(desktop::dock::applets::Message), External { id: String, message: Vec }, + Input(input::Message), Page(Entity), + Panel(desktop::panel::Message), + PanelApplet(desktop::panel::applets_inner::Message), } diff --git a/app/src/pages/sound.rs b/app/src/pages/sound.rs index f851b39..0a03627 100644 --- a/app/src/pages/sound.rs +++ b/app/src/pages/sound.rs @@ -5,6 +5,23 @@ use cosmic::widget::{settings, text}; use cosmic_settings_page::{self as page, section, Section}; use slotmap::SlotMap; +// crate::cache_dynamic_lazy! { +// pub static SOUND_ALERTS_VOLUME: String = fl!("sound-alerts", "volume"); +// pub static SOUND_ALERTS_SOUND: String = fl!("sound-alerts", "sound"); + +// pub static SOUND_APPLICATIONS_DESC: String = fl!("sound-applications", "desc"); + +// pub static SOUND_INPUT_VOLUME: String = fl!("sound-input", "volume"); +// pub static SOUND_INPUT_DEVICE: String = fl!("sound-input", "device"); +// pub static SOUND_INPUT_LEVEL: String = fl!("sound-input", "level"); + +// pub static SOUND_OUTPUT_VOLUME: String = fl!("sound-output", "volume"); +// pub static SOUND_OUTPUT_DEVICE: String = fl!("sound-output", "device"); +// pub static SOUND_OUTPUT_LEVEL: String = fl!("sound-output", "level"); +// pub static SOUND_OUTPUT_CONFIG: String = fl!("sound-output", "config"); +// pub static SOUND_OUTPUT_BALANCE: String = fl!("sound-output", "balance"); +// } + #[derive(Default)] pub struct Page; diff --git a/app/src/theme.rs b/app/src/theme.rs index 6aca215..860820c 100644 --- a/app/src/theme.rs +++ b/app/src/theme.rs @@ -1,7 +1,7 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only -use cosmic::{iced_widget::core::BorderRadius, theme}; +use cosmic::theme; #[must_use] pub fn display_container_frame() -> cosmic::theme::Container { diff --git a/debian/control b/debian/control index bfa23bb..ec1e09e 100644 --- a/debian/control +++ b/debian/control @@ -21,6 +21,6 @@ Homepage: https://github.com/pop-os/cosmic-settings Package: cosmic-settings Architecture: amd64 arm64 -Depends: ${misc:Depends}, ${shlibs:Depends} +Depends: ${misc:Depends}, ${shlibs:Depends}, cosmic-randr Description: Settings application for the COSMIC desktop environment Settings application for the COSMIC desktop environment diff --git a/i18n/en/cosmic_settings.ftl b/i18n/en/cosmic_settings.ftl index 609ce93..aab0136 100644 --- a/i18n/en/cosmic_settings.ftl +++ b/i18n/en/cosmic_settings.ftl @@ -60,6 +60,76 @@ window-management = Window Management .active-hint = Active window hint size .gaps = Gaps around tiled windows +## Desktop: Display + +-requires-restart = Requires restart + +color = Color + .depth = Color depth + .profile = Color profile + .sidebar = Color Profiles + .temperature = Color temperature + +display = Display + .desc = Manage displays, graphics switching, and night light + .arrangement = Display Arrangement + .arrangement-desc = Drag displays to rearrange them. + .enable = Enable display + .external = { $size } { $output } External Display + .laptop = { $size } Laptop Display + .options = Display Options + .refresh-rate = Refresh rate + .resolution = Resolution + .scale = Scale + +graphics-mode = Graphics mode + .mode = { $mode -> + [compute] Compute + *[hybrid] Hybrid + [integrated] Integrated + [nvidia] NVIDIA + } graphics + .enable = Enable { $mode -> + [compute] compute + *[hybrid] hybrid + [integrated] integrated + [nvidia] NVIDIA + } graphics + .desc = { $mode -> + [compute] Uses dedicated graphics for computational workloads only. Disables external displays. { -requires-restart }. + *[hybrid] Applications use integrated graphics unless explicitly requested to use dedicated graphics. { -requires-restart }. + [integrated] Turns off dedicated graphics for a longer battery life and less fan noise. + [nvidia] Better graphical experience and highest power usage. { -requires-restart }. + } + .restart = Restart and switch to { $mode }? + .restart-desc = Switching to { $mode } will close all open applications + +mirroring = Mirroring + .id = Mirroring { $id } + .dont = Don't mirror + .mirror = Mirror { $display } + .project = Project to { $display -> + [all] all displays + *[other] { $display } + } + .project-count = Projecting to { $count} other { $count -> + [1] display + *[other] displays + } + +night-light = Night Light + .auto = Automatic (sunset to sunrise) + .desc = Reduce blue light with warmer colors. + +orientation = Orientation + .landscape = Landscape + .landscape-flipped = Landscape (Flipped) + .portrait = Portrait + .portrait-flipped = Portrait (Flipped) + +scheduling = Scheduling + .manual = Manual schedule + ## Desktop: Notifications notifications = Notifications diff --git a/justfile b/justfile index a08e3cd..f2a923a 100644 --- a/justfile +++ b/justfile @@ -20,10 +20,11 @@ export RUSTFLAGS := linker-arg + env_var_or_default('RUSTFLAGS', '') rootdir := '' prefix := '/usr' +cargo-target-dir := env('CARGO_TARGET_DIR', 'target') default-schema-target := clean(rootdir / prefix) / 'share' / 'cosmic' # File paths -bin-src := 'target' / 'release' / name +bin-src := cargo-target-dir / 'release' / name bin-dest := clean(rootdir / prefix) / 'bin' / name desktop := appid + '.desktop' @@ -116,3 +117,6 @@ version: # Show the current git commit git-rev: @git rev-parse --short HEAD + +info: + echo ${RUSTFLAGS} \ No newline at end of file diff --git a/page/Cargo.toml b/page/Cargo.toml index a8e3a76..3b8e233 100644 --- a/page/Cargo.toml +++ b/page/Cargo.toml @@ -5,10 +5,10 @@ edition = "2021" [dependencies] derive_setters = "0.1.6" -regex = "1.8.3" -slotmap = "1.0.6" +regex = "1.10.2" +slotmap = "1.0.7" libcosmic = { workspace = true } -generator = "0.7.4" +generator = "0.7.5" downcast-rs = "1.2.0" -once_cell = "1.17.2" +once_cell = "1.19.0" url = "2.5.0" diff --git a/pages/desktop/Cargo.toml b/pages/desktop/Cargo.toml index f44656a..8fe8fe2 100644 --- a/pages/desktop/Cargo.toml +++ b/pages/desktop/Cargo.toml @@ -11,10 +11,10 @@ cosmic-config = { workspace = true } dirs = "5.0.1" freedesktop-icons = "0.2.4" futures-lite = "1.13.0" -image = "0.24.6" +image = "0.24.7" infer = "0.15.0" -rayon = "1.7.0" -sctk = { git = "https://github.com/smithay/client-toolkit/", package = "smithay-client-toolkit", rev = "dc8c4a0"} -tokio = { version = "1.28.0", features = ["sync"] } -tracing = "0.1.37" +rayon = "1.8.0" +sctk = { workspace = true } +tokio = { version = "1.35.1", features = ["sync"] } +tracing = "0.1.40" wayland-client = "0.31.1" diff --git a/pages/system/Cargo.toml b/pages/system/Cargo.toml index 190122f..8668a83 100644 --- a/pages/system/Cargo.toml +++ b/pages/system/Cargo.toml @@ -8,11 +8,11 @@ license = "GPL-3.0-only" [dependencies] byte-unit = { version = "4.0.19", default-features = false } -const_format = "0.2.31" +const_format = "0.2.32" concat-in-place = "1.1.0" -sysinfo = "0.29.0" -memchr = "2.5.0" +sysinfo = "0.29.11" +memchr = "2.7.1" [dependencies.bumpalo] -version = "3.13.0" +version = "3.14.0" features = ["collections"] diff --git a/pages/time/Cargo.toml b/pages/time/Cargo.toml index 18fe057..748b82b 100644 --- a/pages/time/Cargo.toml +++ b/pages/time/Cargo.toml @@ -4,11 +4,11 @@ version = "0.1.0" edition = "2021" [dependencies] -icu_calendar = "1.2.0" -icu_timezone = "1.2.0" +icu_calendar = "1.4.0" +icu_timezone = "1.4.0" timedate-zbus = "0.1.0" [dependencies.zbus] -version = "3.13.1" +version = "3.14.1" default-features = false features = ["tokio"]