diff --git a/Cargo.lock b/Cargo.lock index 64e6029..291cf93 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -334,6 +334,12 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + [[package]] name = "as-slice" version = "0.2.1" @@ -529,7 +535,7 @@ checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -600,7 +606,7 @@ dependencies = [ "derive_utils", "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -757,9 +763,9 @@ dependencies = [ [[package]] name = "blocking" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" +checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa" dependencies = [ "async-channel", "async-task", @@ -820,6 +826,7 @@ dependencies = [ [[package]] name = "build_helpers" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "cfg_aliases", ] @@ -859,7 +866,7 @@ checksum = "fc0e56a716f1e132ff6bf4bdac1c944a3fcdc1cae65f70a4a2a1ac3b401d2d1f" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -926,9 +933,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.4.3" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "509591b7bcd67f4ef775afad7662703b4935daaa6ec0e5605cfb1090b32a2b6d" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "jobserver", @@ -949,9 +956,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb693542bcafa528e198be0ebd9d3632ca5b7c93dbe7237460e199910835997c" +checksum = "fe4ece8474b5f766c63426647e7b4b316b67431ade1036a8313cee24a03ae917" dependencies = [ "smallvec", "target-lexicon", @@ -1005,6 +1012,7 @@ dependencies = [ [[package]] name = "clipboard_macos" version = "0.1.0" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "objc", "objc-foundation", @@ -1014,12 +1022,22 @@ dependencies = [ [[package]] name = "clipboard_wayland" version = "0.2.2" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "dnd", "mime 0.1.0", "smithay-clipboard", ] +[[package]] +name = "clipboard_x11" +version = "0.4.2" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" +dependencies = [ + "thiserror 1.0.69", + "x11rb", +] + [[package]] name = "cmov" version = "0.5.4" @@ -1325,25 +1343,13 @@ dependencies = [ "libm", ] -[[package]] -name = "cosmic-client-toolkit" -version = "0.2.0" -dependencies = [ - "bitflags 2.13.1", - "cosmic-protocols 0.2.0", - "libc", - "smithay-client-toolkit", - "wayland-client", - "wayland-protocols", -] - [[package]] name = "cosmic-client-toolkit" version = "0.2.0" source = "git+https://github.com/pop-os/cosmic-protocols?rev=32283d7#32283d76a8d0342da74c4cc022a533c52dcf378f" dependencies = [ "bitflags 2.13.1", - "cosmic-protocols 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=32283d7)", + "cosmic-protocols", "libc", "smithay-client-toolkit", "wayland-client", @@ -1353,6 +1359,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1373,6 +1380,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "quote", "syn 2.0.119", @@ -1380,14 +1388,14 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.6.0" +version = "1.7.0" dependencies = [ "anyhow", "atomic_float", "bstr", "bzip2", "compio", - "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=32283d7)", + "cosmic-client-toolkit", "cosmic-mime-apps", "dirs 6.0.0", "fastrand", @@ -1406,7 +1414,7 @@ dependencies = [ "jiff-icu", "jxl-oxide", "libc", - "libcosmic-yoda", + "libcosmic", "log", "lzma-rust2", "md-5", @@ -1449,7 +1457,7 @@ dependencies = [ [[package]] name = "cosmic-files-applet" -version = "1.6.0" +version = "1.7.0" dependencies = [ "cosmic-files", "log", @@ -1459,6 +1467,7 @@ dependencies = [ [[package]] name = "cosmic-freedesktop-icons" version = "0.4.0" +source = "git+https://github.com/pop-os/freedesktop-icons#ab4c57b8e416c6af9297cb04d101889896fd9a92" dependencies = [ "bstr", "btoi", @@ -1480,19 +1489,6 @@ dependencies = [ "xdg", ] -[[package]] -name = "cosmic-protocols" -version = "0.2.0" -dependencies = [ - "bitflags 2.13.1", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-protocols-wlr", - "wayland-scanner", - "wayland-server", -] - [[package]] name = "cosmic-protocols" version = "0.2.0" @@ -1510,6 +1506,7 @@ dependencies = [ [[package]] name = "cosmic-settings-config" version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#617af3feb74dcf551a7c99b2396b4c9ac22568b3" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1521,7 +1518,8 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon" -version = "0.1.1-yoda.1" +version = "0.1.0" +source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ "zbus 5.19.0", ] @@ -1529,6 +1527,8 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be17b688510d934ce13f48a2beba700e11583e281e0fda99c22bb256a14eda73" dependencies = [ "bitflags 2.13.1", "fontdb", @@ -1546,12 +1546,12 @@ dependencies = [ "unicode-linebreak", "unicode-script", "unicode-segmentation", - "unicode-width", ] [[package]] name = "cosmic-theme" version = "1.0.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "almost", "configparser", @@ -1592,9 +1592,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "8498c871161e1742aaa9d52551b2d6ebdd4c3d45a3be423e3728f33b955be550" dependencies = [ "cfg-if", ] @@ -1642,6 +1642,7 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "cryoglyph" version = "0.1.0" +source = "git+https://github.com/iced-rs/cryoglyph.git?rev=e429a025df36ab8145708acb309080ae3deec17a#e429a025df36ab8145708acb309080ae3deec17a" dependencies = [ "cosmic-text", "etagere", @@ -1677,9 +1678,9 @@ checksum = "42aaeae719fd78ce501d77c6cdf01f7e96f26bcd5617a4903a1c2b97e388543a" [[package]] name = "csscolorparser" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "199f851bd3cb5004c09474252c7f74e7c047441ed0979bf3688a7106a13da952" +checksum = "168dbdf4dced8f57fa4246ac9080598452b49d70bb2d0e46422142f113140dd8" dependencies = [ "num-traits", "phf", @@ -1687,6 +1688,15 @@ dependencies = [ "uncased", ] +[[package]] +name = "ctor" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83cf0d42651b16c6dfe68685716d18480d18a9c39c62d76e8cf3eb6ed5d8bcbf" +dependencies = [ + "dtor", +] + [[package]] name = "ctutils" version = "0.4.2" @@ -1843,7 +1853,7 @@ checksum = "dc05a5d33db20c784f873e84934ad94bb209a090987ac5f62fede2c178234f23" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -1952,7 +1962,7 @@ checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -1967,6 +1977,7 @@ dependencies = [ [[package]] name = "dnd" version = "0.1.0" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "bitflags 2.13.1", "mime 0.1.0", @@ -1993,6 +2004,52 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" version = "0.1.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" + +[[package]] +name = "drm" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" +dependencies = [ + "bitflags 2.13.1", + "bytemuck", + "drm-ffi", + "drm-fourcc", + "rustix 0.38.44", +] + +[[package]] +name = "drm-ffi" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6" +dependencies = [ + "drm-sys", + "rustix 0.38.44", +] + +[[package]] +name = "drm-fourcc" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" + +[[package]] +name = "drm-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d09ff881f92f118b11105ba5e34ff8f4adf27b30dae8f12e28c193af1c83176" +dependencies = [ + "libc", + "linux-raw-sys 0.6.5", +] + +[[package]] +name = "dtor" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edf234dd1594d6dd434a8fb8cada51ddbbc593e40e4a01556a0b31c62da2775b" [[package]] name = "dyn-clone" @@ -2002,9 +2059,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "endi" @@ -2334,9 +2391,9 @@ dependencies = [ [[package]] name = "font-types" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75382bc7392ef10aad10935f92fc3db36d2d4dad0e5d96d8d65e04f89a07ec39" +checksum = "e64eb721ca85a34323425f4041adc5d82704d3782d5f8f03793bc012419dce23" dependencies = [ "bytemuck", ] @@ -2382,7 +2439,7 @@ checksum = "ea5190182e6915eb873ddbc16e23b711b6eb1f9c00a0d0a3a91b5f6228475225" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -2512,7 +2569,7 @@ checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -2569,6 +2626,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "gethostname" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" +dependencies = [ + "rustix 1.1.4", + "windows-link 0.2.1", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -2925,7 +2992,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d37f101bf4c633f7ca2e4b5e136050314503dd198e78e325ea602c327c484ef0" dependencies = [ "arrayvec", - "rand 0.8.7", + "rand 0.8.8", "serde", ] @@ -3047,6 +3114,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "build_helpers", "dnd", @@ -3068,6 +3136,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "accesskit", "accesskit_winit", @@ -3076,11 +3145,12 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "bitflags 2.13.1", "build_helpers", "bytes", - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "dnd", "glam", "lilt", @@ -3101,6 +3171,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "iced_core", "iced_futures", @@ -3110,6 +3181,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "futures", "iced_core", @@ -3123,6 +3195,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "bitflags 2.13.1", "bytemuck", @@ -3143,6 +3216,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "iced_graphics", "iced_runtime", @@ -3151,6 +3225,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3162,10 +3237,11 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "build_helpers", "bytes", - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "dnd", "iced_core", "iced_futures", @@ -3177,6 +3253,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "bytemuck", "cosmic-text", @@ -3193,11 +3270,13 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ + "as-raw-xcb-connection", "bitflags 2.13.1", "build_helpers", "bytemuck", - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "cryoglyph", "futures", "glam", @@ -3211,19 +3290,22 @@ dependencies = [ "rustc-hash 2.1.3", "rustix 0.38.44", "thiserror 2.0.20", + "tiny-xlib", "wayland-backend", "wayland-client", "wayland-protocols", "wayland-sys", "wgpu", + "x11rb", ] [[package]] name = "iced_widget" version = "0.14.2" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "build_helpers", - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "dnd", "iced_renderer", "iced_runtime", @@ -3239,9 +3321,10 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "build_helpers", - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "cursor-icon", "dnd", "iced_debug", @@ -3270,9 +3353,9 @@ dependencies = [ [[package]] name = "icu" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d5080b89807979ab05f8b6f3c6bbd580ece1512a6cf4cf800baa76937e488b3" +checksum = "4867dd3a39b9d48632416cc7fc3dfa1913d89fd36cc02fe7bfc1dddc6fda3cde" dependencies = [ "icu_calendar", "icu_casemap", @@ -3340,9 +3423,9 @@ checksum = "059fcda0fc8d33effc6633a8cf0d8a3c17caf7d7c91918fba9918744f501e4e8" [[package]] name = "icu_collator" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59eea194d189ca897bcb960fd2130f9e7d53998460d4d32e85a60b10d5507cf4" +checksum = "08984ed58ac439ebf3e13d2cf26b0c46a60afcd21721c1d14087c0b240344dda" dependencies = [ "icu_collator_data", "icu_collections", @@ -3495,9 +3578,9 @@ checksum = "4ffef91ee351bd195a803115615a034dfb9f02bb48850980548c31cb78568a91" [[package]] name = "icu_locale" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "250ec6d4ac288584d1d0ba29dbfad7737635b7b0e822441f4026a523e3fdb147" +checksum = "785f595c61ef57169a467eeed7b4b6936a66f6cacbb116a96ee86da983251bf4" dependencies = [ "icu_collections", "icu_locale_core", @@ -3628,9 +3711,9 @@ checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92a7ed671a6aad807a8651a2e1782a6598fda9ce5185dd8158549e95a91c6428" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -4381,14 +4464,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] -name = "libcosmic-yoda" -version = "0.1.0-yoda.2" +name = "libcosmic" +version = "1.0.0" +source = "git+https://github.com/pop-os/libcosmic.git#2a73fbc0edfe1525381bf999e241d73def79b222" dependencies = [ "apply", "ashpd 0.12.3", "auto_enums", "build_helpers", - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "cosmic-config", "cosmic-freedesktop-icons", "cosmic-settings-config", @@ -4469,7 +4553,7 @@ dependencies = [ "bitflags 2.13.1", "libc", "plain", - "redox_syscall 0.9.2", + "redox_syscall 0.9.3", ] [[package]] @@ -4493,6 +4577,12 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" + [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -4535,9 +4625,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "loom" @@ -4732,6 +4822,7 @@ dependencies = [ [[package]] name = "mime" version = "0.1.0" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "smithay-clipboard", ] @@ -5290,9 +5381,9 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "open" -version = "5.4.1" +version = "5.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cfef937e9c486488c7e3d949ae31c0f1d06bdacd75b99c086cb35356e30408" +checksum = "ade3be4664bc1ef537ce133015f04c176b737815c2ba9fd60edf212d6e90dd55" dependencies = [ "is-wsl", "libc", @@ -5316,9 +5407,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "5.3.0" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" +checksum = "8c7c9e0d9b23589f26070720bac724174bfec1083e82f7854cdd0267518343c0" dependencies = [ "num-traits", ] @@ -5708,7 +5799,7 @@ dependencies = [ "proc-macro-error-attr3", "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -5871,9 +5962,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -6043,7 +6134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046a7d674daf459825b32f5062056d6882db0d2f5a479fbd76ccfc870ac18709" dependencies = [ "bytemuck", - "font-types 0.12.3", + "font-types 0.12.4", "once_cell", ] @@ -6090,9 +6181,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c93da5bb2c5d4e6c0ef7abeead62c89169a0a4882bfb83ac892f2423aea2fe" +checksum = "d678d17679829e73d371e96880897e98fee2ded7acc0a50bdf8af2affa4b2fe5" dependencies = [ "bitflags 2.13.1", ] @@ -6121,22 +6212,22 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216e8f773d7923bcba9ceb86a86c93cabb3903a11872fc3f138c49630e50b96d" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9283685feec7d69af75fb0e858d5e7378f33fe4fc699383b2916ab9273e03c" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -6460,7 +6551,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -6485,7 +6576,7 @@ checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -6725,6 +6816,7 @@ dependencies = [ [[package]] name = "smithay-clipboard" version = "0.8.0" +source = "git+https://github.com/pop-os/smithay-clipboard?tag=sctk-0.20#859b02c88f45c554049a67c6ddeec1692ce0e20b" dependencies = [ "libc", "raw-window-handle", @@ -6755,26 +6847,31 @@ dependencies = [ [[package]] name = "softbuffer" version = "0.4.1" +source = "git+https://github.com/pop-os/softbuffer?tag=cosmic-4.0#c2b2c19ddb38ff17495643699f97cb1f2064a1be" dependencies = [ + "as-raw-xcb-connection", "bytemuck", "cfg_aliases", "cocoa", "core-graphics", + "drm", "fastrand", "foreign-types", "js-sys", - "libredox", "log", "memmap2 0.9.11", "objc", "raw-window-handle", + "redox_syscall 0.5.18", "rustix 0.38.44", + "tiny-xlib", "wasm-bindgen", "wayland-backend", "wayland-client", "wayland-sys", "web-sys", "windows-sys 0.52.0", + "x11rb", ] [[package]] @@ -6862,9 +6959,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" dependencies = [ "proc-macro2", "quote", @@ -7057,7 +7154,7 @@ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -7185,6 +7282,19 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tiny-xlib" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a90a0ca3ee6a69f2ad28fd11621a4c3f03b371f366be500b64df260c4ffbafb4" +dependencies = [ + "as-raw-xcb-connection", + "ctor", + "libloading", + "pkg-config", + "tracing", +] + [[package]] name = "tinystr" version = "0.8.4" @@ -7236,7 +7346,7 @@ checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -7597,9 +7707,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.24.1" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cefc03fd367c0c6d4305de1b312cf00248c4114f4a0418ce6a6af769e3b0bd9" +checksum = "f053576934f05a761a402421fbbe3d425d9366f75f978806a037b3ca481abecc" dependencies = [ "getrandom 0.4.3", "js-sys", @@ -8106,10 +8216,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window_clipboard" version = "0.4.1" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "clipboard-win", "clipboard_macos", "clipboard_wayland", + "clipboard_x11", "dnd", "mime 0.1.0", "raw-window-handle", @@ -8611,6 +8723,7 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" dependencies = [ "bitflags 2.13.1", "cfg_aliases", @@ -8630,11 +8743,13 @@ dependencies = [ "winit-wayland", "winit-web", "winit-win32", + "winit-x11", ] [[package]] name = "winit-android" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" dependencies = [ "android-activity", "bitflags 2.13.1", @@ -8649,6 +8764,7 @@ dependencies = [ [[package]] name = "winit-appkit" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" dependencies = [ "bitflags 2.13.1", "block2 0.6.2", @@ -8670,6 +8786,7 @@ dependencies = [ [[package]] name = "winit-common" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" dependencies = [ "memmap2 0.9.11", "objc2 0.6.4", @@ -8677,12 +8794,14 @@ dependencies = [ "smol_str", "tracing", "winit-core", + "x11-dl", "xkbcommon-dl", ] [[package]] name = "winit-core" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" dependencies = [ "bitflags 2.13.1", "cursor-icon", @@ -8696,6 +8815,7 @@ dependencies = [ [[package]] name = "winit-orbital" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" dependencies = [ "bitflags 2.13.1", "dpi", @@ -8711,6 +8831,7 @@ dependencies = [ [[package]] name = "winit-uikit" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" dependencies = [ "bitflags 2.13.1", "block2 0.6.2", @@ -8730,6 +8851,7 @@ dependencies = [ [[package]] name = "winit-wayland" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" dependencies = [ "ahash", "bitflags 2.13.1", @@ -8755,6 +8877,7 @@ dependencies = [ [[package]] name = "winit-web" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" dependencies = [ "atomic-waker", "bitflags 2.13.1", @@ -8776,6 +8899,7 @@ dependencies = [ [[package]] name = "winit-win32" version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" dependencies = [ "bitflags 2.13.1", "cursor-icon", @@ -8788,6 +8912,29 @@ dependencies = [ "winit-core", ] +[[package]] +name = "winit-x11" +version = "0.31.0-beta.2" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#71ce08c043814514a8fd92d9d0599f115ae854e8" +dependencies = [ + "bitflags 2.13.1", + "bytemuck", + "calloop", + "cursor-icon", + "dpi", + "libc", + "percent-encoding", + "raw-window-handle", + "rustix 1.1.4", + "smol_str", + "tracing", + "winit-common", + "winit-core", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + [[package]] name = "winnow" version = "1.0.4" @@ -8818,6 +8965,39 @@ dependencies = [ "either", ] +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix 1.1.4", + "x11rb-protocol", + "xcursor", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" + [[package]] name = "xattr" version = "1.6.1" @@ -9021,7 +9201,7 @@ dependencies = [ "hex", "nix", "ordered-stream", - "rand 0.8.7", + "rand 0.8.8", "serde", "serde_repr", "sha1 0.10.7", @@ -9117,7 +9297,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", "zbus_names 4.3.4", "zvariant 5.15.0", "zvariant_utils 4.2.0", @@ -9233,9 +9413,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b5c6b5976d66c1d703c4fd17d3f5e43c8cedaacf604961b171adc7130896d8" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "serde", "yoke", @@ -9245,13 +9425,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f212a141d820099d57ffafb9569be9617a6f27d3dc881fbee8fb56642f917a9" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -9423,7 +9603,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", "zvariant_utils 4.2.0", ] @@ -9447,25 +9627,6 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 3.0.3", + "syn 3.0.4", "winnow", ] - -[[patch.unused]] -name = "dnd" -version = "0.1.0" -source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#af8e6a872d8ac4956e044b9cb05a615a48261a57" - -[[patch.unused]] -name = "mime" -version = "0.1.0" -source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#af8e6a872d8ac4956e044b9cb05a615a48261a57" - -[[patch.unused]] -name = "window_clipboard" -version = "0.4.1" -source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#af8e6a872d8ac4956e044b9cb05a615a48261a57" - -[[patch.unused]] -name = "winit-x11" -version = "0.31.0-beta.2" diff --git a/Cargo.toml b/Cargo.toml index a2a95dd..f9eae09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.6.0" +version = "1.7.0" authors = ["Jeremy Soller "] edition = "2024" license = "GPL-3.0-only" diff --git a/cosmic-files-applet/Cargo.toml b/cosmic-files-applet/Cargo.toml index cc632ae..8d396ae 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files-applet" -version = "1.6.0" +version = "1.7.0" edition = "2024" [dependencies] diff --git a/debian/changelog b/debian/changelog index 65f6401..6cbee03 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-files (1.7.0) noble; urgency=medium + + * Epoch 1.7.0 version update + + -- Jeremy Soller Tue, 25 Aug 2026 09:20:22 -0600 + cosmic-files (1.6.0) noble; urgency=medium * Epoch 1.6.0 version update diff --git a/i18n/da/cosmic_files.ftl b/i18n/da/cosmic_files.ftl index 2d0e35d..5666fdb 100644 --- a/i18n/da/cosmic_files.ftl +++ b/i18n/da/cosmic_files.ftl @@ -5,7 +5,7 @@ no-results = Fandt ingen resultater filesystem = Filsystem home = Hjem networks = Netværk -notification-in-progress = Fil-operationer er igang. +notification-in-progress = Fil-operationer er igang trash = Papirkurv recents = Seneste undo = Fortryd @@ -69,7 +69,7 @@ name-no-slashes = Navn må ikke indeholde skråstreger ## Open/Save Dialog -cancel = Annuller +cancel = Afbryd create = Opret open = Åbn open-file = Åbn fil @@ -95,7 +95,7 @@ rename-folder = Omdøb mappe ## Replace Dialog replace = Erstat -replace-title = "{ $filename }" eksisterer allerede i denne placering. +replace-title = "{ $filename }" eksisterer allerede i denne placering replace-warning = Ønsker du at erstatte den med den, du er ved at gemme? Erstatning af den vil overskrive dens indhold. replace-warning-operation = Ønsker du at erstatte den? Erstatning af den vil overskrive dens indhold. original-file = Original fil @@ -253,7 +253,7 @@ light = Lyst # Context menu add-to-sidebar = Tilføj til sidebjælke compress = Komprimer… -extract-here = Extract +extract-here = Uddrag new-file = Ny fil... new-folder = Ny mappe... open-in-terminal = Åbn i terminal @@ -332,7 +332,7 @@ deleted = Slettede { $items } { $items -> [one] element *[other] elementer - } fra papirkurven + } fra { trash } removing-from-recents = Fjerner { $items } { $items -> [one] element @@ -360,7 +360,7 @@ remove = Fjern context-action = Konteksthandling context-action-confirm-title = Kør “{ $name }”? context-action-confirm-warning = - This will run on { $items } { $items -> + Dette vil køre på { $items } { $items -> [one] item *[other] items }. diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 2a1938a..b97ff88 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -119,6 +119,9 @@ rename-file = Rename file rename-folder = Rename folder rename-confirm = Rename +## Change Sidebar Label Dialog +sidebar-label = Sidebar label + ## Replace Dialog replace = Replace replace-title = "{$filename}" already exists in this location @@ -299,6 +302,7 @@ unknown-folder = unknown folder ## Open with menu-open-with = Open with... default-app = {$name} (default) +search-application = Search by app name ## Show details show-details = Show details @@ -347,6 +351,7 @@ move-to = Move to... move-to-trash = Move to trash restore-from-trash = Restore from trash remove-from-sidebar = Remove from sidebar +change-sidebar-label = Change sidebar label sort-by-name = Sort by name sort-by-modified = Sort by modified sort-by-size = Sort by size diff --git a/i18n/pt-BR/cosmic_files.ftl b/i18n/pt-BR/cosmic_files.ftl index 75b071d..b47214a 100644 --- a/i18n/pt-BR/cosmic_files.ftl +++ b/i18n/pt-BR/cosmic_files.ftl @@ -109,6 +109,10 @@ permanently-delete-warning = Deseja realmente excluir permanentemente { $target rename-file = Renomear arquivo rename-folder = Renomear pasta +## Change Sidebar Label Dialog + +sidebar-label = Rótulo da barra lateral + ## Replace Dialog replace = Substituir @@ -350,7 +354,7 @@ light = Estilo claro ### Type to Search -type-to-search = Digite para pesquisar +type-to-search = Digitar para pesquisar type-to-search-recursive = Pesquisa na pasta atual e em todas as subpastas type-to-search-enter-path = Insere o caminho do diretório ou arquivo # Context menu @@ -365,6 +369,7 @@ open-in-terminal = Abrir no terminal move-to-trash = Mover para a lixeira restore-from-trash = Restaurar da lixeira remove-from-sidebar = Remover da barra lateral +change-sidebar-label = Alterar rótulo na barra lateral sort-by-name = Ordenar por nome sort-by-modified = Ordenar por data de modificação sort-by-size = Ordenar por tamanho diff --git a/i18n/ru/cosmic_files.ftl b/i18n/ru/cosmic_files.ftl index d3dd432..8b1f7f2 100644 --- a/i18n/ru/cosmic_files.ftl +++ b/i18n/ru/cosmic_files.ftl @@ -174,6 +174,7 @@ unknown-folder = неизвестная папка menu-open-with = Открыть с помощью… default-app = { $name } (по умолчанию) +search-application = Поиск по названию приложения ## Show details diff --git a/src/app.rs b/src/app.rs index 7c0c30b..66fdcb4 100644 --- a/src/app.rs +++ b/src/app.rs @@ -37,7 +37,7 @@ use cosmic::widget::menu::action::MenuAction; use cosmic::widget::menu::key_bind::KeyBind; use cosmic::widget::segmented_button::{self, Entity, ReorderEvent}; use cosmic::widget::{self, icon, settings, space}; -use cosmic::{Application, ApplicationExt, Element, cosmic_theme, executor, style, surface, theme}; +use cosmic::{Application, ApplicationExt, Element, cosmic_theme, executor, surface, theme}; use mime_guess::Mime; use notify_debouncer_full::notify::{self, RecommendedWatcher}; use notify_debouncer_full::{DebouncedEvent, Debouncer, RecommendedCache, new_debouncer}; @@ -428,6 +428,7 @@ pub enum NavMenuAction { Preview(segmented_button::Entity), RunContextAction(segmented_button::Entity, usize), RemoveFromSidebar(segmented_button::Entity), + ChangeSidebarLabel(segmented_button::Entity), } impl MenuAction for NavMenuAction { @@ -503,6 +504,7 @@ pub enum Message { OpenWithBrowse, OpenWithDialog(Option), OpenWithSelection(usize), + OpenWithSearchClear, OpenWithToggleDefault(bool), #[cfg(all(feature = "wayland", feature = "desktop-applet"))] Overlap(window::Id, OverlapNotifyEvent), @@ -691,6 +693,7 @@ pub enum DialogPage { mime: mime_guess::Mime, selected: usize, store_opt: Option>, + search_app_name: String, /// When true, the chosen app is written to mimeapps.list as the /// default handler for `mime` after it spawns. set_default: bool, @@ -701,6 +704,10 @@ pub enum DialogPage { DeleteTrash { items: Vec, }, + ChangeSidebarLabel { + entity: Entity, + label: String, + }, RenameItem { from: PathBuf, parent: PathBuf, @@ -1956,15 +1963,9 @@ impl App { for (favorite_i, favorite) in self.config.favorites.iter().enumerate() { if let Some(path) = favorite.path_opt() { - let name = if matches!(favorite, Favorite::Home) { - fl!("home") - } else if let Favorite::Network { name, .. } = favorite { - name.clone() - } else if let Some(file_name) = path.file_name().and_then(|x| x.to_str()) { - file_name.to_string() - } else { - fl!("filesystem") - }; + let name = favorite + .display_name() + .unwrap_or_else(|| fl!("filesystem")); nav_model = nav_model.insert(move |b| { b.text(name.clone()) .icon( @@ -2601,15 +2602,33 @@ impl App { .favorites .iter() .map(|favorite| { - if let Favorite::Path(path) = favorite { - for (from, to) in path_changes.iter().map(|(f, t)| (f.as_ref(), t.as_ref())) { - if path.starts_with(from) - && let Ok(relative) = path.strip_prefix(from) + match favorite { + Favorite::Path(path) => { + for (from, to) in path_changes.iter().map(|(f, t)| (f.as_ref(), t.as_ref())) { - favorites_changed = true; - return Favorite::from_path(to.join(relative)); + if path.starts_with(from) + && let Ok(relative) = path.strip_prefix(from) + { + favorites_changed = true; + return Favorite::from_path(to.join(relative)); + } } } + Favorite::Named { path, name } => { + for (from, to) in path_changes.iter().map(|(f, t)| (f.as_ref(), t.as_ref())) + { + if path.starts_with(from) + && let Ok(relative) = path.strip_prefix(from) + { + favorites_changed = true; + return Favorite::Named { + path: to.join(relative), + name: name.clone(), + }; + } + } + } + _ => {} } favorite.clone() }) @@ -2925,6 +2944,11 @@ impl Application for App { } items.push(cosmic::widget::menu::Item::Divider); if favorite_index_opt.is_some() { + items.push(cosmic::widget::menu::Item::Button( + fl!("change-sidebar-label"), + None, + NavMenuAction::ChangeSidebarLabel(entity), + )); items.push(cosmic::widget::menu::Item::Button( fl!("remove-from-sidebar"), None, @@ -3216,7 +3240,8 @@ impl Application for App { } else { Favorite::from_path(path) }; - if !favorites.contains(&favorite) { + let favorite_path = favorite.path_opt(); + if !favorites.iter().any(|f| f.path_opt() == favorite_path) { favorites.push(favorite); } } @@ -3523,10 +3548,18 @@ impl Application for App { path, mime, selected, + search_app_name, set_default, .. } => { - let available_apps = self.mime_app_cache.get_apps_for_mime(&mime, true); + let mut available_apps = + self.mime_app_cache.get_apps_for_mime(&mime, true); + available_apps.retain(|(app, _)| { + app.name + .to_lowercase() + .trim() + .contains(search_app_name.to_lowercase().as_str().trim()) + }); if let Some((app, _)) = available_apps.get(selected) { if let Some(mut command) = @@ -3572,6 +3605,18 @@ impl Application for App { DialogPage::DeleteTrash { items } => { tasks.push(self.operation(Operation::DeleteTrash { items })); } + DialogPage::ChangeSidebarLabel { entity, label } => { + if let Some(FavoriteIndex(favorite_i)) = + self.nav_model.data::(entity) + { + let mut favorites = self.config.favorites.clone(); + if let Some(favorite) = favorites.get_mut(*favorite_i) { + *favorite = favorite.with_label(label.trim()); + config_set!(favorites, favorites); + tasks.push(self.update_config()); + } + } + } DialogPage::RenameItem { from, parent, name, .. } => { @@ -4173,21 +4218,25 @@ impl Application for App { let Some(path) = item.path_opt() else { continue; }; - return self.push_dialog( - DialogPage::OpenWith { - path: path.clone(), - mime: item.mime.clone(), - selected: 0, - store_opt: "x-scheme-handler/mime" - .parse::() - .ok() - .and_then(|mime| { - self.mime_app_cache.get(&mime).first().cloned() - }), - set_default: false, - }, - Some(CONFIRM_OPEN_WITH_BUTTON_ID.clone()), - ); + return Task::batch([ + self.push_dialog( + DialogPage::OpenWith { + path: path.clone(), + mime: item.mime.clone(), + selected: 0, + store_opt: "x-scheme-handler/mime" + .parse::() + .ok() + .and_then(|mime| { + self.mime_app_cache.get(&mime).first().cloned() + }), + search_app_name: String::new(), + set_default: false, + }, + Some(CONFIRM_OPEN_WITH_BUTTON_ID.clone()), + ), + widget::text_input::focus(self.dialog_text_input.clone()), + ]); } } } @@ -4203,6 +4252,14 @@ impl Application for App { *set_default = enabled; } } + Message::OpenWithSearchClear => { + if let Some(DialogPage::OpenWith { + search_app_name, .. + }) = self.dialog_pages.front_mut() + { + *search_app_name = String::new(); + } + } Message::Paste(entity_opt) => { let entity = entity_opt.unwrap_or_else(|| self.tab_model.active()); if let Some(tab) = self.tab_model.data_mut::(entity) @@ -4888,7 +4945,8 @@ impl Application for App { tab::Command::AddToSidebar(path) => { let mut favorites = self.config.favorites.clone(); let favorite = Favorite::from_path(path); - if !favorites.contains(&favorite) { + let favorite_path = favorite.path_opt(); + if !favorites.iter().any(|f| f.path_opt() == favorite_path) { favorites.push(favorite); } config_set!(favorites, favorites); @@ -5537,6 +5595,7 @@ impl Application for App { .and_then(|mime| { self.mime_app_cache.get(&mime).first().cloned() }), + search_app_name: String::new(), set_default: false, }, None, @@ -5672,6 +5731,26 @@ impl Application for App { return self.update_config(); } } + + NavMenuAction::ChangeSidebarLabel(entity) => { + if let Some(favorite) = self + .nav_model + .data::(entity) + .and_then(|FavoriteIndex(favorite_i)| { + self.config.favorites.get(*favorite_i) + }) + { + let label = favorite + .display_name() + .unwrap_or_else(|| fl!("filesystem")); + return Task::batch([ + self.dialog_pages + .push_back(DialogPage::ChangeSidebarLabel { entity, label }), + widget::text_input::focus(self.dialog_text_input.clone()), + widget::text_input::select_all(self.dialog_text_input.clone()), + ]); + } + } }, Message::Recents => { if self.config.show_recents { @@ -6394,7 +6473,9 @@ impl Application for App { mime, selected, store_opt, + search_app_name, set_default, + .. } => { let name = match path.file_name() { Some(file_name) => file_name.to_str(), @@ -6402,7 +6483,13 @@ impl Application for App { }; let mut column = widget::list_column(); - let available_apps = self.mime_app_cache.get_apps_for_mime(mime, true); + let mut available_apps = self.mime_app_cache.get_apps_for_mime(mime, true); + available_apps.retain(|(app, _)| { + app.name + .to_lowercase() + .trim() + .contains(search_app_name.to_lowercase().as_str().trim()) + }); let item_height = 32.0; let mut displayed_default = false; let mut last_kind = MimeAppMatch::Exact; @@ -6466,6 +6553,25 @@ impl Application for App { .secondary_action( widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), ) + .control( + widget::text_input::search_input( + fl!("search-application"), + search_app_name, + ) + .id(self.dialog_text_input.clone()) + .on_clear(Message::OpenWithSearchClear) + .on_input(move |search_app_name| { + Message::DialogUpdate(DialogPage::OpenWith { + path: path.clone(), + mime: mime.clone(), + selected: *selected, + store_opt: store_opt.clone(), + search_app_name, + set_default: *set_default, + }) + }) + .on_submit(|_| Message::DialogComplete), + ) .control(widget::scrollable(column).height({ let max_size = self .size @@ -6554,6 +6660,40 @@ impl Application for App { target = target ))) } + DialogPage::ChangeSidebarLabel { entity, label } => { + let entity = *entity; + let complete_maybe = if label.trim().is_empty() { + None + } else { + Some(Message::DialogComplete) + }; + + widget::dialog() + .title(fl!("change-sidebar-label")) + .primary_action( + widget::button::suggested(fl!("save")) + .on_press_maybe(complete_maybe.clone()), + ) + .secondary_action( + widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), + ) + .control( + widget::column::with_children([ + widget::text::body(fl!("sidebar-label")).into(), + widget::text_input("", label.as_str()) + .id(self.dialog_text_input.clone()) + .on_input(move |label| { + Message::DialogUpdate(DialogPage::ChangeSidebarLabel { + entity, + label, + }) + }) + .on_submit_maybe(complete_maybe.map(|maybe| move |_| maybe.clone())) + .into(), + ]) + .spacing(space_xxs), + ) + } DialogPage::RenameItem { from, parent, diff --git a/src/config.rs b/src/config.rs index 8f493c0..aeefafc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -70,6 +70,11 @@ pub enum Favorite { name: String, path: PathBuf, }, + /// A path with a custom name chosen by the user + Named { + path: PathBuf, + name: String, + }, } impl Favorite { @@ -98,6 +103,38 @@ impl Favorite { Self::Videos => dirs::video_dir(), Self::Path(path) => Some(path.clone()), Self::Network { path, .. } => Some(path.clone()), + Self::Named { path, .. } => Some(path.clone()), + } + } + + /// Name shown in the sidebar, or `None` if the path has no usable file name + pub fn display_name(&self) -> Option { + match self { + Self::Home => Some(crate::fl!("home")), + Self::Named { name, .. } | Self::Network { name, .. } => Some(name.clone()), + _ => self + .path_opt()? + .file_name() + .and_then(|x| x.to_str()) + .map(ToString::to_string), + } + } + + /// Return this favorite with a custom sidebar label chosen by the user + pub fn with_label(&self, name: &str) -> Self { + match self { + Self::Network { uri, path, .. } => Self::Network { + uri: uri.clone(), + name: name.to_string(), + path: path.clone(), + }, + other => match other.path_opt() { + Some(path) => Self::Named { + path, + name: name.to_string(), + }, + None => other.clone(), + }, } } } @@ -476,3 +513,66 @@ pub const TIME_CONFIG_ID: &str = "com.system76.CosmicAppletTime"; pub struct TimeConfig { pub military_time: bool, } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn favorite_with_label_converts_path_to_named() { + let favorite = Favorite::Path(PathBuf::from("/some/dir")); + assert_eq!( + favorite.with_label("Custom"), + Favorite::Named { + path: PathBuf::from("/some/dir"), + name: "Custom".to_string(), + } + ); + } + + #[test] + fn favorite_with_label_updates_network_in_place() { + let favorite = Favorite::Network { + uri: "sftp://example.com/".to_string(), + name: "example.com".to_string(), + path: PathBuf::from("/run/mount/example"), + }; + assert_eq!( + favorite.with_label("Custom"), + Favorite::Network { + uri: "sftp://example.com/".to_string(), + name: "Custom".to_string(), + path: PathBuf::from("/run/mount/example"), + } + ); + } + + #[test] + fn favorite_with_label_converts_special_folder_to_named() { + let home = dirs::home_dir().unwrap(); + assert_eq!( + Favorite::Home.with_label("Custom"), + Favorite::Named { + path: home, + name: "Custom".to_string(), + } + ); + } + + #[test] + fn favorite_display_name() { + assert_eq!( + Favorite::Path(PathBuf::from("/some/dir")).display_name(), + Some("dir".to_string()) + ); + assert_eq!(Favorite::Path(PathBuf::from("/")).display_name(), None); + assert_eq!( + Favorite::Named { + path: PathBuf::from("/some/dir"), + name: "Custom".to_string(), + } + .display_name(), + Some("Custom".to_string()) + ); + } +} diff --git a/src/dialog.rs b/src/dialog.rs index 7071ab3..d60a837 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -32,9 +32,7 @@ use std::{env, fmt, fs}; use crate::app::{ Action, ContextPage, Message as AppMessage, PreviewItem, PreviewKind, REPLACE_BUTTON_ID, }; -use crate::config::{ - Config, DialogConfig, Favorite, TIME_CONFIG_ID, ThumbCfg, TimeConfig, TypeToSearch, -}; +use crate::config::{Config, DialogConfig, TIME_CONFIG_ID, ThumbCfg, TimeConfig, TypeToSearch}; use crate::key_bind::key_binds; use crate::localize::LANGUAGE_SORTER; use crate::mounter::{MOUNTERS, MounterItem, MounterItems, MounterKey, MounterMessage}; @@ -895,13 +893,7 @@ impl App { for favorite in &self.flags.config.favorites { if let Some(path) = favorite.path_opt() { - let name = if matches!(favorite, Favorite::Home) { - fl!("home") - } else if let Favorite::Network { name, .. } = favorite { - name.clone() - } else if let Some(file_name) = path.file_name().and_then(|x| x.to_str()) { - file_name.to_string() - } else { + let Some(name) = favorite.display_name() else { continue; }; nav_model = nav_model.insert(move |b| { diff --git a/src/mounter/gvfs.rs b/src/mounter/gvfs.rs index 1b7af76..b675dd0 100644 --- a/src/mounter/gvfs.rs +++ b/src/mounter/gvfs.rs @@ -18,6 +18,15 @@ use crate::tab::{self, ChecksumState, DirSize, ItemMetadata, ItemThumbnail, Loca const TARGET_URI_ATTRIBUTE: &str = "standard::target-uri"; +// Attributes requested when listing a network directory. +const SCAN_ATTRIBUTES: &str = "standard::name,\ +standard::display-name,\ +standard::type,\ +standard::size,\ +standard::icon,\ +standard::is-hidden,\ +time::modified"; + fn resolve_uri(uri: &str) -> (String, gio::File) { let file = gio::File::for_uri(uri); // Resolve the target-uri if it exists @@ -119,9 +128,27 @@ fn network_scan(uri: &str, sizes: IconSizes) -> Result, String> { Box::from([]) }; + // `filesystem::remote` belongs to the filesystem namespace, which `enumerate_children` + // never fills in, so it has to be queried once for the directory being listed. + let remote = file + .query_filesystem_info( + gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE, + gio::Cancellable::NONE, + ) + .map(|info| info.boolean(gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE)) + .unwrap_or_else(|err| { + log::warn!("failed to get GIO filesystem info for {uri}: {err}"); + // Assume remote, so per-entry work is skipped rather than retried + true + }); + let mut items = Vec::new(); for info_res in file - .enumerate_children("*", gio::FileQueryInfoFlags::NONE, gio::Cancellable::NONE) + .enumerate_children( + SCAN_ATTRIBUTES, + gio::FileQueryInfoFlags::NONE, + gio::Cancellable::NONE, + ) .map_err(err_str)? { let info = info_res.map_err(err_str)?; @@ -133,13 +160,17 @@ fn network_scan(uri: &str, sizes: IconSizes) -> Result, String> { //TODO: what is the best way to resolve shortcuts? let location = Location::Network(uri, display_name.clone(), file.child(&name).path()); - let metadata = if !force_dir && !info.boolean(gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE) { + let metadata = if force_dir { + ItemMetadata::SimpleDir { entries: 0 } + } else { let mtime = info.attribute_uint64(gio::FILE_ATTRIBUTE_TIME_MODIFIED); let is_dir = matches!(info.file_type(), gio::FileType::Directory); let size_opt = (!is_dir).then_some(info.size() as u64); let mut children_opt = None; - if is_dir { + // Counting children costs a directory listing per entry, which is far too + // expensive on a remote filesystem + if is_dir && !remote { if let Some(path) = file.child(&name).path() { //TODO: calculate children in the background (and make it cancellable?) match std::fs::read_dir(&path) { @@ -159,9 +190,8 @@ fn network_scan(uri: &str, sizes: IconSizes) -> Result, String> { mtime, size_opt, children_opt, + is_dir, } - } else { - ItemMetadata::SimpleDir { entries: 0 } }; let (mime, icon_handle_grid, icon_handle_list, icon_handle_list_condensed) = { diff --git a/src/tab.rs b/src/tab.rs index 1b72958..635e2d1 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -458,7 +458,9 @@ impl<'a> FormatTime<'a> { impl Display for FormatTime<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let zoned = jiff::Zoned::try_from(self.time).unwrap(); + let Ok(zoned) = jiff::Zoned::try_from(self.time) else { + return Ok(()); + }; let now = jiff::Zoned::now(); let icu_datetime = DateTime::convert_from(zoned.datetime()); if zoned.date() == now.date() { @@ -661,6 +663,41 @@ fn display_name_for_file(path: &Path, name: &str, get_from_gvfs: bool, is_deskto Item::display_name(name) } +// Whether a dir lives on a remote filesystem, according to GIO. +#[cfg(feature = "gvfs")] +fn gvfs_dir_is_remote(dir: &Path) -> bool { + static REMOTE_CACHE: LazyLock>> = + LazyLock::new(|| RwLock::new(FxHashMap::default())); + + if let Some(remote) = REMOTE_CACHE.read().unwrap().get(dir) { + return *remote; + } + + let remote = match gio::prelude::FileExt::query_filesystem_info( + &gio::File::for_path(dir), + gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE, + gio::Cancellable::NONE, + ) { + Ok(info) => info.boolean(gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE), + Err(err) => { + log::warn!( + "failed to get GIO filesystem info for {}: {}", + dir.display(), + err + ); + + //Assume remote so that the "expensive tasks" are rather skipped then actually executed. + true + } + }; + + REMOTE_CACHE + .write() + .unwrap() + .insert(dir.to_path_buf(), remote); + remote +} + #[cfg(feature = "gvfs")] pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconSizes) -> Item { let file_name = file_info @@ -668,7 +705,7 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS .unwrap_or_default(); let mtime = file_info.attribute_uint64(gio::FILE_ATTRIBUTE_TIME_MODIFIED); let mut is_desktop = false; - let remote = file_info.boolean(gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE); + let remote = path.parent().is_none_or(gvfs_dir_is_remote); let is_dir = matches!(file_info.file_type(), gio::FileType::Directory); let size_opt = (!is_dir).then_some(file_info.size() as u64); @@ -729,6 +766,7 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS mtime, size_opt, children_opt, + is_dir, }, hidden, image_dimensions: (!remote && mime.type_() == mime::IMAGE) @@ -783,23 +821,7 @@ pub fn item_from_entry( #[cfg(feature = "gvfs")] FsKind::Gvfs => { is_gvfs = true; - let file = gio::File::for_path(&path); - - match gio::prelude::FileExt::query_filesystem_info( - &file, - gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE, - gio::Cancellable::NONE, - ) { - Ok(info) => info.boolean(gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE), - Err(err) => { - log::warn!( - "failed to get GIO filesystem info for {}: {}", - path.display(), - err - ); - true - } - } + path.parent().is_none_or(gvfs_dir_is_remote) } #[cfg(not(feature = "gvfs"))] FsKind::Gvfs => { @@ -1024,7 +1046,6 @@ pub fn scan_path(tab_path: &PathBuf, sizes: IconSizes) -> Vec { // gio crate expects a comma delimited string let attr_string = [ gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME.as_str(), - gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE.as_str(), gio::FILE_ATTRIBUTE_TIME_MODIFIED.as_str(), gio::FILE_ATTRIBUTE_STANDARD_SIZE.as_str(), gio::FILE_ATTRIBUTE_STANDARD_TYPE.as_str(), @@ -1833,6 +1854,8 @@ pub enum Message { HighlightDeactivate(usize), HighlightActivate(usize), DirectorySize(PathBuf, DirSize), + #[cfg(feature = "gvfs")] + DirectoryChildren(PathBuf, usize), Checksums(PathBuf, ChecksumState), CalculateChecksums(PathBuf), CopyChecksum(String), @@ -1901,6 +1924,7 @@ pub enum ItemMetadata { mtime: u64, size_opt: Option, children_opt: Option, + is_dir: bool, }, } @@ -1915,7 +1939,7 @@ impl ItemMetadata { Self::SimpleDir { .. } => true, Self::SimpleFile { .. } => false, #[cfg(feature = "gvfs")] - Self::GvfsPath { children_opt, .. } => children_opt.is_some(), + Self::GvfsPath { is_dir, .. } => *is_dir, } } @@ -1924,7 +1948,7 @@ impl ItemMetadata { Self::Path { metadata, .. } => metadata.modified().ok(), #[cfg(feature = "gvfs")] Self::GvfsPath { mtime, .. } => { - Some(SystemTime::UNIX_EPOCH + Duration::from_secs(*mtime)) + SystemTime::UNIX_EPOCH.checked_add(Duration::from_secs(*mtime)) } _ => None, } @@ -2346,6 +2370,7 @@ impl Item { ) -> widget::Text<'a, cosmic::Theme, cosmic::Renderer> { widget::text::body(name) .wrapping(text::Wrapping::WordOrGlyph) + .align_x(text::Alignment::Center) .ellipsize(text::Ellipsize::Middle(text::EllipsizeHeightLimit::Lines( 3, ))) @@ -4842,6 +4867,20 @@ impl Tab { } } } + #[cfg(feature = "gvfs")] + Message::DirectoryChildren(path, children) => { + if let Some(ref mut items) = self.items_opt { + for item in items.iter_mut() { + if item.path_opt() == Some(&path) { + if let ItemMetadata::GvfsPath { children_opt, .. } = &mut item.metadata + { + *children_opt = Some(children); + } + break; + } + } + } + } Message::Checksums(path, checksum_state) => { let location = Location::Path(path); if let Some(ref mut item) = self.parent_item_opt @@ -5003,11 +5042,15 @@ impl Tab { ItemMetadata::GvfsPath { size_opt, children_opt, + is_dir, .. - } => match children_opt { - Some(child_count) => (true, *child_count as u64), - None => (false, size_opt.unwrap_or_default()), - }, + } => { + if *is_dir { + (true, children_opt.unwrap_or_default() as u64) + } else { + (false, size_opt.unwrap_or_default()) + } + } }; let (a_is_entry, a_size) = get_size(a.1); let (b_is_entry, b_size) = get_size(b.1); @@ -6185,17 +6228,21 @@ impl Tab { ItemMetadata::GvfsPath { size_opt, children_opt, + is_dir, .. - } => match children_opt { - Some(child_count) => { - if *child_count == 1 { - format!("{child_count} item") - } else { - format!("{child_count} items") + } => { + if *is_dir { + // Children are not counted on remote filesystems + match children_opt { + //TODO: translate + Some(1) => "1 item".to_string(), + Some(child_count) => format!("{child_count} items"), + None => String::new(), } + } else { + format_size(size_opt.unwrap_or_default()) } - None => format_size(size_opt.unwrap_or_default()), - }, + } }; let row = if condensed { @@ -6961,6 +7008,74 @@ impl Tab { Rectangle::new(point, size) }; + // Count the children of visible directories in the background. Doing it while + // scanning costs one directory listing per entry, which stalls remote filesystems. + #[cfg(feature = "gvfs")] + for item in items { + let ItemMetadata::GvfsPath { + children_opt: None, + is_dir: true, + .. + } = &item.metadata + else { + continue; + }; + + // Skip items that are not visible, or have no determined rect + match item.rect_opt.get() { + Some(rect) if rect.intersects(&visible_rect) => {} + _ => continue, + } + + let Some(path) = item.path_opt().cloned() else { + continue; + }; + + struct ChildrenWrapper(PathBuf); + impl Hash for ChildrenWrapper { + fn hash(&self, state: &mut H) { + self.0.hash(state); + } + } + + subscriptions.push(Subscription::run_with( + ChildrenWrapper(path), + |ChildrenWrapper(path)| { + let path = path.clone(); + stream::channel( + 1, + move |mut output: futures::channel::mpsc::Sender<_>| async move { + let message = { + let path = path.clone(); + tokio::task::spawn_blocking(move || { + let children = match fs::read_dir(&path) { + Ok(entries) => entries.count(), + Err(err) => { + log::warn!( + "failed to read directory {}: {}", + path.display(), + err + ); + 0 + } + }; + Message::DirectoryChildren(path, children) + }) + .await + .unwrap() + }; + + if let Err(err) = output.send(message).await { + log::warn!("failed to send directory children: {err}"); + } + + std::future::pending().await + }, + ) + }, + )); + } + for item in items { if item.thumbnail_opt.is_some() { // Skip items that already have a mime type and thumbnail