From b041feec4849d8e399dedae5c3f820d1efd31886 Mon Sep 17 00:00:00 2001 From: Jason Rodney Hansen Date: Fri, 20 Mar 2026 08:41:19 -0600 Subject: [PATCH 001/110] feat: add 'Open item location' to search --- src/menu.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menu.rs b/src/menu.rs index d025a0f..ffec707 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -215,7 +215,7 @@ pub fn context_menu<'a>( .push(menu_item(fl!("open-in-terminal"), Action::OpenTerminal).into()); } } - if tab.location.is_recents() { + if tab.location.is_recents() || matches!(tab.location, Location::Search(..)) { children.push( menu_item(fl!("open-item-location"), Action::OpenItemLocation).into(), ); From 4414d2f4b2363aaabae9fafadd0906ed4434fe7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Sat, 14 Mar 2026 22:20:51 +0100 Subject: [PATCH 002/110] chore: update dependencies Also utilizes the `jxl-oxide` image decoding hook. --- Cargo.lock | 82 +++++++++++++---------------------------------------- Cargo.toml | 10 +++---- src/main.rs | 1 + src/tab.rs | 59 ++++++++++---------------------------- 4 files changed, 40 insertions(+), 112 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e4753b..b277508 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1215,9 +1215,9 @@ checksum = "e57e3272f0190c3f1584272d613719ba5fc7df7f4942fe542e63d949cf3a649b" [[package]] name = "constant_time_eq" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "core-foundation" @@ -1309,26 +1309,13 @@ dependencies = [ "libm", ] -[[package]] -name = "cosmic-client-toolkit" -version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=d0e95be#d0e95be25e423cfe523b11111a3666ed7aaf0dc4" -dependencies = [ - "bitflags 2.11.0", - "cosmic-protocols 0.1.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=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38" dependencies = [ "bitflags 2.11.0", - "cosmic-protocols 0.2.0", + "cosmic-protocols", "libc", "smithay-client-toolkit", "wayland-client", @@ -1373,7 +1360,7 @@ dependencies = [ "bzip2", "chrono", "compio", - "cosmic-client-toolkit 0.1.0", + "cosmic-client-toolkit", "cosmic-mime-apps", "dirs 6.0.0", "env_logger", @@ -1461,20 +1448,6 @@ dependencies = [ "xdg", ] -[[package]] -name = "cosmic-protocols" -version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=d0e95be#d0e95be25e423cfe523b11111a3666ed7aaf0dc4" -dependencies = [ - "bitflags 2.11.0", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-protocols-wlr", - "wayland-scanner", - "wayland-server", -] - [[package]] name = "cosmic-protocols" version = "0.2.0" @@ -1559,21 +1532,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - [[package]] name = "crc32fast" version = "1.5.0" @@ -2386,9 +2344,9 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "fork" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29714eb48a54d35d6f107e38cc58003f2e26825f222119db8369d28b24b79f2a" +checksum = "5bcc4b4161e53d499e41af904acb23950adf85682c772921ef3957cf1ecc98b3" dependencies = [ "libc", ] @@ -2590,11 +2548,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", "r-efi 5.3.0", "wasip2", - "wasm-bindgen", ] [[package]] @@ -2604,10 +2560,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "wasip2", "wasip3", + "wasm-bindgen", ] [[package]] @@ -3075,7 +3033,7 @@ source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0 dependencies = [ "bitflags 2.11.0", "bytes", - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "dnd", "glam", "lilt", @@ -3164,7 +3122,7 @@ version = "0.14.0" source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" dependencies = [ "bytes", - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "dnd", "iced_core", "iced_futures", @@ -3198,7 +3156,7 @@ dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.0", "bytemuck", - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "cryoglyph", "futures", "glam", @@ -3226,7 +3184,7 @@ name = "iced_widget" version = "0.14.2" source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" dependencies = [ - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "dnd", "iced_renderer", "iced_runtime", @@ -3244,7 +3202,7 @@ name = "iced_winit" version = "0.14.0" source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" dependencies = [ - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "cursor-icon", "dnd", "iced_debug", @@ -4307,7 +4265,7 @@ dependencies = [ "apply", "ashpd 0.12.3", "auto_enums", - "cosmic-client-toolkit 0.2.0", + "cosmic-client-toolkit", "cosmic-config", "cosmic-freedesktop-icons", "cosmic-settings-config", @@ -4546,11 +4504,10 @@ dependencies = [ [[package]] name = "lzma-rust2" -version = "0.15.7" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1670343e58806300d87950e3401e820b519b9384281bbabfb15e3636689ffd69" +checksum = "47bb1e988e6fb779cf720ad431242d3f03167c1b3f2b1aae7f1a94b2495b36ae" dependencies = [ - "crc", "sha2", ] @@ -9402,9 +9359,9 @@ dependencies = [ [[package]] name = "zip" -version = "7.2.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42e33efc22a0650c311c2ef19115ce232583abbe80850bc8b66509ebef02de0" +checksum = "b680f2a0cd479b4cff6e1233c483fdead418106eae419dc60200ae9850f6d004" dependencies = [ "aes", "bzip2", @@ -9412,8 +9369,7 @@ dependencies = [ "crc32fast", "deflate64", "flate2", - "generic-array", - "getrandom 0.3.4", + "getrandom 0.4.2", "hmac", "indexmap 2.13.0", "lzma-rust2", diff --git a/Cargo.toml b/Cargo.toml index be0b5ff..c19f30d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ rust-version = "1.90" anyhow = "1" chrono = { version = "0.4", features = ["unstable-locales"] } icu = { version = "2.1.1", features = ["compiled_data"] } -cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "d0e95be", optional = true } +cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "160b086", optional = true } cosmic-mime-apps = { git = "https://github.com/pop-os/cosmic-mime-apps.git", optional = true } dirs = "6.0.0" env_logger = "0.11" @@ -36,14 +36,14 @@ tokio = { version = "1", features = ["process", "sync"] } trash = { git = "https://github.com/jackpot51/trash-rs.git", branch = "cosmic" } url = "2.5" walkdir = "2.5.0" -wayland-client = { version = "0.31.12", optional = true } +wayland-client = { version = "0.31.13", optional = true } xdg = { version = "3.0", optional = true } xdg-mime = { git = "https://github.com/ebassi/xdg-mime-rs" } # Compression bzip2 = { version = "0.6", optional = true } #TODO: replace with pure Rust crate flate2 = "1.1" tar = "0.4.44" -lzma-rust2 = { version = "0.15.7", optional = true } +lzma-rust2 = { version = "0.16", optional = true } ordermap = { version = "1.1.0", features = ["serde"] } # Internationalization i18n-embed = { version = "0.16", features = [ @@ -54,7 +54,7 @@ i18n-embed-fl = "0.10" rust-embed = "8" slotmap = "1.1.1" recently-used-xbel = "1.2.0" -zip = "7" +zip = "8" uzers = "0.12.2" md-5 = "0.10.6" png = "0.18" @@ -124,7 +124,7 @@ inherits = "release" debug = true [target.'cfg(unix)'.dependencies] -fork = "0.6" +fork = "0.7" [target.'cfg(target_os = "linux")'.dependencies] procfs = "0.18" diff --git a/src/main.rs b/src/main.rs index d4cb5bd..276cb9b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,5 +6,6 @@ use tikv_jemallocator::Jemalloc; static GLOBAL: Jemalloc = Jemalloc; fn main() -> Result<(), Box> { + let _ = jxl_oxide::integration::register_image_decoding_hook(); cosmic_files::main() } diff --git a/src/tab.rs b/src/tab.rs index d36aff0..6d5cd60 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2113,55 +2113,26 @@ impl ItemThumbnail { } tried_supported_file = true; - let dyn_img: Option = match mime.subtype().as_str() { - "jxl" => match File::open(path) { - Ok(file) => match JxlDecoder::new(file) { - Ok(mut decoder) => { - let mut limits = image::Limits::default(); - let max_ram = max_mem * 1000 * 1000 / jobs as u64; - limits.max_alloc = Some(max_ram); - let _ = decoder.set_limits(limits); - match image::DynamicImage::from_decoder(decoder) { - Ok(img) => Some(img), - Err(err) => { - log::warn!("failed to decode jxl {}: {}", path.display(), err); - None - } - } - } + let dyn_img = match image::ImageReader::open(path) + .and_then(image::ImageReader::with_guessed_format) + { + Ok(mut reader) => { + let mut limits = image::Limits::default(); + let max_ram = max_mem * 1000 * 1000 / jobs as u64; + limits.max_alloc = Some(max_ram); + reader.limits(limits); + match reader.decode() { + Ok(reader) => Some(reader), Err(err) => { - log::warn!("failed to create jxl decoder {}: {}", path.display(), err); - None - } - }, - Err(err) => { - log::warn!("failed to open path {}: {}", path.display(), err); - None - } - }, - _ => { - match image::ImageReader::open(path) - .and_then(image::ImageReader::with_guessed_format) - { - Ok(mut reader) => { - let mut limits = image::Limits::default(); - let max_ram = max_mem * 1000 * 1000 / jobs as u64; - limits.max_alloc = Some(max_ram); - reader.limits(limits); - match reader.decode() { - Ok(reader) => Some(reader), - Err(err) => { - log::warn!("failed to decode {}: {}", path.display(), err); - None - } - } - } - Err(err) => { - log::warn!("failed to read {}: {}", path.display(), err); + log::warn!("failed to decode {}: {}", path.display(), err); None } } } + Err(err) => { + log::warn!("failed to read {}: {}", path.display(), err); + None + } }; if let Some(dyn_img) = dyn_img { From 3b1bc4430b460ebdee1a87b0afe657a6fa53353a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Sat, 14 Mar 2026 20:53:50 +0100 Subject: [PATCH 003/110] refactor: use `jiff` instead of `chrono` --- Cargo.lock | 21 +++++++++++++-------- Cargo.toml | 3 ++- src/archive.rs | 33 ++++++++++++++++----------------- src/tab.rs | 29 +++++++---------------------- 4 files changed, 38 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b277508..a18409e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -953,7 +953,6 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", - "pure-rust-locales", "serde", "wasm-bindgen", "windows-link 0.2.1", @@ -1358,7 +1357,6 @@ version = "1.0.8" dependencies = [ "anyhow", "bzip2", - "chrono", "compio", "cosmic-client-toolkit", "cosmic-mime-apps", @@ -1376,6 +1374,8 @@ dependencies = [ "icu", "ignore", "image", + "jiff", + "jiff-icu", "jxl-oxide", "libc", "libcosmic", @@ -3893,6 +3893,17 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "jiff-icu" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e67c2beaae8b10a82d849b9aabb698a43a682f32b17bcdc035d5ecadb44d646" +dependencies = [ + "icu_calendar", + "icu_time", + "jiff", +] + [[package]] name = "jiff-static" version = "0.2.23" @@ -5691,12 +5702,6 @@ dependencies = [ "syn", ] -[[package]] -name = "pure-rust-locales" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869675ad2d7541aea90c6d88c81f46a7f4ea9af8cd0395d38f11a95126998a0d" - [[package]] name = "pxfm" version = "0.1.28" diff --git a/Cargo.toml b/Cargo.toml index c19f30d..174e04c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,8 @@ rust-version = "1.90" [dependencies] anyhow = "1" -chrono = { version = "0.4", features = ["unstable-locales"] } +jiff = "0.2" +jiff-icu = "0.2" icu = { version = "2.1.1", features = ["compiled_data"] } cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "160b086", optional = true } cosmic-mime-apps = { git = "https://github.com/pop-os/cosmic-mime-apps.git", optional = true } diff --git a/src/archive.rs b/src/archive.rs index 5786ff7..92024d8 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -2,9 +2,8 @@ use crate::{ mime_icon::mime_for_path, operation::{Controller, OpReader, OperationError, OperationErrorType, sync_to_disk}, }; -use chrono::TimeZone; -use chrono::{Datelike, Timelike}; use cosmic::iced::futures; +use jiff::{Zoned, civil::DateTime, tz::TimeZone}; use std::{ collections::HashSet, fs, @@ -285,25 +284,25 @@ fn zip_extract>( } fn zip_date_time_to_system_time(date_time: zip::DateTime) -> Option { - let date = chrono::NaiveDate::from_ymd_opt( - date_time.year() as i32, - date_time.month() as u32, - date_time.day() as u32, - )?; - let time = chrono::NaiveTime::from_hms_opt( - date_time.hour() as u32, - date_time.minute() as u32, - date_time.second() as u32, - )?; - let naive = chrono::NaiveDateTime::new(date, time); - chrono::Local - .from_local_datetime(&naive) - .latest() + let dt = DateTime::new( + date_time.year() as i16, + date_time.month() as i8, + date_time.day() as i8, + date_time.hour() as i8, + date_time.minute() as i8, + date_time.second() as i8, + 0, + ) + .ok()?; + TimeZone::system() + .to_ambiguous_zoned(dt) + .later() + .ok() .map(SystemTime::from) } pub fn system_time_to_zip_date_time(system_time: SystemTime) -> Option { - let date_time: chrono::DateTime = system_time.into(); + let date_time = Zoned::try_from(system_time).ok()?; zip::DateTime::from_date_and_time( date_time.year() as u16, diff --git a/src/tab.rs b/src/tab.rs index 6d5cd60..9f05c3f 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1,4 +1,3 @@ -use chrono::{Datelike, Timelike, Utc}; use cosmic::{ Apply, Element, cosmic_theme, desktop::fde::{DesktopEntry, get_languages_from_env}, @@ -40,6 +39,7 @@ use icu::{ locale::preferences::extensions::unicode::keywords::HourCycle, }; use image::{DynamicImage, ImageDecoder, ImageReader}; +use jiff_icu::ConvertFrom; use jxl_oxide::integration::JxlDecoder; use mime_guess::{Mime, mime}; use regex::Regex; @@ -444,25 +444,10 @@ impl<'a> FormatTime<'a> { impl Display for FormatTime<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let datetime = chrono::DateTime::::from(self.time); - let now = chrono::Local::now(); - let icu_datetime = DateTime { - date: Date::try_new_gregorian( - datetime.year(), - datetime.month() as u8, - datetime.day() as u8, - ) - .unwrap(), - time: Time::try_new( - datetime.hour() as u8, - datetime.minute() as u8, - datetime.second() as u8, - 0, - ) - .unwrap(), - }; - - if datetime.date_naive() == now.date_naive() { + let zoned = jiff::Zoned::try_from(self.time).unwrap(); + let now = jiff::Zoned::now(); + let icu_datetime = DateTime::convert_from(zoned.datetime()); + if zoned.date() == now.date() { f.write_str(fl!("today").as_str())?; f.write_str(", ")?; self.time_formatter.format(&icu_datetime).fmt(f) @@ -1340,8 +1325,8 @@ pub fn scan_recents(sizes: IconSizes) -> Vec { .into_iter() .filter_map(|bookmark| { let path = uri_to_path(bookmark.href)?; - let last_edit = bookmark.modified.parse::>().ok()?; - let last_visit = bookmark.visited.parse::>().ok()?; + let last_edit = bookmark.modified.parse::().ok()?; + let last_visit = bookmark.visited.parse::().ok()?; if path.exists() { let file_name = path.file_name()?; From 6e2eafe16c03b3f26fa0c0afe22e05fac1cbbdfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Sat, 14 Mar 2026 23:32:47 +0100 Subject: [PATCH 004/110] chore: clippy --- src/app.rs | 8 +++--- src/dialog.rs | 4 +-- src/mouse_area.rs | 2 +- src/operation/mod.rs | 11 ++++---- src/tab.rs | 60 +++++++++++++++++++------------------------- 5 files changed, 38 insertions(+), 47 deletions(-) diff --git a/src/app.rs b/src/app.rs index 4e20f48..a8d4c53 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1452,7 +1452,7 @@ impl App { }; search_location.map(|search_location| { - return ( + ( Location::Search( search_location, term, @@ -1460,7 +1460,7 @@ impl App { Instant::now(), ), true, - ); + ) }) } None => match &tab.location { @@ -6194,11 +6194,11 @@ impl Application for App { .button_height(32) .button_spacing(space_xxs) .enable_tab_drag(String::from("x-cosmic-files/tab-dnd")) - .on_reorder(move |event| Message::ReorderTab(event)) + .on_reorder(Message::ReorderTab) .tab_drag_threshold(25.) .on_activate(Message::TabActivate) .on_close(|entity| Message::TabClose(Some(entity))) - .on_dnd_enter(|entity, mimes| Message::DndEnterTab(entity, mimes)) + .on_dnd_enter(Message::DndEnterTab) .on_dnd_leave(|_| Message::DndExitTab) .on_dnd_drop(|entity, data, action| { Message::DndDropTab(entity, data, action) diff --git a/src/dialog.rs b/src/dialog.rs index 6f0e5cb..bcfac6c 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -798,7 +798,7 @@ impl App { }; search_location.map(|search_location| { - return ( + ( Location::Search( search_location, term, @@ -806,7 +806,7 @@ impl App { Instant::now(), ), true, - ); + ) }) } None => match &self.tab.location { diff --git a/src/mouse_area.rs b/src/mouse_area.rs index dea4b25..56b86bb 100644 --- a/src/mouse_area.rs +++ b/src/mouse_area.rs @@ -395,7 +395,7 @@ where update( self, - &event, + event, layout, cursor, shell, diff --git a/src/operation/mod.rs b/src/operation/mod.rs index 3aad6fc..fa1aba1 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -762,13 +762,12 @@ impl Operation { OperationError::from_err(e, &controller) })?; - if let Ok(modified) = metadata.modified() { - if let Some(last_modified) = + if let Ok(modified) = metadata.modified() + && let Some(last_modified) = archive::system_time_to_zip_date_time(modified) - { - zip_options = - zip_options.last_modified_time(last_modified); - } + { + zip_options = + zip_options.last_modified_time(last_modified); } #[cfg(unix)] diff --git a/src/tab.rs b/src/tab.rs index 9f05c3f..1e0d3ce 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -8,9 +8,8 @@ use cosmic::{ graphics, text::{self, Paragraph}, }, - alignment::{Horizontal, Vertical}, + alignment::Vertical, clipboard::dnd::DndAction, - event, futures::{self, SinkExt}, keyboard::Modifiers, padding, stream, @@ -24,7 +23,7 @@ use cosmic::{ iced_core::{mouse::ScrollDelta, widget::tree}, theme, widget::{ - self, DndDestination, DndSource, Id, RcElementWrapper, Space, Widget, + self, DndDestination, DndSource, Id, RcElementWrapper, Widget, menu::{action::MenuAction, key_bind::KeyBind}, space, }, @@ -32,15 +31,13 @@ use cosmic::{ use i18n_embed::LanguageLoader; use icu::{ datetime::{ - DateTimeFormatter, DateTimeFormatterPreferences, fieldsets, - input::{Date, DateTime, Time}, + DateTimeFormatter, DateTimeFormatterPreferences, fieldsets, input::DateTime, options::TimePrecision, }, locale::preferences::extensions::unicode::keywords::HourCycle, }; -use image::{DynamicImage, ImageDecoder, ImageReader}; +use image::{DynamicImage, ImageReader}; use jiff_icu::ConvertFrom; -use jxl_oxide::integration::JxlDecoder; use mime_guess::{Mime, mime}; use regex::Regex; use rustc_hash::FxHashMap; @@ -1284,10 +1281,8 @@ pub mod trash_helpers { log::warn!("failed to get metadata for trash item {entry:?}: {err}") }) { let name = entry.name.to_string_lossy(); - if regex.is_match(&name) { - if !callback(SearchItem::Trash(entry, metadata)) { - break; - } + if regex.is_match(&name) && !callback(SearchItem::Trash(entry, metadata)) { + break; } } } @@ -2601,13 +2596,12 @@ impl Item { } column = column.push(details); - if let Some(path) = self.path_opt() { - if self.selected { - column = column.push( - widget::button::standard(fl!("open")) - .on_press(Message::Open(Some(path.clone()))), - ); - } + if let Some(path) = self.path_opt() + && self.selected + { + column = column.push( + widget::button::standard(fl!("open")).on_press(Message::Open(Some(path.clone()))), + ); } if !settings.is_empty() { @@ -5917,12 +5911,13 @@ impl Tab { }; let button_row = button(row.into()); - let button_row: Element<_> = - if item.metadata.is_dir() && item.location_opt.is_some() { - self.dnd_dest(item.location_opt.as_ref().unwrap(), button_row) - } else { - button_row.into() - }; + let button_row: Element<_> = if item.metadata.is_dir() + && let Some(location) = item.location_opt.as_ref() + { + self.dnd_dest(location, button_row) + } else { + button_row.into() + }; if item.selected || !drag_items.is_empty() { let dnd_row = if !item.selected { @@ -6289,8 +6284,7 @@ impl Tab { if item.selected { item.location_opt .as_ref() - .map(Location::path_opt) - .flatten() + .and_then(Location::path_opt) .is_some() } else { false @@ -6688,17 +6682,15 @@ impl Tab { // Don't send if the result is too old if let Some(last_modified) = *last_modified_opt.read().unwrap() - { - if let SearchItem::Path(_, _, ref metadata) = + && let SearchItem::Path(_, _, ref metadata) = search_item - { - if let Ok(modified) = metadata.modified() { - if modified < last_modified { - return true; - } - } else { + { + if let Ok(modified) = metadata.modified() { + if modified < last_modified { return true; } + } else { + return true; } } From 88bfd76a955c74b9f2a2ad1b6a198a13c9fc0e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Tue, 17 Mar 2026 23:25:10 +0100 Subject: [PATCH 005/110] chore: update libcosmic --- Cargo.lock | 75 +++++++++++++++++++----------------------------------- 1 file changed, 26 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a18409e..2e3dbdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -980,7 +980,7 @@ dependencies = [ [[package]] name = "clipboard_macos" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "objc", "objc-foundation", @@ -990,7 +990,7 @@ dependencies = [ [[package]] name = "clipboard_wayland" version = "0.2.2" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "dnd", "mime 0.1.0", @@ -1000,7 +1000,7 @@ dependencies = [ [[package]] name = "clipboard_x11" version = "0.4.2" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "thiserror 1.0.69", "x11rb", @@ -1324,7 +1324,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1345,7 +1345,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "quote", "syn", @@ -1509,7 +1509,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "almost", "configparser", @@ -1856,7 +1856,7 @@ dependencies = [ [[package]] name = "dnd" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "bitflags 2.11.0", "mime 0.1.0", @@ -2984,7 +2984,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.61.2", ] [[package]] @@ -2999,7 +2999,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "dnd", "iced_accessibility", @@ -3020,7 +3020,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "accesskit", "accesskit_winit", @@ -3029,7 +3029,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "bitflags 2.11.0", "bytes", @@ -3053,7 +3053,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "iced_core", "iced_futures", @@ -3063,7 +3063,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "futures", "iced_core", @@ -3077,7 +3077,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "bitflags 2.11.0", "bytemuck", @@ -3098,7 +3098,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "iced_graphics", "iced_runtime", @@ -3107,7 +3107,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3119,7 +3119,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3134,7 +3134,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "bytemuck", "cosmic-text", @@ -3151,7 +3151,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.0", @@ -3182,7 +3182,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3200,7 +3200,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -4190,9 +4190,9 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "known-folders" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770919970f7d2f74fea948900d35e2ef64f44129e8ae4015f59de1f0aca7c2a5" +checksum = "7a1886916523694cd6ea3d175f03a1e5010699a2a4cc13696d83d7bea1d80638" dependencies = [ "windows-sys 0.61.2", ] @@ -4271,7 +4271,7 @@ checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#9602dfd2f12b667e0afacdccd0e403d8152dde5a" +source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" dependencies = [ "apply", "ashpd 0.12.3", @@ -4305,7 +4305,6 @@ dependencies = [ "mime 0.3.17", "palette", "phf 0.13.1", - "raw-window-handle", "rfd", "rust-embed", "rustix 1.1.4", @@ -4623,7 +4622,7 @@ dependencies = [ [[package]] name = "mime" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "smithay-clipboard", ] @@ -7979,7 +7978,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window_clipboard" version = "0.4.1" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "clipboard-win", "clipboard_macos", @@ -8071,19 +8070,6 @@ dependencies = [ "windows-strings 0.4.2", ] -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - [[package]] name = "windows-future" version = "0.2.1" @@ -8238,15 +8224,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link 0.2.1", -] - [[package]] name = "windows-sys" version = "0.45.0" From 34f35842df8e325711a0a6360a2a5cf3357f2be3 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Tue, 24 Mar 2026 15:07:11 -0400 Subject: [PATCH 006/110] chore: update deps --- Cargo.lock | 353 +++++++++++++++++++++++++++-------------------------- 1 file changed, 179 insertions(+), 174 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e3dbdf..ce19605 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,23 +187,21 @@ checksum = "3aa2999eb46af81abb65c2d30d446778d7e613b60bbf4e174a027e80f90a3c14" [[package]] name = "android-activity" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" dependencies = [ "android-properties", "bitflags 2.11.0", "cc", - "cesu8", "jni", - "jni-sys", "libc", "log", "ndk", "ndk-context", "ndk-sys", "num_enum", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] @@ -223,9 +221,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -244,9 +242,9 @@ checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -300,9 +298,9 @@ checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "arc-swap" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f3647c145568cec02c42054e07bdf9a5a698e15b466fb2341bfc393cd24aa5" +checksum = "a07d1f37ff60921c83bdfc7407723bdefe89b44b98a9b772f225c8f9d67141a6" dependencies = [ "rustversion", ] @@ -756,10 +754,11 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" dependencies = [ + "bytes", "cfg_aliases", ] @@ -905,12 +904,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - [[package]] name = "cfb" version = "0.7.3" @@ -1086,9 +1079,9 @@ dependencies = [ [[package]] name = "compio-buf" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e8777c3ad31ab42f8a3a4a1bd629b78f688371df9b0f528d94dfbdbe5c945c9" +checksum = "a00d719dbd8c602ab0d25d219cbc6b517008858de7a8d6c51b4dc95aefff4dce" dependencies = [ "arrayvec", "bytes", @@ -1324,7 +1317,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1345,7 +1338,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "quote", "syn", @@ -1465,7 +1458,7 @@ dependencies = [ [[package]] name = "cosmic-settings-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#e37160f14d1e7ee428f973cd2848b4e95f83dfe1" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#8d83e2a4179bbe193d195cd42efe9ce50bcc9926" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1509,7 +1502,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "almost", "configparser", @@ -1710,9 +1703,9 @@ checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" [[package]] name = "deflate64" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807800ff3288b621186fe0a8f3392c4652068257302709c24efd918c3dffcdc2" +checksum = "ac6b926516df9c60bfa16e107b21086399f8285a44ca9711344b9e553c5146e2" [[package]] name = "deranged" @@ -1965,9 +1958,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", "regex", @@ -1975,9 +1968,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ "anstream", "anstyle", @@ -2040,9 +2033,9 @@ dependencies = [ [[package]] name = "euclid" -version = "0.22.13" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df61bf483e837f88d5c2291dcf55c67be7e676b3a51acc48db3a7b163b91ed63" +checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" dependencies = [ "num-traits", ] @@ -2285,9 +2278,9 @@ dependencies = [ [[package]] name = "font-types" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4d2d0cf79d38430cc9dc9aadec84774bff2e1ba30ae2bf6c16cfce9385a23" +checksum = "73829a7b5c91198af28a99159b7ae4afbb252fb906159ff7f189f3a2ceaa3df2" dependencies = [ "bytemuck", ] @@ -2984,7 +2977,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.61.2", + "windows-core 0.62.2", ] [[package]] @@ -2999,7 +2992,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "dnd", "iced_accessibility", @@ -3020,7 +3013,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "accesskit", "accesskit_winit", @@ -3029,7 +3022,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "bitflags 2.11.0", "bytes", @@ -3053,7 +3046,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "iced_core", "iced_futures", @@ -3063,7 +3056,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "futures", "iced_core", @@ -3077,7 +3070,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "bitflags 2.11.0", "bytemuck", @@ -3098,7 +3091,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "iced_graphics", "iced_runtime", @@ -3107,7 +3100,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3119,7 +3112,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3134,7 +3127,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "bytemuck", "cosmic-text", @@ -3151,7 +3144,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.0", @@ -3182,7 +3175,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3200,7 +3193,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3694,7 +3687,7 @@ dependencies = [ "rgb", "tiff", "zune-core 0.5.1", - "zune-jpeg 0.5.13", + "zune-jpeg 0.5.14", ] [[package]] @@ -3868,9 +3861,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "ixdtf" @@ -3932,25 +3925,61 @@ dependencies = [ [[package]] name = "jni" -version = "0.21.1" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" dependencies = [ - "cesu8", "cfg-if", "combine", - "jni-sys", + "jni-macros", + "jni-sys 0.4.1", "log", - "thiserror 1.0.69", + "simd_cesu8", + "thiserror 2.0.18", "walkdir", - "windows-sys 0.45.0", + "windows-link 0.2.1", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn", ] [[package]] name = "jni-sys" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn", +] [[package]] name = "jobserver" @@ -4271,7 +4300,7 @@ checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#d7fd880ac6e3ea03b421541837d654bd036437ea" +source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" dependencies = [ "apply", "ashpd 0.12.3", @@ -4348,9 +4377,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" dependencies = [ "bitflags 2.11.0", "libc", @@ -4503,9 +4532,9 @@ dependencies = [ [[package]] name = "lyon_tessellation" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05a35a7dd71b845ff317ce1834c4185506b79790294bde397df8d5c23031e357" +checksum = "8e43b7e44161571868f5c931d12583592c223c5583eef86b08aa02b7048a3552" dependencies = [ "float_next_after", "lyon_path", @@ -4720,7 +4749,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ "bitflags 2.11.0", - "jni-sys", + "jni-sys 0.3.1", "log", "ndk-sys", "num_enum", @@ -4740,7 +4769,7 @@ version = "0.6.0+11769913" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" dependencies = [ - "jni-sys", + "jni-sys 0.3.1", ] [[package]] @@ -5946,7 +5975,7 @@ checksum = "7b634fabf032fab15307ffd272149b622260f55974d9fad689292a5d33df02e5" dependencies = [ "bytemuck", "core_maths", - "font-types 0.11.0", + "font-types 0.11.1", ] [[package]] @@ -6189,6 +6218,15 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.44" @@ -6366,9 +6404,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98" dependencies = [ "serde_core", ] @@ -6457,6 +6495,16 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + [[package]] name = "simd_helpers" version = "0.1.0" @@ -6466,6 +6514,12 @@ dependencies = [ "quote", ] +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "simplecss" version = "0.2.2" @@ -6759,9 +6813,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" dependencies = [ "filetime", "libc", @@ -6902,7 +6956,7 @@ dependencies = [ "half", "quick-error", "weezl", - "zune-jpeg 0.5.13", + "zune-jpeg 0.5.14", ] [[package]] @@ -7082,7 +7136,7 @@ dependencies = [ "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", - "winnow", + "winnow 0.7.15", ] [[package]] @@ -7096,39 +7150,39 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "1.0.0+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" +checksum = "97251a7c317e03ad83774a8752a7e81fb6067740609f75ea2b585b569a59198f" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.25.4+spec-1.1.0" +version = "0.25.8+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" +checksum = "16bff38f1d86c47f9ff0647e6838d7bb362522bdf44006c7068c2b1e606f1f3c" dependencies = [ "indexmap 2.13.0", - "toml_datetime 1.0.0+spec-1.1.0", + "toml_datetime 1.1.0+spec-1.1.0", "toml_parser", - "winnow", + "winnow 1.0.0", ] [[package]] name = "toml_parser" -version = "1.0.9+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +checksum = "2334f11ee363607eb04df9b8fc8a13ca1715a72ba8662a26ac285c98aabb4011" dependencies = [ - "winnow", + "winnow 1.0.0", ] [[package]] name = "toml_writer" -version = "1.0.6+spec-1.1.0" +version = "1.1.0+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" +checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed" [[package]] name = "tracing" @@ -7334,9 +7388,9 @@ checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "a559e63b5d8004e12f9bce88af5c6d939c58de839b7532cfe9653846cedd2a9e" [[package]] name = "unicode-vo" @@ -8070,6 +8124,19 @@ dependencies = [ "windows-strings 0.4.2", ] +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + [[package]] name = "windows-future" version = "0.2.1" @@ -8225,12 +8292,12 @@ dependencies = [ ] [[package]] -name = "windows-sys" -version = "0.45.0" +name = "windows-strings" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-targets 0.42.2", + "windows-link 0.2.1", ] [[package]] @@ -8278,21 +8345,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -8359,12 +8411,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -8383,12 +8429,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -8407,12 +8447,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -8443,12 +8477,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -8467,12 +8495,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -8491,12 +8513,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -8515,12 +8531,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -8763,6 +8773,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.51.0" @@ -9146,7 +9165,7 @@ dependencies = [ "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow", + "winnow 0.7.15", "zbus_macros 5.14.0", "zbus_names 4.3.1", "zvariant 5.10.0", @@ -9222,7 +9241,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" dependencies = [ "serde", - "winnow", + "winnow 0.7.15", "zvariant 5.10.0", ] @@ -9246,18 +9265,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.42" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.42" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" dependencies = [ "proc-macro2", "quote", @@ -9290,20 +9309,6 @@ name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] [[package]] name = "zerotrie" @@ -9341,9 +9346,9 @@ dependencies = [ [[package]] name = "zip" -version = "8.2.0" +version = "8.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b680f2a0cd479b4cff6e1233c483fdead418106eae419dc60200ae9850f6d004" +checksum = "7756d0206d058333667493c4014f545f4b9603c4330ccd6d9b3f86dcab59f7d9" dependencies = [ "aes", "bzip2", @@ -9450,9 +9455,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5f41c76397b7da451efd19915684f727d7e1d516384ca6bd0ec43ec94de23c" +checksum = "0b7a1c0af6e5d8d1363f4994b7a091ccf963d8b694f7da5b0b9cceb82da2c0a6" dependencies = [ "zune-core 0.5.1", ] @@ -9480,7 +9485,7 @@ dependencies = [ "enumflags2", "serde", "url", - "winnow", + "winnow 0.7.15", "zvariant_derive 5.10.0", "zvariant_utils 3.3.0", ] @@ -9532,5 +9537,5 @@ dependencies = [ "quote", "serde", "syn", - "winnow", + "winnow 0.7.15", ] From f6ca0cb460809ca6a4a543e5358063ac57e3350c Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Tue, 24 Mar 2026 15:07:31 -0400 Subject: [PATCH 007/110] cleanup --- src/operation/recursive.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/operation/recursive.rs b/src/operation/recursive.rs index a807594..61c4841 100644 --- a/src/operation/recursive.rs +++ b/src/operation/recursive.rs @@ -419,10 +419,10 @@ impl Op { use std::os::unix::prelude::MetadataExt; log::info!("{}", metadata.mtime()); } - if let Ok(time) = dbg!(metadata.modified()) { + if let Ok(time) = metadata.modified() { times = times.set_modified(time); } - if let Ok(time) = dbg!(metadata.accessed()) { + if let Ok(time) = metadata.accessed() { times = times.set_accessed(time); } //TODO: upstream set_times implementation to compio? From 3a88d7fcf754749f99a9de458c5a7c369cb32c14 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Tue, 24 Mar 2026 15:08:24 -0400 Subject: [PATCH 008/110] fix: update cached clipboard --- src/app.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index a8d4c53..de5cb3a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2781,7 +2781,12 @@ impl Application for App { tab.refresh_cut(&[]); } let paths = self.selected_paths(entity_opt); - let contents = ClipboardCopy::new(ClipboardKind::Copy, paths); + self.clipboard_cache = ClipboardCache::Files(ClipboardPaste { + paths: paths.map(|p| p.to_path_buf()).collect(), + kind: ClipboardKind::Copy, + }); + let contents = + ClipboardCopy::new(ClipboardKind::Copy, self.selected_paths(entity_opt)); return clipboard::write_data(contents); } Message::CopyPath(entity_opt) => { @@ -2822,7 +2827,15 @@ impl Application for App { Message::Cut(entity_opt) => { self.set_cut(entity_opt); let paths = self.selected_paths(entity_opt); - let contents = ClipboardCopy::new(ClipboardKind::Cut { is_dnd: false }, paths); + self.clipboard_cache = ClipboardCache::Files(ClipboardPaste { + paths: paths.map(|p| p.to_path_buf()).collect(), + kind: ClipboardKind::Cut { is_dnd: false }, + }); + let contents = ClipboardCopy::new( + ClipboardKind::Cut { is_dnd: false }, + self.selected_paths(entity_opt), + ); + return clipboard::write_data(contents); } Message::CloseToast(id) => { From 75fe043e73d0f456eb0bb97ec6367df4e80cfdbd Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 25 Mar 2026 10:49:27 -0400 Subject: [PATCH 009/110] fix: don't read files if list empty --- src/app.rs | 8 ++++---- src/clipboard.rs | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/app.rs b/src/app.rs index de5cb3a..9d8e0db 100644 --- a/src/app.rs +++ b/src/app.rs @@ -3840,10 +3840,10 @@ impl Application for App { // Check if clipboard has any paste-able content and cache it return clipboard::read_data::().map(|contents_opt| { match contents_opt { - Some(contents) => cosmic::action::app(Message::ClipboardCached( - ClipboardCache::Files(contents), - )), - None => cosmic::action::app(Message::CheckClipboardImage), + Some(contents) if !contents.paths.is_empty() => cosmic::action::app( + Message::ClipboardCached(ClipboardCache::Files(contents)), + ), + _ => cosmic::action::app(Message::CheckClipboardImage), } }); } diff --git a/src/clipboard.rs b/src/clipboard.rs index 637303e..6b0be96 100644 --- a/src/clipboard.rs +++ b/src/clipboard.rs @@ -128,9 +128,14 @@ impl TryFrom<(Vec, String)> for ClipboardPaste { // Assume the kind is Copy if not provided by the mime type let mut kind = ClipboardKind::Copy; let mut paths = Vec::new(); + match mime.as_str() { "text/uri-list" => { let text = str::from_utf8(&data)?; + let lines = text.lines(); + if text.is_empty() || lines.count() == 0 { + Err(format!("Empty file url"))?; + } for line in text.lines() { let url = Url::parse(line)?; match url.to_file_path() { @@ -141,6 +146,10 @@ impl TryFrom<(Vec, String)> for ClipboardPaste { } "x-special/gnome-copied-files" => { let text = str::from_utf8(&data)?; + let lines = text.lines(); + if text.is_empty() || lines.count() == 0 { + Err(format!("Empty file url"))?; + } for (i, line) in text.lines().enumerate() { if i == 0 { kind = match line { From e50c41aa247a9dd9f9ab6dae9d8f4a720701825a Mon Sep 17 00:00:00 2001 From: Josh Megnauth Date: Tue, 24 Mar 2026 19:48:49 -0400 Subject: [PATCH 010/110] fix: Respect show_recents conf in dialog Closes: #1698 --- src/dialog.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dialog.rs b/src/dialog.rs index bcfac6c..80dbdda 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -889,11 +889,13 @@ impl App { fn update_nav_model(&mut self) { let mut nav_model = segmented_button::ModelBuilder::default(); - nav_model = nav_model.insert(|b| { - b.text(fl!("recents")) - .icon(widget::icon::from_name("document-open-recent-symbolic")) - .data(Location::Recents) - }); + if self.flags.config.show_recents { + nav_model = nav_model.insert(|b| { + b.text(fl!("recents")) + .icon(widget::icon::from_name("document-open-recent-symbolic")) + .data(Location::Recents) + }); + } for favorite in &self.flags.config.favorites { if let Some(path) = favorite.path_opt() { From 17325a5f5aa58600bebf6f25faf465d4d04e21c5 Mon Sep 17 00:00:00 2001 From: Jonatan Pettersson Date: Mon, 5 Jan 2026 20:18:52 +0100 Subject: [PATCH 011/110] feat: add open-with in multi preview Adds the ability to set the open-with setting for multiple selected items. This setting will only appear if all selected items have the same mime type. --- src/app.rs | 2 +- src/dialog.rs | 2 +- src/tab.rs | 42 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/app.rs b/src/app.rs index 9d8e0db..402efb5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2010,7 +2010,7 @@ impl App { match (selected.next(), selected.next()) { // At least two selected items - (Some(_), Some(_)) => Some(tab.multi_preview_view()), + (Some(_), Some(_)) => Some(tab.multi_preview_view(Some(&self.mime_app_cache))), // Exactly one selected item (Some(item), None) => { Some(item.preview_view(Some(&self.mime_app_cache), military_time)) diff --git a/src/dialog.rs b/src/dialog.rs index 80dbdda..a16b5f3 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -717,7 +717,7 @@ impl App { match (selected.next(), selected.next()) { // At least two selected items - (Some(_), Some(_)) => Some(self.tab.multi_preview_view()), + (Some(_), Some(_)) => Some(self.tab.multi_preview_view(None)), // Exactly one selected item (Some(item), None) => Some(item.preview_view(None, military_time)), // No selected items diff --git a/src/tab.rs b/src/tab.rs index 1e0d3ce..77ab0a1 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -6248,7 +6248,10 @@ impl Tab { dnd_dest.into() } - pub fn multi_preview_view<'a>(&'a self) -> Element<'a, Message> { + pub fn multi_preview_view<'a>( + &'a self, + mime_app_cache_opt: Option<&'a mime_app::MimeAppCache>, + ) -> Element<'a, Message> { let cosmic_theme::Spacing { space_xxxs, space_m, @@ -6362,6 +6365,43 @@ impl Tab { column = column.push(widget::button::standard(fl!("open")).on_press(Message::Open(None))); + let mut settings = Vec::new(); + if mime_types.len() == 1 { + if let Some(mime) = mime_types + .get(0) + .and_then(|(mime, _)| mime.parse::().ok()) + { + if let Some(mime_app_cache) = mime_app_cache_opt { + let mime_apps = mime_app_cache.get(&mime); + if !mime_apps.is_empty() { + let mime_closure = mime.clone(); + settings.push( + widget::settings::item::builder(fl!("open-with")).control( + Element::from( + widget::dropdown( + mime_apps, + mime_apps.iter().position(|x| x.is_default), + move |index| (index, mime_closure.clone()), + ) + .icons(Cow::Borrowed(mime_app_cache.icons(&mime))), + ) + .map(|(index, mime)| { + let mime_app = &mime_apps[index]; + Message::SetOpenWith(mime, mime_app.id.clone()) + }), + ), + ); + } + } + } + } + + if !settings.is_empty() { + let mut section = widget::settings::section(); + section = section.extend(settings); + column = column.push(section); + } + column.into() } pub fn view<'a>( From 41cdf896043f215a62992a98e06d8e2dc0431bdf Mon Sep 17 00:00:00 2001 From: Jonatan Pettersson Date: Tue, 6 Jan 2026 21:51:45 +0100 Subject: [PATCH 012/110] feat: allow setting permissions in multi preview This adds a Message::ShiftPermissions to handle setting permissions for user, group or other for either 1 or more items and a Command::SetMultiplePermissions to set permissions on multiple items at the same time. The permission dropdown will only have a selection if all selected items have the same permission, otherwise it will be empty but still allow changing. Up to 5 owners and groups will be displayed for all selected items with an ellipses if there are more. The OperationSelection for setting permissions now also returns the path as selected such that the tab will be re-scanned and update the dropdown to correctly. --- src/app.rs | 7 +++ src/operation/mod.rs | 7 ++- src/tab.rs | 140 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 152 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index 402efb5..f1e18c0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -4478,6 +4478,13 @@ impl Application for App { tab::Command::SetPermissions(path, mode) => { commands.push(self.operation(Operation::SetPermissions { path, mode })); } + tab::Command::SetMultiplePermissions(permissions) => { + commands.push(Task::batch(permissions.into_iter().map( + |(path, mode)| { + self.operation(Operation::SetPermissions { path, mode }) + }, + ))); + } tab::Command::WindowDrag => { if let Some(window_id) = self.core.main_window_id() { commands.push(window::drag(window_id)); diff --git a/src/operation/mod.rs b/src/operation/mod.rs index fa1aba1..da4a83b 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -1180,8 +1180,10 @@ impl Operation { .map_err(|s| OperationError::from_state(s, &controller))?; let controller_clone = controller.clone(); + let path_clone = path.clone(); compio::runtime::spawn_blocking(move || -> Result<(), OperationError> { let controller = controller_clone; + let path = path_clone; //TODO: what to do on non-Unix systems? #[cfg(unix)] { @@ -1196,7 +1198,10 @@ impl Operation { .await .map_err(wrap_compio_spawn_error)? .map_err(|e| OperationError::from_err(e, &controller))?; - Ok(OperationSelection::default()) + Ok(OperationSelection { + ignored: Vec::new(), + selected: vec![path], + }) } }; diff --git a/src/tab.rs b/src/tab.rs index 77ab0a1..31a82d4 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -46,7 +46,7 @@ use std::{ borrow::Cow, cell::Cell, cmp::{Ordering, Reverse}, - collections::{BTreeMap, HashMap}, + collections::{BTreeMap, BTreeSet, HashMap}, error::Error, fmt::{self, Display}, fs::{self, File, Metadata}, @@ -1796,6 +1796,7 @@ pub enum Command { Preview(PreviewKind), SetOpenWith(Mime, String), SetPermissions(PathBuf, u32), + SetMultiplePermissions(Vec<(PathBuf, u32)>), SetSort(String, HeadingOptions, bool), WindowDrag, WindowToggleMaximize, @@ -1852,6 +1853,7 @@ pub enum Message { SelectLast, SetOpenWith(Mime, String), SetPermissions(PathBuf, u32), + ShiftPermissions(Option<(PathBuf, u32)>, u32, u32), SetSort(HeadingOptions, bool), TabComplete(PathBuf, Vec<(String, PathBuf)>), Thumbnail(PathBuf, ItemThumbnail), @@ -4335,6 +4337,31 @@ impl Tab { Message::SetPermissions(path, mode) => { commands.push(Command::SetPermissions(path, mode)); } + Message::ShiftPermissions(path_mode_opt, shift, bits) => match path_mode_opt { + Some((path, mode)) => commands.push(Command::SetPermissions( + path, + set_mode_part(mode, shift, bits.try_into().unwrap()), + )), + // Shift permissions on all selected items + None => { + let mut permissions = Vec::new(); + for item in self.items_opt().map_or(Vec::new(), |items| { + items.iter().filter(|item| item.selected).collect() + }) { + if let (Some(path), Some(mode)) = ( + item.path_opt(), + item.file_metadata() + .and_then(|metadata| Some(metadata.mode())), + ) { + permissions.push(( + path.clone(), + set_mode_part(mode, shift, bits.try_into().unwrap()), + )); + } + } + commands.push(Command::SetMultiplePermissions(permissions)); + } + }, Message::SetSort(heading_option, dir) => { if !matches!(self.location, Location::Search(..)) { self.sort_name = heading_option; @@ -6304,6 +6331,11 @@ impl Tab { let mut total_size: u64 = 0; let mut mime_type_counts: BTreeMap = BTreeMap::new(); + let mut user_name: BTreeSet = BTreeSet::new(); + let mut mode_user: BTreeSet = BTreeSet::new(); + let mut group_name: BTreeSet = BTreeSet::new(); + let mut mode_group: BTreeSet = BTreeSet::new(); + let mut mode_other: BTreeSet = BTreeSet::new(); let mut calculating_dir_size = false; let mut dir_size_error: Option = None; @@ -6327,6 +6359,20 @@ impl Tab { } else { total_size = total_size.saturating_add(metadata.len()); } + let mode = metadata.mode(); + user_name.insert( + get_user_by_uid(metadata.uid()) + .and_then(|user| user.name().to_str().map(ToOwned::to_owned)) + .unwrap_or_default(), + ); + mode_user.insert(get_mode_part(mode, MODE_SHIFT_USER)); + group_name.insert( + get_group_by_gid(metadata.gid()) + .and_then(|group| group.name().to_str().map(ToOwned::to_owned)) + .unwrap_or_default(), + ); + mode_group.insert(get_mode_part(mode, MODE_SHIFT_GROUP)); + mode_other.insert(get_mode_part(mode, MODE_SHIFT_OTHER)); } } let mut mime_types: Vec<(String, u64)> = mime_type_counts.into_iter().collect(); @@ -6366,6 +6412,7 @@ impl Tab { column = column.push(widget::button::standard(fl!("open")).on_press(Message::Open(None))); let mut settings = Vec::new(); + // Only allow modifying open-with if all mime types are the same if mime_types.len() == 1 { if let Some(mime) = mime_types .get(0) @@ -6396,6 +6443,97 @@ impl Tab { } } + #[cfg(unix)] + { + // The following is a bit of a hack to make the dropdown selector + // fill the available space when selected is None so it can be + // clicked on easier. + fn dropdown_width(use_default: bool) -> Length { + if use_default { + Length::Shrink + } else { + Length::Fill + } + } + + // Only return mode part if it's the only one + fn selected_mode_part(mut modes: BTreeSet) -> Option { + match (modes.pop_first(), modes.pop_first()) { + (Some(mode), None) => Some(mode.try_into().unwrap()), + _ => None, + } + } + + // Convert a limited number of values from a set into a comma separated list + fn join_set(set: BTreeSet) -> String { + let limit = 5; + let mut title = set.into_iter().collect::>(); + if title.len() > limit { + title.truncate(limit); + title.push("...".to_string()); + } + title.join(", ") + } + + let mode_part_user = selected_mode_part(mode_user); + settings.push( + widget::settings::item::builder(join_set(user_name)) + .description(fl!("owner")) + .control( + widget::dropdown( + Cow::Borrowed(MODE_NAMES.as_slice()), + mode_part_user, + move |selected| { + Message::ShiftPermissions( + None, + MODE_SHIFT_USER, + selected.try_into().unwrap(), + ) + }, + ) + .width(dropdown_width(mode_part_user.is_some())), + ), + ); + + let mode_part_group = selected_mode_part(mode_group); + settings.push( + widget::settings::item::builder(join_set(group_name)) + .description(fl!("group")) + .control( + widget::dropdown( + Cow::Borrowed(MODE_NAMES.as_slice()), + mode_part_group, + move |selected| { + Message::ShiftPermissions( + None, + MODE_SHIFT_GROUP, + selected.try_into().unwrap(), + ) + }, + ) + .width(dropdown_width(mode_part_group.is_some())), + ), + ); + + let mode_part_other = selected_mode_part(mode_other); + settings.push( + widget::settings::item::builder(fl!("other")).control( + widget::dropdown( + Cow::Borrowed(MODE_NAMES.as_slice()), + mode_part_other, + move |selected| { + Message::ShiftPermissions( + None, + MODE_SHIFT_OTHER, + selected.try_into().unwrap(), + ) + }, + ) + .width(dropdown_width(mode_part_other.is_some())), + ), + ); + } + if !settings.is_empty() { let mut section = widget::settings::section(); section = section.extend(settings); From 4c6f2db5f22bec7ef496c43d3e8d79b7cefab4cf Mon Sep 17 00:00:00 2001 From: Jonatan Pettersson Date: Sun, 11 Jan 2026 19:50:28 +0100 Subject: [PATCH 013/110] feat: join multiple operations Allow for joining operations into a single Task that will produce a single Message:PendingResults message such that multiple Message::PendingComplete and Message::PendingError messages can be handled together to, for example, show a single error dialog with multiple errors. --- src/app.rs | 295 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 195 insertions(+), 100 deletions(-) diff --git a/src/app.rs b/src/app.rs index f1e18c0..074e4eb 100644 --- a/src/app.rs +++ b/src/app.rs @@ -418,6 +418,7 @@ pub enum Message { PendingComplete(u64, OperationSelection), PendingDismiss, PendingError(u64, OperationError), + PendingResults(Vec<(u64, OperationSelection)>, Vec<(u64, OperationError)>), PendingPause(u64, bool), PendingPauseAll(bool), PermanentlyDelete(Option), @@ -531,6 +532,7 @@ pub enum DialogPage { }, EmptyTrash, FailedOperation(u64), + FailedOperations(Vec), ExtractPassword { id: u64, password: String, @@ -1278,6 +1280,158 @@ impl App { .map(cosmic::Action::App) } + /// Will join operations together into a single task that will return a single + /// Message::PendingResults message when all operations are complete. + fn join_operations(&mut self, operations: Vec) -> Task { + Task::batch( + operations + .into_iter() + .map(|operation| self.operation(operation)), + ) + .collect() + .map(|messages| { + let results = messages.into_iter().fold( + Message::PendingResults(Vec::new(), Vec::new()), + |mut acc, message| { + if let Message::PendingResults(completed, errors) = &mut acc { + match message { + cosmic::Action::App(Message::PendingComplete(id, selection)) => { + completed.push((id, selection)); + } + cosmic::Action::App(Message::PendingError(id, err)) => { + errors.push((id, err)); + } + _ => {} + } + } + acc + }, + ); + cosmic::Action::App(results) + }) + } + + fn handle_completed_operations( + &mut self, + completed: Vec<(u64, OperationSelection)>, + ) -> Task { + let mut commands = Vec::with_capacity(4 * completed.len()); + let mut op_sel = OperationSelection::default(); + for (id, op_sel_pending) in completed { + op_sel.ignored.extend(op_sel_pending.ignored); + op_sel.selected.extend(op_sel_pending.selected); + if let Some((op, _)) = self.pending_operations.remove(&id) { + // Show toast for some operations + if let Some(description) = op.toast() { + if let Operation::Delete { ref paths } = op { + let paths: Arc<[PathBuf]> = Arc::from(paths.as_slice()); + commands.push( + self.toasts + .push( + widget::toaster::Toast::new(description) + .action(fl!("undo"), move |tid| { + Message::UndoTrash(tid, paths.clone()) + }), + ) + .map(cosmic::Action::App), + ); + } else { + commands.push( + self.toasts + .push(widget::toaster::Toast::new(description)) + .map(cosmic::Action::App), + ); + } + } + + // If a favorite for a path has been renamed or moved, update it. + if let Operation::Rename { ref from, ref to } = op { + if self.update_favorites([(from, to)].as_slice()) { + commands.push(self.update_config()); + } + } else if let Operation::Move { + ref paths, ref to, .. + } = op + { + let path_changes: Box<[_]> = paths + .iter() + .filter_map(|from| from.file_name().map(|name| (from, to.join(name)))) + .collect(); + if self.update_favorites(&path_changes) { + commands.push(self.update_config()); + } + } + + if matches!(op, Operation::RemoveFromRecents { .. }) { + commands.push(self.rescan_recents()); + } + + self.complete_operations.insert(id, op); + } + } + // Close progress notification if all relevant operations are finished + if !self + .pending_operations + .values() + .any(|(op, _)| op.show_progress_notification()) + { + self.progress_operations.clear(); + } + // Potentially show a notification + commands.push(self.update_notification()); + // Rescan and select based on operation + commands.push(self.rescan_operation_selection(op_sel)); + // Manually rescan any trash tabs after any operation is completed + commands.push(self.rescan_trash()); + + return Task::batch(commands); + } + + fn handle_operation_errors(&mut self, errors: Vec<(u64, OperationError)>) -> Task { + let mut tasks = Vec::new(); + let mut failed = Vec::new(); + for (id, err) in errors.into_iter() { + if let Some((op, controller)) = self.pending_operations.remove(&id) { + // Only show dialog if not cancelled + if !controller.is_cancelled() { + match err.kind { + OperationErrorType::Generic(_) => failed.push(id), + OperationErrorType::PasswordRequired => { + tasks.push(self.dialog_pages.push_back(DialogPage::ExtractPassword { + id, + password: String::new(), + })); + } + } + } + + // Remove from progress + self.progress_operations.remove(&id); + self.failed_operations + .insert(id, (op, controller, err.to_string())); + } + } + if !failed.is_empty() { + tasks.push( + self.dialog_pages + .push_back(DialogPage::FailedOperations(failed)), + ); + tasks.push(widget::text_input::focus(self.dialog_text_input.clone())); + } + + // Close progress notification if all relevant operations are finished + if !self + .pending_operations + .values() + .any(|(op, _)| op.show_progress_notification()) + { + self.progress_operations.clear(); + } + // Manually rescan any trash tabs after any operation is completed + tasks.push(self.rescan_trash()); + return Task::batch(tasks); + } + fn remove_window(&mut self, id: &window::Id) { if let Some(window) = self.windows.remove(id) { match window.kind { @@ -2979,6 +3133,9 @@ impl Application for App { DialogPage::FailedOperation(id) => { log::warn!("TODO: retry operation {id}"); } + DialogPage::FailedOperations(_ids) => { + log::warn!("TODO: retry operations"); + } DialogPage::ExtractPassword { id, password } => { let (operation, _, _err) = self.failed_operations.get(&id).unwrap(); let new_op = match &operation { @@ -3891,106 +4048,19 @@ impl Application for App { } } Message::PendingComplete(id, op_sel) => { - let mut commands = Vec::with_capacity(4); - if let Some((op, _)) = self.pending_operations.remove(&id) { - // Show toast for some operations - if let Some(description) = op.toast() { - if let Operation::Delete { ref paths } = op { - let paths: Arc<[PathBuf]> = Arc::from(paths.as_slice()); - commands.push( - self.toasts - .push( - widget::toaster::Toast::new(description) - .action(fl!("undo"), move |tid| { - Message::UndoTrash(tid, paths.clone()) - }), - ) - .map(cosmic::Action::App), - ); - } else { - commands.push( - self.toasts - .push(widget::toaster::Toast::new(description)) - .map(cosmic::Action::App), - ); - } - } - - // If a favorite for a path has been renamed or moved, update it. - if let Operation::Rename { ref from, ref to } = op { - if self.update_favorites([(from, to)].as_slice()) { - commands.push(self.update_config()); - } - } else if let Operation::Move { - ref paths, ref to, .. - } = op - { - let path_changes: Box<[_]> = paths - .iter() - .filter_map(|from| from.file_name().map(|name| (from, to.join(name)))) - .collect(); - if self.update_favorites(&path_changes) { - commands.push(self.update_config()); - } - } - - if matches!(op, Operation::RemoveFromRecents { .. }) { - commands.push(self.rescan_recents()); - } - - self.complete_operations.insert(id, op); - } - // Close progress notification if all relevant operations are finished - if !self - .pending_operations - .values() - .any(|(op, _)| op.show_progress_notification()) - { - self.progress_operations.clear(); - } - // Potentially show a notification - commands.push(self.update_notification()); - // Rescan and select based on operation - commands.push(self.rescan_operation_selection(op_sel)); - // Manually rescan any trash tabs after any operation is completed - commands.push(self.rescan_trash()); - - return Task::batch(commands); + return self.handle_completed_operations(vec![(id, op_sel)]); } Message::PendingDismiss => { self.progress_operations.clear(); } Message::PendingError(id, err) => { - let mut tasks = Vec::new(); - if let Some((op, controller)) = self.pending_operations.remove(&id) { - // Only show dialog if not cancelled - if !controller.is_cancelled() { - tasks.push(self.dialog_pages.push_back(match err.kind { - OperationErrorType::Generic(_) => DialogPage::FailedOperation(id), - OperationErrorType::PasswordRequired => DialogPage::ExtractPassword { - id, - password: String::new(), - }, - })); - } - tasks.push(widget::text_input::focus(self.dialog_text_input.clone())); - - // Remove from progress - self.progress_operations.remove(&id); - self.failed_operations - .insert(id, (op, controller, err.to_string())); - } - // Close progress notification if all relevant operations are finished - if !self - .pending_operations - .values() - .any(|(op, _)| op.show_progress_notification()) - { - self.progress_operations.clear(); - } - // Manually rescan any trash tabs after any operation is completed - tasks.push(self.rescan_trash()); - return Task::batch(tasks); + return self.handle_operation_errors(vec![(id, err)]); + } + Message::PendingResults(completed, errors) => { + return Task::batch(vec![ + self.handle_completed_operations(completed), + self.handle_operation_errors(errors), + ]); } Message::PendingPause(id, pause) => { if let Some((_, controller)) = self.pending_operations.get(&id) { @@ -4479,11 +4549,17 @@ impl Application for App { commands.push(self.operation(Operation::SetPermissions { path, mode })); } tab::Command::SetMultiplePermissions(permissions) => { - commands.push(Task::batch(permissions.into_iter().map( - |(path, mode)| { - self.operation(Operation::SetPermissions { path, mode }) - }, - ))); + commands.push( + self.join_operations( + permissions + .into_iter() + .map(|(path, mode)| Operation::SetPermissions { + path, + mode, + }) + .collect(), + ), + ); } tab::Command::WindowDrag => { if let Some(window_id) = self.core.main_window_id() { @@ -5447,6 +5523,25 @@ impl Application for App { widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), ) } + DialogPage::FailedOperations(ids) => { + let errors: Vec = ids + .into_iter() + .filter_map(|id| match self.failed_operations.get(id) { + Some((operation, _, err)) => Some(format!("{operation:#?}\n{err}")), + _ => None, + }) + .collect(); + + //TODO: nice description of error + widget::dialog() + .title("Failed operations") + .body(errors.join("\n\n")) + .icon(icon::from_name("dialog-error").size(64)) + //TODO: retry action + .primary_action( + widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), + ) + } DialogPage::ExtractPassword { id, password } => widget::dialog() .title(fl!("extract-password-required")) .icon(icon::from_name("dialog-error").size(64)) From 23b5d98dcc3fef32e9ca6b734be94834a8f7013a Mon Sep 17 00:00:00 2001 From: Jonatan Pettersson Date: Fri, 16 Jan 2026 21:54:31 +0100 Subject: [PATCH 014/110] feat: set placeholder for permission dropdowns --- i18n/en/cosmic_files.ftl | 1 + i18n/sv/cosmic_files.ftl | 1 + src/tab.rs | 17 +++-------------- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 654e9ab..6a852bb 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -131,6 +131,7 @@ open-with = Open with owner = Owner group = Group other = Other +mixed = Mixed ### Mode 0 none = None ### Mode 1 (unusual) diff --git a/i18n/sv/cosmic_files.ftl b/i18n/sv/cosmic_files.ftl index 2527c4e..cbd28dd 100644 --- a/i18n/sv/cosmic_files.ftl +++ b/i18n/sv/cosmic_files.ftl @@ -101,6 +101,7 @@ open-with = Öppna med owner = Ägare group = Grupp other = Andra +mixed = Blandade # Listvy name = Namn modified = Ändrad diff --git a/src/tab.rs b/src/tab.rs index 31a82d4..08b2c45 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -6445,17 +6445,6 @@ impl Tab { #[cfg(unix)] { - // The following is a bit of a hack to make the dropdown selector - // fill the available space when selected is None so it can be - // clicked on easier. - fn dropdown_width(use_default: bool) -> Length { - if use_default { - Length::Shrink - } else { - Length::Fill - } - } - // Only return mode part if it's the only one fn selected_mode_part(mut modes: BTreeSet) -> Option { match (modes.pop_first(), modes.pop_first()) { @@ -6491,7 +6480,7 @@ impl Tab { ) }, ) - .width(dropdown_width(mode_part_user.is_some())), + .placeholder(fl!("mixed")), ), ); @@ -6511,7 +6500,7 @@ impl Tab { ) }, ) - .width(dropdown_width(mode_part_group.is_some())), + .placeholder(fl!("mixed")), ), ); @@ -6529,7 +6518,7 @@ impl Tab { ) }, ) - .width(dropdown_width(mode_part_other.is_some())), + .placeholder(fl!("mixed")), ), ); } From 39281a633654d1c31702a66e1e69d9bd497b09a0 Mon Sep 17 00:00:00 2001 From: darkfated Date: Mon, 6 Apr 2026 06:16:27 +0300 Subject: [PATCH 015/110] Add user-defined context actions --- i18n/en/cosmic_files.ftl | 7 +++ src/app.rs | 104 +++++++++++++++++++++++++++++++++++++++ src/config.rs | 4 ++ src/context_action.rs | 83 +++++++++++++++++++++++++++++++ src/dialog.rs | 63 ++++++++++++++++++++++-- src/lib.rs | 1 + src/menu.rs | 21 +++++++- src/tab.rs | 31 ++++++++++-- 8 files changed, 305 insertions(+), 9 deletions(-) create mode 100644 src/context_action.rs diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 6a852bb..69a76c6 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -99,6 +99,13 @@ open-with-title = How do you want to open "{$name}"? browse-store = Browse {$store} other-apps = Other applications related-apps = Related applications +context-action = Context action +context-action-confirm-title = Run "{$name}"? +context-action-confirm-warning = This will run on {$items} {$items -> + [one] item + *[other] items + }. +run = Run ## Permanently delete Dialog selected-items = The {$items} selected items diff --git a/src/app.rs b/src/app.rs index 074e4eb..9d4f3fb 100644 --- a/src/app.rs +++ b/src/app.rs @@ -80,6 +80,7 @@ use crate::{ AppTheme, Config, DesktopConfig, Favorite, IconSizes, State, TIME_CONFIG_ID, TabConfig, TimeConfig, TypeToSearch, }, + context_action, dialog::{Dialog, DialogKind, DialogMessage, DialogResult, DialogSettings}, fl, home_dir, key_bind::key_binds, @@ -109,6 +110,9 @@ static DELETE_TRASH_BUTTON_ID: LazyLock = static CONFIRM_OPEN_WITH_BUTTON_ID: LazyLock = LazyLock::new(|| widget::Id::new("confirm-open-with-button")); +static CONFIRM_CONTEXT_ACTION_BUTTON_ID: LazyLock = + LazyLock::new(|| widget::Id::new("confirm-context-action-button")); + static EMPTY_TRASH_BUTTON_ID: LazyLock = LazyLock::new(|| widget::Id::new("empty-trash-button")); @@ -180,6 +184,7 @@ pub enum Action { OpenItemLocation, OpenTerminal, OpenWith, + RunContextAction(usize), Paste, PermanentlyDelete, Preview, @@ -252,6 +257,9 @@ impl Action { Self::OpenItemLocation => Message::OpenItemLocation(entity_opt), Self::OpenTerminal => Message::OpenTerminal(entity_opt), Self::OpenWith => Message::OpenWithDialog(entity_opt), + Self::RunContextAction(action) => { + Message::TabMessage(entity_opt, tab::Message::RunContextAction(*action)) + } Self::Paste => Message::Paste(entity_opt), Self::PermanentlyDelete => Message::PermanentlyDelete(entity_opt), Self::Preview => Message::Preview(entity_opt), @@ -323,6 +331,7 @@ pub enum NavMenuAction { OpenInNewTab(segmented_button::Entity), OpenInNewWindow(segmented_button::Entity), Preview(segmented_button::Entity), + RunContextAction(segmented_button::Entity, usize), RemoveFromSidebar(segmented_button::Entity), } @@ -558,6 +567,10 @@ pub enum DialogPage { name: String, dir: bool, }, + RunContextAction { + action: usize, + paths: Box<[PathBuf]>, + }, OpenWith { path: PathBuf, mime: mime_guess::Mime, @@ -2593,6 +2606,28 @@ impl Application for App { NavMenuAction::OpenInNewWindow(entity), )); } + if let Some(path) = location_opt.and_then(Location::path_opt) { + let selected_dir = usize::from(path.is_dir()); + let action_items: Vec<_> = self + .config + .context_actions + .iter() + .enumerate() + .filter(|(_, action)| action.matches_selection(1, selected_dir)) + .map(|(i, action)| { + cosmic::widget::menu::Item::Button( + action.name.clone(), + None, + NavMenuAction::RunContextAction(entity, i), + ) + }) + .collect(); + + if !action_items.is_empty() { + items.push(cosmic::widget::menu::Item::Divider); + items.extend(action_items); + } + } items.push(cosmic::widget::menu::Item::Divider); if matches!(location_opt, Some(Location::Path(..))) { items.push(cosmic::widget::menu::Item::Button( @@ -3185,6 +3220,9 @@ impl Application for App { Operation::NewFile { path } })); } + DialogPage::RunContextAction { action, paths } => { + context_action::run(&self.config.context_actions, action, &paths); + } DialogPage::OpenWith { path, mime, @@ -4505,6 +4543,25 @@ impl Application for App { tab::Command::ExecEntryAction(entry, action) => { Self::exec_entry_action(&entry, action); } + tab::Command::RunContextAction(action) => { + let paths: Box<[_]> = self.selected_paths(Some(entity)).collect(); + if let Some(preset) = self.config.context_actions.get(action) { + if preset.confirm { + commands.push(self.push_dialog( + DialogPage::RunContextAction { action, paths }, + Some(CONFIRM_CONTEXT_ACTION_BUTTON_ID.clone()), + )); + } else { + context_action::run( + &self.config.context_actions, + action, + &paths, + ); + } + } else { + log::warn!("invalid context action index `{action}`"); + } + } tab::Command::Iced(iced_command) => { commands.push(iced_command.0.map(move |x| { cosmic::action::app(Message::TabMessage(Some(entity), x)) @@ -5012,6 +5069,30 @@ impl Application for App { } } } + NavMenuAction::RunContextAction(entity, action) => { + if let Some(path) = self + .nav_model + .data::(entity) + .and_then(Location::path_opt) + .cloned() + { + let paths = vec![path]; + if let Some(preset) = self.config.context_actions.get(action) { + if preset.confirm { + return self.push_dialog( + DialogPage::RunContextAction { + action, + paths: paths.into_boxed_slice(), + }, + Some(CONFIRM_CONTEXT_ACTION_BUTTON_ID.clone()), + ); + } + context_action::run(&self.config.context_actions, action, &paths); + } else { + log::warn!("invalid context action index `{action}`"); + } + } + } NavMenuAction::OpenInNewTab(entity) => { let open_task = match self.nav_model.data::(entity) { Some(Location::Network(uri, display_name, path)) => self.open_tab( @@ -5788,6 +5869,26 @@ impl Application for App { .spacing(space_xxs), ) } + DialogPage::RunContextAction { action, paths } => { + let name = self + .config + .context_actions + .get(*action) + .map_or_else(|| fl!("context-action"), |preset| preset.name.clone()); + + widget::dialog() + .title(fl!("context-action-confirm-title", name = name)) + .body(fl!("context-action-confirm-warning", items = paths.len())) + .icon(icon::from_name("dialog-error").size(64)) + .primary_action( + widget::button::suggested(fl!("run")) + .on_press(Message::DialogComplete) + .id(CONFIRM_CONTEXT_ACTION_BUTTON_ID.clone()), + ) + .secondary_action( + widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), + ) + } DialogPage::OpenWith { path, mime, @@ -6333,6 +6434,7 @@ impl Application for App { &self.key_binds, &self.modifiers, self.clipboard_has_content(), + &self.config.context_actions, ) .map(move |message| Message::TabMessage(Some(entity), message)); tab_column = tab_column.push(tab_view); @@ -6361,6 +6463,7 @@ impl Application for App { &self.key_binds, &window.modifiers, self.clipboard_has_content(), + &self.config.context_actions, ) .map(|x| Message::TabMessage(Some(*entity), x)), id.clone(), @@ -6378,6 +6481,7 @@ impl Application for App { &self.key_binds, &window.modifiers, self.clipboard_has_content(), + &self.config.context_actions, ) .map(move |message| Message::TabMessage(Some(*entity), message)), None => widget::space::vertical().into(), diff --git a/src/config.rs b/src/config.rs index cbe84a6..0ce9c22 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,6 +16,8 @@ use crate::{ tab::{HeadingOptions, Location, View}, }; +pub use crate::context_action::{ContextActionPreset, ContextActionSelection}; + pub const CONFIG_VERSION: u64 = 1; // Default icon sizes @@ -164,6 +166,7 @@ pub struct Config { pub app_theme: AppTheme, pub dialog: DialogConfig, pub desktop: DesktopConfig, + pub context_actions: Vec, pub thumb_cfg: ThumbCfg, pub favorites: Vec, pub show_details: bool, @@ -220,6 +223,7 @@ impl Default for Config { app_theme: AppTheme::System, desktop: DesktopConfig::default(), dialog: DialogConfig::default(), + context_actions: Vec::new(), thumb_cfg: ThumbCfg::default(), favorites: vec![ Favorite::Home, diff --git a/src/context_action.rs b/src/context_action.rs new file mode 100644 index 0000000..b12a48a --- /dev/null +++ b/src/context_action.rs @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-3.0-only + +use std::path::PathBuf; + +use serde::{Deserialize, Serialize}; + +use crate::{mime_app, spawn_detached::spawn_detached}; + +#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +pub enum ContextActionSelection { + #[default] + #[serde(alias = "any")] + Any, + #[serde(alias = "files")] + Files, + #[serde(alias = "folders")] + Folders, +} + +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +#[serde(default)] +pub struct ContextActionPreset { + pub name: String, + pub confirm: bool, + pub selection: ContextActionSelection, + pub steps: Vec, +} + +impl ContextActionPreset { + pub fn matches_selection(&self, selected: usize, selected_dir: usize) -> bool { + if selected == 0 { + return false; + } + + match self.selection { + ContextActionSelection::Any => true, + ContextActionSelection::Files => selected_dir == 0, + ContextActionSelection::Folders => selected_dir == selected, + } + } + + pub fn run(&self, paths: &[PathBuf]) { + if self.steps.is_empty() { + log::warn!("context action {:?} has no steps", self.name); + return; + } + + for step in &self.steps { + let Some(commands) = mime_app::exec_to_command(step, paths) else { + log::warn!( + "failed to parse context action {:?}: invalid Exec {:?}", + self.name, + step + ); + return; + }; + + for mut command in commands { + if let Err(err) = spawn_detached(&mut command) { + log::warn!( + "failed to run context action {:?} step {:?}: {}", + self.name, + step, + err + ); + return; + } + } + } + } +} + +pub fn action_name(actions: &[ContextActionPreset], action: usize) -> Option { + actions.get(action).map(|preset| preset.name.clone()) +} + +pub fn run(actions: &[ContextActionPreset], action: usize, paths: &[PathBuf]) { + if let Some(preset) = actions.get(action) { + preset.run(paths); + } else { + log::warn!("invalid context action index `{action}`"); + } +} diff --git a/src/dialog.rs b/src/dialog.rs index a16b5f3..6bb9a0e 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -45,7 +45,7 @@ use crate::{ Action, ContextPage, Message as AppMessage, PreviewItem, PreviewKind, REPLACE_BUTTON_ID, }, config::{Config, DialogConfig, Favorite, TIME_CONFIG_ID, ThumbCfg, TimeConfig, TypeToSearch}, - fl, home_dir, + context_action, fl, home_dir, key_bind::key_binds, localize::LANGUAGE_SORTER, menu, @@ -441,8 +441,17 @@ impl Dialog { #[derive(Clone, Debug)] enum DialogPage { - NewFolder { parent: PathBuf, name: String }, - Replace { filename: String }, + NewFolder { + parent: PathBuf, + name: String, + }, + RunContextAction { + action: usize, + paths: Box<[PathBuf]>, + }, + Replace { + filename: String, + }, } #[derive(Clone, Debug)] @@ -1203,6 +1212,21 @@ impl Application for App { .spacing(space_xxs), ) } + DialogPage::RunContextAction { action, paths } => { + let name = context_action::action_name(&self.flags.config.context_actions, *action) + .unwrap_or_else(|| fl!("context-action")); + + widget::dialog() + .title(fl!("context-action-confirm-title", name = name)) + .body(fl!("context-action-confirm-warning", items = paths.len())) + .icon(widget::icon::from_name("dialog-error").size(64)) + .primary_action( + widget::button::suggested(fl!("run")).on_press(Message::DialogComplete), + ) + .secondary_action( + widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), + ) + } DialogPage::Replace { filename } => widget::dialog() .title(fl!("replace-title", filename = filename.as_str())) .icon(widget::icon::from_name("dialog-question").size(64)) @@ -1425,6 +1449,9 @@ impl Application for App { } } } + DialogPage::RunContextAction { action, paths } => { + context_action::run(&self.flags.config.context_actions, action, &paths); + } DialogPage::Replace { .. } => { return self.update(Message::Save(true)); } @@ -1831,6 +1858,7 @@ impl Application for App { &app.key_binds, &app.modifiers, false, // Paste not used in dialogs + &app.flags.config.context_actions, ) .map(Message::TabMessage) .map(cosmic::Action::App), @@ -1851,6 +1879,28 @@ impl Application for App { } } } + tab::Command::RunContextAction(action) => { + let paths: Box<[_]> = self + .tab + .selected_locations() + .into_iter() + .filter_map(Location::into_path_opt) + .collect(); + if let Some(preset) = self.flags.config.context_actions.get(action) { + if preset.confirm { + self.dialog_pages + .push_back(DialogPage::RunContextAction { action, paths }); + } else { + context_action::run( + &self.flags.config.context_actions, + action, + &paths, + ); + } + } else { + log::warn!("invalid context action index `{action}`"); + } + } tab::Command::Iced(iced_command) => { commands.push(iced_command.0.map(|tab_message| { cosmic::action::app(Message::TabMessage(tab_message)) @@ -2024,7 +2074,12 @@ impl Application for App { col = col.push( self.tab - .view(&self.key_binds, &self.modifiers, false) + .view( + &self.key_binds, + &self.modifiers, + false, + &self.flags.config.context_actions, + ) .map(Message::TabMessage), ); diff --git a/src/lib.rs b/src/lib.rs index 159af08..cc0bcc1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ use app::{App, Flags}; pub mod app; mod archive; pub mod clipboard; +mod context_action; use config::Config; pub mod config; pub mod dialog; diff --git a/src/menu.rs b/src/menu.rs index ffec707..8db61d7 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -20,7 +20,7 @@ use std::{collections::HashMap, sync::LazyLock}; use crate::{ app::{Action, Message}, - config::Config, + config::{Config, ContextActionPreset}, fl, tab::{self, HeadingOptions, Location, LocationMenuAction, SearchLocation, Tab}, }; @@ -60,6 +60,7 @@ pub fn context_menu<'a>( key_binds: &HashMap, modifiers: &Modifiers, clipboard_paste_available: bool, + context_actions: &[ContextActionPreset], ) -> Element<'a, tab::Message> { let find_key = |action: &Action| -> String { for (key_bind, key_action) in key_binds { @@ -157,6 +158,14 @@ pub fn context_menu<'a>( selected_types.sort_unstable(); selected_types.dedup(); selected_trash_only = selected_trash_only && selected == 1; + let context_action_items = |selected: usize, selected_dir: usize| { + context_actions + .iter() + .enumerate() + .filter(|(_, action)| action.matches_selection(selected, selected_dir)) + .map(|(i, action)| menu_item(action.name.clone(), Action::RunContextAction(i)).into()) + .collect::>>() + }; // Parse the desktop entry if it is the only selection #[cfg(feature = "desktop")] let selected_desktop_entry = selected_desktop_entry.and_then(|path| { @@ -204,6 +213,11 @@ pub fn context_menu<'a>( } // Should this simply bypass trash and remove the shortcut? children.push(menu_item(fl!("move-to-trash"), Action::Delete).into()); + let action_items = context_action_items(selected, selected_dir); + if !action_items.is_empty() { + children.push(divider::horizontal::light().into()); + children.extend(action_items); + } } else if selected > 0 { if selected_dir == 1 && selected == 1 || selected_dir == 0 { children.push(menu_item(fl!("open"), Action::Open).into()); @@ -226,6 +240,11 @@ pub fn context_menu<'a>( children .push(menu_item(fl!("open-in-new-window"), Action::OpenInNewWindow).into()); } + let action_items = context_action_items(selected, selected_dir); + if !action_items.is_empty() { + children.push(divider::horizontal::light().into()); + children.extend(action_items); + } children.push(divider::horizontal::light().into()); if selected_mount_point == 0 { children.push(menu_item(fl!("rename"), Action::Rename).into()); diff --git a/src/tab.rs b/src/tab.rs index 08b2c45..578726f 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -66,7 +66,10 @@ use crate::{ FxOrderMap, app::{Action, PreviewItem, PreviewKind}, clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste}, - config::{DesktopConfig, ICON_SCALE_MAX, ICON_SIZE_GRID, IconSizes, TabConfig, ThumbCfg}, + config::{ + ContextActionPreset, DesktopConfig, ICON_SCALE_MAX, ICON_SIZE_GRID, IconSizes, TabConfig, + ThumbCfg, + }, dialog::DialogKind, fl, large_image::{ @@ -1794,6 +1797,7 @@ pub enum Command { OpenInNewWindow(PathBuf), OpenTrash, Preview(PreviewKind), + RunContextAction(usize), SetOpenWith(Mime, String), SetPermissions(PathBuf, u32), SetMultiplePermissions(Vec<(PathBuf, u32)>), @@ -1852,6 +1856,7 @@ pub enum Message { SelectFirst, SelectLast, SetOpenWith(Mime, String), + RunContextAction(usize), SetPermissions(PathBuf, u32), ShiftPermissions(Option<(PathBuf, u32)>, u32, u32), SetSort(HeadingOptions, bool), @@ -3566,6 +3571,11 @@ impl Tab { commands.push(Command::Action(action)); } + Message::RunContextAction(action) => { + self.context_menu = None; + + commands.push(Command::RunContextAction(action)); + } Message::ContextMenu(point_opt, _) => { self.edit_location = None; self.context_menu = point_opt; @@ -6083,6 +6093,7 @@ impl Tab { modifiers: &'a Modifiers, size: Size, clipboard_paste_available: bool, + context_actions: &'a [ContextActionPreset], ) -> Element<'a, Message> { // Update cached size self.size_opt.set(Some(size)); @@ -6170,8 +6181,13 @@ impl Tab { if let Some(point) = self.context_menu && (!cfg!(feature = "wayland") || !crate::is_wayland()) { - let context_menu = - menu::context_menu(self, key_binds, modifiers, clipboard_paste_available); + let context_menu = menu::context_menu( + self, + key_binds, + modifiers, + clipboard_paste_available, + context_actions, + ); popover = popover .popup(context_menu) .position(widget::popover::Position::Point(point)); @@ -6536,10 +6552,17 @@ impl Tab { key_binds: &'a HashMap, modifiers: &'a Modifiers, clipboard_paste_available: bool, + context_actions: &'a [ContextActionPreset], ) -> Element<'a, Message> { widget::responsive(move |size| { widget::id_container( - self.view_responsive(key_binds, modifiers, size, clipboard_paste_available), + self.view_responsive( + key_binds, + modifiers, + size, + clipboard_paste_available, + context_actions, + ), Id::new(format!( "tab-{}-{}", self.scrollable_id, self.location_title From 635bff7c1eadaf9b5426efe52decc00c49153300 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Fri, 3 Apr 2026 19:29:48 -0400 Subject: [PATCH 016/110] chore: udpate libcosmic --- Cargo.lock | 533 +++++++++++++++++++++++++---------------------------- Cargo.toml | 1 + 2 files changed, 250 insertions(+), 284 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce19605..bbed562 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -859,9 +859,9 @@ dependencies = [ [[package]] name = "calendrical_calculations" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a0b39595c6ee54a8d0900204ba4c401d0ab4eb45adaf07178e8d017541529e7" +checksum = "5abbd6eeda6885048d357edc66748eea6e0268e3dd11f326fff5bd248d779c26" dependencies = [ "core_maths", "displaydoc", @@ -894,9 +894,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.57" +version = "1.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" +checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ "find-msvc-tools", "jobserver", @@ -1090,9 +1090,9 @@ dependencies = [ [[package]] name = "compio-driver" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8557d3804525f0e97594681f675929931782c9f8783a51c9f86da86b819150" +checksum = "74d42d98dc890ee4db00c1e68a723391711aab6d67085880d716b72830f7c715" dependencies = [ "cfg-if", "cfg_aliases", @@ -1317,7 +1317,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1327,7 +1327,7 @@ dependencies = [ "iced_futures", "known-folders", "notify", - "ron 0.12.0", + "ron 0.12.1", "serde", "tokio", "tracing", @@ -1338,7 +1338,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "quote", "syn", @@ -1387,7 +1387,7 @@ dependencies = [ "recently-used-xbel", "regex", "rust-embed", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "serde", "shlex", "slotmap", @@ -1458,7 +1458,7 @@ dependencies = [ [[package]] name = "cosmic-settings-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#8d83e2a4179bbe193d195cd42efe9ce50bcc9926" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#716da6d6af0b252e2f78aba2ad72ee19ae0241e0" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1479,7 +1479,7 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.18.2" -source = "git+https://github.com/pop-os/cosmic-text.git#d5a972a2b63649fad11ea3a7e80f7dc4c592f01a" +source = "git+https://github.com/pop-os/cosmic-text.git#9a5579f5231bc52b3688a2de3643091f1ce32cbd" dependencies = [ "bitflags 2.11.0", "fontdb", @@ -1487,9 +1487,9 @@ dependencies = [ "linebender_resource_handle", "log", "rangemap", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "self_cell", - "skrifa 0.40.0", + "skrifa", "smol_str", "swash", "sys-locale", @@ -1502,7 +1502,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "almost", "configparser", @@ -1510,7 +1510,7 @@ dependencies = [ "csscolorparser", "dirs 6.0.0", "palette", - "ron 0.12.0", + "ron 0.12.1", "serde", "serde_json", "thiserror 2.0.18", @@ -1582,7 +1582,7 @@ dependencies = [ "cosmic-text", "etagere", "lru", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "wgpu", ] @@ -2154,9 +2154,9 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixed_decimal" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35eabf480f94d69182677e37571d3be065822acfafd12f2f085db44fbbcc8e57" +checksum = "79c3c892f121fff406e5dd6b28c1b30096b95111c30701a899d4f2b18da6d1bd" dependencies = [ "displaydoc", "smallvec", @@ -2215,7 +2215,7 @@ dependencies = [ "fluent-syntax", "intl-memoizer", "intl_pluralrules", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "self_cell", "smallvec", "unic-langid", @@ -2269,18 +2269,9 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "font-types" -version = "0.10.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a654f404bbcbd48ea58c617c2993ee91d1cb63727a37bf2323a4edeed1b8c5" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "font-types" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73829a7b5c91198af28a99159b7ae4afbb252fb906159ff7f189f3a2ceaa3df2" +checksum = "2d9237c6d82152100c691fb77ea18037b402bcc7257d2c876a4ffac81bc22a1c" dependencies = [ "bytemuck", ] @@ -2374,7 +2365,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6d3a3635983a889f065aa9ce760384713f23a9b4a04f696f86c39a5d7a6a5a" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "nom 8.0.0", ] @@ -2831,7 +2822,7 @@ dependencies = [ "bitflags 2.11.0", "bytemuck", "core_maths", - "read-fonts 0.37.0", + "read-fonts", "smallvec", ] @@ -2992,7 +2983,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "dnd", "iced_accessibility", @@ -3013,7 +3004,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "accesskit", "accesskit_winit", @@ -3022,7 +3013,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "bitflags 2.11.0", "bytes", @@ -3035,7 +3026,7 @@ dependencies = [ "num-traits", "palette", "raw-window-handle", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "serde", "smol_str", "thiserror 2.0.18", @@ -3046,7 +3037,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "iced_core", "iced_futures", @@ -3056,12 +3047,12 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "futures", "iced_core", "log", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "tokio", "wasm-bindgen-futures", "wasmtimer", @@ -3070,7 +3061,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "bitflags 2.11.0", "bytemuck", @@ -3083,7 +3074,7 @@ dependencies = [ "log", "lyon_path", "raw-window-handle", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "thiserror 2.0.18", "unicode-segmentation", ] @@ -3091,7 +3082,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "iced_graphics", "iced_runtime", @@ -3100,7 +3091,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3112,7 +3103,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3127,7 +3118,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "bytemuck", "cosmic-text", @@ -3136,7 +3127,7 @@ dependencies = [ "kurbo 0.10.4", "log", "resvg", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "softbuffer", "tiny-skia", ] @@ -3144,7 +3135,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.0", @@ -3160,7 +3151,7 @@ dependencies = [ "lyon", "raw-window-handle", "resvg", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "rustix 0.38.44", "thiserror 2.0.18", "tiny-xlib", @@ -3175,7 +3166,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3184,7 +3175,7 @@ dependencies = [ "log", "num-traits", "ouroboros", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "thiserror 2.0.18", "unicode-segmentation", "window_clipboard", @@ -3193,7 +3184,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3205,7 +3196,7 @@ dependencies = [ "iced_runtime", "log", "raw-window-handle", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "rustix 0.38.44", "thiserror 2.0.18", "wasm-bindgen-futures", @@ -3224,9 +3215,9 @@ dependencies = [ [[package]] name = "icu" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ab713dd86fa032cb5487f9ac3a85d47b5dcf4c7b8c7dd00210b3cadd6a6551" +checksum = "00380f83691e089bcfa4aeb03a2d96a910b1c9ea406d6f822fc19dfb8b58d1ec" dependencies = [ "icu_calendar", "icu_casemap", @@ -3248,9 +3239,9 @@ dependencies = [ [[package]] name = "icu_calendar" -version = "2.1.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f0e52e009b6b16ba9c0693578796f2dd4aaa59a7f8f920423706714a89ac4e" +checksum = "a2b2acc6263f494f1df50685b53ff8e57869e47d5c6fe39c23d518ae9a4f3e45" dependencies = [ "calendrical_calculations", "displaydoc", @@ -3266,15 +3257,15 @@ dependencies = [ [[package]] name = "icu_calendar_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527f04223b17edfe0bd43baf14a0cb1b017830db65f3950dc00224860a9a446d" +checksum = "118577bcf3a0fa7c6ac0a7d6e951814da84ee56b9b1f68fb4d8d10b08cefaf4d" [[package]] name = "icu_casemap" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4ca9983e8bf51223c2f89014fa4eaa9e9b336c47f3af0d000538f86f841fba1" +checksum = "070f98b5b82798fcb93654bf96ed9f40064fc44c86f51a09ea711092cd5cc5be" dependencies = [ "icu_casemap_data", "icu_collections", @@ -3288,15 +3279,15 @@ dependencies = [ [[package]] name = "icu_casemap_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d4663d0f99b301033a19e0acf94e9d2fa4b107638580165e5a6ccc49ad1450" +checksum = "846b0857ca091204be3c874bc93daaf89d4777e8d2d20b0d3ffe8f671d98014b" [[package]] name = "icu_collator" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32eed11a5572f1088b63fa21dc2e70d4a865e5739fc2d10abc05be93bae97019" +checksum = "b521b92a2666061ddda902769d8a4cf730b5c9529a845cc1b69770b12a6c9a71" dependencies = [ "icu_collator_data", "icu_collections", @@ -3313,19 +3304,20 @@ dependencies = [ [[package]] name = "icu_collator_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab06f0e83a613efddba3e4913e00e43ed4001fae651cb7d40fc7e66b83b6fb9" +checksum = "038ed8e5817f2059c2f3efb0945ba78d060d3d25e8f1a1bea5139f821a21a2f0" [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", "serde", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -3333,9 +3325,9 @@ dependencies = [ [[package]] name = "icu_datetime" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9d49f41ded8e63761b6b4c3120dfdc289415a1ed10107db6198eb311057ca5" +checksum = "989d56ea5bbc43ae2b4e0388874b002884eaf4ed3a76c84a6c8c5ad575e04d72" dependencies = [ "displaydoc", "fixed_decimal", @@ -3356,20 +3348,23 @@ dependencies = [ [[package]] name = "icu_datetime_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46597233625417b7c8052a63d916e4fdc73df21614ac0b679492a5d6e3b01aeb" +checksum = "40d3cc1b690d9703202bc319692ac8a1f3a6390686f0930ff40542450fa34f0b" [[package]] name = "icu_decimal" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38c52231bc348f9b982c1868a2af3195199623007ba2c7650f432038f5b3e8e" +checksum = "288247df2e32aa776ac54fdd64de552149ac43cb840f2761811f0e8d09719dd4" dependencies = [ + "displaydoc", "fixed_decimal", "icu_decimal_data", "icu_locale", "icu_locale_core", + "icu_pattern", + "icu_plurals", "icu_provider", "serde", "writeable", @@ -3378,15 +3373,15 @@ dependencies = [ [[package]] name = "icu_decimal_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2905b4044eab2dd848fe84199f9195567b63ab3a93094711501363f63546fef7" +checksum = "6f14a5ca9e8af29eef62064f269078424283d90dbaffeac5225addf62aaabc22" [[package]] name = "icu_experimental" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ffa4d60b9cb8b024082afaf9e94d853184e483ec69322c74dc437bf8a882a5" +checksum = "0a881116e620fd635f564fd9cb9bc36c256b9da2221df8b3f55643d8ef32140f" dependencies = [ "displaydoc", "either", @@ -3417,15 +3412,15 @@ dependencies = [ [[package]] name = "icu_experimental_data" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0bce39e12480e91c7ddb748218050c459e241f491d130ea6ee92c3e5cd254f7" +checksum = "f72090d4f08a2bc94565cb02de6d5b87939424e462d9927d73a34f6f8e5d1232" [[package]] name = "icu_list" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a0b7b126e2fc42777d3c348611553d540bd3683caa39b387c5dd1036bb21a8" +checksum = "aeeaf517689324395bed4767f7c65504f5455942ed4c14ee54c2087ca00b816e" dependencies = [ "icu_list_data", "icu_locale", @@ -3438,15 +3433,15 @@ dependencies = [ [[package]] name = "icu_list_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51044c242fe2a882cc0a464314bbdb9f441556a1cb238fb527fc47355ec2827b" +checksum = "ed62dbf114db9a4163481ed071509c4cd52cbcef9cb85979eba08a95549d73f3" [[package]] name = "icu_locale" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532b11722e350ab6bf916ba6eb0efe3ee54b932666afec989465f9243fe6dd60" +checksum = "d5a396343c7208121dc86e35623d3dfe19814a7613cfd14964994cdc9c9a2e26" dependencies = [ "icu_collections", "icu_locale_core", @@ -3459,9 +3454,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -3473,15 +3468,15 @@ dependencies = [ [[package]] name = "icu_locale_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c5f1d16b4c3a2642d3a719f18f6b06070ab0aef246a6418130c955ae08aa831" +checksum = "d5fdcc9ac77c6d74ff5cf6e65ef3181d6af32003b16fce3a77fb451d2f695993" [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -3496,15 +3491,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_pattern" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a7ff8c0ff6f61cdce299dcb54f557b0a251adbc78f6f0c35a21332c452b4a1b" +checksum = "1c4c568054ffe735398a9f4c55aec37ad7c768844553cc0978f09cc9b933a1fb" dependencies = [ "displaydoc", "either", @@ -3516,9 +3511,9 @@ dependencies = [ [[package]] name = "icu_plurals" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f9cfe49f5b1d1163cc58db451562339916a9ca5cbcaae83924d41a0bf839474" +checksum = "2a50023f1d49ad5c4333380328a0d4a19e4b9d6d842ec06639affd5ba47c8103" dependencies = [ "fixed_decimal", "icu_locale", @@ -3529,15 +3524,15 @@ dependencies = [ [[package]] name = "icu_plurals_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f018a98dccf7f0eb02ba06ac0ff67d102d8ded80734724305e924de304e12ff0" +checksum = "8485497155dc865f901decb93ecc20d3e467df67bfeceb91e3ba34e2b11e8e1d" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -3550,15 +3545,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -3573,9 +3568,9 @@ dependencies = [ [[package]] name = "icu_segmenter" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a807a7488f3f758629ae86d99d9d30dce24da2fb2945d74c80a4f4a62c71db73" +checksum = "5c0794db0b1a86193ac9c48768d0e6c52c54448e0870ad87907d456ee0dac964" dependencies = [ "core_maths", "icu_collections", @@ -3589,15 +3584,15 @@ dependencies = [ [[package]] name = "icu_segmenter_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ebbb7321d9e21d25f5660366cb6c08201d0175898a3a6f7a41ee9685af21c80" +checksum = "e4a2c462a4d927d512f5f882a033ddd62f33a05bb9f230d98f736ac3dc85938f" [[package]] name = "icu_time" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8242b00da3b3b6678f731437a11c8833a43c821ae081eca60ba1b7579d45b6d8" +checksum = "ec3af0c141da0a61d4f6970cd1d5f4b388b17ea22f8124f8f6049d3d5147586a" dependencies = [ "calendrical_calculations", "displaydoc", @@ -3613,9 +3608,9 @@ dependencies = [ [[package]] name = "icu_time_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e10b0e5e87a2c84bd5fa407705732052edebe69291d347d0c3033785470edbf" +checksum = "6f2f8aeca682d874a5247084aa4fb7d1cef9ba45d889c21209a8818dcaaa0ec9" [[package]] name = "id-arena" @@ -3687,7 +3682,7 @@ dependencies = [ "rgb", "tiff", "zune-core 0.5.1", - "zune-jpeg 0.5.14", + "zune-jpeg 0.5.15", ] [[package]] @@ -3725,9 +3720,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -3867,9 +3862,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "ixdtf" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84de9d95a6d2547d9b77ee3f25fa0ee32e3c3a6484d47a55adebc0439c077992" +checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1" [[package]] name = "jiff" @@ -3993,10 +3988,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.91" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" +checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -4293,14 +4290,14 @@ checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" [[package]] name = "libc" -version = "0.2.183" +version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#8e439c842ccc37a5df0821141c61766aef10c53e" +source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" dependencies = [ "apply", "ashpd 0.12.3", @@ -4422,9 +4419,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "litrs" @@ -4690,9 +4687,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "log", @@ -4731,7 +4728,7 @@ dependencies = [ "half", "hashbrown 0.16.1", "hexf-parse", - "indexmap 2.13.0", + "indexmap 2.13.1", "libm", "log", "num-traits", @@ -4891,9 +4888,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-derive" @@ -5218,9 +5215,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "5.1.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" +checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" dependencies = [ "num-traits", ] @@ -5241,7 +5238,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfa78c92071bbd3628c22b1a964f7e0eb201dc1456555db072beb1662ecd6715" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "serde", "serde_core", ] @@ -5588,9 +5585,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "serde_core", "writeable", @@ -5957,16 +5954,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "read-fonts" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358" -dependencies = [ - "bytemuck", - "font-types 0.10.1", -] - [[package]] name = "read-fonts" version = "0.37.0" @@ -5975,7 +5962,7 @@ checksum = "7b634fabf032fab15307ffd272149b622260f55974d9fad689292a5d33df02e5" dependencies = [ "bytemuck", "core_maths", - "font-types 0.11.1", + "font-types", ] [[package]] @@ -6154,9 +6141,9 @@ dependencies = [ [[package]] name = "ron" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd490c5b18261893f14449cbd28cb9c0b637aebf161cd77900bfdedaff21ec32" +checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" dependencies = [ "bitflags 2.11.0", "once_cell", @@ -6214,9 +6201,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc_version" @@ -6383,7 +6370,7 @@ version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "itoa", "memchr", "serde", @@ -6404,9 +6391,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ "serde_core", ] @@ -6421,7 +6408,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.13.0", + "indexmap 2.13.1", "schemars 0.9.0", "schemars 1.2.1", "serde_core", @@ -6491,9 +6478,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simd_cesu8" @@ -6535,16 +6522,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" -[[package]] -name = "skrifa" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841" -dependencies = [ - "bytemuck", - "read-fonts 0.35.0", -] - [[package]] name = "skrifa" version = "0.40.0" @@ -6552,7 +6529,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbdfe3d2475fbd7ddd1f3e5cf8288a30eb3e5f95832829570cd88115a7434ac" dependencies = [ "bytemuck", - "read-fonts 0.37.0", + "read-fonts", ] [[package]] @@ -6736,11 +6713,11 @@ dependencies = [ [[package]] name = "swash" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47846491253e976bdd07d0f9cc24b7daf24720d11309302ccbbc6e6b6e53550a" +checksum = "842f3cd369c2ba38966204f983eaa5e54a8e84a7d7159ed36ade2b6c335aae64" dependencies = [ - "skrifa 0.37.0", + "skrifa", "yazi", "zeno", ] @@ -6758,9 +6735,9 @@ dependencies = [ [[package]] name = "synchrony" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5f5d3091c2d998f6ab4c8b495c0d232ad0aecbc1fa9ac52c247a79d497e16" +checksum = "c174d82fd56da8214ec095cfe4568e59e5ccb49d060e70c2f98e3ba352b23e45" dependencies = [ "futures-util", "loom", @@ -6788,14 +6765,14 @@ dependencies = [ [[package]] name = "system-deps" -version = "7.0.7" +version = "7.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c8f33736f986f16d69b6cb8b03f55ddcad5c41acc4ccc39dd88e84aa805e7f" +checksum = "396a35feb67335377e0251fcbc1092fc85c484bd4e3a7a54319399da127796e7" dependencies = [ "cfg-expr", "heck 0.5.0", "pkg-config", - "toml 0.9.12+spec-1.1.0", + "toml 1.1.2+spec-1.1.0", "version-compare", ] @@ -6956,7 +6933,7 @@ dependencies = [ "half", "quick-error", "weezl", - "zune-jpeg 0.5.14", + "zune-jpeg 0.5.15", ] [[package]] @@ -7052,9 +7029,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "serde_core", @@ -7078,9 +7055,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.50.0" +version = "1.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" dependencies = [ "bytes", "libc", @@ -7095,9 +7072,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -7126,63 +7103,54 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.12+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "serde_core", "serde_spanned", - "toml_datetime 0.7.5+spec-1.1.0", + "toml_datetime", "toml_parser", "toml_writer", - "winnow 0.7.15", + "winnow 1.0.1", ] [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_datetime" -version = "1.1.0+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97251a7c317e03ad83774a8752a7e81fb6067740609f75ea2b585b569a59198f" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.25.8+spec-1.1.0" +version = "0.25.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16bff38f1d86c47f9ff0647e6838d7bb362522bdf44006c7068c2b1e606f1f3c" +checksum = "a82418ca169e235e6c399a84e395ab6debeb3bc90edc959bf0f48647c6a32d1b" dependencies = [ - "indexmap 2.13.0", - "toml_datetime 1.1.0+spec-1.1.0", + "indexmap 2.13.1", + "toml_datetime", "toml_parser", - "winnow 1.0.0", + "winnow 1.0.1", ] [[package]] name = "toml_parser" -version = "1.1.0+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2334f11ee363607eb04df9b8fc8a13ca1715a72ba8662a26ac285c98aabb4011" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.0", + "winnow 1.0.1", ] [[package]] name = "toml_writer" -version = "1.1.0+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "tracing" @@ -7278,7 +7246,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90" dependencies = [ - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", ] [[package]] @@ -7388,9 +7356,9 @@ checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" [[package]] name = "unicode-segmentation" -version = "1.13.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a559e63b5d8004e12f9bce88af5c6d939c58de839b7532cfe9653846cedd2a9e" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-vo" @@ -7476,9 +7444,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ "js-sys", "serde_core", @@ -7560,9 +7528,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" +checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" dependencies = [ "cfg-if", "once_cell", @@ -7573,23 +7541,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.64" +version = "0.4.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" +checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" dependencies = [ - "cfg-if", - "futures-util", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" +checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7597,9 +7561,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" +checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" dependencies = [ "bumpalo", "proc-macro2", @@ -7610,9 +7574,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" +checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" dependencies = [ "unicode-ident", ] @@ -7634,7 +7598,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap 2.13.0", + "indexmap 2.13.1", "wasm-encoder", "wasmparser", ] @@ -7647,7 +7611,7 @@ checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags 2.11.0", "hashbrown 0.15.5", - "indexmap 2.13.0", + "indexmap 2.13.1", "semver", ] @@ -7667,9 +7631,9 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa75f400b7f719bcd68b3f47cd939ba654cedeef690f486db71331eec4c6a406" +checksum = "2857dd20b54e916ec7253b3d6b4d5c4d7d4ca2c33c2e11c6c76a99bd8744755d" dependencies = [ "cc", "downcast-rs", @@ -7681,9 +7645,9 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.13" +version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab51d9f7c071abeee76007e2b742499e535148035bb835f97aaed1338cf516c3" +checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" dependencies = [ "bitflags 2.11.0", "rustix 1.1.4", @@ -7704,9 +7668,9 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.13" +version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b3298683470fbdc6ca40151dfc48c8f2fd4c41a26e13042f801f85002384091" +checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d" dependencies = [ "rustix 1.1.4", "wayland-client", @@ -7715,9 +7679,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.11" +version = "0.32.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b23b5df31ceff1328f06ac607591d5ba360cf58f90c8fad4ac8d3a55a3c4aec7" +checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" dependencies = [ "bitflags 2.11.0", "wayland-backend", @@ -7741,9 +7705,9 @@ dependencies = [ [[package]] name = "wayland-protocols-misc" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "429b99200febaf95d4f4e46deff6fe4382bcff3280ee16a41cf887b3c3364984" +checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" dependencies = [ "bitflags 2.11.0", "wayland-backend", @@ -7754,9 +7718,9 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d392fc283a87774afc9beefcd6f931582bb97fe0e6ced0b306a62cb1d026527c" +checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" dependencies = [ "bitflags 2.11.0", "wayland-backend", @@ -7767,9 +7731,9 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78248e4cc0eff8163370ba5c158630dcae1f3497a586b826eca2ef5f348d6235" +checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" dependencies = [ "bitflags 2.11.0", "wayland-backend", @@ -7781,9 +7745,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.9" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86287151a309799b821ca709b7345a048a2956af05957c89cb824ab919fa4e3" +checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a" dependencies = [ "proc-macro2", "quick-xml 0.39.2", @@ -7792,9 +7756,9 @@ dependencies = [ [[package]] name = "wayland-server" -version = "0.31.12" +version = "0.31.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63736a4a73e781cf6a736aa32c5d6773c3eb5389197562742a8c611b49b5e359" +checksum = "cc1846eb04c49182e04f4a099e2a830a2b745610bbc1d61246e206f29c7000a0" dependencies = [ "bitflags 2.11.0", "downcast-rs", @@ -7805,9 +7769,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.10" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374f6b70e8e0d6bf9461a32988fd553b59ff630964924dad6e4a4eb6bd538d17" +checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be" dependencies = [ "dlib", "log", @@ -7817,9 +7781,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.91" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" +checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" dependencies = [ "js-sys", "wasm-bindgen", @@ -7884,7 +7848,7 @@ dependencies = [ "cfg_aliases", "document-features", "hashbrown 0.16.1", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", "naga", "once_cell", @@ -8775,9 +8739,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" dependencies = [ "memchr", ] @@ -8810,7 +8774,7 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck 0.5.0", - "indexmap 2.13.0", + "indexmap 2.13.1", "prettyplease", "syn", "wasm-metadata", @@ -8841,7 +8805,7 @@ checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags 2.11.0", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", "serde", "serde_derive", @@ -8860,7 +8824,7 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", "semver", "serde", @@ -8878,9 +8842,9 @@ checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" dependencies = [ "either", ] @@ -9076,9 +9040,9 @@ checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -9087,9 +9051,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -9265,18 +9229,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.47" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.47" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", @@ -9285,18 +9249,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -9312,20 +9276,21 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", "zerofrom", + "zerovec", ] [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "serde", "yoke", @@ -9335,9 +9300,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", @@ -9346,9 +9311,9 @@ dependencies = [ [[package]] name = "zip" -version = "8.4.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7756d0206d058333667493c4014f545f4b9603c4330ccd6d9b3f86dcab59f7d9" +checksum = "2726508a48f38dceb22b35ecbbd2430efe34ff05c62bd3285f965d7911b33464" dependencies = [ "aes", "bzip2", @@ -9358,7 +9323,7 @@ dependencies = [ "flate2", "getrandom 0.4.2", "hmac", - "indexmap 2.13.0", + "indexmap 2.13.1", "lzma-rust2", "memchr", "pbkdf2", @@ -9455,9 +9420,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7a1c0af6e5d8d1363f4994b7a091ccf963d8b694f7da5b0b9cceb82da2c0a6" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" dependencies = [ "zune-core 0.5.1", ] diff --git a/Cargo.toml b/Cargo.toml index 174e04c..54ce6fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,7 @@ default-features = false #TODO: a11y feature crashes features = [ "about", + "advanced-shaping", "autosize", "desktop", "multi-window", From 079c82ee433b46f9681d722a300a76e032c28187 Mon Sep 17 00:00:00 2001 From: User Date: Mon, 6 Apr 2026 20:27:23 +0700 Subject: [PATCH 017/110] fix: assign replace dialog button id --- src/dialog.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dialog.rs b/src/dialog.rs index a16b5f3..c717a73 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -1208,7 +1208,9 @@ impl Application for App { .icon(widget::icon::from_name("dialog-question").size(64)) .body(fl!("replace-warning")) .primary_action( - widget::button::suggested(fl!("replace")).on_press(Message::DialogComplete), + widget::button::suggested(fl!("replace")) + .on_press(Message::DialogComplete) + .id(REPLACE_BUTTON_ID.clone()), ) .secondary_action( widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), From 11b2617b6c3d2c1405168583d1006a74140dc3ae Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 6 Apr 2026 15:10:18 -0600 Subject: [PATCH 018/110] Epoch 1.0.9 version update Generated by cosmic-epoch scripts/version-update.sh --- Cargo.lock | 56 +++++++++++++++++----------------- Cargo.toml | 2 +- cosmic-files-applet/Cargo.toml | 2 +- debian/changelog | 6 ++++ 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbed562..7b69614 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -298,9 +298,9 @@ checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "arc-swap" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a07d1f37ff60921c83bdfc7407723bdefe89b44b98a9b772f225c8f9d67141a6" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" dependencies = [ "rustversion", ] @@ -1317,7 +1317,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1338,7 +1338,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "quote", "syn", @@ -1346,7 +1346,7 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.0.8" +version = "1.0.9" dependencies = [ "anyhow", "bzip2", @@ -1409,7 +1409,7 @@ dependencies = [ [[package]] name = "cosmic-files-applet" -version = "1.0.8" +version = "1.0.9" dependencies = [ "cosmic-files", "log", @@ -1479,7 +1479,7 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.18.2" -source = "git+https://github.com/pop-os/cosmic-text.git#9a5579f5231bc52b3688a2de3643091f1ce32cbd" +source = "git+https://github.com/pop-os/cosmic-text.git#9a2ab09f06905e91f41d64ac6eee887726e7fd76" dependencies = [ "bitflags 2.11.0", "fontdb", @@ -1502,7 +1502,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "almost", "configparser", @@ -2084,9 +2084,9 @@ checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "a043dc74da1e37d6afe657061213aa6f425f855399a11d3463c6ecccc4dfda1f" [[package]] name = "fax" @@ -2983,7 +2983,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "dnd", "iced_accessibility", @@ -3004,7 +3004,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "accesskit", "accesskit_winit", @@ -3013,7 +3013,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "bitflags 2.11.0", "bytes", @@ -3037,7 +3037,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "iced_core", "iced_futures", @@ -3047,7 +3047,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "futures", "iced_core", @@ -3061,7 +3061,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "bitflags 2.11.0", "bytemuck", @@ -3082,7 +3082,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "iced_graphics", "iced_runtime", @@ -3091,7 +3091,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3103,7 +3103,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3118,7 +3118,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "bytemuck", "cosmic-text", @@ -3135,7 +3135,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.0", @@ -3166,7 +3166,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3184,7 +3184,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -4297,7 +4297,7 @@ checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#34219d1fd4171fb14ea7b4f6f572f9cbd4952150" +source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" dependencies = [ "apply", "ashpd 0.12.3", @@ -4846,9 +4846,9 @@ dependencies = [ [[package]] name = "notify-rust" -version = "4.12.0" +version = "4.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21af20a1b50be5ac5861f74af1a863da53a11c38684d9818d82f1c42f7fdc6c2" +checksum = "1b2c9bc1689653cfbc04400b8719f2562638ff9c545bbd48cc58c657a14526df" dependencies = [ "futures-lite", "log", @@ -6330,9 +6330,9 @@ checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89" [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" diff --git a/Cargo.toml b/Cargo.toml index 54ce6fc..8be8b9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.0.8" +version = "1.0.9" 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 0fc8e0e..952b380 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files-applet" -version = "1.0.8" +version = "1.0.9" edition = "2024" [dependencies] diff --git a/debian/changelog b/debian/changelog index c4358c8..c9cdde6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-files (1.0.9) noble; urgency=medium + + * Epoch 1.0.9 version update + + -- Jeremy Soller Mon, 06 Apr 2026 15:10:13 -0600 + cosmic-files (1.0.8) noble; urgency=medium * Epoch 1.0.8 version update From 781e99d29318f6624901b278571fc0d21095b74c Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 6 Apr 2026 15:33:32 -0600 Subject: [PATCH 019/110] Use row, column with_capacity --- examples/dialog.rs | 2 +- src/app.rs | 4 +++- src/tab.rs | 22 +++++++++++----------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/examples/dialog.rs b/examples/dialog.rs index 687d070..d1d5515 100644 --- a/examples/dialog.rs +++ b/examples/dialog.rs @@ -148,7 +148,7 @@ impl Application for App { } fn view(&self) -> Element<'_, Message> { - let mut column = widget::column().spacing(8).padding(8); + let mut column = widget::column::with_capacity(8).spacing(8).padding(8); { let mut button = widget::button::standard("Open File"); if self.dialog_opt.is_none() { diff --git a/src/app.rs b/src/app.rs index 074e4eb..1eee6f4 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2164,7 +2164,9 @@ impl App { match (selected.next(), selected.next()) { // At least two selected items - (Some(_), Some(_)) => Some(tab.multi_preview_view(Some(&self.mime_app_cache))), + (Some(_), Some(_)) => { + Some(tab.multi_preview_view(Some(&self.mime_app_cache))) + } // Exactly one selected item (Some(item), None) => { Some(item.preview_view(Some(&self.mime_app_cache), military_time)) diff --git a/src/tab.rs b/src/tab.rs index 08b2c45..f53028c 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2440,7 +2440,7 @@ impl Item { .. } = theme::active().cosmic().spacing; - let mut column = widget::column().spacing(space_m); + let mut column = widget::column::with_capacity(4).spacing(space_m); column = column.push( widget::container(self.preview()) @@ -2448,7 +2448,7 @@ impl Item { .max_height(THUMBNAIL_SIZE as f32), ); - let mut details = widget::column().spacing(space_xxxs); + let mut details = widget::column::with_capacity(8).spacing(space_xxxs); details = details.push(widget::text::heading(self.name.clone())); details = details.push(widget::text::body(fl!( "type", @@ -2618,10 +2618,10 @@ impl Item { pub fn replace_view(&self, heading: String, military_time: bool) -> Element<'_, Message> { let cosmic_theme::Spacing { space_xxxs, .. } = theme::active().cosmic().spacing; - let mut row = widget::row().spacing(space_xxxs); + let mut row = widget::row::with_capacity(2).spacing(space_xxxs); row = row.push(self.preview()); - let mut column = widget::column().spacing(space_xxxs); + let mut column = widget::column::with_capacity(3).spacing(space_xxxs); column = column.push(widget::text::heading(heading)); //TODO: translate! @@ -4828,14 +4828,14 @@ impl Tab { let content: cosmic::Element<'_, Message> = if let Some(error_msg) = error_msg_opt { - widget::column() + widget::column::with_capacity(2) .push(widget::image(image_handle)) .push(widget::text(format!("⚠ {}", error_msg)).size(13)) .padding(space_xs) .align_x(cosmic::iced::Alignment::Center) .into() } else if is_loading { - widget::column() + widget::column::with_capacity(2) .push(widget::image(image_handle)) .push(widget::text("Loading higher resolution...").size(14)) .padding(space_xs) @@ -5323,7 +5323,7 @@ impl Tab { }) .into(), ]), - Mode::Desktop => widget::column(), + Mode::Desktop => widget::column::with_capacity(0), } .align_x(Alignment::Center) .spacing(space_xxs), @@ -5531,7 +5531,7 @@ impl Tab { // Add a spacer if the row is empty, so scroll works if grid_elements[row].is_empty() { grid_elements[row].push(Element::from( - widget::column() + widget::column::with_capacity(0) .width(Length::Fill) .height(Length::Fixed(item_height as f32)), )); @@ -6027,7 +6027,7 @@ impl Tab { button_row } else { - widget::column() + widget::column::with_capacity(0) .width(Length::Fill) .height(Length::Fixed(f32::from(row_height))) .into() @@ -6285,7 +6285,7 @@ impl Tab { .. } = theme::active().cosmic().spacing; - let mut column = widget::column().spacing(space_m); + let mut column = widget::column::with_capacity(4).spacing(space_m); let handle = widget::icon::from_name("text-x-generic") .size(IconSizes::default().grid()) @@ -6323,7 +6323,7 @@ impl Tab { .collect() }); - let mut details = widget::column().spacing(space_xxxs); + let mut details = widget::column::with_capacity(3).spacing(space_xxxs); details = details.push(widget::text::body(fl!( "items", items = selected_items.len() From d38d55525b5610e555e11a9c8ebc3bc8507d5480 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Mon, 6 Apr 2026 18:58:34 -0400 Subject: [PATCH 020/110] chore: update libcosmic --- Cargo.lock | 60 +++++++++++++++++------------------------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7b69614..16311fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1317,7 +1317,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1338,7 +1338,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "quote", "syn", @@ -1502,7 +1502,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "almost", "configparser", @@ -2762,7 +2762,7 @@ dependencies = [ "log", "presser", "thiserror 1.0.69", - "windows 0.58.0", + "windows 0.56.0", ] [[package]] @@ -2968,7 +2968,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.56.0", ] [[package]] @@ -2983,7 +2983,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "dnd", "iced_accessibility", @@ -3004,7 +3004,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "accesskit", "accesskit_winit", @@ -3013,7 +3013,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "bitflags 2.11.0", "bytes", @@ -3037,7 +3037,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "iced_core", "iced_futures", @@ -3047,7 +3047,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "futures", "iced_core", @@ -3061,7 +3061,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "bitflags 2.11.0", "bytemuck", @@ -3082,7 +3082,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "iced_graphics", "iced_runtime", @@ -3091,7 +3091,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3103,7 +3103,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3118,7 +3118,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "bytemuck", "cosmic-text", @@ -3135,7 +3135,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.0", @@ -3166,7 +3166,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3184,7 +3184,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -4297,7 +4297,7 @@ checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#ab3eedd0f2e2ed7de9108ba6728261d8bae9e48d" +source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" dependencies = [ "apply", "ashpd 0.12.3", @@ -8088,19 +8088,6 @@ dependencies = [ "windows-strings 0.4.2", ] -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - [[package]] name = "windows-future" version = "0.2.1" @@ -8255,15 +8242,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link 0.2.1", -] - [[package]] name = "windows-sys" version = "0.48.0" From 9547da2b25be00b8df028881374da920bbf88040 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Mon, 6 Apr 2026 20:33:43 -0400 Subject: [PATCH 021/110] fix: reset focus when opening a new tab --- src/app.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/app.rs b/src/app.rs index 1eee6f4..6bac6f3 100644 --- a/src/app.rs +++ b/src/app.rs @@ -32,7 +32,8 @@ use cosmic::{ widget::scrollable, window::{self, Event as WindowEvent, Id as WindowId}, }, - iced_runtime::clipboard, + iced_core::widget::operation::focusable::unfocus, + iced_runtime::{clipboard, task}, iced_widget::{button::focus, scrollable::AbsoluteOffset}, style, surface, theme, widget::{ @@ -1177,14 +1178,14 @@ impl App { entity.id() }; - ( - entity, - Task::batch([ - self.update_title(), - self.update_watcher(), - self.update_tab(entity, location, selection_paths), - ]), - ) + let mut tasks = Vec::with_capacity(4); + if activate { + tasks.push(task::widget(unfocus())); + } + tasks.push(self.update_title()); + tasks.push(self.update_watcher()); + tasks.push(self.update_tab(entity, location, selection_paths)); + (entity, Task::batch(tasks)) } fn open_tab( From b17f8889a8a350a9a07ab3e00155d9b35f136152 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Wed, 8 Apr 2026 13:10:59 -0600 Subject: [PATCH 022/110] chore: update to the latest libcosmic --- Cargo.lock | 80 ++++++++++++++++++++++++++++++----------------- src/app.rs | 57 +++++++++++++++++---------------- src/dialog.rs | 10 +++--- src/key_bind.rs | 2 +- src/load_image.rs | 2 +- src/mouse_area.rs | 4 +-- src/tab.rs | 20 ++++++------ 7 files changed, 98 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 16311fb..f89c7f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -499,9 +499,9 @@ dependencies = [ [[package]] name = "async-signal" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" dependencies = [ "async-io", "async-lock", @@ -1317,7 +1317,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1338,7 +1338,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "quote", "syn", @@ -1502,7 +1502,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "almost", "configparser", @@ -2084,9 +2084,9 @@ checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" [[package]] name = "fastrand" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a043dc74da1e37d6afe657061213aa6f425f855399a11d3463c6ecccc4dfda1f" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "fax" @@ -2762,7 +2762,7 @@ dependencies = [ "log", "presser", "thiserror 1.0.69", - "windows 0.56.0", + "windows 0.58.0", ] [[package]] @@ -2968,7 +2968,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.56.0", + "windows-core 0.62.2", ] [[package]] @@ -2983,7 +2983,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "dnd", "iced_accessibility", @@ -3004,7 +3004,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "accesskit", "accesskit_winit", @@ -3013,7 +3013,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "bitflags 2.11.0", "bytes", @@ -3037,7 +3037,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "iced_core", "iced_futures", @@ -3047,7 +3047,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "futures", "iced_core", @@ -3061,7 +3061,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "bitflags 2.11.0", "bytemuck", @@ -3082,7 +3082,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "iced_graphics", "iced_runtime", @@ -3091,7 +3091,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3103,7 +3103,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3118,7 +3118,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "bytemuck", "cosmic-text", @@ -3135,7 +3135,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.0", @@ -3166,7 +3166,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3184,7 +3184,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -4297,7 +4297,7 @@ checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#9aa87cd66b94b3d7d4dc2047e9c85b93f968d1d0" +source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" dependencies = [ "apply", "ashpd 0.12.3", @@ -7055,9 +7055,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.51.0" +version = "1.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" +checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" dependencies = [ "bytes", "libc", @@ -7127,9 +7127,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.10+spec-1.1.0" +version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82418ca169e235e6c399a84e395ab6debeb3bc90edc959bf0f48647c6a32d1b" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ "indexmap 2.13.1", "toml_datetime", @@ -8088,6 +8088,19 @@ dependencies = [ "windows-strings 0.4.2", ] +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + [[package]] name = "windows-future" version = "0.2.1" @@ -8242,6 +8255,15 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -9289,9 +9311,9 @@ dependencies = [ [[package]] name = "zip" -version = "8.5.0" +version = "8.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2726508a48f38dceb22b35ecbbd2430efe34ff05c62bd3285f965d7911b33464" +checksum = "dcab981e19633ebcf0b001ddd37dd802996098bc1864f90b7c5d970ce76c1d59" dependencies = [ "aes", "bzip2", diff --git a/src/app.rs b/src/app.rs index 6bac6f3..1af6b8b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,6 +1,8 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only +#[cfg(all(feature = "wayland", feature = "desktop-applet"))] +use cosmic::iced::platform_specific::shell::wayland::commands::overlap_notify::overlap_notify; #[cfg(all(feature = "wayland", feature = "desktop-applet"))] use cosmic::iced::{ Limits, Point, @@ -12,8 +14,6 @@ use cosmic::iced::{ Anchor, KeyboardInteractivity, Layer, destroy_layer_surface, get_layer_surface, }, }; -#[cfg(all(feature = "wayland", feature = "desktop-applet"))] -use cosmic::iced_winit::commands::overlap_notify::overlap_notify; use cosmic::{ Application, ApplicationExt, Element, app::{self, Core, Task, context_drawer}, @@ -21,6 +21,9 @@ use cosmic::{ cosmic_theme, desktop::fde::DesktopEntry, executor, + iced::core::widget::operation::focusable::unfocus, + iced::runtime::{clipboard, task}, + iced::widget::{button::focus, scrollable::AbsoluteOffset}, iced::{ self, Alignment, Event, Length, Rectangle, Size, Subscription, clipboard::dnd::DndAction, @@ -32,9 +35,6 @@ use cosmic::{ widget::scrollable, window::{self, Event as WindowEvent, Id as WindowId}, }, - iced_core::widget::operation::focusable::unfocus, - iced_runtime::{clipboard, task}, - iced_widget::{button::focus, scrollable::AbsoluteOffset}, style, surface, theme, widget::{ self, @@ -1253,31 +1253,28 @@ impl App { .insert(id, (operation.clone(), controller.clone())); // Use a task to send operations to the compio runtime thread. - cosmic::Task::stream(cosmic::iced_futures::stream::channel( - 4, - move |msg_tx| async move { - let (tx, rx) = tokio::sync::oneshot::channel(); + cosmic::Task::stream(cosmic::iced::stream::channel(4, move |msg_tx| async move { + let (tx, rx) = tokio::sync::oneshot::channel(); - let msg_tx = Arc::new(tokio::sync::Mutex::new(msg_tx)); + let msg_tx = Arc::new(tokio::sync::Mutex::new(msg_tx)); - let msg_tx_clone = msg_tx.clone(); + let msg_tx_clone = msg_tx.clone(); - _ = compio_tx - .send(Box::pin(async move { - let msg = match operation.perform(&msg_tx_clone, controller).await { - Ok(result_paths) => Message::PendingComplete(id, result_paths), - Err(err) => Message::PendingError(id, err), - }; + _ = compio_tx + .send(Box::pin(async move { + let msg = match operation.perform(&msg_tx_clone, controller).await { + Ok(result_paths) => Message::PendingComplete(id, result_paths), + Err(err) => Message::PendingError(id, err), + }; - _ = tx.send(msg); - })) - .await; + _ = tx.send(msg); + })) + .await; - if let Ok(msg) = rx.await { - let _ = msg_tx.lock().await.send(msg).await; - } - }, - )) + if let Ok(msg) = rx.await { + let _ = msg_tx.lock().await.send(msg).await; + } + })) .map(cosmic::Action::App) } @@ -2054,7 +2051,8 @@ impl App { let progress = controller.progress(); section = section.add(widget::column::with_children([ widget::row::with_children([ - widget::progress_bar(0.0..=1.0, progress) + widget::determinate_linear(progress) + .width(Length::Fill) .girth(progress_bar_height) .into(), if controller.is_paused() { @@ -4431,7 +4429,7 @@ impl Application for App { use cctk::wayland_protocols::xdg::shell::client::xdg_positioner::{ Anchor, Gravity, }; - use cosmic::iced_runtime::platform_specific::wayland::popup::{ + use cosmic::iced::runtime::platform_specific::wayland::popup::{ SctkPopupSettings, SctkPositioner, }; let window_id = WindowId::unique(); @@ -6178,8 +6176,9 @@ impl Application for App { //TODO: get height from theme? let progress_bar_height = Length::Fixed(4.0); - let progress_bar = - widget::progress_bar(0.0..=1.0, total_progress).girth(progress_bar_height); + let progress_bar = widget::determinate_linear(total_progress) + .width(Length::Fill) + .girth(progress_bar_height); let container = widget::layer_container(widget::column::with_children([ widget::row::with_children([ diff --git a/src/dialog.rs b/src/dialog.rs index c717a73..c193da9 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -5,6 +5,9 @@ use cosmic::{ Application, ApplicationExt, Element, app::{Core, Task, context_drawer, cosmic::Cosmic}, cosmic_config, cosmic_theme, executor, + iced::core::widget::operation, + iced::platform_specific::shell::{self as iced_winit, SurfaceIdWrapper}, + iced::widget::scrollable::AbsoluteOffset, iced::{ self, Alignment, Event, Length, Size, Subscription, core::SmolStr, @@ -15,9 +18,6 @@ use cosmic::{ widget::scrollable, window, }, - iced_core::widget::operation, - iced_widget::scrollable::AbsoluteOffset, - iced_winit::{self, SurfaceIdWrapper}, theme, widget::{ self, Operation, @@ -203,7 +203,7 @@ impl> From for DialogLabel { impl<'a, M: Clone + 'static> From<&'a DialogLabel> for Element<'a, M> { fn from(label: &'a DialogLabel) -> Self { - let mut iced_spans: Vec> = + let mut iced_spans: Vec> = Vec::with_capacity(label.spans.len()); for span in &label.spans { iced_spans.push(cosmic::iced::widget::span(&span.text).underline(span.underline)); @@ -1791,7 +1791,7 @@ impl Application for App { use cctk::wayland_protocols::xdg::shell::client::xdg_positioner::{ Anchor, Gravity, }; - use cosmic::iced_runtime::platform_specific::wayland::popup::{ + use cosmic::iced::runtime::platform_specific::wayland::popup::{ SctkPopupSettings, SctkPositioner, }; use cosmic::iced::Rectangle; diff --git a/src/key_bind.rs b/src/key_bind.rs index 8340580..57a9dbf 100644 --- a/src/key_bind.rs +++ b/src/key_bind.rs @@ -1,6 +1,6 @@ use cosmic::{ + iced::core::keyboard::key::Named, iced::keyboard::Key, - iced_core::keyboard::key::Named, widget::menu::key_bind::{KeyBind, Modifier}, }; use std::collections::HashMap; diff --git a/src/load_image.rs b/src/load_image.rs index 00e9bdf..d54fe7f 100644 --- a/src/load_image.rs +++ b/src/load_image.rs @@ -1,4 +1,4 @@ -use cosmic::{iced_core, iced_widget}; +use cosmic::iced::{core as iced_core, widget as iced_widget}; use iced_core::event::Event; use iced_core::layout; use iced_core::mouse; diff --git a/src/mouse_area.rs b/src/mouse_area.rs index 56b86bb..a57b36a 100644 --- a/src/mouse_area.rs +++ b/src/mouse_area.rs @@ -5,7 +5,7 @@ use std::time::Instant; use crate::tab::DOUBLE_CLICK_DURATION; use cosmic::{ Element, Renderer, Theme, - iced_core::{ + iced::core::{ Clipboard, Color, Layout, Length, Point, Rectangle, Shell, Size, Vector, Widget, border::Border, event::Event, @@ -488,7 +488,7 @@ where state: &Tree, layout: Layout<'_>, renderer: &Renderer, - dnd_rectangles: &mut cosmic::iced_core::clipboard::DndDestinationRectangles, + dnd_rectangles: &mut cosmic::iced::core::clipboard::DndDestinationRectangles, ) { self.content.as_widget().drag_destinations( &state.children[0], diff --git a/src/tab.rs b/src/tab.rs index f53028c..31fe881 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2,6 +2,7 @@ use cosmic::{ Apply, Element, cosmic_theme, desktop::fde::{DesktopEntry, get_languages_from_env}, font, + iced::core::{mouse::ScrollDelta, widget::tree}, iced::{ Alignment, Border, Color, ContentFit, Length, Point, Rectangle, Size, Subscription, Vector, advanced::{ @@ -20,7 +21,6 @@ use cosmic::{ }, window, }, - iced_core::{mouse::ScrollDelta, widget::tree}, theme, widget::{ self, DndDestination, DndSource, Id, RcElementWrapper, Widget, @@ -6244,7 +6244,7 @@ impl Tab { tab_view = tab_view.style(|t| { let mut a = widget::container::Style::default(); let c = t.cosmic(); - a.border = cosmic::iced_core::Border { + a.border = cosmic::iced::core::Border { color: (c.accent_color()).into(), width: 1., radius: c.radius_0().into(), @@ -6992,7 +6992,7 @@ pub fn respond_to_scroll_direction(delta: ScrollDelta, modifiers: &Modifiers) -> fn text_editor_class( theme: &cosmic::Theme, status: cosmic::widget::text_editor::Status, -) -> cosmic::iced_widget::text_editor::Style { +) -> cosmic::iced::widget::text_editor::Style { let cosmic = theme.cosmic(); let container = theme.current_container(); @@ -7005,9 +7005,9 @@ fn text_editor_class( let placeholder = placeholder.into(); match status { - cosmic::iced_widget::text_editor::Status::Active - | cosmic::iced_widget::text_editor::Status::Disabled => { - cosmic::iced_widget::text_editor::Style { + cosmic::iced::widget::text_editor::Status::Active + | cosmic::iced::widget::text_editor::Status::Disabled => { + cosmic::iced::widget::text_editor::Style { background: background.into(), border: cosmic::iced::Border { radius: cosmic.corner_radii.radius_m.into(), @@ -7019,9 +7019,9 @@ fn text_editor_class( selection, } } - cosmic::iced_widget::text_editor::Status::Hovered - | cosmic::iced_widget::text_editor::Status::Focused { .. } => { - cosmic::iced_widget::text_editor::Style { + cosmic::iced::widget::text_editor::Status::Hovered + | cosmic::iced::widget::text_editor::Status::Focused { .. } => { + cosmic::iced::widget::text_editor::Style { background: background.into(), border: cosmic::iced::Border { radius: cosmic.corner_radii.radius_m.into(), @@ -7040,7 +7040,7 @@ fn text_editor_class( mod tests { use std::{fs, io, path::PathBuf}; - use cosmic::{iced::mouse::ScrollDelta, iced_runtime::keyboard::Modifiers, widget}; + use cosmic::{iced::mouse::ScrollDelta, iced::runtime::keyboard::Modifiers, widget}; use log::{debug, trace}; use tempfile::TempDir; use test_log::test; From ad0e66dceb4d0f21c2b1e02333490b33eeac18bf Mon Sep 17 00:00:00 2001 From: darkfated Date: Fri, 10 Apr 2026 02:58:20 +0300 Subject: [PATCH 023/110] Fix: remove context actions from open/save dialog --- src/context_action.rs | 4 ---- src/dialog.rs | 55 +++---------------------------------------- 2 files changed, 3 insertions(+), 56 deletions(-) diff --git a/src/context_action.rs b/src/context_action.rs index b12a48a..86f3bc6 100644 --- a/src/context_action.rs +++ b/src/context_action.rs @@ -70,10 +70,6 @@ impl ContextActionPreset { } } -pub fn action_name(actions: &[ContextActionPreset], action: usize) -> Option { - actions.get(action).map(|preset| preset.name.clone()) -} - pub fn run(actions: &[ContextActionPreset], action: usize, paths: &[PathBuf]) { if let Some(preset) = actions.get(action) { preset.run(paths); diff --git a/src/dialog.rs b/src/dialog.rs index 6bb9a0e..9fab965 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -45,7 +45,7 @@ use crate::{ Action, ContextPage, Message as AppMessage, PreviewItem, PreviewKind, REPLACE_BUTTON_ID, }, config::{Config, DialogConfig, Favorite, TIME_CONFIG_ID, ThumbCfg, TimeConfig, TypeToSearch}, - context_action, fl, home_dir, + fl, home_dir, key_bind::key_binds, localize::LANGUAGE_SORTER, menu, @@ -445,10 +445,6 @@ enum DialogPage { parent: PathBuf, name: String, }, - RunContextAction { - action: usize, - paths: Box<[PathBuf]>, - }, Replace { filename: String, }, @@ -1212,21 +1208,6 @@ impl Application for App { .spacing(space_xxs), ) } - DialogPage::RunContextAction { action, paths } => { - let name = context_action::action_name(&self.flags.config.context_actions, *action) - .unwrap_or_else(|| fl!("context-action")); - - widget::dialog() - .title(fl!("context-action-confirm-title", name = name)) - .body(fl!("context-action-confirm-warning", items = paths.len())) - .icon(widget::icon::from_name("dialog-error").size(64)) - .primary_action( - widget::button::suggested(fl!("run")).on_press(Message::DialogComplete), - ) - .secondary_action( - widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), - ) - } DialogPage::Replace { filename } => widget::dialog() .title(fl!("replace-title", filename = filename.as_str())) .icon(widget::icon::from_name("dialog-question").size(64)) @@ -1449,9 +1430,6 @@ impl Application for App { } } } - DialogPage::RunContextAction { action, paths } => { - context_action::run(&self.flags.config.context_actions, action, &paths); - } DialogPage::Replace { .. } => { return self.update(Message::Save(true)); } @@ -1879,28 +1857,6 @@ impl Application for App { } } } - tab::Command::RunContextAction(action) => { - let paths: Box<[_]> = self - .tab - .selected_locations() - .into_iter() - .filter_map(Location::into_path_opt) - .collect(); - if let Some(preset) = self.flags.config.context_actions.get(action) { - if preset.confirm { - self.dialog_pages - .push_back(DialogPage::RunContextAction { action, paths }); - } else { - context_action::run( - &self.flags.config.context_actions, - action, - &paths, - ); - } - } else { - log::warn!("invalid context action index `{action}`"); - } - } tab::Command::Iced(iced_command) => { commands.push(iced_command.0.map(|tab_message| { cosmic::action::app(Message::TabMessage(tab_message)) @@ -2073,13 +2029,8 @@ impl Application for App { } col = col.push( - self.tab - .view( - &self.key_binds, - &self.modifiers, - false, - &self.flags.config.context_actions, - ) + self.tab + .view(&self.key_binds, &self.modifiers, false, &[]) .map(Message::TabMessage), ); From e60ae4e41fea45c1b55f7a979f69658d8aaa8bc6 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Sun, 12 Apr 2026 18:49:45 +0200 Subject: [PATCH 024/110] i18n: translation updates from weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Aindriú Mac Giolla Eoin Co-authored-by: Amadɣas Co-authored-by: Aman Alam Co-authored-by: Asier Saratsua Garmendia Co-authored-by: Baurzhan Muftakhidinov Co-authored-by: ButterflyOfFire Co-authored-by: David Carvalho Co-authored-by: Ettore Atalan Co-authored-by: Fedorov Alexei Co-authored-by: Geeson Wan Co-authored-by: Hosted Weblate Co-authored-by: Jiri Grönroos Co-authored-by: Julien Brouillard Co-authored-by: Jun Hwi Ku Co-authored-by: Otto Domínguez Co-authored-by: Priit Jõerüüt Co-authored-by: Thomas Worofsky Co-authored-by: Tommi Nieminen Co-authored-by: Urocissa Caerulea.Tw Co-authored-by: VandaL Co-authored-by: Vilius Paliokas Co-authored-by: Walter William Beckerleg Bruckman Co-authored-by: Zahid Rizky Fakhri Co-authored-by: defaultUser822 Co-authored-by: jonnysemon Co-authored-by: lorduskordus Co-authored-by: taijuin Lee Co-authored-by: therealmate Co-authored-by: Димко Co-authored-by: 麋麓 BigELK176 Co-authored-by: 김유빈 Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ar/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/cs/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/de/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/es_419/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/fi/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/fr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ga/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/id/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/kab/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/kk/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ko/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/lt/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/pa/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/pl/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ru/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/uk/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/zh_Hant/ Translation: Pop OS/COSMIC Files --- i18n/ar/cosmic_files.ftl | 21 +-- i18n/cs/cosmic_files.ftl | 3 +- i18n/de/cosmic_files.ftl | 13 +- i18n/es-419/cosmic_files.ftl | 2 +- i18n/eu/cosmic_files.ftl | 0 i18n/fi/cosmic_files.ftl | 189 +++++++++++++++------ i18n/fr/cosmic_files.ftl | 1 + i18n/ga/cosmic_files.ftl | 1 + i18n/hu/cosmic_files.ftl | 1 + i18n/id/cosmic_files.ftl | 1 + i18n/kab/cosmic_files.ftl | 321 +++++++++++++++++++++++++++++++++++ i18n/kk/cosmic_files.ftl | 3 +- i18n/ko/cosmic_files.ftl | 7 +- i18n/lt/cosmic_files.ftl | 2 +- i18n/pa/cosmic_files.ftl | 14 +- i18n/pl/cosmic_files.ftl | 1 + i18n/pt-BR/cosmic_files.ftl | 7 +- i18n/ru/cosmic_files.ftl | 3 +- i18n/uk/cosmic_files.ftl | 2 +- i18n/zh-CN/cosmic_files.ftl | 27 +-- i18n/zh-TW/cosmic_files.ftl | 217 ++++++++++++++++------- 21 files changed, 684 insertions(+), 152 deletions(-) create mode 100644 i18n/eu/cosmic_files.ftl diff --git a/i18n/ar/cosmic_files.ftl b/i18n/ar/cosmic_files.ftl index f9b641d..867e83c 100644 --- a/i18n/ar/cosmic_files.ftl +++ b/i18n/ar/cosmic_files.ftl @@ -22,10 +22,10 @@ empty-trash-warning = سيتم حذف العناصر الموجودة في مج ## New File/Folder Dialog -create-new-file = إنشاء ملف جديد -create-new-folder = إنشاء مجلد جديد +create-new-file = أنشئ ملف جديد +create-new-folder = أنشئ مجلَّد جديد file-name = اسم الملف -folder-name = اسم المجلد +folder-name = اسم المجلَّد file-already-exists = يوجد ملف بهذا الاسم بالفعل folder-already-exists = يوجد مجلد بهذا الاسم بالفعل name-hidden = الاسماء التي تبدأ بنقطة «.» ستكون مخفية @@ -34,10 +34,10 @@ name-no-slashes = لا يمكن أن يحتوي الاسم على شرطات م ## Open/Save Dialog -cancel = إلغاء -open = فتح -open-file = فتح ملف -open-folder = افتح مجلد +cancel = ألغِ +open = افتح +open-file = افتح ملف +open-folder = افتح مجلَّد open-in-new-tab = افتح في لسان جديد open-in-new-window = افتح في نافذة جديدة open-multiple-files = افتح عدة ملفات @@ -150,12 +150,12 @@ trashed-on = مهمل details = التفاصيل pause = ألبث resume = استئناف -create-archive = إنشاء أرشيف +create-archive = أنشئ أرشيف extract-password-required = كلمة السر مطلوبة extract-to = استخرِج إلى... extract-to-title = استخرِج إلى مجلّد mount-error = تعذر الوصول إلى القرص -create = إنشاء +create = أنشئ open-item-location = افتح مكان العنصر set-executable-and-launch-description = أتريد تعيين «{ $name }» كقابل للتنفيذ وتشغيله؟ favorite-path-error-description = @@ -259,7 +259,7 @@ related-apps = تطبيقات ذات صلة selected-items = العناصر { $items } المحدّدة permanently-delete-question = احذف نهائيًا؟ delete = احذف -permanently-delete-warning = هل أنت متأكد من أنك تريد حذف { $target } نهائيًا؟ لا يمكن التراجع عن هذا الإجراء. +permanently-delete-warning = سيُحذف { $target } نهائيًا. لا يمكن التراجع عن هذا الإجراء. replace-warning-operation = أتريد استبداله؟ استبداله سيكتب فوق محتواه. original-file = الملف الأصلي replace-with = استبدل بـ @@ -371,3 +371,4 @@ move-to = انقل إلى... show-recents = مجلد الحديثة في الشريط الجانبي clear-recents-history = امحُ التأريخ الحديث copy-path = انسخ المسار +mixed = مختلط diff --git a/i18n/cs/cosmic_files.ftl b/i18n/cs/cosmic_files.ftl index fde9f4f..54b9e10 100644 --- a/i18n/cs/cosmic_files.ftl +++ b/i18n/cs/cosmic_files.ftl @@ -176,7 +176,7 @@ set-executable-and-launch-description = Chcete povolit spouštění souboru „{ set-and-launch = Povolit a spustit open-with = Otevřít pomocí other = Ostatní -none = Žádný +none = Žádné icon-size-and-spacing = Velikost a rozestupy ikon grid-spacing = Rozestupy mřížky deleting = @@ -417,3 +417,4 @@ move-to-title = Vyberte cíl přesunutí show-recents = Složka „Nedávné“ v postranním panelu copy-path = Kopírovat cestu clear-recents-history = Vymazat historii „Nedávné“ +mixed = Různé diff --git a/i18n/de/cosmic_files.ftl b/i18n/de/cosmic_files.ftl index c300df6..98d2f1b 100644 --- a/i18n/de/cosmic_files.ftl +++ b/i18n/de/cosmic_files.ftl @@ -330,7 +330,7 @@ light = Hell type-to-search = Zum Suchen tippen type-to-search-recursive = Durchsucht den aktuellen Ordner und alle Unterordner -type-to-search-enter-path = Gibt den Pfad zu einem Verzeichnis oder einer Datei ein +type-to-search-enter-path = Gib den Pfad zum Verzeichnis oder zur Datei ein # Kontextmenü add-to-sidebar = Zur Seitenleiste hinzufügen compress = Komprimieren... @@ -376,9 +376,9 @@ select-all = Alles auswählen ## Ansicht -zoom-in = Vergrößern +zoom-in = Hineinzoomen default-size = Standardgröße -zoom-out = Verkleinern +zoom-out = Herauszoomen view = Ansicht grid-view = Rasteransicht list-view = Listenansicht @@ -390,7 +390,7 @@ menu-about = Über COSMIC Dateien... ## Sortieren -sort = Sortieren +sort = Sortierung sort-a-z = A-Z sort-z-a = Z-A sort-newest-first = Neueste zuerst @@ -424,3 +424,8 @@ clear-recents-history = Verlauf zuletzt verwendeter Elemente leeren comment = Dateimanager für den COSMIC Desktop keywords = Ordner;Manager; move-to-button-label = Verschieben +move-to-title = Verschiebeziel auswählen +remove-from-recents = Aus den zuletzt verwendeten Elementen entfernen +move-to = Verschieben nach... +copy-path = Pfad kopieren +mixed = Gemischt diff --git a/i18n/es-419/cosmic_files.ftl b/i18n/es-419/cosmic_files.ftl index ca17ec5..9f8ef72 100644 --- a/i18n/es-419/cosmic_files.ftl +++ b/i18n/es-419/cosmic_files.ftl @@ -5,7 +5,7 @@ no-results = No se encontraron resultados filesystem = Sistema de archivos home = Inicio networks = Redes -notification-in-progress = Las operaciones de archivo están en progreso. +notification-in-progress = Las operaciones de archivo están en progreso trash = Papelera recents = Recientes undo = Deshacer diff --git a/i18n/eu/cosmic_files.ftl b/i18n/eu/cosmic_files.ftl new file mode 100644 index 0000000..e69de29 diff --git a/i18n/fi/cosmic_files.ftl b/i18n/fi/cosmic_files.ftl index 105bff6..f22b7b4 100644 --- a/i18n/fi/cosmic_files.ftl +++ b/i18n/fi/cosmic_files.ftl @@ -5,7 +5,7 @@ no-results = Ei tuloksia filesystem = Tiedostojärjestelmä home = Koti networks = Verkot -notification-in-progress = Tiedostotoimintoja käynnissä. +notification-in-progress = Tiedostotoimintoja käynnissä trash = Roskakori recents = Viimeaikaiset undo = Kumoa @@ -16,7 +16,7 @@ today = Tänään desktop-view-options = Työpöytänäkymän asetukset… show-on-desktop = Näytä työpöydällä desktop-folder-content = Työpöytäkansion sisältö -mounted-drives = Tiedostojärjestelmään liitetyt kovalevyt +mounted-drives = Liitetyt asemat trash-folder-icon = Roskakorikansion kuvake icon-size-and-spacing = Kuvakkeen koko ja välistys icon-size = Kuvakkeen koko @@ -38,7 +38,7 @@ create-archive = Luo arkisto ## Empty Trash Dialog empty-trash = Tyhjennä roskakori -empty-trash-warning = Haluatko varmasti tyhjentää koko roskakorin pysyvästi? +empty-trash-warning = Roskakorikansion kohteet poistetaan pysyvästi ## Mount Error Dialog @@ -73,8 +73,8 @@ save-file = Tallenna tiedosto ## Open With Dialog -open-with-title = Kuinka haluat avata kohteen "{ $name }"? -browse-store = Selaa { $store } +open-with-title = Miten haluat avata kohteen "{ $name }"? +browse-store = Selaa { $store }a ## Rename Dialog @@ -88,15 +88,15 @@ replace-title = "{ $filename }" on jo olemassa tässä sijainnissa replace-warning = Haluatko korvata sen tallentamallasi kohteella? Korvaaminen ylikirjoittaa kohteen sisällön. replace-warning-operation = Haluatko korvata sen? Korvaaminen ylikirjoittaa sen sisällön. original-file = Alkuperäinen tiedosto -replace-with = Korvaa kohteella -apply-to-all = Sovella kaikkiin +replace-with = Korvaa käyttäen +apply-to-all = Toteuta kaikkiin keep-both = Pidä molemmat skip = Ohita ## Set as Executable and Launch Dialog set-executable-and-launch = Aseta käynnistettäväksi ja käynnistä -set-executable-and-launch-description = Haluatko asettaa kohteen "{ $name }" käynnistettväksi ja käynnistää sen? +set-executable-and-launch-description = Haluatko asettaa kohteen "{ $name }" käynnistettäväksi ja käynnistää sen? set-and-launch = Aseta ja käynnistä ## Metadata Dialog @@ -116,9 +116,9 @@ other = Muut add-network-drive = Lisää verkkolevy connect = Yhdistä connect-anonymously = Yhdistä nimettömästi -connecting = Yhdistää… +connecting = Yhdistetään… domain = Verkkotunnus -enter-server-address = Syötä palvelimen osoite +enter-server-address = Kirjoita palvelimen osoite network-drive-description = Palvelinosoitteet sisältävät protokollaetuliitteen sekä osoitteen. Esimerkkejä: ssh://192.168.0.1, ftp://[2001:db8::1] @@ -126,91 +126,91 @@ network-drive-description = ### Make sure to keep the comma which separates the columns network-drive-schemes = - Saatavissa olevat protokollat,Etuliite + Saatavilla olevat yhteyskäytännöt,Etuliite AppleTalk,afp:// - File Transfer Protocol,ftp:// or ftps:// + File Transfer Protocol,ftp:// tai ftps:// Network File System,nfs:// Server Message Block,smb:// - SSH File Transfer Protocol,sftp:// or ssh:// - WebDav,dav:// or davs:// -network-drive-error = Verkkolevy saavuttamattomissa + SSH File Transfer Protocol,sftp:// tai ssh:// + WebDav,dav:// tai davs:// +network-drive-error = Verkkolevy ei saatavilla password = Salasana remember-password = Muista salasana try-again = Yritä uudelleen -username = Käyttäjänimi +username = Käyttäjätunnus ## Operations edit-history = Muokkaa historiaa history = Historia no-history = Historia on tyhjä. -pending = Odottaa käsittelyä -failed = Epäonnistui -complete = Valmis +pending = Jonossa +failed = Epäonnistuneet +complete = Valmiit compressing = - Tiivistetään { $items } { $items -> + Pakataan { $items } { $items -> [one] kohde - *[other] kohteita - } lähteestä "{ $from }" arkistoon "{ $to }" + *[other] kohdetta + } sijainnista "{ $from }" arkistoon "{ $to }" ({ $progress })… compressed = - Tiivistetty { $items } { $items -> + Pakattu { $items } { $items -> [one] kohde - *[other] kohteet - } lähteestä "{ $from }" arkistoon "{ $to }" + *[other] kohdetta + } sijainnista "{ $from }" arkistoon "{ $to }" copy_noun = Kopio -creating = Luodaan kohdetta "{ $name }" kohteen "{ $parent }" alle -created = Luotu kohde "{ $name }" kohteen "{ $parent }" alle +creating = Luodaan "{ $name }" kohteen "{ $parent }" alle +created = Luotu "{ $name }" kohteen "{ $parent }" alle copying = Kopioidaan { $items } { $items -> [one] kohde - *[other] kohteita - } lähteestä "{ $from }" kohteeseen "{ $to }" + *[other] kohdetta + } sijainnista "{ $from }" kohteeseen "{ $to }" ({ $progress })… copied = Kopioitu { $items } { $items -> [one] kohde - *[other] kohteet - } lähteestä "{ $from }" kohteeseen "{ $to }" -emptying-trash = Tyhjennetään { trash } + *[other] kohdetta + } sijainnista "{ $from }" kohteeseen "{ $to }" +emptying-trash = Tyhjennetään { trash } ({ $progress })… emptied-trash = Tyhjennetty { trash } extracting = Puretaan { $items } { $items -> [one] kohde - *[other] kohteet - } arkistosta "{ $from }" kohteeseen "{ $to }" + *[other] kohdetta + } arkistosta "{ $from }" kohteeseen "{ $to }" ({ $progress })… extracted = Purettu { $items } { $items -> [one] kohde - *[other] kohteet + *[other] kohdetta } arkistosta "{ $from }" kohteeseen "{ $to }" setting-executable-and-launching = Asetetaan "{ $name }" käynnistettäväksi ja käynnistetään set-executable-and-launched = Asetettu "{ $name }" käynnistettäväksi ja käynnistetty moving = Siirretään { $items } { $items -> [one] kohde - *[other] kohteet - } lähteestä "{ $from }" kohteeseen "{ $to }" + *[other] kohdetta + } sijainnista "{ $from }" kohteeseen "{ $to }" ({ $progress })… moved = Siirretty { $items } { $items -> [one] kohde - *[other] kohteet - } lähteestä "{ $from }" kohteeseen "{ $to }" + *[other] kohdetta + } sijainnista "{ $from }" kohteeseen "{ $to }" renaming = Nimetään kohde "{ $from }" muotoon "{ $to }" renamed = Nimetty kohde "{ $from }" muotoon "{ $to }" restoring = Palautetaan { $items } { $items -> [one] kohde - *[other] kohteet - } { trash }sta + *[other] kohdetta + } roskakorista ({ $progress })… restored = Palautettu { $items } { $items -> [one] kohde - *[other] kohteet - } { trash }sta -unknown-folder = Tuntematon kansio + *[other] kohdetta + } roskakorista +unknown-folder = tuntematon kansio ## Open with -menu-open-with = Avaa ohjelmalla… +menu-open-with = Avaa sovelluksella… default-app = { $name } (oletus) ## Show details @@ -225,14 +225,14 @@ settings = Asetukset appearance = Ulkoasu theme = Teema -match-desktop = Sovita yhteen työpöydän kanssa +match-desktop = Sovita työpöytään dark = Tumma light = Vaalea # Context menu add-to-sidebar = Lisää sivupalkkiin -compress = Pakkaa +compress = Pakkaa… extract-here = Pura new-file = Uusi tiedosto… new-folder = Uusi kansio… @@ -241,9 +241,9 @@ move-to-trash = Siirrä roskakoriin restore-from-trash = Palauta roskakorista remove-from-sidebar = Poista sivupalkista sort-by-name = Järjestä nimen mukaan -sort-by-modified = Järjestä muokkauspäivämäärän mukaan +sort-by-modified = Järjestä muokkausajan mukaan sort-by-size = Järjestä koon mukaan -sort-by-trashed = Järjestä poistamispäivämäärän mukaan +sort-by-trashed = Järjestä poistamisajan mukaan ## Desktop @@ -281,9 +281,9 @@ grid-view = Ruudukkonäkymä list-view = Listanäkymä show-hidden-files = Näytä piilotetut tiedostot list-directories-first = Näytä kansiot ensin -gallery-preview = Gallerian esinäkymä +gallery-preview = Gallerian esikatselu menu-settings = Asetukset… -menu-about = Tietoa COSMIC Tiedostoista… +menu-about = Tietoa COSMICin tiedostonhallinnasta… ## Sort @@ -318,3 +318,90 @@ move-to-button-label = Siirrä clear-recents-history = Tyhjennä viimeaikaisten historia copy-path = Kopioi polku dismiss = Hylkää viesti +operations-running = + { $running } { $running -> + [one] toiminto + *[other] toimintoa + } käynnissä ({ $percent } %)... +operations-running-finished = + { $running } { $running -> + [one] toiminto + *[other] toimintoa + } käynnissä ({ $percent } %), { $finished } valmistunut… +pause = Keskeytä +extract-to = Pura sijaintiin… +permanently-delete-warning = { $target } tullaan poistamaan pysyvästi. Tätä toimintoa ei voi perua. +execute-only = Vain suoritus +write-only = Vain kirjoitus +write-execute = Kirjoita ja suorita +read-only = Vain luku +read-execute = Lue ja suorita +read-write = Lue ja kirjoita +read-write-execute = Lue, kirjoita sekä suorita +calculating = Lasketaan… +single-click = Yhden napsautuksen avaus +type-to-search = Kirjoita etsiäksesi +type-to-search-recursive = Etsii nykyisestä kansiosta ja kaikista alikansioista +remove-from-recents = Poista viimeaikaisista +selected-items = { $items } valittua kohdetta +show-recents = Viimeaikaisten kansio sivupalkissa +copy-to = Kopioi… +move-to = Siirrä… +details = Yksityiskohdat +grid-spacing = Ruudukkovälit +none = Ei mitään +favorite-path-error = Virhe avattaessa kansiota +favorite-path-error-description = + Polun { $path } avaaminen ei onnistunut + "{ $path }" ei välttämättä ole olemassa tai oikeutesi eivät riitä sen avaamiseen + + Haluatko poistaa sen sivupalkista? +keep = Pidä +repository = Tietovarasto +support = Tuki +progress = { $percent } % +progress-cancelled = { $percent } %, peruttu +progress-failed = { $percent } %, epäonnistui +progress-paused = { $percent } %, keskeytetty +setting-permissions = Asetetaan kohteen "{ $name }" käyttöoikeudeksi { $mode } +set-permissions = Asetettu kohteen { $name } käyttöoikeudeksi { $mode } +permanently-deleting = + Poistetaan pysyvästi { $items } { $items -> + [one] kohde + *[other] kohdetta + } +permanently-deleted = + Poistettu pysyvästi { $items } { $items -> + [one] kohde + *[other] kohdetta + } +items = Kohteita: { $items } +item-accessed = Käytetty: { $accessed } +type-to-search-enter-path = Kirjoittaa polun kansioon tai tiedostoon +eject = Poista asemasta +copy-to-title = Valitse mihin kopioidaan +move-to-title = Valitse mihin siirretään +pasted-image = Liitetty kuva +pasted-text = Liitetty teksti +pasted-video = Liitetty video +type-to-search-select = Valitsee ensimmäisen täsmäävän tiedoston tai kansion +deleting = + Poistetaan { $items } { $items -> + [one] kohde + *[other] kohdetta + } roskakorista ({ $progress })… +deleted = + Poistettu { $items } { $items -> + [one] kohde + *[other] kohdetta + } roskakorista +removing-from-recents = + Poistetaan { $items } { $items -> + [one] kohde + *[other] kohdetta + } viimeaikaisista +removed-from-recents = + Poistettu { $items } { $items -> + [one] kohde + *[other] kohdetta + } viimeaikaisista diff --git a/i18n/fr/cosmic_files.ftl b/i18n/fr/cosmic_files.ftl index fa54fd7..a461a9f 100644 --- a/i18n/fr/cosmic_files.ftl +++ b/i18n/fr/cosmic_files.ftl @@ -436,3 +436,4 @@ keywords = Dossier;Gestionnaire; show-recents = Dossier Récents dans la barre latérale copy-path = Copier le chemin clear-recents-history = Effacer l'historique des Récents +mixed = Mixte diff --git a/i18n/ga/cosmic_files.ftl b/i18n/ga/cosmic_files.ftl index 7a9cfdf..5a9aa9a 100644 --- a/i18n/ga/cosmic_files.ftl +++ b/i18n/ga/cosmic_files.ftl @@ -433,3 +433,4 @@ keywords = Fillteán;Bainisteoir; show-recents = Fillteán le déanaí sa bharra taoibh clear-recents-history = Glan stair na n-earraí le déanaí copy-path = Cóipeáil an chosán +mixed = Measctha diff --git a/i18n/hu/cosmic_files.ftl b/i18n/hu/cosmic_files.ftl index dcf9f84..6a87c44 100644 --- a/i18n/hu/cosmic_files.ftl +++ b/i18n/hu/cosmic_files.ftl @@ -436,3 +436,4 @@ move-to = Áthelyezés ide… show-recents = Legutóbbiak mappa megjelenítése az oldalsávban copy-path = Útvonal másolása clear-recents-history = Legutóbbiak előzményének törlése +mixed = Vegyes diff --git a/i18n/id/cosmic_files.ftl b/i18n/id/cosmic_files.ftl index 9a1e8c4..2f1f21b 100644 --- a/i18n/id/cosmic_files.ftl +++ b/i18n/id/cosmic_files.ftl @@ -318,3 +318,4 @@ comment = Pengelola berkas untuk desktop COSMIC show-recents = Map terbaru di bilah sisi clear-recents-history = Bersihkan riwayat Terbaru copy-path = Salin jalur +mixed = Bercampur diff --git a/i18n/kab/cosmic_files.ftl b/i18n/kab/cosmic_files.ftl index e759fa5..233c47d 100644 --- a/i18n/kab/cosmic_files.ftl +++ b/i18n/kab/cosmic_files.ftl @@ -1 +1,322 @@ change-wallpaper = Beddel aɣrab n ugdil… +cosmic-files = Ifuyla COSMIC +empty-folder = Akaram d ilem +empty-folder-hidden = Akaram d ilem (yesɛa iferdisen yeffren) +no-results = Ulac igmaḍ yettwafen +home = Agejdan +networks = Iẓeḍwa +notification-in-progress = Timhalin ɣef ifuyla la tteddunt +trash = Iḍumman +recents = Melmi kan +undo = Ssemmet +today = Ass-a +desktop-view-options = Iɣewwaṛen n tmeẓri n tnarit… +show-on-desktop = Sken deg tnarit +desktop-folder-content = Agbur n ukaram n tnarit +trash-folder-icon = Tignit n ukaram n iḍumman +icon-size-and-spacing = Tiddi n tignit akked tallunt +icon-size = Tiddi n tignit +name = Isem +modified = Ittusnifel +trashed-on = Yettwakkes ɣer tqecwalt n yiḍumman +size = Tiddi +details = Talqayt +pause = Serǧu +resume = Kemmel +create-archive = Snulfu-d aɣbaṛ +extract-to = Ssef ɣer... +extract-to-title = Ssef ɣer ukaram +empty-trash = Silem iḍumman +rename-folder = Snifel isem n ukaram +filesystem = Anagraw n yifuyla +dismiss = Zgel izen +empty-trash-title = Silem iḍumman? +empty-trash-warning = Iferdisen n ukaram n iḍumman ad ttwakksen i lebda +create-new-file = Snulfu-d afaylu amaynut +create-new-folder = Snulfu-d akaram amaynut +file-name = Isem n ufaylu +folder-name = Isem n ukaram +file-already-exists = Afaylu s yisem-agi yella yakan +folder-already-exists = Akaram s yisem-agi yella yakan +name-hidden = Ismawen ibeddun s "." ad ttwaffren +name-invalid = Isem ur yezmir ara ad yili "{ $filename }" +cancel = Sefsex +create = Snulfu-d +open = Ldi +open-file = Ldi afaylu +open-folder = Ldi akaram +open-in-new-tab = Ldi deg yiccer amaynut +open-in-new-window = Ldi deg usfaylu amaynut +open-item-location = Ldi adig n uferdis +open-multiple-files = Ldi aget n ifuyla +mounted-drives = imeɣriyen yettuserkben +mount-error = Ulamek anekcum ɣer umeɣri +operations-running = + { $running } { $running -> + [one] n temhelt la tteddu + *[other] n temhal la tteddunt + } ({ $percent }%)... +operations-running-finished = + { $running } { $running -> + [one] n temhelt la tteddu + *[other] n temhal la tteddunt + } ({ $percent }%), { $finished } { $finished -> + [one] tfukk + *[other] fukkent + }... +copy-to-title = Fren taɣerwaḍt n unɣel +copy-to-button-label = Nɣel +move-to-title = Fren taɣerwaḍt n usmutti +move-to-button-label = Smutti +comment = Amsefrak n yifuyla i tnarit COSMIC +keywords = Akaram;Amsefrak; +delete = kkes +replace = Semselsi +support = Tallalt +settings = Iɣewwaṛen +appearance = Timeẓri +theme = Asentel +dark = Aɣmayan +light = Aceɛlal +paste = Senteḍ +select-all = Fren akk +zoom-in = Asemɣeṛ +default-size = Tiddi tamezwert +zoom-out = Asemẓi +view = Wali +menu-settings = Iɣewwaṛen… +save = Sekles +match-desktop = Amṣada d tnarit +file = Afaylu +new-window = Asfaylu amaynut +quit = Tuffɣa +edit = Ẓreg +cut = Gzem +copy = Nɣel +repository = Asarsay +pasted-image = Tettwasenṭeḍ tugna +pasted-text = Yettwasenṭeḍ uḍris +pasted-video = Tettwasenṭeḍ tvidyut +compress = Skussem… +grid-spacing = Tallunt n iẓiki +extract-password-required = Awal uffir yettwasra +permanently-delete-question = Kkes s wudem imezgi? +permanently-delete-warning = { $target } ad yettwakkes s wudem imezgi. Tigawt-agi ur tezmir ara ad tettwasefsex. +rename-file = Snifel isem n ufaylu +replace-title = "{ $filename }" yella yakan deg wadig-a +replace-warning = Tebɣiḍ ad t-tsemselsiḍ s win ara teskelseḍ? Asemselsi-ines ad yaru sennig ugbur-is. +replace-warning-operation = Tebɣiḍ ad t-tsemselsiḍ? Asemselsi-ines ad yaru sennig ugbur-is. +original-file = Afaylu aneṣli +replace-with = Semselsi s +apply-to-all = Snes i meṛṛa +keep-both = Eǧǧ-iten deg sin +skip = Zgel +set-executable-and-launch = Sbeddet am umselkam syinna senker +set-executable-and-launch-description = Tebɣiḍ ad tesbeddeḍ "{ $name }" am umselkam syinna ad tessenkreḍ? +set-and-launch = Sbadu sakin senker +add-network-drive = Rnu ameɣri n uẓeṭṭa +connect = Qqen +connect-anonymously = Qqen s wudem udrig +connecting = Tuqqna… +domain = Taɣult +enter-server-address = Sekcem tansa n uqeddac +network-drive-description = + Tansiwin n uqeddac gebrent azwir n uneggaf akked tansa. + Imedyaten: ssh://192.168.0.1, ftp://[2001:db8::1] +network-drive-error = Ur izmir ara ad yekcem ɣer umeɣri n uzeṭṭa +password = Awal uffir +remember-password = Cfu ɣef wawal uffir +try-again = ɛreḍ tikelt nniḍen +username = Isem n useqdac +cancelled = Yettwasefsex +edit-history = Ẓreg amazray +history = Amazray +no-history = Ulac iferdisen deg umazray. +pending = Yettṛaǧu +progress-cancelled = { $percent }%, yettwasefsex +progress-failed = { $percent }%, ur yeddi ara +failed = Ur yeddi ara +renaming = Asnifel n yisem "{ $from }" ɣer "{ $to }" +renamed = Yettwasenfel yisem n "{ $from }" ɣer "{ $to }" +unknown-folder = akaram arussin +menu-open-with = Ldi s… +default-app = { $name } (amezwer) +show-details = Sken talqayt +type = Anaw: { $mime } +items = Iferdisen: { $items } +item-size = Tiddi: { $size } +item-created = Yettwarna: { $created } +item-modified = Ittusnifel: { $modified } +item-accessed = Yettwakcem: { $accessed } +calculating = Asiḍen… +single-click = Asiti asuf i ulday +type-to-search = Aru iwakken ad tnadiḍ +type-to-search-recursive = Nadi akaram amiran akked ikaramen inaddawen meṛṛa +type-to-search-enter-path = Sekcem abrid ɣer ukaram neɣ afaylu +add-to-sidebar = Rnu ɣer ufeggag adisan +delete-permanently = Kkes i lebda +grid-view = Askan s iẓiki +list-view = Askan s tebdart +show-hidden-files = Sken ifuyla uffiren +gallery-preview = Taskant n temidelt +menu-about = Ɣef Ifuyla COSMIC… +sort = Asmizzwer +sort-newest-first = Amaynut d amezwaru +sort-oldest-first = Aqbur d amezwaru +sort-smallest-to-largest = Seg umeẓyan akk ɣer umeqqran +sort-largest-to-smallest = Seg umeqqran akk ɣer umeẓyan +open-multiple-folders = Ldi usgit n ikaramen +save-file = Sekles afaylu +open-with-title = Amek tebɣiḍ ad teldiḍ "{ $name }"? +browse-store = Snirem { $store } +other-apps = Isnasen-nniḍen +emptying-trash = Silem { trash } ({ $progress })… +emptied-trash = D ilem { trash } +set-permissions = Sbadu isirigen i "{ $name }" ɣer { $mode } +eject = Ḍeqqer +extract-here = Ssef +new-file = Afaylu amaynut… +new-folder = Akaram amaynut… +open-in-terminal = Ldi deg yixef +move-to-trash = Smutti ɣer tqecwalt n yiḍumman +restore-from-trash = Err-d seg tqecwalt n yiḍumman +remove-from-sidebar = Kkes seg ugalis adisan +sort-by-name = Smizzwer s yisem +sort-by-modified = Asmizzwer s usnifel +sort-by-size = Asmizzwer s tiddi +sort-by-trashed = Asmizzwer s wakud n tukksa +remove-from-recents = Kkes seg ineggura +desktop-appearance = Timeẓri n tnarit… +display-settings = Iɣewwaṛen n ubeqqeḍ... +new-tab = Iccer amaynut +reload-folder = Ales asali n ukaram +rename = Snifel isem... +close-tab = Mdel iccer +list-directories-first = Sken di tazwara ikaramen +open-with = Ldi s +owner = Bab +group = Agraw +other = Ayen nniḍen +none = Ula Yiwen +execute-only = Selkem kan +write-only = Aru kan +write-execute = Aru u selkem +read-only = I tɣuri kan +read-execute = Ɣeṛ u selkem +read-write = Ɣeṛ u aru +read-write-execute = Ɣeṛ, aru, u selkem +favorite-path-error = Tuccḍa deg ulday n ukaram +remove = Kkes +keep = Eǧǧ +progress = { $percent }% +progress-paused = { $percent }%, ibedd +complete = Immed +copy_noun = Nɣel +creating = Asnulfu n "{ $name }" deg "{ $parent }" +created = Yettwarna "{ $name }" deg "{ $parent }" +setting-executable-and-launching = Asbadu n "{ $name }" am umselkam syin ad yettwasekker +set-executable-and-launched = Sbadu "{ $name }" am umselkam syin sekker-it +setting-permissions = Asbadu n tsirag i "{ $name }" ɣer { $mode } +related-apps = Isnasen icudden +favorite-path-error-description = + Ur izmir ara ad yeldi "{ $path }" + "{ $path }" yezmer lḥal ulac-it neɣ ahat ur tesɛiḍ ara tisirag akken ad t-teldiḍ + + Tebɣiḍ ad t-tekkseḍ seg ufeggag adisan? +compressing = + La issekkussum { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg "{ $from }" ɣer "{ $to }" ({ $progress })... +compressed = + Yekussem { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg "{ $from }" ɣer "{ $to }" +copying = + Anɣal { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg "{ $from }" ɣer "{ $to }" ({ $progress })... +copied = + Yettwanɣel { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg "{ $from }" ɣer "{ $to }" +deleting = + Tukksa { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg { trash } ({ $progress })... +deleted = + Yettwakkes { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg { trash } +extracting = + Tussfa { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg "{ $from }" ɣer "{ $to }" ({ $progress })... +extracted = + Yettusef { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg "{ $from }" ɣer "{ $to }" +moving = + Asmutti { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg "{ $from }" ɣer "{ $to }" ({ $progress })... +moved = + Yettwasenkez { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg "{ $from }" ɣer "{ $to }" +permanently-deleting = + Tukksa i lebda { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } +permanently-deleted = + I lebda yettwakkes { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } +removing-from-recents = + Tukksa { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg { recents } +removed-from-recents = + Yettwakkes { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg { recents } +restoring = + Tiririt { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg { trash } ({ $progress })… +restored = + Yettwarr-d { $items } { $items -> + [one] n uferdis + *[other] n yiferdisen + } seg { trash } +network-drive-schemes = + Ineggafen iwejden, azwir + AppleTalk,afp:// + Aneggaf n usiweḍ n yifuyla,ftp:// neɣ ftps:// + Anagraw n yifuyla n uzeṭṭa,nfs:// + Iḥder n yizen n uqeddac,smb:// + SSH Aneggaf n usiweḍ n yifuyla,sftp:// neɣ ssh:// + WebDAV:// neɣ davs:// +sort-a-z = A-Ẓ +sort-z-a = Ẓ-A +selected-items = { $items } n yiferdisen yettwafernen +type-to-search-select = Fren afaylu amezwaru neɣ akaram yemṣadan +copy-to = Nɣel ɣer... +move-to = Smutti ɣer… +show-recents = Akaram n melmi kan deg ufeggag adisan +clear-recents-history = Sfeḍ azray n melmi kan +copy-path = Nɣel abrid diff --git a/i18n/kk/cosmic_files.ftl b/i18n/kk/cosmic_files.ftl index 6afb314..3b97025 100644 --- a/i18n/kk/cosmic_files.ftl +++ b/i18n/kk/cosmic_files.ftl @@ -256,7 +256,7 @@ type-to-search-recursive = Ағымдағы бума мен барлық ішк type-to-search-enter-path = Бумаға немесе файлға жолды енгізеді type-to-search-select = Бірінші сәйкес келетін файлды немесе буманы таңдайды add-to-sidebar = Бүйірлік панельге қосу -compress = Сығу +compress = Сығу... delete-permanently = Біржолата өшіру eject = Шығару extract-here = Тарқату @@ -318,3 +318,4 @@ keywords = Folder;Manager;Бума;Басқарушы; show-recents = Бүйір панеліндегі «Жуырдағы құжаттар» бумасы clear-recents-history = Жуырдағылар тарихын өшіру copy-path = Орналасқан жолын көшіру +mixed = Аралас diff --git a/i18n/ko/cosmic_files.ftl b/i18n/ko/cosmic_files.ftl index aec0e3f..3a9f2f6 100644 --- a/i18n/ko/cosmic_files.ftl +++ b/i18n/ko/cosmic_files.ftl @@ -110,7 +110,7 @@ dismiss = 메시지 무시 copy_noun = 복사 progress = { $percent }% related-apps = 관련 앱 -compress = 압축 +compress = 압축... network-drive-error = 네트워크 드라이브에 접근할 수 없음 icon-size-and-spacing = 아이콘 크기 및 간격 password = 암호 @@ -272,3 +272,8 @@ network-drive-schemes = WebDAV,dav:// 또는 davs:// type-to-search-select = 일치하는 첫 번째 파일 또는 폴더를 선택합니다 comment = COSMIC 데스크톱용 위한 파일 관리자 +keywords = 폴더;관리자; +copy-to-button-label = 복사 +move-to-button-label = 이동 +clear-recents-history = 최근 기록 비우기 +copy-path = 복사 경로 diff --git a/i18n/lt/cosmic_files.ftl b/i18n/lt/cosmic_files.ftl index 8faf6d7..acceb7c 100644 --- a/i18n/lt/cosmic_files.ftl +++ b/i18n/lt/cosmic_files.ftl @@ -252,7 +252,7 @@ type-to-search = Norint ieškoti, pradėkite rašyti type-to-search-recursive = Paieška dabartiniame aplanke ir jo poaplankiuose type-to-search-enter-path = Įvedamas aplanko ar failo kelias add-to-sidebar = Pridėti į šonjuostę -compress = Suspausti +compress = Suspausti... delete-permanently = Ištrinti visam laikui eject = Išstumti extract-here = Išskleisti diff --git a/i18n/pa/cosmic_files.ftl b/i18n/pa/cosmic_files.ftl index e5c829f..be7163e 100644 --- a/i18n/pa/cosmic_files.ftl +++ b/i18n/pa/cosmic_files.ftl @@ -32,7 +32,7 @@ pause = ਵਿਰਾਮ resume = ਮੁੜ-ਚਾਲੂ create-archive = ਅਕਾਇਵ ਬਣਾਓ extract-password-required = ਪਾਸਵਰਡ ਚਾਹੀਦਾ ਹੈ -extract-to = Extract To... +extract-to = ਖਿਲਾਰੋ... extract-to-title = ਫੋਲਡਰ ਵਿੱਚ ਖਿਲਾਰੋ empty-trash = ਰੱਦੀ ਨੂੰ ਖਾਲੀ ਕਰੋ empty-trash-title = ਰੱਦੀ ਨੂੰ ਖਾਲੀ ਕਰਨਾ ਹੈ? @@ -113,7 +113,7 @@ replace-title = "{ $filename }" ਪਹਿਲਾਂ ਹੀ ਇਸ ਟਿਕਾਣ favorite-path-error = ਡਾਇਰੈਕਟਰੀ ਖੋਲ੍ਹਣ ਦੌਰਾਨ ਗਲਤੀ add-network-drive = ਨੈੱਟਵਰਕ ਡਰਾਇਵ ਜੋੜੋ connect-anonymously = ਅਣਪਛਾਤੇ ਵਜੋਂ ਕਨੈਕਟ ਕਰੋ -connecting = Connecting... +connecting = ਕਨੈਕਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ... domain = ਡੋਮੇਨ enter-server-address = ਸਰਵਰ ਦਾ ਸਿਰਨਾਵਾਂ ਦਿਓ password = ਪਾਸਵਰਡ @@ -138,9 +138,9 @@ sort-by-modified = ਸੋਧ ਨਾਲ ਲੜੀਬੱਧ sort-by-size = ਆਕਾਰ ਨਾਲ ਲੜੀਬੱਧ sort-by-trashed = ਹਟਾਉਣ ਸਮੇਂ ਨਾਲ ਲੜੀਬੱਧ remove-from-recents = ਸੱਜਰਿਆਂ ਵਿੱਚੋਂ ਹਟਾਓ -change-wallpaper = Change wallpaper... -desktop-appearance = Desktop appearance... -display-settings = Display settings... +change-wallpaper = ਵਾਲਪੇਪਰ ਨੂੰ ਬਦਲੋ... +desktop-appearance = ਡੈਸਕਟਾਪ ਦੀ ਦਿੱਖ... +display-settings = ਡਿਸਪਲੇਅ ਸੈਟਿੰਗਾਂ... file = ਫ਼ਾਇਲ new-tab = ਨਵੀਂ ਟੈਬ new-window = ਨਵੀਂ ਵਿੰਡੋ @@ -195,11 +195,11 @@ type-to-search = ਖੋਜਣ ਲਈ ਲਿਖੋ type-to-search-recursive = ਮੌਜੂਦਾ ਫੋਲਡਰ ਅਤੇ ਸਭ ਅਧੀਨ-ਫੋਲਡਰਾਂ ਵਿੱਚ ਖੋਜੋ add-to-sidebar = ਬਾਹੀ ਵਿੱਚ ਜੋੜੋ compress = ਕੰਪਰੈਸ -copy-to = Copy to... +copy-to = ਇੱਥੇ ਕਾਪੀ ਕਰੋ... delete-permanently = ਪੱਕੇ ਤੌਰ ਉੱਤੇ ਹਟਾਓ eject = ਬਾਹਰ extract-here = ਖਿਲਾਰੋ -move-to = Move to... +move-to = ਇੱਥੇ ਭੇਜੋ... remove-from-sidebar = ਬਾਹੀ ਵਿੱਚੋਂ ਹਟਾਓ reload-folder = ਫੋਲਡਰ ਨੂੰ ਮੁੜ-ਲੋਡ ਕਰੋ list-view = ਸੂਚੀ ਝਲਕ diff --git a/i18n/pl/cosmic_files.ftl b/i18n/pl/cosmic_files.ftl index daf1007..b0bc7a8 100644 --- a/i18n/pl/cosmic_files.ftl +++ b/i18n/pl/cosmic_files.ftl @@ -437,3 +437,4 @@ move-to = Przenieś do… show-recents = Ostatnie katalogi w panelu bocznym clear-recents-history = Wyczyść bierzącą historię copy-path = Skopiuj ścieżkę +mixed = Mieszane diff --git a/i18n/pt-BR/cosmic_files.ftl b/i18n/pt-BR/cosmic_files.ftl index 732d0fb..86ebd88 100644 --- a/i18n/pt-BR/cosmic_files.ftl +++ b/i18n/pt-BR/cosmic_files.ftl @@ -424,8 +424,8 @@ sort-largest-to-smallest = Do maior para o menor empty-trash-title = Esvaziar a lixeira? type-to-search-select = Seleciona o primeiro arquivo ou pasta correspondente pasted-image = Imagem colada -pasted-text = Texto copiado -pasted-video = Vídeo copiado +pasted-text = Texto colado +pasted-video = Vídeo colado copy-to-title = Selecione o destino da cópia copy-to-button-label = Copiar move-to-title = Selecione o destino da movimentação @@ -433,6 +433,7 @@ move-to-button-label = Mover copy-to = Copiar para... move-to = Mover para... keywords = Pasta;Gerenciador; -show-recents = Pasta Recentes na barra lateral +show-recents = Pasta de recentes na barra lateral clear-recents-history = Limpar histórico de recentes copy-path = Copiar caminho +mixed = Misto diff --git a/i18n/ru/cosmic_files.ftl b/i18n/ru/cosmic_files.ftl index 15b8eb1..e9673f1 100644 --- a/i18n/ru/cosmic_files.ftl +++ b/i18n/ru/cosmic_files.ftl @@ -195,7 +195,7 @@ dark = Тёмная light = Светлая # Context menu add-to-sidebar = Добавить на боковую панель -compress = Сжать +compress = Сжать... extract-here = Распаковать new-file = Новый файл… new-folder = Новая папка… @@ -380,3 +380,4 @@ keywords = Папка;Менеджер; show-recents = «Недавние документы» в бок. панели clear-recents-history = Очистить историю недавних copy-path = Копировать путь +mixed = Смешанные diff --git a/i18n/uk/cosmic_files.ftl b/i18n/uk/cosmic_files.ftl index 1413460..611c2b1 100644 --- a/i18n/uk/cosmic_files.ftl +++ b/i18n/uk/cosmic_files.ftl @@ -317,7 +317,7 @@ single-click = Відкривати одним клацанням type-to-search = Введіть для пошуку type-to-search-recursive = Шукає у поточній теці та всіх підтеках type-to-search-enter-path = Вводить шлях до каталогу або файлу -compress = Стиснути +compress = Стиснути... delete-permanently = Остаточно видалити eject = Безпечно вилучити extract-here = Видобути diff --git a/i18n/zh-CN/cosmic_files.ftl b/i18n/zh-CN/cosmic_files.ftl index 0002c17..11441d1 100644 --- a/i18n/zh-CN/cosmic_files.ftl +++ b/i18n/zh-CN/cosmic_files.ftl @@ -11,7 +11,7 @@ recents = 最近访问 undo = 撤销 today = 今天 # Desktop view options -desktop-view-options = 桌面视图选项... +desktop-view-options = 桌面视图选项… show-on-desktop = 在桌面显示 desktop-folder-content = 桌面文件夹内容 mounted-drives = 已装载驱动器 @@ -31,7 +31,7 @@ operations-running = 正在进行 { $running } { $running -> [one] 个操作 *[other] 个操作 - }({ $percent }%)... + }({ $percent }%)… operations-running-finished = 正在进行 { $running } { $running -> [one] 个操作 @@ -50,7 +50,7 @@ create-archive = 创建压缩包 ## Extract Dialog extract-password-required = 需要密码 -extract-to = 提取到... +extract-to = 提取到… extract-to-title = 提取到文件夹 ## Empty Trash Dialog @@ -317,7 +317,7 @@ unknown-folder = 未知文件夹 ## Open with -menu-open-with = 打开方式... +menu-open-with = 打开方式… default-app = { $name }(默认) ## Show details @@ -329,7 +329,7 @@ item-size = 文件大小:{ $size } item-created = 创建于:{ $created } item-modified = 修改于:{ $modified } item-accessed = 访问于:{ $accessed } -calculating = 计算中... +calculating = 计算中… ## Settings @@ -355,8 +355,8 @@ compress = 压缩… delete-permanently = 永久删除 eject = 弹出 extract-here = 解压到此处 -new-file = 新建文件... -new-folder = 新建文件夹... +new-file = 新建文件… +new-folder = 新建文件夹… open-in-terminal = 在终端模拟器中打开 move-to-trash = 移动到回收站 restore-from-trash = 从回收站中还原 @@ -369,9 +369,9 @@ remove-from-recents = 从最近访问中移除 ## Desktop -change-wallpaper = 更改壁纸... -desktop-appearance = 桌面外观... -display-settings = 显示设置... +change-wallpaper = 更改壁纸… +desktop-appearance = 桌面外观… +display-settings = 显示设置… # Menu @@ -382,7 +382,7 @@ file = 文件 new-tab = 新建标签 new-window = 新建窗口 reload-folder = 刷新文件夹 -rename = 重命名... +rename = 重命名… close-tab = 关闭标签 quit = 退出 @@ -405,7 +405,7 @@ list-view = 列表视图 show-hidden-files = 显示隐藏文件 list-directories-first = 优先列出目录 gallery-preview = 图库预览 -menu-settings = 设置... +menu-settings = 设置… menu-about = 关于 COSMIC 文件… ## Sort @@ -435,4 +435,5 @@ comment = COSMIC 桌面的文件管理器 keywords = 文件夹;管理器; clear-recents-history = 清除最近访问历史 copy-path = 复制文件路径 -show-recents = 侧边栏显示最近访问 +show-recents = 侧边栏中的最近访问 +mixed = 混合 diff --git a/i18n/zh-TW/cosmic_files.ftl b/i18n/zh-TW/cosmic_files.ftl index 1149a62..2bf8e5b 100644 --- a/i18n/zh-TW/cosmic_files.ftl +++ b/i18n/zh-TW/cosmic_files.ftl @@ -1,11 +1,11 @@ -cosmic-files = COSMIC 檔案總管 +cosmic-files = COSMIC 檔案 empty-folder = 空資料夾 empty-folder-hidden = 空資料夾(包含隱藏項目) no-results = 找不到結果 filesystem = 檔案系統 -home = 主目錄 +home = 家目錄 networks = 網路 -notification-in-progress = 檔案操作正在進行中。 +notification-in-progress = 檔案操作正在進行中 trash = 垃圾桶 recents = 最近使用 undo = 復原 @@ -25,7 +25,7 @@ create-archive = 建立壓縮檔案 ## Empty Trash Dialog empty-trash = 清空垃圾桶 -empty-trash-warning = 你確定要永久刪除垃圾桶中的所有項目嗎? +empty-trash-warning = 垃圾桶中的項目將被永久刪除 ## New File/Folder Dialog @@ -33,16 +33,16 @@ create-new-file = 建立新檔案 create-new-folder = 建立新資料夾 file-name = 檔案名稱 folder-name = 資料夾名稱 -file-already-exists = 已存在同名檔案。 -folder-already-exists = 已存在同名資料夾。 -name-hidden = 以「.」開頭的名稱將會被隱藏。 -name-invalid = 名稱不能是 「{ $filename }」。 -name-no-slashes = 名稱不能包含斜線。 +file-already-exists = 相同名稱的檔案已經存在 +folder-already-exists = 相同名稱的資料夾已經存在 +name-hidden = 以「.」開頭的名稱將會被隱藏 +name-invalid = 名稱不能是「{ $filename }」 +name-no-slashes = 名稱不能包含斜線 ## Open/Save Dialog cancel = 取消 -create = 建立 +create = 創作 open = 開啟 open-file = 開啟檔案 open-folder = 開啟資料夾 @@ -62,12 +62,12 @@ rename-folder = 重新命名資料夾 ## Replace Dialog replace = 取代 -replace-title = 檔案「{ $filename }」已存在於此位置。 +replace-title = 「{ $filename }」已存在於此位置 replace-warning = 你要取代它嗎?取代將覆蓋其內容。 replace-warning-operation = 你要取代它嗎?取代將覆蓋其內容。 original-file = 原始檔案 replace-with = 取代為 -apply-to-all = 套用至所有項目 +apply-to-all = 套用至全部 keep-both = 保留兩者 skip = 跳過 @@ -95,13 +95,13 @@ network-drive-description = 伺服器地址包括協定前綴和地址。 範例:ssh://192.168.0.1, ftp://[2001:db8::1] network-drive-schemes = - 可用協定,前綴 - AppleTalk,afp:// - 檔案傳輸協定,ftp:// 或 ftps:// - 網路檔案系統,nfs:// - 伺服器訊息區塊,smb:// - SSH 檔案傳輸協定,sftp:// 或 ssh:// - WebDav,dav:// 或 davs:// + 可用協定,前綴 + AppleTalk,afp:// + 檔案傳輸協定,ftp:// 或 ftps:// + 網路檔案系統,nfs:// + 伺服器訊息區塊,smb:// + SSH 檔案傳輸協定,sftp:// 或 ssh:// + WebDav,dav:// 或 davs:// network-drive-error = 無法存取網路磁碟機 password = 密碼 remember-password = 記住密碼 @@ -112,7 +112,7 @@ username = 使用者名稱 edit-history = 編輯歷史 history = 歷史紀錄 -no-history = 沒有歷史項目。 +no-history = 無歷史記錄項目。 pending = 待處理 failed = 失敗 complete = 完成 @@ -133,51 +133,51 @@ copying = 正在複製 { $items } { $items -> [one] 項目 *[other] 項目 - } 從「{ $from }」到「{ $to }」({ $progress })... + }從「{ $from }」到「{ $to }」({ $progress })... copied = 已複製 { $items } { $items -> [one] 項目 *[other] 項目 }從「{ $from }」到「{ $to }」 -emptying-trash = 正在清空{ trash }({ $progress })… -emptied-trash = 已清空{ trash } +emptying-trash = 正在清空 { trash }({ $progress })… +emptied-trash = 已經清空 { trash } extracting = 正在解壓縮 { $items } 項目 { $items -> [one] 項目 *[other] 項目 - } 從「{ $from }」到「{ $to }」({ $progress })... + }從「{ $from }」至「{ $to }」({ $progress })... extracted = 已解壓縮 { $items } 項目 { $items -> [one] 項目 *[other] 項目 - } 從 { $from } 到 { $to } + }從「{ $from }」到「{ $to }」 moving = 正在移動 { $items } { $items -> [one] 項目 *[other] 項目 - } 從「{ $from }」到「{ $to }」({ $progress })... + }從「{ $from }」到「{ $to }」({ $progress })... moved = - 已移動 { $items } { $items -> + 已經移動 { $items } { $items -> [one] 項目 *[other] 項目 - } 從「{ $from }」到「{ $to }」 -renaming = 正在重新命名「{ $from }」為「{ $to }」 -renamed = 已重新命名 { $from } 為 { $to } + } 從「{ $from }」至「{ $to }」 +renaming = 正在重新命名「{ $from }」至「{ $to }」 +renamed = 已經重新命名「{ $from }」至「{ $to }」 restoring = 正在還原 { $items } 項目 { $items -> [one] 項目 *[other] 項目 - } 從{ trash }({ $progress })... + }自 { trash } ({ $progress })... restored = - 已還原 { $items } 項目 { $items -> + 已經還原 { $items } 項目 { $items -> [one] 項目 *[other] 項目 - } 從{ trash } -unknown-folder = 未知資料夾 + }從 { trash } +unknown-folder = 不明資料夾 ## Open with -menu-open-with = 開啟方式... +menu-open-with = 開啟檔案... default-app = { $name } (預設) ## Show details @@ -192,15 +192,15 @@ settings = 設定 appearance = 外觀 theme = 主題 -match-desktop = 與桌面一致 -dark = 暗色模式 -light = 亮色模式 +match-desktop = 符合桌面 +dark = 深色 +light = 淺色 # Context menu -add-to-sidebar = 加入側邊欄 -compress = 壓縮 -extract-here = 解壓縮至此 -new-file = 新檔案... -new-folder = 新資料夾... +add-to-sidebar = 添加至側邊欄 +compress = 壓縮… +extract-here = 解壓縮 +new-file = 新建檔案... +new-folder = 新建資料夾... open-in-terminal = 在終端機中開啟 move-to-trash = 移動至垃圾桶 restore-from-trash = 從垃圾桶還原 @@ -215,8 +215,8 @@ sort-by-size = 依大小排序 ## File file = 檔案 -new-tab = 新分頁 -new-window = 新視窗 +new-tab = 新建分頁 +new-window = 新建視窗 rename = 重新命名... close-tab = 關閉分頁 quit = 退出 @@ -238,36 +238,36 @@ view = 檢視 grid-view = 網格檢視 list-view = 列表檢視 show-hidden-files = 顯示隱藏檔案 -list-directories-first = 優先列出目錄 +list-directories-first = 目錄優先列出 menu-settings = 設定... -menu-about = 關於 COSMIC 檔案總管... +menu-about = 關於 COSMIC 檔案... ## Sort sort = 排序 sort-a-z = A-Z sort-z-a = Z-A -sort-newest-first = 最新的在前 -sort-oldest-first = 最舊的在前 -sort-smallest-to-largest = 由小至大 -sort-largest-to-smallest = 由大至小 +sort-newest-first = 最新優先 +sort-oldest-first = 最舊優先 +sort-smallest-to-largest = 從小到大 +sort-largest-to-smallest = 從大到小 deleted = - 已刪除 { $items } { $items -> + 已經刪除 { $items } { $items -> [one] 項目 *[other] 項目 - }從{ trash } + }從 { trash } permanently-deleting = 正在永久刪除 { $items } { $items -> [one] 项目 *[other] 项目 } permanently-deleted = - 已永久刪除 { $items } { $items -> + 已經永久刪除 { $items } { $items -> [one] 项目 *[other] 项目 } removing-from-recents = - 正在從{ recents }中移除 { $items } { $items -> + 正在從 { recents } 中移除 { $items } { $items -> [one] 项目 *[other] 项目 } @@ -275,9 +275,112 @@ deleting = 正在刪除 { $items } { $items -> [one] 项目 *[other] 项目 - }從{ trash }({ $progress })… + }從 { trash }({ $progress })… removed-from-recents = - 已從{ recents }中移除 { $items } { $items -> + 已經從 { recents } 中移除 { $items } { $items -> [one] 项目 *[other] 项目 } +repository = 軟體庫源 +desktop-view-options = 桌面檢視選項... +show-on-desktop = 顯示在桌面 +desktop-folder-content = 桌面資料夾內容 +mounted-drives = 已經掛載的磁碟機 +trash-folder-icon = 垃圾桶圖示 +trashed-on = 遺棄時間 +icon-size-and-spacing = 圖示大小與間距 +icon-size = 圖示大小 +grid-spacing = 網格間距 +details = 詳情 +dismiss = 撤停訊息 +delete = 刪除 +remove = 移除 +support = 支援 +cancelled = 已取消 +keywords = 資料夾;管理器; +empty-trash-title = 清空垃圾桶? +pause = 暫停 +resume = 繼續 +extract-password-required = 需要密碼 +extract-to = 解壓縮至... +extract-to-title = 解壓縮至資料夾 +mount-error = 無法存取磁碟機 +open-with-title = 您要如何開啟「{ $name }」? +browse-store = 瀏覽 { $store } +other-apps = 其他應用程式 +related-apps = 相關應用程式 +permanently-delete-question = 永久刪除? +set-executable-and-launch = 設定為可以執行並啟動 +read-only = 唯讀 +read-execute = 讀取和執行 +read-write = 讀取和寫入 +read-write-execute = 讀取、寫入和執行 +favorite-path-error = 開啟目錄時發生錯誤 +set-executable-and-launch-description = 您是否要將「{ $name }」設為可執行並啟動它? +set-and-launch = 設定並啟動 +none = 無 +execute-only = 僅執行 +write-only = 僅寫入 +write-execute = 寫入和執行 +operations-running = + { $running } { $running -> + [one] 個操作 + *[other] 個操作 + }正在執行({ $percent }%)... +operations-running-finished = + { $running } { $running -> + [one] 個操作 + *[other] 個操作 + }正在執行({ $percent }%), { $finished } 個已經完成... +permanently-delete-warning = 「{ $target }」將被永久刪除。此操作無法復原。 +open-with = 開啟檔案 +selected-items = 已經選定 { $items } 個項目 +copy-to-title = 選擇複製目的地 +copy-to-button-label = 複製 +move-to-title = 選擇移動目的地 +move-to-button-label = 移動 +keep = 保留 +progress = { $percent }% +progress-cancelled = { $percent }%,已經取消 +progress-failed = { $percent }%,失敗 +progress-paused = { $percent }%,已經暫停 +favorite-path-error-description = + 無法開啟「{ $path }」 + 「{ $path }」可能不存在,或您可能沒有權限開啟它。 + + 您是否要將它從側邊欄移除? +comment = COSMIC 桌面檔案管理器 +pasted-image = 已經貼上的圖片 +pasted-text = 已經貼上的文字 +pasted-video = 已經貼上的影片 +sort-by-trashed = 依丟入時間排序 +calculating = 計算中... +single-click = 點按以開啟 +type-to-search = 輸入進行搜尋 +type-to-search-recursive = 搜尋目前資料夾及全部子資料夾 +type-to-search-enter-path = 輸入目錄或檔案的路徑 +delete-permanently = 永久刪除 +eject = 彈出 +remove-from-recents = 從最近項目中移除 +change-wallpaper = 變更桌布... +desktop-appearance = 桌面外觀... +display-settings = 顯示設定... +reload-folder = 重新載入資料夾 +gallery-preview = 圖庫預覽 +type = 類型:{ $mime } +items = 項目:{ $items } +item-size = 大小:{ $size } +item-created = 建立時間:{ $created } +item-modified = 修改時間:{ $modified } +item-accessed = 存取時間:{ $accessed } +type-to-search-select = 選取第一個符合條件的檔案或資料夾 +copy-to = 複製至... +move-to = 移動至... +show-recents = 側邊欄中的最近使用資料夾 +clear-recents-history = 清除最近使用歷史記錄 +copy-path = 複製路徑 +setting-executable-and-launching = 設定「{ $name }」為可以執行並進行啟動 +set-executable-and-launched = 設定「{ $name }」為可以執行並已經啟動 +setting-permissions = 設定「{ $name }」的權限至 { $mode } +set-permissions = 設定「{ $name }」的權限至 { $mode } +mixed = 混合 From cf328771c3bb199256ff3f3550c0e183dbef0a5e Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 26 Mar 2026 13:21:17 -0400 Subject: [PATCH 025/110] fix: handle slight delay in availability of clipboard data a better fix in the future would probably be an event indicating availability of the data. --- src/app.rs | 37 ++++++++++++++++++++++++++++++++++--- src/clipboard.rs | 9 ++------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/app.rs b/src/app.rs index 254827b..0561db4 100644 --- a/src/app.rs +++ b/src/app.rs @@ -422,6 +422,7 @@ pub enum Message { CheckClipboardImage, CheckClipboardVideo, CheckClipboardText, + RetryCheckClipboard(ClipboardCache), ClipboardCached(ClipboardCache), PendingCancel(u64), PendingCancelAll, @@ -4036,9 +4037,12 @@ impl Application for App { // Check if clipboard has any paste-able content and cache it return clipboard::read_data::().map(|contents_opt| { match contents_opt { - Some(contents) if !contents.paths.is_empty() => cosmic::action::app( - Message::ClipboardCached(ClipboardCache::Files(contents)), + Some(contents) if contents.paths.is_empty() => cosmic::action::app( + Message::RetryCheckClipboard(ClipboardCache::Files(contents)), ), + Some(contents) => cosmic::action::app(Message::ClipboardCached( + ClipboardCache::Files(contents), + )), _ => cosmic::action::app(Message::CheckClipboardImage), } }); @@ -4071,6 +4075,28 @@ impl Application for App { })) }); } + Message::RetryCheckClipboard(cache) => { + let mut cmds = Vec::new(); + cmds.push(self.update(Message::ClipboardCached(cache))); + + cmds.push( + iced::Task::future(tokio::time::sleep(Duration::from_millis(300))) + .discard() + .chain( + clipboard::read_data::().map(|contents_opt| { + match contents_opt { + Some(contents) if !contents.paths.is_empty() => { + cosmic::action::app(Message::ClipboardCached( + ClipboardCache::Files(contents), + )) + } + _ => cosmic::action::app(Message::CheckClipboardImage), + } + }), + ), + ); + return Task::batch(cmds); + } Message::ClipboardCached(cache) => { self.clipboard_cache = cache; } @@ -4478,6 +4504,7 @@ impl Application for App { widget::Id::unique(), )), ); + commands.push(self.update(Message::CheckClipboard)); commands.push(self.update(Message::Surface( cosmic::surface::action::app_popup( move |app: &mut Self| -> SctkPopupSettings { @@ -5344,7 +5371,11 @@ impl Application for App { }; } // Check clipboard when window gains focus - return self.update(Message::CheckClipboard); + // HACK: Wait a moment for the data to be available. + return cosmic::task::future(async { + _ = tokio::time::sleep(Duration::from_millis(300)).await; + cosmic::action::app(Message::CheckClipboard) + }); } Message::Surface(action) => { return cosmic::task::message(cosmic::Action::Cosmic( diff --git a/src/clipboard.rs b/src/clipboard.rs index 6b0be96..5892071 100644 --- a/src/clipboard.rs +++ b/src/clipboard.rs @@ -133,9 +133,7 @@ impl TryFrom<(Vec, String)> for ClipboardPaste { "text/uri-list" => { let text = str::from_utf8(&data)?; let lines = text.lines(); - if text.is_empty() || lines.count() == 0 { - Err(format!("Empty file url"))?; - } + for line in text.lines() { let url = Url::parse(line)?; match url.to_file_path() { @@ -146,10 +144,7 @@ impl TryFrom<(Vec, String)> for ClipboardPaste { } "x-special/gnome-copied-files" => { let text = str::from_utf8(&data)?; - let lines = text.lines(); - if text.is_empty() || lines.count() == 0 { - Err(format!("Empty file url"))?; - } + for (i, line) in text.lines().enumerate() { if i == 0 { kind = match line { From 1c1f8fdf6e41361345156e1a6e2f03e8d5fb3902 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Fri, 27 Mar 2026 11:51:16 -0400 Subject: [PATCH 026/110] fix: retry reading clipboard if data is empty --- src/app.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/app.rs b/src/app.rs index 0561db4..19dc54d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -3890,6 +3890,24 @@ impl Application for App { // Use cached clipboard data if available (needed for Wayland popups) match &self.clipboard_cache { ClipboardCache::Files(contents) => { + if contents.paths.is_empty() { + return iced::Task::future(tokio::time::sleep( + std::time::Duration::from_millis(300), + )) + .discard() + .chain( + clipboard::read_data::().map( + move |contents_opt| match contents_opt { + Some(contents) => cosmic::action::app( + Message::PasteContents(to.clone(), contents), + ), + None => { + cosmic::action::app(Message::PasteImage(to.clone())) + } + }, + ), + ); + } return self .update(Message::PasteContents(to.clone(), contents.clone())); } From fc25260a5ffbb1ce55408ac03f0372f93c3fdcf8 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Mon, 6 Apr 2026 23:14:06 -0600 Subject: [PATCH 027/110] feat: select file name until the extension in rename and save dialog --- Cargo.lock | 98 +++++++++++++++++++++++++++------------------------ src/app.rs | 15 ++++++-- src/dialog.rs | 11 ++++++ 3 files changed, 75 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f89c7f4..97505bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1317,7 +1317,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1338,7 +1338,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "quote", "syn", @@ -1479,7 +1479,7 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.18.2" -source = "git+https://github.com/pop-os/cosmic-text.git#9a2ab09f06905e91f41d64ac6eee887726e7fd76" +source = "git+https://github.com/pop-os/cosmic-text.git#4d74f795cc771fdcc7ea0f9cacba63fcf036fad6" dependencies = [ "bitflags 2.11.0", "fontdb", @@ -1502,7 +1502,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "almost", "configparser", @@ -2365,7 +2365,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6d3a3635983a889f065aa9ce760384713f23a9b4a04f696f86c39a5d7a6a5a" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "nom 8.0.0", ] @@ -2584,9 +2584,9 @@ dependencies = [ [[package]] name = "gif" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e" +checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159" dependencies = [ "color_quant", "weezl", @@ -2850,6 +2850,12 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + [[package]] name = "heck" version = "0.4.1" @@ -2983,7 +2989,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "dnd", "iced_accessibility", @@ -3004,7 +3010,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "accesskit", "accesskit_winit", @@ -3013,7 +3019,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "bitflags 2.11.0", "bytes", @@ -3037,7 +3043,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "iced_core", "iced_futures", @@ -3047,7 +3053,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "futures", "iced_core", @@ -3061,7 +3067,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "bitflags 2.11.0", "bytemuck", @@ -3082,7 +3088,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "iced_graphics", "iced_runtime", @@ -3091,7 +3097,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3103,7 +3109,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3118,7 +3124,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "bytemuck", "cosmic-text", @@ -3135,7 +3141,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.0", @@ -3166,7 +3172,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3184,7 +3190,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3671,7 +3677,7 @@ dependencies = [ "byteorder-lite", "color_quant", "exr", - "gif 0.14.1", + "gif 0.14.2", "image-webp", "moxcms", "num-traits", @@ -3720,12 +3726,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.0", "serde", "serde_core", ] @@ -4297,7 +4303,7 @@ checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#a44cff8011d81209e18de86f24da248c88b5a28d" +source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" dependencies = [ "apply", "ashpd 0.12.3", @@ -4374,14 +4380,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ "bitflags 2.11.0", "libc", "plain", - "redox_syscall 0.7.3", + "redox_syscall 0.7.4", ] [[package]] @@ -4728,7 +4734,7 @@ dependencies = [ "half", "hashbrown 0.16.1", "hexf-parse", - "indexmap 2.13.1", + "indexmap 2.14.0", "libm", "log", "num-traits", @@ -5234,11 +5240,11 @@ dependencies = [ [[package]] name = "ordermap" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfa78c92071bbd3628c22b1a964f7e0eb201dc1456555db072beb1662ecd6715" +checksum = "7f7476a5b122ff1fce7208e7ee9dccd0a516e835f5b8b19b8f3c98a34cf757c1" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "serde", "serde_core", ] @@ -5992,9 +5998,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" dependencies = [ "bitflags 2.11.0", ] @@ -6370,7 +6376,7 @@ version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "itoa", "memchr", "serde", @@ -6408,7 +6414,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.13.1", + "indexmap 2.14.0", "schemars 0.9.0", "schemars 1.2.1", "serde_core", @@ -7107,7 +7113,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "serde_core", "serde_spanned", "toml_datetime", @@ -7131,7 +7137,7 @@ version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.14.0", "toml_datetime", "toml_parser", "winnow 1.0.1", @@ -7598,7 +7604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap 2.13.1", + "indexmap 2.14.0", "wasm-encoder", "wasmparser", ] @@ -7611,7 +7617,7 @@ checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags 2.11.0", "hashbrown 0.15.5", - "indexmap 2.13.1", + "indexmap 2.14.0", "semver", ] @@ -7848,7 +7854,7 @@ dependencies = [ "cfg_aliases", "document-features", "hashbrown 0.16.1", - "indexmap 2.13.1", + "indexmap 2.14.0", "log", "naga", "once_cell", @@ -8615,7 +8621,7 @@ dependencies = [ "libredox", "orbclient", "raw-window-handle", - "redox_syscall 0.7.3", + "redox_syscall 0.7.4", "smol_str", "tracing", "winit-core", @@ -8774,7 +8780,7 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck 0.5.0", - "indexmap 2.13.1", + "indexmap 2.14.0", "prettyplease", "syn", "wasm-metadata", @@ -8805,7 +8811,7 @@ checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags 2.11.0", - "indexmap 2.13.1", + "indexmap 2.14.0", "log", "serde", "serde_derive", @@ -8824,7 +8830,7 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap 2.13.1", + "indexmap 2.14.0", "log", "semver", "serde", @@ -9323,7 +9329,7 @@ dependencies = [ "flate2", "getrandom 0.4.2", "hmac", - "indexmap 2.13.1", + "indexmap 2.14.0", "lzma-rust2", "memchr", "pbkdf2", diff --git a/src/app.rs b/src/app.rs index 254827b..ace9cb1 100644 --- a/src/app.rs +++ b/src/app.rs @@ -4218,12 +4218,14 @@ impl Application for App { .collect(); if !selected.is_empty() { //TODO: batch rename - let tasks = selected + let mut last_name = String::new(); + let tasks: Vec<_> = selected .into_iter() .filter_map(|path| { let parent = path.parent()?.to_path_buf(); let name = path.file_name()?.to_str()?.to_string(); let dir = path.is_dir(); + last_name = name.clone(); Some(self.dialog_pages.push_back(DialogPage::RenameItem { from: path, parent, @@ -4231,9 +4233,15 @@ impl Application for App { dir, })) }) - .chain(std::iter::once(widget::text_input::focus( + .collect(); + let tasks = tasks.into_iter().chain([ + widget::text_input::focus(self.dialog_text_input.clone()), + widget::text_input::select_until_last( self.dialog_text_input.clone(), - ))); + &last_name, + '.', + ), + ]); return Task::batch(tasks); } } @@ -6102,6 +6110,7 @@ impl Application for App { .into(), widget::text_input("", name.as_str()) .id(self.dialog_text_input.clone()) + .double_click_select_delimiter('.') .on_input(move |name| { Message::DialogUpdate(DialogPage::RenameItem { from: from.clone(), diff --git a/src/dialog.rs b/src/dialog.rs index 0ed4474..f9894ac 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -600,6 +600,7 @@ impl App { col = col.push( widget::text_input("", filename) .id(self.filename_id.clone()) + .double_click_select_delimiter('.') .on_input(Message::Filename) .on_submit(|_| Message::Save(false)), ); @@ -1962,6 +1963,16 @@ impl Application for App { if self.search_get().is_some() { return widget::text_input::focus(self.search_id.clone()); } + if let DialogKind::SaveFile { filename } = &self.flags.kind { + return Task::batch([ + widget::text_input::focus(self.filename_id.clone()), + widget::text_input::select_until_last( + self.filename_id.clone(), + filename, + '.', + ), + ]); + } return widget::text_input::focus(self.filename_id.clone()); } } From da05a85fc57973e020cbf5d4a78ee69b534729d6 Mon Sep 17 00:00:00 2001 From: sandroid Date: Tue, 17 Mar 2026 18:21:10 +0100 Subject: [PATCH 028/110] feat: start type-to-select search from the current focus --- src/tab.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/src/tab.rs b/src/tab.rs index d0eac54..222a758 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -3017,7 +3017,7 @@ impl Tab { /// Returns true if an item was selected. pub fn select_by_prefix(&mut self, prefix: &str) -> bool { let prefix_lower = prefix.to_lowercase(); - self.select_focus = None; + let focus = self.select_focus.take(); if let Some(ref mut items) = self.items_opt { // First, deselect all items @@ -3025,18 +3025,63 @@ impl Tab { item.selected = false; } - // Find first matching item - for (i, item) in items.iter_mut().enumerate() { - if item.name.to_lowercase().starts_with(&prefix_lower) { - item.selected = true; - self.select_focus = Some(i); - return true; - } - } + // Determine the start index of the search. When the index is before the currently focused item, it will be + // considered first, otherwise last. Consider the focused item last when only a single character has been + // typed, so we eagerly switch focus on the first character and stay on the same item as long as the prefix + // matches. + let start = if prefix_lower.chars().count() == 1 { + Self::index_after_focus(focus, self.sort_direction) + } else { + Self::index_before_focus(focus, self.sort_direction) + }; + let Some((until, after)) = items.split_at_mut_checked(start) else { + log::error!( + "invalid select focus index {start} for items of length {}", + items.len() + ); + return false; + }; + let search_items = after + .into_iter() + .enumerate() + .map(|(i, item)| (i + start, item)) + .chain(until.into_iter().enumerate()); + + self.select_focus = if self.sort_direction { + Self::select_first_prefix_match(&prefix_lower, search_items) + } else { + Self::select_first_prefix_match(&prefix_lower, search_items.rev()) + }; + + return self.select_focus.is_some(); } false } + fn index_before_focus(current_focus: Option, forward: bool) -> usize { + current_focus.map_or(0, |i| if forward { i } else { i + 1 }) + } + + fn index_after_focus(current_focus: Option, forward: bool) -> usize { + current_focus.map_or(0, |i| if forward { i + 1 } else { i }) + } + + /// Selects the first item in the given iterator whose name starts with the given prefix. + /// + /// The `prefix` must be lowercase. + fn select_first_prefix_match<'a>( + prefix: &str, + items: impl Iterator, + ) -> Option { + for (i, item) in items { + if item.name.to_lowercase().starts_with(&prefix) { + item.selected = true; + return Some(i); + } + } + None + } + pub fn select_paths(&mut self, paths: Vec) { self.select_focus = None; if let Some(ref mut items) = self.items_opt { From 91243b99b556586c16c7c9b89872d4784f93c654 Mon Sep 17 00:00:00 2001 From: sandroid Date: Tue, 17 Mar 2026 18:29:51 +0100 Subject: [PATCH 029/110] feat: repeat a key to cycle through items in type-to-select mode --- src/tab.rs | 75 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/src/tab.rs b/src/tab.rs index 222a758..b0b3a34 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -3029,30 +3029,44 @@ impl Tab { // considered first, otherwise last. Consider the focused item last when only a single character has been // typed, so we eagerly switch focus on the first character and stay on the same item as long as the prefix // matches. - let start = if prefix_lower.chars().count() == 1 { + let single_char = prefix_lower.chars().count() == 1; + let start = if single_char { Self::index_after_focus(focus, self.sort_direction) } else { Self::index_before_focus(focus, self.sort_direction) }; - let Some((until, after)) = items.split_at_mut_checked(start) else { - log::error!( - "invalid select focus index {start} for items of length {}", - items.len() - ); - return false; - }; - let search_items = after - .into_iter() - .enumerate() - .map(|(i, item)| (i + start, item)) - .chain(until.into_iter().enumerate()); + self.select_focus = Self::select_first_prefix_from_index( + &prefix_lower, + items, + start, + self.sort_direction, + ); - self.select_focus = if self.sort_direction { - Self::select_first_prefix_match(&prefix_lower, search_items) - } else { - Self::select_first_prefix_match(&prefix_lower, search_items.rev()) + if self.select_focus.is_some() || single_char { + return self.select_focus.is_some(); + } + + let mut chars = prefix_lower.chars(); + let Some(first) = chars.next() else { + log::error!("search term is empty"); + return self.select_focus.is_some(); }; + // Check if all entered characters are the same + if !chars.all(|c| c == first) { + return self.select_focus.is_some(); + } + + // Search for a single character when all entered characters are the same. + // This allows cycling through items starting with the same character by repeatedly pressing a key. + let start = Self::index_after_focus(focus, self.sort_direction); + self.select_focus = Self::select_first_prefix_from_index( + &first.to_string(), + items, + start, + self.sort_direction, + ); + return self.select_focus.is_some(); } false @@ -3066,6 +3080,33 @@ impl Tab { current_focus.map_or(0, |i| if forward { i + 1 } else { i }) } + fn select_first_prefix_from_index( + prefix_lower: &str, + items: &mut [Item], + start: usize, + forward: bool, + ) -> Option { + // Order the search item so they begin at `start`. + let Some((until, after)) = items.split_at_mut_checked(start) else { + log::error!( + "invalid start index {start} for items of length {}", + items.len() + ); + return None; + }; + let search_items = after + .into_iter() + .enumerate() + .map(|(i, item)| (i + start, item)) + .chain(until.into_iter().enumerate()); + + if forward { + Self::select_first_prefix_match(prefix_lower, search_items) + } else { + Self::select_first_prefix_match(prefix_lower, search_items.rev()) + } + } + /// Selects the first item in the given iterator whose name starts with the given prefix. /// /// The `prefix` must be lowercase. From c114759c9ed4164939914c6eae61b4567377a73c Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Fri, 10 Apr 2026 05:48:58 +0200 Subject: [PATCH 030/110] chore: use tracing for structured logs --- Cargo.toml | 3 ++- src/lib.rs | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8be8b9a..1b90a4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,6 @@ icu = { version = "2.1.1", features = ["compiled_data"] } cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "160b086", optional = true } cosmic-mime-apps = { git = "https://github.com/pop-os/cosmic-mime-apps.git", optional = true } dirs = "6.0.0" -env_logger = "0.11" gio = { version = "0.21", optional = true } glib = { version = "0.21", optional = true } glob = "0.3" @@ -62,6 +61,8 @@ png = "0.18" jxl-oxide = { version = "0.12.5", features = ["image"] } num_cpus = "1.17.0" filetime = "0.2" +tracing = "0.1.44" +tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } # Completion-based IO runtime to enable io_uring / IOCP file IO support. [dependencies.compio] diff --git a/src/lib.rs b/src/lib.rs index cc0bcc1..b4c85c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ use cosmic::{app::Settings, iced::Limits}; use std::{env, fs, path::PathBuf, process}; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; use app::{App, Flags}; pub mod app; @@ -73,7 +74,22 @@ pub fn is_wayland() -> bool { /// Runs application in desktop mode #[rustfmt::skip] pub fn desktop() -> Result<(), Box> { - env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init(); + let log_format = tracing_subscriber::fmt::format() + .pretty() + .without_time() + .with_line_number(true) + .with_file(true) + .with_target(false) + .with_thread_names(true); + + let log_layer = tracing_subscriber::fmt::Layer::default() + .with_writer(std::io::stderr) + .event_format(log_format); + + tracing_subscriber::registry() + .with(tracing_subscriber::EnvFilter::from_env("RUST_LOG")) + .with(log_layer) + .init(); localize::localize(); @@ -108,7 +124,21 @@ pub fn desktop() -> Result<(), Box> { /// Runs application with these settings #[rustfmt::skip] pub fn main() -> Result<(), Box> { - env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init(); + let log_format = tracing_subscriber::fmt::format() + .pretty() + .with_line_number(true) + .with_file(true) + .with_target(false) + .with_thread_names(true); + + let log_layer = tracing_subscriber::fmt::Layer::default() + .with_writer(std::io::stderr) + .event_format(log_format); + + tracing_subscriber::registry() + .with(tracing_subscriber::EnvFilter::from_env("RUST_LOG")) + .with(log_layer) + .init(); localize::localize(); From b299f1a172388e73f0c3405f82b08ca4d3cc8884 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Fri, 10 Apr 2026 05:57:34 +0200 Subject: [PATCH 031/110] chore: add methods to `Controller` to pause and unpause futures - Use `Controller::until_paused` as a signal in a select to pause futures - Use `Controller::until_unpaused` to block futures in a select loop --- src/operation/controller.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/operation/controller.rs b/src/operation/controller.rs index f4b26fe..960a28d 100644 --- a/src/operation/controller.rs +++ b/src/operation/controller.rs @@ -86,6 +86,35 @@ impl Controller { self.set_state(ControllerState::Paused); } + /// Returns when the state is paused. + /// + /// Use this to pause futures. + pub async fn until_paused(&self) { + loop { + if matches!(self.state(), ControllerState::Paused) { + return; + } + + self.inner.notify.notified().await; + } + } + + /// Returns when state is neither paused, cancelled, nor failed. + /// + /// Use this to resume futures. + pub async fn until_unpaused(&self) { + loop { + if !matches!( + self.state(), + ControllerState::Paused | ControllerState::Cancelled | ControllerState::Failed + ) { + return; + } + + self.inner.notify.notified().await; + } + } + pub fn unpause(&self) { if !self.is_cancelled() | !self.is_failed() { self.set_state(ControllerState::Running); From e2bdcf8da4df1cdb2a4d707ed52a14b04eb4c0ff Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Fri, 10 Apr 2026 06:03:16 +0200 Subject: [PATCH 032/110] fix: use gio file copy fallback to fix MTP unsupported I/O errors --- Cargo.toml | 1 + src/operation/recursive.rs | 441 ++++++++++++++++++++++++++----------- 2 files changed, 311 insertions(+), 131 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1b90a4a..9447640 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,6 +63,7 @@ num_cpus = "1.17.0" filetime = "0.2" tracing = "0.1.44" tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } +thiserror = "2.0.18" # Completion-based IO runtime to enable io_uring / IOCP file IO support. [dependencies.compio] diff --git a/src/operation/recursive.rs b/src/operation/recursive.rs index 61c4841..befe69c 100644 --- a/src/operation/recursive.rs +++ b/src/operation/recursive.rs @@ -1,15 +1,31 @@ -use compio::BufResult; -use compio::buf::{IntoInner, IoBuf}; -use compio::io::{AsyncReadAt, AsyncWriteAt}; -use std::future::Future; -use std::pin::Pin; -use std::time::Instant; -use std::{cell::Cell, error::Error, fs, ops::ControlFlow, path::PathBuf, rc::Rc}; -use walkdir::WalkDir; - -use crate::operation::{OperationError, sync_to_disk}; +// Copyright 2023 System76 +// SPDX-License-Identifier: GPL-3.0-only use super::{Controller, OperationSelection, ReplaceResult, copy_unique_path}; +use crate::operation::{OperationError, sync_to_disk}; +use anyhow::Context as AnyhowContext; +use compio::BufResult; +use compio::buf::{IntoInner, IoBuf}; +use compio::driver::{ToSharedFd, op::AsyncifyFd}; +use compio::io::{AsyncReadAt, AsyncWriteAt}; +use cosmic::iced::futures; +use futures::future::Either; +use futures::{FutureExt, StreamExt}; +use gio::prelude::FileExtManual; +use std::future::Future; +use std::pin::Pin; +use std::rc::Rc; +use std::time::Instant; +use std::{cell::Cell, error::Error, fs, ops::ControlFlow, path::PathBuf}; +use walkdir::WalkDir; + +#[derive(thiserror::Error, Debug)] +pub enum GioCopyError { + #[error("controller state")] + Controller(OperationError), + #[error("gio copy failed")] + GLib(#[from] glib::Error), +} pub enum Method { Copy, @@ -313,136 +329,26 @@ impl Op { }) } - async fn run( - &mut self, - ctx: &mut Context, - mut progress: Progress, - ) -> Result> { + async fn run(&mut self, ctx: &mut Context, progress: Progress) -> Result> { if self.skipped.normal.get() || (self.is_cleanup && self.skipped.cleanup.get()) { return Ok(true); } match self.kind { OpKind::Copy => { - // Remove `to` if overwriting and it is an existing file - if self.to.is_file() { - match ctx.replace(self).await? { - ControlFlow::Continue(to) => { - self.to = to; - } - ControlFlow::Break(ret) => { - return Ok(ret); - } - } + let result = self.copy(ctx, progress).await; + + if result.is_err() { + _ = compio::fs::remove_file(&self.to).await; } - let (from_file, metadata, mut to_file) = cosmic::iced::futures::try_join!( - async { - compio::fs::OpenOptions::new() - .read(true) - .open(&self.from) - .await - }, - compio::fs::metadata(&self.from), - // This is atomic and ensures `to` is not created by any other process - async { - compio::fs::OpenOptions::new() - .create_new(true) - .write(true) - .open(&self.to) - .await - } - )?; - - progress.total_bytes = Some(metadata.len()); - (ctx.on_progress)(self, &progress); - if let Err(err) = to_file.set_permissions(metadata.permissions()).await { - // This error is not propagated upwards as some filesystems do not support setting permissions - log::warn!( - "failed to set permissions for {}: {}", - self.to.display(), - err - ); - } - - // Prevent spamming the progress callbacks. - let mut last_progress_update = Instant::now(); - // io_uring/IOCP requires transferring ownership of the buffer to the kernel. - let mut buf_in = std::mem::take(&mut ctx.buf); - // Track where the current read/write position is at. - let mut pos = 0; - - loop { - let BufResult(result, buf_out) = from_file.read_at(buf_in, pos).await; - - let count = match result { - Ok(0) => { - ctx.buf = buf_out; - break; - } - Ok(count) => count, - Err(why) => { - ctx.buf = buf_out; - return Err(why.into()); - } - }; - - let BufResult(result, buf_out_slice) = - to_file.write_at(buf_out.slice(..count), pos).await; - let buf_out = buf_out_slice.into_inner(); - - if let Err(why) = result { - ctx.buf = buf_out; - return Err(why.into()); - } - - progress.current_bytes += count as u64; - pos += count as u64; - - // Avoid spamming progress messages too early. - let current = Instant::now(); - if current.duration_since(last_progress_update).as_millis() > 49 { - last_progress_update = current; - (ctx.on_progress)(self, &progress); - - // Also check if the progress was cancelled. - if let Err(state) = ctx.controller.check().await { - ctx.buf = buf_out; - return Err(OperationError::from_state(state, &ctx.controller).into()); - } - } - - buf_in = buf_out; - } - - let mut times = fs::FileTimes::new(); - { - use std::os::unix::prelude::MetadataExt; - log::info!("{}", metadata.mtime()); - } - if let Ok(time) = metadata.modified() { - times = times.set_modified(time); - } - if let Ok(time) = metadata.accessed() { - times = times.set_accessed(time); - } - //TODO: upstream set_times implementation to compio? - { - use compio::driver::{ToSharedFd, op::AsyncifyFd}; - let op = - AsyncifyFd::new(to_file.to_shared_fd(), move |file: &std::fs::File| { - BufResult(file.set_times(times).map(|_| 0), ()) - }); - match compio::runtime::submit(op).await.0.map(|_| ()) { - Ok(()) => { - log::info!("set times for {} to {:?}", self.to.display(), times); - } - Err(err) => { - log::warn!("failed to set times for {}: {}", self.to.display(), err); - } - } - } + return result; } OpKind::Move { cross_device_copy } => { + // Do not clean up if cross_device_copy is set + if cross_device_copy { + self.skipped.cleanup.set(true); + } + // Remove `to` if overwriting and it is an existing file if self.to.is_file() { match ctx.replace(self).await? { @@ -520,4 +426,277 @@ impl Op { } Ok(true) } + + async fn copy( + &mut self, + ctx: &mut Context, + mut progress: Progress, + ) -> Result> { + // Remove `to` if overwriting and it is an existing file + if self.to.is_file() { + match ctx.replace(self).await? { + ControlFlow::Continue(to) => { + self.to = to; + } + ControlFlow::Break(ret) => { + return Ok(ret); + } + } + } + + let (from_file, metadata, to_file) = cosmic::iced::futures::join!( + async { + compio::fs::OpenOptions::new() + .read(true) + .open(&self.from) + .await + .with_context(|| format!("failed to open {} for reading", self.from.display(),)) + }, + async { compio::fs::metadata(&self.from).await.ok() }, + // This is atomic and ensures `to` is not created by any other process + async { + compio::fs::OpenOptions::new() + .create_new(true) + .write(true) + .open(&self.to) + .await + .with_context(|| format!("failed to open {} for writing", self.to.display())) + } + ); + + let from_file = from_file?; + let mut to_file = to_file?; + progress.total_bytes = metadata.as_ref().map(|m| m.len()); + (ctx.on_progress)(self, &progress); + + if let Some(metadata) = metadata.as_ref() { + if let Err(why) = to_file.set_permissions(metadata.permissions()).await { + // This error is not propagated upwards as some filesystems do not support setting permissions + if !matches!(why.kind(), std::io::ErrorKind::Unsupported) { + tracing::warn!(?why, "failed to set permissions for {}", self.to.display(),); + } + } + } + + // Prevent spamming the progress callbacks. + let mut last_progress_update = Instant::now(); + // io_uring/IOCP requires transferring ownership of the buffer to the kernel. + let mut buf_in = std::mem::take(&mut ctx.buf); + // Track where the current read/write position is at. + let mut pos = 0; + + loop { + let BufResult(result, buf_out) = from_file.read_at(buf_in, pos).await; + + let count = match result { + Ok(0) => { + buf_in = buf_out; + break; + } + Ok(count) => count, + Err(why) => { + ctx.buf = buf_out; + tracing::error!("failed to read: {:?}", why); + _ = futures::future::join(from_file.close(), to_file.close()).await; + return Err(why).context("failed to read")?; + } + }; + + let BufResult(result, buf_out_slice) = + to_file.write_at(buf_out.slice(..count), pos).await; + let buf_out = buf_out_slice.into_inner(); + + if let Err(why) = result { + if let std::io::ErrorKind::Unsupported = why.kind() { + ctx.buf = buf_out; + _ = futures::future::join(from_file.close(), to_file.close()).await; + return self + .gio_file_copy(ctx, progress) + .await + .map(|_| true) + .map_err(Into::into); + } + + tracing::error!("failed to write: {:?}", why); + ctx.buf = buf_out; + _ = futures::future::join(from_file.close(), to_file.close()).await; + return Err(why).context("failed to write")?; + } + + progress.current_bytes += count as u64; + pos += count as u64; + + // Avoid spamming progress messages too early. + let current = Instant::now(); + if current.duration_since(last_progress_update).as_millis() > 49 { + last_progress_update = current; + (ctx.on_progress)(self, &progress); + + // Also check if the progress was cancelled. + if let Err(state) = ctx.controller.check().await { + ctx.buf = buf_out; + tracing::warn!( + "operation to copy from {:?} to {:?} cancelled", + self.from, + self.to + ); + _ = futures::future::join(from_file.close(), to_file.close()).await; + return Err(OperationError::from_state(state, &ctx.controller).into()); + } + } + + buf_in = buf_out; + } + + ctx.buf = buf_in; + + if let Some(metadata) = metadata.as_ref() { + let mut times = fs::FileTimes::new(); + if let Ok(time) = metadata.modified() { + times = times.set_modified(time); + } + if let Ok(time) = metadata.accessed() { + times = times.set_accessed(time); + } + //TODO: upstream set_times implementation to compio? + let op = AsyncifyFd::new(to_file.to_shared_fd(), move |file: &std::fs::File| { + BufResult(file.set_times(times).map(|_| 0), ()) + }); + match compio::runtime::submit(op).await.0.map(|_| ()) { + Ok(()) => { + tracing::info!("set times for {} to {:?}", self.to.display(), times); + } + Err(why) => { + if !matches!(why.kind(), std::io::ErrorKind::Unsupported) { + tracing::error!(?why, "failed to set times for {}", self.to.display()); + } + } + } + } + + _ = to_file.close().await; + + Ok(true) + } + + /// Fallback mechanism in the event that unsupported I/O error errors occur. + /// Fixes unsupported errors when copying large files over MTP. + /// TODO: Find what Gio.File does to work around this. + async fn gio_file_copy( + &self, + ctx: &mut Context, + mut progress: Progress, + ) -> Result<(), GioCopyError> { + _ = compio::fs::remove_file(&self.to).await; + + let from = gio::File::for_path(&self.from); + let to = gio::File::for_path(&self.to); + let (progress_tx, mut progress_rx) = tokio::sync::mpsc::unbounded_channel(); + let (tx, rx) = tokio::sync::oneshot::channel(); + let (pause_tx, mut pause_rx) = tokio::sync::watch::channel(false); + + let task = compio::runtime::spawn_blocking(move || { + let glib_context = glib::MainContext::new(); + let glib_loop = glib::MainLoop::new(Some(&glib_context), false); + glib_context.with_thread_default(move || { + let glib_loop2 = glib_loop.clone(); + glib::MainContext::ref_thread_default().spawn_local(async move { + // Create a future for copying the file with `gio::File`. This also creates a progress stream. + let (gio_copy_fut, mut progress_stream) = from.copy_future( + &to, + gio::FileCopyFlags::OVERWRITE | gio::FileCopyFlags::ALL_METADATA, + glib::Priority::LOW, + ); + + let mut copy_fut = + gio_copy_fut.map(|result| result.map_err(GioCopyError::GLib)); + + let mut progress_fut = std::pin::pin!(async { + while let Some((current_bytes, _)) = progress_stream.next().await { + _ = progress_tx.send(current_bytes); + } + + drop(progress_tx); + futures::future::pending::<()>().await; + }); + + // Poll the progress future while waiting for the copy future to finish. + let mut main_fut = std::pin::pin!(async { + loop { + if let Either::Right((result, _)) = + futures::future::select(&mut progress_fut, &mut copy_fut).await + { + return result; + } + } + }); + + let mut pause_rx2 = pause_rx.clone(); + + loop { + let until_paused = std::pin::pin!(pause_rx.wait_for(|paused| *paused)); + match futures::future::select(until_paused, &mut main_fut).await { + Either::Left(_) => { + _ = pause_rx2.wait_for(|paused| !*paused).await; + } + + Either::Right((result, _)) => { + _ = tx.send(result.map(|_| ())); + glib_loop2.quit(); + return; + } + } + } + }); + + glib_loop.run(); + }) + }); + + let mut last_progress_update = Instant::now(); + let mut task = task.fuse(); + let mut rx = rx.fuse(); + + loop { + let until_paused = std::pin::pin!(ctx.controller.until_paused()); + + futures::select! { + value = progress_rx.recv().fuse() => { + if let Some(current_bytes) = value { + progress.current_bytes = current_bytes as u64; + let current = Instant::now(); + if current.duration_since(last_progress_update).as_millis() > 49 { + last_progress_update = current; + (ctx.on_progress)(self, &progress); + + tracing::info!("checking controller"); + + // Also check if the progress was cancelled. + if let Err(state) = ctx.controller.check().await { + tracing::warn!( + "operation to copy from {:?} to {:?} cancelled", + self.from, + self.to + ); + return Err::<(), GioCopyError>(GioCopyError::Controller( + OperationError::from_state(state, &ctx.controller), + )); + } + } + } + } + + result = rx => return result.unwrap(), + + _ = task => (), + + _ = until_paused.fuse() => { + // Pauses an active copy while the controller state is paused. + _ = pause_tx.send(true); + ctx.controller.until_unpaused().await; + _ = pause_tx.send(false); + } + } + } + } } From bb15f30fe5adcea4df8418adf867ba8bea876ae2 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Fri, 10 Apr 2026 15:49:04 +0200 Subject: [PATCH 033/110] chore: update Cargo.lock --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f89c7f4..55dead6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1354,7 +1354,6 @@ dependencies = [ "cosmic-client-toolkit", "cosmic-mime-apps", "dirs 6.0.0", - "env_logger", "fastrand", "filetime", "flate2", @@ -1394,8 +1393,11 @@ dependencies = [ "tar", "tempfile", "test-log", + "thiserror 2.0.18", "tikv-jemallocator", "tokio", + "tracing", + "tracing-subscriber", "trash", "url", "uzers", @@ -1963,7 +1965,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", - "regex", ] [[package]] @@ -1975,7 +1976,6 @@ dependencies = [ "anstream", "anstyle", "env_filter", - "jiff", "log", ] From 93dd775f3c6452ec8b82998d002b7351085c70a5 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 14 Apr 2026 16:23:10 +0200 Subject: [PATCH 034/110] perf: get image dimensions from background thread This caused the tab subscription to block the tokio executor. Instead store the image dimensions in the `Item`, which is created on a background thread. --- src/mounter/gvfs.rs | 1 + src/tab.rs | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/mounter/gvfs.rs b/src/mounter/gvfs.rs index cd4ea68..8ac42dc 100644 --- a/src/mounter/gvfs.rs +++ b/src/mounter/gvfs.rs @@ -199,6 +199,7 @@ fn network_scan(uri: &str, sizes: IconSizes) -> Result, String> { metadata, hidden, location_opt: Some(location), + image_dimensions: None, mime, icon_handle_grid, icon_handle_list, diff --git a/src/tab.rs b/src/tab.rs index b0b3a34..1e63588 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -708,6 +708,9 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS children_opt, }, hidden, + image_dimensions: (!remote && mime.type_() == mime::IMAGE) + .then(|| image::image_dimensions(&path).ok()) + .flatten(), location_opt: Some(Location::Path(path)), mime, icon_handle_grid, @@ -843,6 +846,7 @@ pub fn item_from_entry( }, hidden, location_opt: Some(Location::Path(path)), + image_dimensions: None, mime, icon_handle_grid, icon_handle_list, @@ -896,6 +900,9 @@ pub fn item_from_trash_entry( metadata: ItemMetadata::Trash { metadata, entry }, hidden: false, location_opt: None, + image_dimensions: (mime.type_() == mime::IMAGE) + .then(|| image::image_dimensions(&original_path).ok()) + .flatten(), mime, icon_handle_grid, icon_handle_list, @@ -1444,6 +1451,7 @@ pub fn scan_desktop( metadata, hidden: false, location_opt: Some(Location::Trash), + image_dimensions: None, mime, icon_handle_grid, icon_handle_list, @@ -2319,6 +2327,7 @@ pub struct Item { pub hidden: bool, pub location_opt: Option, pub mime: Mime, + pub image_dimensions: Option<(u32, u32)>, pub icon_handle_grid: widget::icon::Handle, pub icon_handle_list: widget::icon::Handle, pub icon_handle_list_condensed: widget::icon::Handle, @@ -6713,13 +6722,13 @@ impl Tab { // Determine effective memory budget based on image size let (effective_max_mb, effective_jobs) = if mime.type_() == mime::IMAGE { - match image::image_dimensions(&path) { - Ok((width, height)) => { + match item.image_dimensions { + Some((width, height)) => { let (_use_dedicated, eff_mb, eff_jobs) = should_use_dedicated_worker(width, height, max_mb, max_jobs); (eff_mb, eff_jobs) } - Err(_) => (max_mb, max_jobs), + None => (max_mb, max_jobs), } } else { (max_mb, max_jobs) From 971374f60ba701cb2a8728985c9d2742c590b036 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 14 Apr 2026 16:27:53 +0200 Subject: [PATCH 035/110] perf: use atomics for controller progress and state --- Cargo.lock | 8 ++++++++ Cargo.toml | 2 ++ src/operation/controller.rs | 29 +++++++++++++++++++---------- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 55dead6..9a0d3f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -538,6 +538,12 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "atomic_float" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628d228f918ac3b82fe590352cc719d30664a0c13ca3a60266fe02c7132d480a" + [[package]] name = "atomicwrites" version = "0.4.2" @@ -1349,6 +1355,7 @@ name = "cosmic-files" version = "1.0.9" dependencies = [ "anyhow", + "atomic_float", "bzip2", "compio", "cosmic-client-toolkit", @@ -1378,6 +1385,7 @@ dependencies = [ "notify-debouncer-full", "notify-rust", "num_cpus", + "num_enum", "open", "ordermap", "paste", diff --git a/Cargo.toml b/Cargo.toml index 9447640..74e554b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,6 +64,8 @@ filetime = "0.2" tracing = "0.1.44" tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } thiserror = "2.0.18" +atomic_float = "1.1.0" +num_enum = "0.7.6" # Completion-based IO runtime to enable io_uring / IOCP file IO support. [dependencies.compio] diff --git a/src/operation/controller.rs b/src/operation/controller.rs index 960a28d..691316c 100644 --- a/src/operation/controller.rs +++ b/src/operation/controller.rs @@ -1,7 +1,11 @@ -use std::sync::{Arc, Mutex}; +use atomic_float::AtomicF32; +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use std::sync::Arc; +use std::sync::atomic::{self, AtomicU16}; use tokio::sync::Notify; -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)] +#[repr(u16)] pub enum ControllerState { Cancelled, Failed, @@ -11,8 +15,8 @@ pub enum ControllerState { #[derive(Debug)] struct ControllerInner { - state: Mutex, - progress: Mutex, + state: AtomicU16, + progress: AtomicF32, notify: Notify, } @@ -27,8 +31,8 @@ impl Default for Controller { Self { primary: true, inner: Arc::new(ControllerInner { - state: Mutex::new(ControllerState::Running), - progress: Mutex::new(0.0), + state: AtomicU16::new(ControllerState::Running.into()), + progress: AtomicF32::new(0.0), notify: Notify::new(), }), } @@ -50,19 +54,24 @@ impl Controller { } pub fn progress(&self) -> f32 { - *self.inner.progress.lock().unwrap() + self.inner.progress.load(atomic::Ordering::Relaxed) } pub fn set_progress(&self, progress: f32) { - *self.inner.progress.lock().unwrap() = progress; + self.inner + .progress + .swap(progress, atomic::Ordering::Relaxed); } pub fn state(&self) -> ControllerState { - *self.inner.state.lock().unwrap() + ControllerState::try_from(self.inner.state.load(atomic::Ordering::Relaxed)) + .unwrap_or(ControllerState::Failed) } pub fn set_state(&self, state: ControllerState) { - *self.inner.state.lock().unwrap() = state; + self.inner + .state + .store(state.into(), atomic::Ordering::Relaxed); self.inner.notify.notify_waiters(); } From e35d5123f05bdd0ca2c06d0a3a60a04e0cb324ee Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 14 Apr 2026 16:38:56 +0200 Subject: [PATCH 036/110] perf: avoid holding async mutex guards across await points tokio recommends using a sync mutex with a notifier instead of the async mutex where possible. Rust forbids holding a sync mutex guard across await points so we can prevent a potential deadlock this way. This adds a custom channel based on the tokio mpmc example for handling gvfs events from callbacks to avoid the async mutex requirement. Messages are held in a `VecDeque` behind a sync mutex and the receiver will get notified via the notifier when a message is added to the queue. Weak references used in gio callbacks in case the sender is dropped by the application. --- src/app.rs | 5 +-- src/channel.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 +- src/mounter/gvfs.rs | 70 +++++++++++++++++++++++++++++------------ src/tab.rs | 23 ++++++-------- 5 files changed, 139 insertions(+), 39 deletions(-) create mode 100644 src/channel.rs diff --git a/src/app.rs b/src/app.rs index 19dc54d..a427065 100644 --- a/src/app.rs +++ b/src/app.rs @@ -6958,8 +6958,7 @@ impl Application for App { |_| { stream::channel( 1, - move |msg_tx: futures::channel::mpsc::Sender<_>| async move { - let msg_tx = Arc::new(tokio::sync::Mutex::new(msg_tx)); + move |mut msg_tx: futures::channel::mpsc::Sender<_>| async move { tokio::task::spawn_blocking(move || { match notify_rust::Notification::new() .summary(&fl!("notification-in-progress")) @@ -6969,8 +6968,6 @@ impl Application for App { Ok(notification) => { let _ = futures::executor::block_on(async { msg_tx - .lock() - .await .send(Message::Notification(Arc::new( Mutex::new(notification), ))) diff --git a/src/channel.rs b/src/channel.rs new file mode 100644 index 0000000..e91bc35 --- /dev/null +++ b/src/channel.rs @@ -0,0 +1,77 @@ +// Copyright 2025 System76 +// SPDX-License-Identifier: MPL-2.0 + +use std::{ + collections::VecDeque, + sync::{ + Arc, Mutex, + atomic::{AtomicBool, Ordering}, + }, +}; + +/// Create a channel backed by `tokio::sync::Notify` and a sync mutex with a vec deque. +pub fn channel() -> (Sender, Receiver) { + let channel = Arc::new(Channel { + queue: Mutex::new(VecDeque::default()), + notify: tokio::sync::Notify::const_new(), + closed: AtomicBool::new(false), + }); + + (Sender(channel.clone()), Receiver(channel)) +} + +/// A channel backed by `tokio::sync::Notify` and a sync mutex with a vec deque. +struct Channel { + pub(self) queue: Mutex>, + /// Set when a new message has been stored. + pub(self) notify: tokio::sync::Notify, + /// Set when the receiver is dropped. + pub(self) closed: AtomicBool, +} + +pub struct Sender(Arc>); + +impl Sender { + pub fn send(&self, message: Message) { + self.0.queue.lock().unwrap().push_back(message); + self.0.notify.notify_one(); + } +} + +impl Drop for Sender { + fn drop(&mut self) { + self.0.closed.store(true, Ordering::SeqCst); + self.0.notify.notify_one(); + } +} + +pub struct Receiver(Arc>); + +impl Receiver { + /// Returns a value until the sender is dropped. + pub async fn recv(&self) -> Option { + loop { + { + let mut queue = self.0.queue.lock().unwrap(); + if let Some(value) = queue.pop_front() { + if queue.capacity() - queue.len() > 32 { + let capacity = queue.len().next_power_of_two(); + queue.shrink_to(capacity); + } + drop(queue); + return Some(value); + } + } + + if self.0.closed.load(Ordering::SeqCst) { + return None; + } + + self.0.notify.notified().await; + } + } + + pub fn try_recv(&self) -> Option { + self.0.queue.lock().unwrap().pop_front() + } +} diff --git a/src/lib.rs b/src/lib.rs index b4c85c7..9214a7f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; use app::{App, Flags}; pub mod app; mod archive; +pub mod channel; pub mod clipboard; mod context_action; use config::Config; @@ -136,7 +137,7 @@ pub fn main() -> Result<(), Box> { .event_format(log_format); tracing_subscriber::registry() - .with(tracing_subscriber::EnvFilter::from_env("RUST_LOG")) + .with(tracing_subscriber::EnvFilter::from_default_env()) .with(log_layer) .init(); diff --git a/src/mounter/gvfs.rs b/src/mounter/gvfs.rs index 8ac42dc..d6294b6 100644 --- a/src/mounter/gvfs.rs +++ b/src/mounter/gvfs.rs @@ -5,7 +5,7 @@ use cosmic::{ }; use gio::{glib, prelude::*}; use std::{any::TypeId, cell::Cell, future::pending, hash::Hash, path::PathBuf, sync::Arc}; -use tokio::sync::{Mutex, mpsc}; +use tokio::sync::mpsc; use super::{Mounter, MounterAuth, MounterItem, MounterItems, MounterMessage}; use crate::{ @@ -230,7 +230,10 @@ fn dir_info(uri: &str) -> Result<(String, String, Option), glib::Error> Ok((resolved_uri, info.display_name().into(), file.path())) } -fn mount_op(uri: String, event_tx: mpsc::UnboundedSender) -> gio::MountOperation { +fn mount_op( + uri: String, + event_tx: std::sync::Weak>, +) -> gio::MountOperation { let mount_op = gio::MountOperation::new(); mount_op.connect_ask_password( move |mount_op, message, default_user, default_domain, flags| { @@ -253,9 +256,9 @@ fn mount_op(uri: String, event_tx: mpsc::UnboundedSender) -> gio::MountOp .then_some(false), }; let (auth_tx, mut auth_rx) = mpsc::channel(1); - event_tx - .send(Event::NetworkAuth(uri.clone(), auth, auth_tx)) - .unwrap(); + if let Some(event_tx) = event_tx.upgrade() { + event_tx.send(Event::NetworkAuth(uri.clone(), auth, auth_tx)); + } //TODO: async recv? if let Some(auth) = auth_rx.blocking_recv() { if auth.anonymous_opt == Some(true) { @@ -358,37 +361,45 @@ impl Item { pub struct Gvfs { command_tx: mpsc::UnboundedSender, - event_rx: Arc>>, + event_rx: Arc>, } impl Gvfs { pub fn new() -> Self { //TODO: switch to using gvfs-zbus which will better integrate with async rust let (command_tx, mut command_rx) = mpsc::unbounded_channel(); - let (event_tx, event_rx) = mpsc::unbounded_channel(); + let (event_tx, event_rx) = crate::channel::channel(); + let event_tx = Arc::new(event_tx); std::thread::spawn(move || { let main_loop = glib::MainLoop::new(None, false); main_loop.context().spawn_local(async move { + let event_tx = Arc::downgrade(&event_tx); let monitor = gio::VolumeMonitor::get(); { let event_tx = event_tx.clone(); monitor.connect_mount_changed(move |_monitor, mount| { log::info!("mount changed {}", MountExt::name(mount)); - event_tx.send(Event::Changed).unwrap(); + if let Some(event_tx) = event_tx.upgrade() { + event_tx.send(Event::Changed); + } }); } { let event_tx = event_tx.clone(); monitor.connect_mount_added(move |_monitor, mount| { log::info!("mount added {}", MountExt::name(mount)); - event_tx.send(Event::Changed).unwrap(); + if let Some(event_tx) = event_tx.upgrade() { + event_tx.send(Event::Changed); + } }); } { let event_tx = event_tx.clone(); monitor.connect_mount_removed(move |_monitor, mount| { log::info!("mount removed {}", MountExt::name(mount)); - event_tx.send(Event::Changed).unwrap(); + if let Some(event_tx) = event_tx.upgrade() { + event_tx.send(Event::Changed); + } }); } @@ -396,21 +407,27 @@ impl Gvfs { let event_tx = event_tx.clone(); monitor.connect_volume_changed(move |_monitor, volume| { log::info!("volume changed {}", VolumeExt::name(volume)); - event_tx.send(Event::Changed).unwrap(); + if let Some(event_tx) = event_tx.upgrade() { + event_tx.send(Event::Changed); + } }); } { let event_tx = event_tx.clone(); monitor.connect_volume_added(move |_monitor, volume| { log::info!("volume added {}", VolumeExt::name(volume)); - event_tx.send(Event::Changed).unwrap(); + if let Some(event_tx) = event_tx.upgrade() { + event_tx.send(Event::Changed); + } }); } { let event_tx = event_tx.clone(); monitor.connect_volume_removed(move |_monitor, volume| { log::info!("volume removed {}", VolumeExt::name(volume)); - event_tx.send(Event::Changed).unwrap(); + if let Some(event_tx) = event_tx.upgrade() { + event_tx.send(Event::Changed); + } }); } @@ -420,7 +437,11 @@ impl Gvfs { items_tx.send(items(&monitor, sizes)).await.unwrap(); } Cmd::Rescan => { - event_tx.send(Event::Items(items(&monitor, IconSizes::default()))).unwrap(); + let Some(event_tx) = event_tx.upgrade() else { + return; + }; + + event_tx.send(Event::Items(items(&monitor, IconSizes::default()))); } Cmd::Mount(mounter_item, complete_tx) => { let MounterItem::Gvfs(ref item) = mounter_item else { @@ -472,6 +493,9 @@ impl Gvfs { .ok().map(|info| info.boolean(gio::FILE_ATTRIBUTE_FILESYSTEM_REMOTE)) .unwrap_or(true); } + let Some(event_tx) = event_tx.upgrade() else { + return; + }; event_tx.send(Event::MountResult(updated_item, match res { Ok(()) => { _ = complete_tx.send(Ok(())); @@ -483,7 +507,7 @@ impl Gvfs { Some(gio::IOErrorEnum::FailedHandled) => Ok(false), _ => Err(format!("{err}")) }} - })).unwrap(); + })); }, ); break; @@ -499,6 +523,9 @@ impl Gvfs { gio::Cancellable::NONE, move |res| { log::info!("network drive {uri}: result {res:?}"); + let Some(event_tx) = event_tx.upgrade() else { + return; + }; event_tx.send(Event::NetworkResult(uri, match res { Ok(()) => { _ = result_tx.send(Ok(())); @@ -509,7 +536,7 @@ impl Gvfs { Some(gio::IOErrorEnum::FailedHandled) => Ok(false), _ => Err(format!("{err}")) }} - })).unwrap(); + })); } ); } @@ -533,6 +560,9 @@ impl Gvfs { // FIXME sometimes a uri can be mounted and then not recognized as mounted... // seems to be related to uri with a path items_tx.blocking_send(network_scan(&uri, sizes)).unwrap(); + let Some(event_tx) = event_tx.upgrade() else { + return; + }; event_tx.send(Event::NetworkResult(resolved_uri, match res { Ok(()) => { Ok(true) @@ -541,7 +571,7 @@ impl Gvfs { Some(gio::IOErrorEnum::FailedHandled) => Ok(false), _ => Err(format!("{err}")) } - })).unwrap(); + })); } ); } else { @@ -597,7 +627,7 @@ impl Gvfs { }); Self { command_tx, - event_rx: Arc::new(Mutex::new(event_rx)), + event_rx: Arc::new(event_rx), } } } @@ -671,7 +701,7 @@ impl Mounter for Gvfs { let event_rx = self.event_rx.clone(); struct Wrapper { command_tx: mpsc::UnboundedSender, - event_rx: Arc>>, + event_rx: Arc>, } impl Hash for Wrapper { fn hash(&self, state: &mut H) { @@ -695,7 +725,7 @@ impl Mounter for Gvfs { MounterMessage, >| async move { command_tx.send(Cmd::Rescan).unwrap(); - while let Some(event) = event_rx.lock().await.recv().await { + while let Some(event) = event_rx.recv().await { match event { Event::Changed => command_tx.send(Cmd::Rescan).unwrap(), Event::Items(items) => { diff --git a/src/tab.rs b/src/tab.rs index 1e63588..a0f95a0 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -6955,9 +6955,8 @@ impl Tab { .await .unwrap(); - let output = Arc::new(tokio::sync::Mutex::new(output)); + let (watch_tx, mut watch_rx) = tokio::sync::watch::channel(true); { - let output = output.clone(); tokio::task::spawn_blocking(move || { scan_search( &search_location, @@ -6985,14 +6984,7 @@ impl Tab { true } else { // Wake up update method - futures::executor::block_on(async { - output - .lock() - .await - .send(Message::SearchReady(false)) - .await - }) - .is_ok() + watch_tx.send(false).is_ok() } } Err(_) => false, @@ -7005,13 +6997,16 @@ impl Tab { search_location, start.elapsed(), ); - }) - .await - .unwrap(); + }); + } + + while watch_rx.changed().await.is_ok() { + let is_ready = *watch_rx.borrow_and_update(); + let _ = output.send(Message::SearchReady(is_ready)).await; } // Send final ready - let _ = output.lock().await.send(Message::SearchReady(true)).await; + let _ = output.send(Message::SearchReady(true)).await; std::future::pending().await }, From 0bd20e57e7d9023f4372f5fb65ac77710b2fdae3 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 14 Apr 2026 16:51:21 +0200 Subject: [PATCH 037/110] refactor: use select macro for gio copy futures --- src/operation/recursive.rs | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/operation/recursive.rs b/src/operation/recursive.rs index befe69c..bbe89d1 100644 --- a/src/operation/recursive.rs +++ b/src/operation/recursive.rs @@ -9,7 +9,6 @@ use compio::buf::{IntoInner, IoBuf}; use compio::driver::{ToSharedFd, op::AsyncifyFd}; use compio::io::{AsyncReadAt, AsyncWriteAt}; use cosmic::iced::futures; -use futures::future::Either; use futures::{FutureExt, StreamExt}; use gio::prelude::FileExtManual; use std::future::Future; @@ -608,10 +607,11 @@ impl Op { glib::Priority::LOW, ); - let mut copy_fut = - gio_copy_fut.map(|result| result.map_err(GioCopyError::GLib)); + let mut copy_fut = gio_copy_fut + .map(|result| result.map_err(GioCopyError::GLib)) + .fuse(); - let mut progress_fut = std::pin::pin!(async { + let progress_fut = std::pin::pin!(async { while let Some((current_bytes, _)) = progress_stream.next().await { _ = progress_tx.send(current_bytes); } @@ -620,31 +620,23 @@ impl Op { futures::future::pending::<()>().await; }); - // Poll the progress future while waiting for the copy future to finish. - let mut main_fut = std::pin::pin!(async { - loop { - if let Either::Right((result, _)) = - futures::future::select(&mut progress_fut, &mut copy_fut).await - { - return result; - } - } - }); - + let mut progress_fut = progress_fut.fuse(); let mut pause_rx2 = pause_rx.clone(); loop { let until_paused = std::pin::pin!(pause_rx.wait_for(|paused| *paused)); - match futures::future::select(until_paused, &mut main_fut).await { - Either::Left(_) => { - _ = pause_rx2.wait_for(|paused| !*paused).await; - } + futures::select! { + _ = &mut progress_fut => {}, - Either::Right((result, _)) => { + result = &mut copy_fut => { _ = tx.send(result.map(|_| ())); glib_loop2.quit(); return; } + + _ = until_paused.fuse() => { + _ = pause_rx2.wait_for(|paused| !*paused).await; + } } } }); @@ -659,7 +651,6 @@ impl Op { loop { let until_paused = std::pin::pin!(ctx.controller.until_paused()); - futures::select! { value = progress_rx.recv().fuse() => { if let Some(current_bytes) = value { @@ -668,9 +659,6 @@ impl Op { if current.duration_since(last_progress_update).as_millis() > 49 { last_progress_update = current; (ctx.on_progress)(self, &progress); - - tracing::info!("checking controller"); - // Also check if the progress was cancelled. if let Err(state) = ctx.controller.check().await { tracing::warn!( From 15e40461e545a70871e21bcd1e698748abd523ed Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Fri, 10 Apr 2026 06:08:21 +0200 Subject: [PATCH 038/110] fix: do not generate thumbnail if file is being written --- src/operation/mod.rs | 3 ++ src/operation/notifiers.rs | 58 ++++++++++++++++++++++++++++++++++++++ src/operation/recursive.rs | 2 ++ src/tab.rs | 4 +++ 4 files changed, 67 insertions(+) create mode 100644 src/operation/notifiers.rs diff --git a/src/operation/mod.rs b/src/operation/mod.rs index da4a83b..1daed41 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -22,6 +22,9 @@ use zip::AesMode::Aes256; pub use self::controller::{Controller, ControllerState}; pub mod controller; +pub use notifiers::*; +mod notifiers; + pub use self::reader::OpReader; pub mod reader; diff --git a/src/operation/notifiers.rs b/src/operation/notifiers.rs new file mode 100644 index 0000000..0e27ce9 --- /dev/null +++ b/src/operation/notifiers.rs @@ -0,0 +1,58 @@ +// Copyright 2026 System76 +// SPDX-License-Identifier: GPL-3.0-only + +use std::path::{Path, PathBuf}; +use std::sync::{Arc, LazyLock, Mutex}; +use tokio::sync::Notify; + +/// Monitor files which are being written to. +pub struct FileWritingNotifier { + data: Vec, + notify: Arc, +} + +static ACTIVELY_WRITING: LazyLock> = LazyLock::new(|| { + Mutex::new(FileWritingNotifier { + data: Vec::new(), + notify: Arc::new(Notify::new()), + }) +}); + +/// Append path that is being written to. +pub fn actively_writing_add(path: PathBuf) { + ACTIVELY_WRITING.lock().unwrap().data.push(path); +} + +/// Remove path to file that has finished writing and notify waiters. +pub fn actively_writing_remove(path: &Path) { + let mut guard = ACTIVELY_WRITING.lock().unwrap(); + guard.data.retain(|p| p != path); + guard.notify.notify_waiters(); +} + +/// Wait until the actively-writing queue is empty or a file has been removed. +pub async fn actively_writing_tick() { + let notify = (|| { + let guard = ACTIVELY_WRITING.lock().unwrap(); + + if !guard.data.is_empty() { + return Some(guard.notify.clone()); + } + + None + })(); + + if let Some(notify) = notify { + notify.notified().await + } +} + +/// Check if a file is being written to. Avoid thumbnail generation until after it is finished. +pub fn is_actively_writing_to(path: &Path) -> bool { + ACTIVELY_WRITING + .lock() + .unwrap() + .data + .iter() + .any(|p| p == path) +} diff --git a/src/operation/recursive.rs b/src/operation/recursive.rs index bbe89d1..a38ea74 100644 --- a/src/operation/recursive.rs +++ b/src/operation/recursive.rs @@ -334,12 +334,14 @@ impl Op { } match self.kind { OpKind::Copy => { + crate::operation::actively_writing_add(self.to.clone()); let result = self.copy(ctx, progress).await; if result.is_err() { _ = compio::fs::remove_file(&self.to).await; } + crate::operation::actively_writing_remove(&self.to); return result; } OpKind::Move { cross_device_copy } => { diff --git a/src/tab.rs b/src/tab.rs index a0f95a0..9d9d2a2 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -6771,6 +6771,10 @@ impl Tab { stream::channel( 1, move |mut output: futures::channel::mpsc::Sender<_>| async move { + while crate::operation::is_actively_writing_to(&path) { + crate::operation::actively_writing_tick().await; + } + let message = { let path = path.clone(); From e21989aaa31a830005bb912e275b30815d5639ac Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Fri, 10 Apr 2026 06:09:51 +0200 Subject: [PATCH 039/110] chore: use compio::fs::rename for quick renames --- src/operation/mod.rs | 64 +++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/src/operation/mod.rs b/src/operation/mod.rs index 1daed41..f9fae0d 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -114,7 +114,7 @@ async fn copy_or_move( ); // Handle duplicate file names by renaming paths - let mut from_to_pairs: Vec<(PathBuf, PathBuf)> = paths + let from_to_pairs_iter = paths .into_iter() .zip(std::iter::repeat(to.as_path())) .filter_map(|(from, to)| { @@ -132,36 +132,46 @@ async fn copy_or_move( //TODO: how to handle from missing file name? None } - }) - .collect(); + }); // Attempt quick and simple renames //TODO: allow rename to be used for directories in recursive context? - if matches!(method, Method::Move { .. }) { - from_to_pairs.retain(|(from, to)| { - //TODO: show replace dialog here? - if to.exists() { - return true; - } - //TODO: use compio::fs::rename? - match fs::rename(from, to) { - Ok(()) => { - log::info!("renamed {} to {}", from.display(), to.display()); - false + let from_to_pairs: Vec<(PathBuf, PathBuf)> = if matches!(method, Method::Move { .. }) { + from_to_pairs_iter + .map(|(from, to)| async move { + //TODO: show replace dialog here? + if to.exists() { + return Some((from, to)); } - Err(err) => { - log::info!( - "failed to rename {} to {}, fallback to recursive move: {}", - from.display(), - to.display(), - err - ); - true + + match compio::fs::rename(&from, &to).await { + Ok(()) => { + log::info!("renamed {} to {}", from.display(), to.display()); + None + } + Err(err) => { + log::info!( + "failed to rename {} to {}, fallback to recursive move: {}", + from.display(), + to.display(), + err + ); + Some((from, to)) + } } - } - }); - } + }) + .collect::>() + .fold(Vec::new(), |mut pairs, pair| async move { + if let Some(pair) = pair { + pairs.push(pair); + } + pairs + }) + .await + } else { + from_to_pairs_iter.collect() + }; let mut context = Context::new(controller.clone()); @@ -219,7 +229,7 @@ pub async fn sync_to_disk( } })) .buffer_unordered(32) - .collect::>() + .collect::<()>() .await; // Sync directories to disk @@ -229,7 +239,7 @@ pub async fn sync_to_disk( } })) .buffer_unordered(16) - .collect::>() + .collect::<()>() .await; } From 1c4ab758143244c4b7b0c612831fb5346b03d291 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 14 Apr 2026 17:15:19 +0200 Subject: [PATCH 040/110] fix: gate gio file copy fallback with gvfs feature --- src/operation/recursive.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/operation/recursive.rs b/src/operation/recursive.rs index a38ea74..9a33ebd 100644 --- a/src/operation/recursive.rs +++ b/src/operation/recursive.rs @@ -10,7 +10,6 @@ use compio::driver::{ToSharedFd, op::AsyncifyFd}; use compio::io::{AsyncReadAt, AsyncWriteAt}; use cosmic::iced::futures; use futures::{FutureExt, StreamExt}; -use gio::prelude::FileExtManual; use std::future::Future; use std::pin::Pin; use std::rc::Rc; @@ -18,10 +17,14 @@ use std::time::Instant; use std::{cell::Cell, error::Error, fs, ops::ControlFlow, path::PathBuf}; use walkdir::WalkDir; +#[cfg(feature = "gvfs")] +use gio::prelude::FileExtManual; + #[derive(thiserror::Error, Debug)] pub enum GioCopyError { #[error("controller state")] Controller(OperationError), + #[cfg(feature = "gvfs")] #[error("gio copy failed")] GLib(#[from] glib::Error), } @@ -508,6 +511,7 @@ impl Op { let buf_out = buf_out_slice.into_inner(); if let Err(why) = result { + #[cfg(feature = "gvfs")] if let std::io::ErrorKind::Unsupported = why.kind() { ctx.buf = buf_out; _ = futures::future::join(from_file.close(), to_file.close()).await; @@ -583,6 +587,7 @@ impl Op { /// Fallback mechanism in the event that unsupported I/O error errors occur. /// Fixes unsupported errors when copying large files over MTP. /// TODO: Find what Gio.File does to work around this. + #[cfg(feature = "gvfs")] async fn gio_file_copy( &self, ctx: &mut Context, From 908f30a571b496a3658ad60a1c7f6a10e92fde50 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 14 Apr 2026 17:47:50 +0200 Subject: [PATCH 041/110] example(dialog): switch logger to fix build --- examples/dialog.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/examples/dialog.rs b/examples/dialog.rs index d1d5515..be93576 100644 --- a/examples/dialog.rs +++ b/examples/dialog.rs @@ -9,9 +9,25 @@ use cosmic_files::dialog::{ Dialog, DialogChoice, DialogChoiceOption, DialogFilter, DialogFilterPattern, DialogKind, DialogMessage, DialogResult, DialogSettings, }; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; fn main() -> Result<(), Box> { - env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init(); + let log_format = tracing_subscriber::fmt::format() + .pretty() + .without_time() + .with_line_number(true) + .with_file(true) + .with_target(false) + .with_thread_names(true); + + let log_layer = tracing_subscriber::fmt::Layer::default() + .with_writer(std::io::stderr) + .event_format(log_format); + + tracing_subscriber::registry() + .with(tracing_subscriber::EnvFilter::from_env("RUST_LOG")) + .with(log_layer) + .init(); let settings = Settings::default(); app::run::(settings, ())?; From 33890633b5ee25a02126d6a8c01f38cf6cfaff23 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 14 Apr 2026 11:09:50 -0600 Subject: [PATCH 042/110] Epoch 1.0.11 version update Generated by cosmic-epoch scripts/version-update.sh --- Cargo.lock | 348 +++++++++++++++++---------------- Cargo.toml | 2 +- cosmic-files-applet/Cargo.toml | 2 +- debian/changelog | 6 + 4 files changed, 187 insertions(+), 171 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18345fc..0084c8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,7 +192,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" dependencies = [ "android-properties", - "bitflags 2.11.0", + "bitflags 2.11.1", "cc", "jni", "libc", @@ -361,7 +361,7 @@ dependencies = [ "enumflags2", "futures-channel", "futures-util", - "rand 0.9.2", + "rand 0.9.4", "raw-window-handle", "serde", "serde_repr", @@ -379,7 +379,7 @@ dependencies = [ "enumflags2", "futures-channel", "futures-util", - "rand 0.9.2", + "rand 0.9.4", "serde", "serde_repr", "tokio", @@ -696,20 +696,20 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" dependencies = [ "serde_core", ] [[package]] name = "bitstream-io" -version = "4.9.0" +version = "4.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757" +checksum = "7eff00be299a18769011411c9def0d827e8f2d7bf0c3dbf53633147a8867fd1f" dependencies = [ - "core2", + "no_std_io2", ] [[package]] @@ -879,7 +879,7 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "polling", "rustix 1.1.4", "slab", @@ -900,9 +900,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.59" +version = "1.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", "jobserver", @@ -1273,20 +1273,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "core-foundation 0.10.1", "libc", ] -[[package]] -name = "core2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" -dependencies = [ - "memchr", -] - [[package]] name = "core_affinity" version = "0.8.3" @@ -1312,7 +1303,7 @@ name = "cosmic-client-toolkit" version = "0.2.0" source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cosmic-protocols", "libc", "smithay-client-toolkit", @@ -1323,7 +1314,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1344,7 +1335,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "quote", "syn", @@ -1352,7 +1343,7 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.0.9" +version = "1.0.11" dependencies = [ "anyhow", "atomic_float", @@ -1419,7 +1410,7 @@ dependencies = [ [[package]] name = "cosmic-files-applet" -version = "1.0.9" +version = "1.0.11" dependencies = [ "cosmic-files", "log", @@ -1429,7 +1420,7 @@ dependencies = [ [[package]] name = "cosmic-freedesktop-icons" version = "0.4.0" -source = "git+https://github.com/pop-os/freedesktop-icons#7a61a704f6d1ec41f71cbe766e3cc484858523fa" +source = "git+https://github.com/pop-os/freedesktop-icons#9c562fe3ecf03241a46a60c0078cd6ea10bd75ce" dependencies = [ "bstr", "btoi", @@ -1456,7 +1447,7 @@ name = "cosmic-protocols" version = "0.2.0" source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -1491,7 +1482,7 @@ name = "cosmic-text" version = "0.18.2" source = "git+https://github.com/pop-os/cosmic-text.git#4d74f795cc771fdcc7ea0f9cacba63fcf036fad6" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "fontdb", "harfrust", "linebender_resource_handle", @@ -1512,7 +1503,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "almost", "configparser", @@ -1830,7 +1821,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.6.2", "libc", "objc2 0.6.4", @@ -1861,7 +1852,7 @@ name = "dnd" version = "0.1.0" source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "mime 0.1.0", "raw-window-handle", "smithay-client-toolkit", @@ -1886,7 +1877,7 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" version = "0.1.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" [[package]] name = "drm" @@ -1894,7 +1885,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytemuck", "drm-ffi", "drm-fourcc", @@ -2277,9 +2268,9 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "font-types" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d9237c6d82152100c691fb77ea18037b402bcc7257d2c876a4ffac81bc22a1c" +checksum = "5b38ad915f6dadd993ced50848a8291a543bd41ca62bc10740d5e64e2ab4cfd7" dependencies = [ "bytemuck", ] @@ -2653,7 +2644,7 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16de123c2e6c90ce3b573b7330de19be649080ec612033d397d72da265f1bd8b" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "futures-channel", "futures-core", "futures-executor", @@ -2748,7 +2739,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "gpu-alloc-types", ] @@ -2758,7 +2749,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -2779,7 +2770,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "gpu-descriptor-types", "hashbrown 0.15.5", ] @@ -2790,7 +2781,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -2827,7 +2818,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9da2e5ae821f6e96664977bf974d6d6a2d6682f9ccee23e62ec1d134246845f9" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytemuck", "core_maths", "read-fonts", @@ -2997,7 +2988,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "dnd", "iced_accessibility", @@ -3018,7 +3009,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "accesskit", "accesskit_winit", @@ -3027,9 +3018,9 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytes", "cosmic-client-toolkit", "dnd", @@ -3051,7 +3042,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "iced_core", "iced_futures", @@ -3061,7 +3052,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "futures", "iced_core", @@ -3075,9 +3066,9 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytemuck", "cosmic-text", "half", @@ -3096,7 +3087,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "iced_graphics", "iced_runtime", @@ -3105,7 +3096,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3117,7 +3108,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3132,7 +3123,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "bytemuck", "cosmic-text", @@ -3149,10 +3140,10 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "as-raw-xcb-connection", - "bitflags 2.11.0", + "bitflags 2.11.1", "bytemuck", "cosmic-client-toolkit", "cryoglyph", @@ -3180,7 +3171,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3198,7 +3189,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3699,6 +3690,15 @@ dependencies = [ "zune-jpeg 0.5.15", ] +[[package]] +name = "image-extras" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86d29ba92ef6970a2685cc758b455d190842b8b9e96c865ffd31cdb9954b7548" +dependencies = [ + "image", +] + [[package]] name = "image-webp" version = "0.2.4" @@ -3759,7 +3759,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd5b3eaf1a28b758ac0faa5a4254e8ab2705605496f1b1f3fbbc3988ad73d199" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "inotify-sys", "libc", ] @@ -3818,7 +3818,7 @@ version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdd7bddefd0a8833b88a4b68f90dae22c7450d11b354198baee3874fd811b344" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "libc", ] @@ -4002,9 +4002,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.94" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" +checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" dependencies = [ "cfg-if", "futures-util", @@ -4207,7 +4207,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fbe853b403ae61a04233030ae8a79d94975281ed9770a1f9e246732b534b28d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "serde", ] @@ -4298,20 +4298,20 @@ checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" [[package]] name = "libbz2-rs-sys" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" +checksum = "b3a6a8c165077efc8f3a971534c50ea6a1a18b329ef4a66e897a7e3a1494565f" [[package]] name = "libc" -version = "0.2.184" +version = "0.2.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#6caccaba337ed9bab21c5fe3c2aa7392e322e89c" +source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" dependencies = [ "apply", "ashpd 0.12.3", @@ -4339,6 +4339,7 @@ dependencies = [ "iced_widget", "iced_winit", "image", + "image-extras", "jiff", "libc", "log", @@ -4392,7 +4393,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "libc", "plain", "redox_syscall 0.7.4", @@ -4496,9 +4497,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" +checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" [[package]] name = "lyon" @@ -4650,7 +4651,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block", "core-graphics-types 0.2.0", "foreign-types", @@ -4735,7 +4736,7 @@ checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8" dependencies = [ "arrayvec", "bit-set", - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "codespan-reporting", @@ -4759,7 +4760,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "jni-sys 0.3.1", "log", "ndk-sys", @@ -4795,13 +4796,22 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "libc", "memoffset", ] +[[package]] +name = "no_std_io2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b51ed7824b6e07d354605f4abb3d9d300350701299da96642ee084f5ce631550" +dependencies = [ + "memchr", +] + [[package]] name = "nom" version = "7.1.3" @@ -4833,7 +4843,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "fsevent-sys", "inotify", "kqueue", @@ -4860,9 +4870,9 @@ dependencies = [ [[package]] name = "notify-rust" -version = "4.14.0" +version = "4.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b2c9bc1689653cfbc04400b8719f2562638ff9c545bbd48cc58c657a14526df" +checksum = "3c8146c105ae33d744e2d645f684d063b01176a99daf5986556266777b428816" dependencies = [ "futures-lite", "log", @@ -4878,7 +4888,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -5030,7 +5040,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -5046,7 +5056,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.6.2", "objc2 0.6.4", "objc2-core-foundation", @@ -5059,7 +5069,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -5071,7 +5081,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.6.2", "dispatch2", "objc2 0.6.4", @@ -5083,7 +5093,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "libc", "objc2-core-foundation", ] @@ -5106,7 +5116,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "objc2-core-foundation", "objc2-core-graphics", ] @@ -5123,7 +5133,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -5135,7 +5145,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.6.2", "libc", "objc2 0.6.4", @@ -5148,7 +5158,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -5160,7 +5170,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -5173,7 +5183,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "objc2 0.6.4", "objc2-core-foundation", "objc2-foundation 0.3.2", @@ -5416,7 +5426,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared 0.11.3", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -5526,9 +5536,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "plain" @@ -5555,7 +5565,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "crc32fast", "fdeflate", "flate2", @@ -5590,9 +5600,9 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ "portable-atomic", ] @@ -5704,7 +5714,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "chrono", "flate2", "procfs-core", @@ -5717,7 +5727,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "chrono", "hex", ] @@ -5743,9 +5753,9 @@ dependencies = [ [[package]] name = "pxfm" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a041e753da8b807c9255f28de81879c78c876392ff2469cde94799b2896b9d" +checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f" [[package]] name = "qoi" @@ -5823,9 +5833,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -5834,9 +5844,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -5919,7 +5929,7 @@ dependencies = [ "num-traits", "paste", "profiling", - "rand 0.9.2", + "rand 0.9.4", "rand_chacha 0.9.0", "simd_helpers", "thiserror 2.0.18", @@ -5950,9 +5960,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "rayon" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ "either", "rayon-core", @@ -6001,7 +6011,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -6010,7 +6020,7 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -6147,7 +6157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" dependencies = [ "base64", - "bitflags 2.11.0", + "bitflags 2.11.1", "serde", "serde_derive", "unicode-ident", @@ -6159,7 +6169,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "once_cell", "serde", "serde_derive", @@ -6234,7 +6244,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys 0.4.15", @@ -6247,7 +6257,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys 0.12.1", @@ -6266,7 +6276,7 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytemuck", "core_maths", "log", @@ -6573,7 +6583,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytemuck", "calloop", "calloop-wayland-source", @@ -6673,7 +6683,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", ] [[package]] @@ -7069,9 +7079,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.51.1" +version = "1.52.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" +checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" dependencies = [ "bytes", "libc", @@ -7458,9 +7468,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ "js-sys", "serde_core", @@ -7542,9 +7552,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" +checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" dependencies = [ "cfg-if", "once_cell", @@ -7555,9 +7565,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.67" +version = "0.4.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" +checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" dependencies = [ "js-sys", "wasm-bindgen", @@ -7565,9 +7575,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" +checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7575,9 +7585,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" +checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" dependencies = [ "bumpalo", "proc-macro2", @@ -7588,9 +7598,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.117" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" +checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" dependencies = [ "unicode-ident", ] @@ -7623,7 +7633,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "hashbrown 0.15.5", "indexmap 2.14.0", "semver", @@ -7663,7 +7673,7 @@ version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "rustix 1.1.4", "wayland-backend", "wayland-scanner", @@ -7675,7 +7685,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cursor-icon", "wayland-backend", ] @@ -7697,7 +7707,7 @@ version = "0.32.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "wayland-backend", "wayland-client", "wayland-scanner", @@ -7710,7 +7720,7 @@ version = "20250721.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7723,7 +7733,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7736,7 +7746,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7749,7 +7759,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7774,7 +7784,7 @@ version = "0.31.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc1846eb04c49182e04f4a099e2a830a2b745610bbc1d61246e206f29c7000a0" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "downcast-rs", "rustix 1.1.4", "wayland-backend", @@ -7795,9 +7805,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.94" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" +checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" dependencies = [ "js-sys", "wasm-bindgen", @@ -7826,7 +7836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77" dependencies = [ "arrayvec", - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "document-features", @@ -7857,7 +7867,7 @@ dependencies = [ "arrayvec", "bit-set", "bit-vec", - "bitflags 2.11.0", + "bitflags 2.11.1", "bytemuck", "cfg_aliases", "document-features", @@ -7917,7 +7927,7 @@ dependencies = [ "arrayvec", "ash", "bit-set", - "bitflags 2.11.0", + "bitflags 2.11.1", "block", "bytemuck", "cfg-if", @@ -7962,7 +7972,7 @@ version = "27.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytemuck", "js-sys", "log", @@ -8530,9 +8540,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cfg_aliases", "cursor-icon", "dpi", @@ -8556,10 +8566,10 @@ dependencies = [ [[package]] name = "winit-android" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "android-activity", - "bitflags 2.11.0", + "bitflags 2.11.1", "dpi", "ndk", "raw-window-handle", @@ -8571,9 +8581,9 @@ dependencies = [ [[package]] name = "winit-appkit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.6.2", "dispatch2", "dpi", @@ -8593,7 +8603,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#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "memmap2 0.9.10", "objc2 0.6.4", @@ -8608,9 +8618,9 @@ dependencies = [ [[package]] name = "winit-core" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cursor-icon", "dpi", "keyboard-types", @@ -8622,9 +8632,9 @@ dependencies = [ [[package]] name = "winit-orbital" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "dpi", "libredox", "orbclient", @@ -8638,9 +8648,9 @@ dependencies = [ [[package]] name = "winit-uikit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "block2 0.6.2", "dispatch2", "dpi", @@ -8658,10 +8668,10 @@ dependencies = [ [[package]] name = "winit-wayland" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "ahash", - "bitflags 2.11.0", + "bitflags 2.11.1", "calloop", "cursor-icon", "dpi", @@ -8684,10 +8694,10 @@ dependencies = [ [[package]] name = "winit-web" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "atomic-waker", - "bitflags 2.11.0", + "bitflags 2.11.1", "concurrent-queue", "cursor-icon", "dpi", @@ -8706,9 +8716,9 @@ dependencies = [ [[package]] name = "winit-win32" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "cursor-icon", "dpi", "raw-window-handle", @@ -8722,9 +8732,9 @@ dependencies = [ [[package]] name = "winit-x11" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "bytemuck", "calloop", "cursor-icon", @@ -8818,7 +8828,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.0", + "bitflags 2.11.1", "indexmap 2.14.0", "log", "serde", @@ -8991,7 +9001,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.11.0", + "bitflags 2.11.1", "dlib", "log", "once_cell", @@ -9099,7 +9109,7 @@ dependencies = [ "hex", "nix", "ordered-stream", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_repr", "sha1", diff --git a/Cargo.toml b/Cargo.toml index 74e554b..9ef9807 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.0.9" +version = "1.0.11" 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 952b380..b20226b 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files-applet" -version = "1.0.9" +version = "1.0.11" edition = "2024" [dependencies] diff --git a/debian/changelog b/debian/changelog index c9cdde6..bea1aee 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-files (1.0.11) noble; urgency=medium + + * Epoch 1.0.11 version update + + -- Jeremy Soller Tue, 14 Apr 2026 11:09:44 -0600 + cosmic-files (1.0.9) noble; urgency=medium * Epoch 1.0.9 version update From 9c0eb63b8259813503ccd4ed72830553b8263ff8 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 17 Apr 2026 12:01:28 -0600 Subject: [PATCH 043/110] Refactor trash handling to improve portability --- src/app.rs | 22 ++----- src/dialog.rs | 11 +--- src/lib.rs | 16 ++--- src/menu.rs | 3 +- src/operation/mod.rs | 4 +- src/tab.rs | 140 +++--------------------------------------- src/trash.rs | 143 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 173 insertions(+), 166 deletions(-) create mode 100644 src/trash.rs diff --git a/src/app.rs b/src/app.rs index 2ab62a6..af0ecbe 100644 --- a/src/app.rs +++ b/src/app.rs @@ -99,6 +99,7 @@ use crate::{ self, HOVER_DURATION, HeadingOptions, ItemMetadata, Location, SORT_OPTION_FALLBACK, SearchLocation, Tab, }, + trash::{Trash, TrashExt}, zoom::{zoom_in_view, zoom_out_view, zoom_to_default}, }; @@ -1794,7 +1795,7 @@ impl App { nav_model = nav_model.insert(|b| { b.text(fl!("trash")) - .icon(icon::icon(tab::trash_helpers::trash_icon_symbolic(16))) + .icon(icon::icon(Trash::icon_symbolic(16))) .data(Location::Trash) .divider_above() }); @@ -2655,9 +2656,7 @@ impl Application for App { )); } - if matches!(location_opt, Some(Location::Trash)) - && !trash::os_limited::is_empty().unwrap_or(true) - { + if matches!(location_opt, Some(Location::Trash)) && !Trash::is_empty() { items.push(cosmic::widget::menu::Item::Button( fl!("empty-trash"), None, @@ -4237,10 +4236,8 @@ impl Application for App { .is_some_and(|loc| matches!(loc, Location::Trash)) }); if let Some(entity) = maybe_entity { - self.nav_model.icon_set( - entity, - icon::icon(tab::trash_helpers::trash_icon_symbolic(16)), - ); + self.nav_model + .icon_set(entity, icon::icon(Trash::icon_symbolic(16))); } return Task::batch([self.rescan_trash(), self.update_desktop()]); @@ -6803,14 +6800,7 @@ impl Application for App { }, ); - // TODO: Trash watching support for Windows, macOS, and other OSes - #[cfg(all( - unix, - not(target_os = "macos"), - not(target_os = "ios"), - not(target_os = "android") - ))] - match (watcher_res, trash::os_limited::trash_folders()) { + match (watcher_res, Trash::folders()) { (Ok(mut watcher), Ok(trash_bins)) => { // Watch the "bins" themselves as well as the files folder where // trashed items are placed. This allows us to avoid recursively diff --git a/src/dialog.rs b/src/dialog.rs index f9894ac..cac5907 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -441,13 +441,8 @@ impl Dialog { #[derive(Clone, Debug)] enum DialogPage { - NewFolder { - parent: PathBuf, - name: String, - }, - Replace { - filename: String, - }, + NewFolder { parent: PathBuf, name: String }, + Replace { filename: String }, } #[derive(Clone, Debug)] @@ -2042,7 +2037,7 @@ impl Application for App { } col = col.push( - self.tab + self.tab .view(&self.key_binds, &self.modifiers, false, &[]) .map(Message::TabMessage), ); diff --git a/src/lib.rs b/src/lib.rs index 9214a7f..644b64d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,14 +5,18 @@ use cosmic::{app::Settings, iced::Limits}; use std::{env, fs, path::PathBuf, process}; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; -use app::{App, Flags}; +use crate::{ + app::{App, Flags}, + config::{Config, State}, + tab::Location, +}; + pub mod app; mod archive; pub mod channel; pub mod clipboard; -mod context_action; -use config::Config; pub mod config; +mod context_action; pub mod dialog; mod key_bind; pub(crate) mod large_image; @@ -25,13 +29,11 @@ mod mounter; mod mouse_area; pub mod operation; mod spawn_detached; -use tab::Location; -mod zoom; - -use crate::config::State; pub mod tab; mod thumbnail_cacher; mod thumbnailer; +pub(crate) mod trash; +mod zoom; pub(crate) type FxOrderMap = ordermap::OrderMap; diff --git a/src/menu.rs b/src/menu.rs index 8db61d7..89e4a02 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -23,6 +23,7 @@ use crate::{ config::{Config, ContextActionPreset}, fl, tab::{self, HeadingOptions, Location, LocationMenuAction, SearchLocation, Tab}, + trash::{Trash, TrashExt}, }; static MENU_ID: LazyLock = @@ -192,7 +193,7 @@ pub fn context_menu<'a>( ) => { if selected_trash_only { children.push(menu_item(fl!("open"), Action::Open).into()); - if !trash::os_limited::is_empty().unwrap_or(true) { + if !Trash::is_empty() { children.push(menu_item(fl!("empty-trash"), Action::EmptyTrash).into()); } } else if let Some(entry) = selected_desktop_entry { diff --git a/src/operation/mod.rs b/src/operation/mod.rs index f9fae0d..b4a66e9 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -1125,7 +1125,9 @@ impl Operation { #[cfg(target_os = "macos")] Self::Restore { .. } => { // TODO: add support for macos - return OperationError::from_msg("Restoring from trash is not supported on macos"); + return Err(OperationError::from_msg( + "Restoring from trash is not supported on macos", + )); } #[cfg(not(target_os = "macos"))] Self::Restore { items } => { diff --git a/src/tab.rs b/src/tab.rs index 9d9d2a2..a350f08 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -39,7 +39,6 @@ use icu::{ use image::{DynamicImage, ImageReader}; use jiff_icu::ConvertFrom; use mime_guess::{Mime, mime}; -use regex::Regex; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; use std::{ @@ -84,6 +83,7 @@ use crate::{ operation::{Controller, OperationError}, thumbnail_cacher::{CachedThumbnail, ThumbnailCacher, ThumbnailSize}, thumbnailer::thumbnailer, + trash::{Trash, TrashExt}, }; use uzers::{get_group_by_gid, get_user_by_uid}; @@ -1168,133 +1168,7 @@ pub fn scan_search bool + Sync>( } } SearchLocation::Trash => { - trash_helpers::scan_search_trash(callback, ®ex); - } - } -} - -// This config statement is from trash::os_limited, inverted -#[cfg(not(any( - target_os = "windows", - all( - unix, - not(target_os = "macos"), - not(target_os = "ios"), - not(target_os = "android") - ) -)))] -mod trash_helpers { - use super::*; - - pub fn trash_entries() -> usize { - 0 - } - - pub fn trash_icon(icon_size: u16) -> widget::icon::Handle { - widget::icon::from_name("user-trash") - .size(icon_size) - .handle() - } - - pub fn trash_icon_symbolic(icon_size: u16) -> widget::icon::Handle { - widget::icon::from_name("user-trash-symbolic") - .size(icon_size) - .handle() - } - - pub fn scan_trash(_sizes: IconSizes) -> Vec { - log::warn!("viewing trash not supported on this platform"); - Vec::new() - } - - pub fn scan_search_trash bool + Sync>(callback: F, regex: &Regex) {} -} - -// This config statement is from trash::os_limited -#[cfg(any( - target_os = "windows", - all( - unix, - not(target_os = "macos"), - not(target_os = "ios"), - not(target_os = "android") - ) -))] -pub mod trash_helpers { - use super::*; - - pub fn trash_entries() -> usize { - match trash::os_limited::list() { - Ok(entries) => entries.len(), - Err(_err) => 0, - } - } - - pub fn trash_icon(icon_size: u16) -> widget::icon::Handle { - widget::icon::from_name(if trash::os_limited::is_empty().unwrap_or(true) { - "user-trash" - } else { - "user-trash-full" - }) - .size(icon_size) - .handle() - } - - pub fn trash_icon_symbolic(icon_size: u16) -> widget::icon::Handle { - widget::icon::from_name(if trash::os_limited::is_empty().unwrap_or(true) { - "user-trash-symbolic" - } else { - "user-trash-full-symbolic" - }) - .size(icon_size) - .handle() - } - - pub fn scan_trash(sizes: IconSizes) -> Vec { - let entries = match trash::os_limited::list() { - Ok(entry) => entry, - Err(err) => { - log::warn!("failed to read trash items: {err}"); - return Vec::new(); - } - }; - let mut items: Vec<_> = entries - .into_iter() - .filter_map(|entry| { - let metadata = trash::os_limited::metadata(&entry) - .inspect_err(|err| { - log::warn!("failed to get metadata for trash item {entry:?}: {err}") - }) - .ok()?; - Some(item_from_trash_entry(entry, metadata, sizes)) - }) - .collect(); - items.sort_by(|a, b| match (a.metadata.is_dir(), b.metadata.is_dir()) { - (true, false) => Ordering::Less, - (false, true) => Ordering::Greater, - _ => LANGUAGE_SORTER.compare(&a.display_name, &b.display_name), - }); - items - } - - pub fn scan_search_trash bool + Sync>(callback: F, regex: &Regex) { - let entries = match trash::os_limited::list() { - Ok(entries) => entries, - Err(err) => { - log::warn!("failed to read trash items: {err}"); - return; - } - }; - - for entry in entries { - if let Ok(metadata) = trash::os_limited::metadata(&entry).inspect_err(|err| { - log::warn!("failed to get metadata for trash item {entry:?}: {err}") - }) { - let name = entry.name.to_string_lossy(); - if regex.is_match(&name) && !callback(SearchItem::Trash(entry, metadata)) { - break; - } - } + Trash::scan_search(callback, ®ex); } } } @@ -1432,15 +1306,15 @@ pub fn scan_desktop( let display_name = Item::display_name(&name); let metadata = ItemMetadata::SimpleDir { - entries: trash_helpers::trash_entries() as u64, + entries: Trash::entries() as u64, }; let (mime, icon_handle_grid, icon_handle_list, icon_handle_list_condensed) = { ( "inode/directory".parse().unwrap(), - trash_helpers::trash_icon(sizes.grid()), - trash_helpers::trash_icon(sizes.list()), - trash_helpers::trash_icon(sizes.list_condensed()), + Trash::icon(sizes.grid()), + Trash::icon(sizes.list()), + Trash::icon(sizes.list_condensed()), ) }; @@ -1681,7 +1555,7 @@ impl Location { // Search is done incrementally Vec::new() } - Self::Trash => trash_helpers::scan_trash(sizes), + Self::Trash => Trash::scan(sizes), Self::Recents => scan_recents(sizes), Self::Network(uri, _, _) => scan_network(uri, sizes), }; diff --git a/src/trash.rs b/src/trash.rs new file mode 100644 index 0000000..0262ba9 --- /dev/null +++ b/src/trash.rs @@ -0,0 +1,143 @@ +use cosmic::widget; +use regex::Regex; +use std::{collections::HashSet, path::PathBuf}; + +use crate::{ + config::IconSizes, + tab::{Item, SearchItem}, +}; + +pub trait TrashExt { + fn is_empty() -> bool { + true + } + + fn entries() -> usize { + 0 + } + + fn folders() -> Result, trash::Error> { + Err(trash::Error::Unknown { + description: "reading trash folders not supported on this platform".into(), + }) + } + + fn scan(_sizes: IconSizes) -> Vec { + log::warn!("viewing trash not supported on this platform"); + Vec::new() + } + + fn scan_search bool + Sync>(callback: F, regex: &Regex) {} + + fn icon(icon_size: u16) -> widget::icon::Handle { + widget::icon::from_name(if Self::is_empty() { + "user-trash" + } else { + "user-trash-full" + }) + .size(icon_size) + .handle() + } + + fn icon_symbolic(icon_size: u16) -> widget::icon::Handle { + widget::icon::from_name(if Self::is_empty() { + "user-trash-symbolic" + } else { + "user-trash-full-symbolic" + }) + .size(icon_size) + .handle() + } +} + +pub struct Trash; + +// This config statement is from trash::os_limited +#[cfg(any( + target_os = "windows", + all( + unix, + not(target_os = "macos"), + not(target_os = "ios"), + not(target_os = "android") + ) +))] +impl TrashExt for Trash { + fn is_empty() -> bool { + trash::os_limited::is_empty().unwrap_or(true) + } + + fn entries() -> usize { + match trash::os_limited::list() { + Ok(entries) => entries.len(), + Err(_err) => 0, + } + } + + fn folders() -> Result, trash::Error> { + trash::os_limited::trash_folders() + } + + fn scan(sizes: IconSizes) -> Vec { + use crate::{localize::LANGUAGE_SORTER, tab::item_from_trash_entry}; + use std::cmp::Ordering; + + let entries = match trash::os_limited::list() { + Ok(entry) => entry, + Err(err) => { + log::warn!("failed to read trash items: {err}"); + return Vec::new(); + } + }; + let mut items: Vec<_> = entries + .into_iter() + .filter_map(|entry| { + let metadata = trash::os_limited::metadata(&entry) + .inspect_err(|err| { + log::warn!("failed to get metadata for trash item {entry:?}: {err}") + }) + .ok()?; + Some(item_from_trash_entry(entry, metadata, sizes)) + }) + .collect(); + items.sort_by(|a, b| match (a.metadata.is_dir(), b.metadata.is_dir()) { + (true, false) => Ordering::Less, + (false, true) => Ordering::Greater, + _ => LANGUAGE_SORTER.compare(&a.display_name, &b.display_name), + }); + items + } + + fn scan_search bool + Sync>(callback: F, regex: &Regex) { + let entries = match trash::os_limited::list() { + Ok(entries) => entries, + Err(err) => { + log::warn!("failed to read trash items: {err}"); + return; + } + }; + + for entry in entries { + if let Ok(metadata) = trash::os_limited::metadata(&entry).inspect_err(|err| { + log::warn!("failed to get metadata for trash item {entry:?}: {err}") + }) { + let name = entry.name.to_string_lossy(); + if regex.is_match(&name) && !callback(SearchItem::Trash(entry, metadata)) { + break; + } + } + } + } +} + +// This config statement is from trash::os_limited, inverted +#[cfg(not(any( + target_os = "windows", + all( + unix, + not(target_os = "macos"), + not(target_os = "ios"), + not(target_os = "android") + ) +)))] +impl TrashExt for Trash {} From 62bfcc3550cdac1a492b1f4c040e09aa7de09bc3 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 17 Apr 2026 12:41:02 -0600 Subject: [PATCH 044/110] Put libcosmic/desktop behind desktop feature --- Cargo.toml | 3 +-- src/app.rs | 16 ++++++++++------ src/tab.rs | 19 ++++++++++++++++--- src/thumbnailer.rs | 1 + 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9ef9807..949f99d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,7 +81,6 @@ features = [ "about", "advanced-shaping", "autosize", - "desktop", "multi-window", "tokio", "winit", @@ -113,7 +112,7 @@ default = [ "wgpu", ] dbus-config = ["libcosmic/dbus-config"] -desktop = ["dep:cosmic-mime-apps", "dep:xdg"] +desktop = ["libcosmic/desktop", "dep:cosmic-mime-apps", "dep:xdg"] desktop-applet = [] gvfs = ["dep:gio", "dep:glib"] io-uring = ["compio/io-uring"] diff --git a/src/app.rs b/src/app.rs index af0ecbe..feca9c5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -18,9 +18,7 @@ use cosmic::{ Application, ApplicationExt, Element, app::{self, Core, Task, context_drawer}, cosmic_config::{self, ConfigSet}, - cosmic_theme, - desktop::fde::DesktopEntry, - executor, + cosmic_theme, executor, iced::core::widget::operation::focusable::unfocus, iced::runtime::{clipboard, task}, iced::widget::{button::focus, scrollable::AbsoluteOffset}, @@ -835,9 +833,12 @@ impl App { // First launch apps that can be launched directly if mime == "application/x-desktop" { - // Try opening desktop application - Self::launch_desktop_entries(&paths); - continue; + #[cfg(feature = "desktop")] + { + // Try opening desktop application + Self::launch_desktop_entries(&paths); + continue; + } } else if mime == "application/x-executable" || mime == "application/vnd.appimage" { // Try opening executable for path in paths { @@ -898,7 +899,10 @@ impl App { Task::batch(tasks) } + #[cfg(feature = "desktop")] fn launch_desktop_entries(paths: &[impl AsRef]) { + use cosmic::desktop::fde::DesktopEntry; + for path in paths.iter().map(AsRef::as_ref) { match DesktopEntry::from_path::<&str>(path, None) { Ok(entry) => match entry.exec() { diff --git a/src/tab.rs b/src/tab.rs index a350f08..2aeea04 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1,7 +1,7 @@ +#[cfg(feature = "desktop")] +use cosmic::desktop::fde::{DesktopEntry, get_languages_from_env}; use cosmic::{ - Apply, Element, cosmic_theme, - desktop::fde::{DesktopEntry, get_languages_from_env}, - font, + Apply, Element, cosmic_theme, font, iced::core::{mouse::ScrollDelta, widget::tree}, iced::{ Alignment, Border, Color, ContentFit, Length, Point, Rectangle, Size, Subscription, Vector, @@ -557,6 +557,12 @@ pub fn fs_kind(_metadata: &Metadata) -> FsKind { FsKind::Local } +#[cfg(not(feature = "desktop"))] +fn get_desktop_file_display_name(path: &Path) -> Option { + None +} + +#[cfg(feature = "desktop")] fn get_desktop_file_display_name(path: &Path) -> Option { let locales = get_languages_from_env(); let entry = match DesktopEntry::from_path(path, Some(&locales)) { @@ -570,6 +576,12 @@ fn get_desktop_file_display_name(path: &Path) -> Option { entry.name(&locales).map(|s| s.into_owned()) } +#[cfg(not(feature = "desktop"))] +fn get_desktop_file_icon(path: &Path) -> Option { + None +} + +#[cfg(feature = "desktop")] fn get_desktop_file_icon(path: &Path) -> Option { let entry = match DesktopEntry::from_path::<&str>(path, None) { Ok(ok) => ok, @@ -593,6 +605,7 @@ fn desktop_icon_handle(icon: &str, size: u16) -> widget::icon::Handle { } } +#[cfg(feature = "desktop")] pub fn parse_desktop_file(path: &Path) -> (Option, Option) { let locales = get_languages_from_env(); let entry = match DesktopEntry::from_path(path, Some(&locales)) { diff --git a/src/thumbnailer.rs b/src/thumbnailer.rs index f996f03..f7786ed 100644 --- a/src/thumbnailer.rs +++ b/src/thumbnailer.rs @@ -1,6 +1,7 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only +#[cfg(feature = "desktop")] use cosmic::desktop::fde::GenericEntry; use mime_guess::Mime; use rustc_hash::FxHashMap; From 8c57060db206c13a12a97c6946663a2197529a47 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 17 Apr 2026 12:48:39 -0600 Subject: [PATCH 045/110] Only use uzers on unix, do not fork on mac --- Cargo.toml | 2 +- src/lib.rs | 2 +- src/tab.rs | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 949f99d..c1b75ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,6 @@ rust-embed = "8" slotmap = "1.1.1" recently-used-xbel = "1.2.0" zip = "8" -uzers = "0.12.2" md-5 = "0.10.6" png = "0.18" jxl-oxide = { version = "0.12.5", features = ["image"] } @@ -130,6 +129,7 @@ debug = true [target.'cfg(unix)'.dependencies] fork = "0.7" +uzers = "0.12.2" [target.'cfg(target_os = "linux")'.dependencies] procfs = "0.18" diff --git a/src/lib.rs b/src/lib.rs index 644b64d..3e89861 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -191,7 +191,7 @@ pub fn main() -> Result<(), Box> { } if daemonize { - #[cfg(all(unix, not(target_os = "redox")))] + #[cfg(all(unix, not(any(target_os = "macos", target_os = "redox"))))] match fork::daemon(true, true) { Ok(fork::Fork::Child) => (), Ok(fork::Fork::Parent(_child_pid)) => process::exit(0), diff --git a/src/tab.rs b/src/tab.rs index 2aeea04..82dd03d 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -85,7 +85,6 @@ use crate::{ thumbnailer::thumbnailer, trash::{Trash, TrashExt}, }; -use uzers::{get_group_by_gid, get_user_by_uid}; pub const DOUBLE_CLICK_DURATION: Duration = Duration::from_millis(500); pub const HOVER_DURATION: Duration = Duration::from_millis(1600); @@ -2429,7 +2428,7 @@ impl Item { let mode = metadata.mode(); - let user_name = get_user_by_uid(metadata.uid()) + let user_name = uzers::get_user_by_uid(metadata.uid()) .and_then(|user| user.name().to_str().map(ToOwned::to_owned)) .unwrap_or_default(); let user_path = path.clone(); @@ -2452,7 +2451,7 @@ impl Item { )), ); - let group_name = get_group_by_gid(metadata.gid()) + let group_name = uzers::get_group_by_gid(metadata.gid()) .and_then(|group| group.name().to_str().map(ToOwned::to_owned)) .unwrap_or_default(); let group_path = path.clone(); @@ -6358,14 +6357,16 @@ impl Tab { total_size = total_size.saturating_add(metadata.len()); } let mode = metadata.mode(); + #[cfg(unix)] user_name.insert( - get_user_by_uid(metadata.uid()) + uzers::get_user_by_uid(metadata.uid()) .and_then(|user| user.name().to_str().map(ToOwned::to_owned)) .unwrap_or_default(), ); mode_user.insert(get_mode_part(mode, MODE_SHIFT_USER)); + #[cfg(unix)] group_name.insert( - get_group_by_gid(metadata.gid()) + uzers::get_group_by_gid(metadata.gid()) .and_then(|group| group.name().to_str().map(ToOwned::to_owned)) .unwrap_or_default(), ); From 4afacccc8adf2df7ef4c127f961d1cc2d20e5c89 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 17 Apr 2026 13:31:55 -0600 Subject: [PATCH 046/110] Fix windows compilation issues --- src/archive.rs | 14 ++++++++++---- src/mime_icon.rs | 25 ++++++++++++++++++++++++- src/tab.rs | 35 +++++++++++++++++++---------------- src/thumbnail_cacher.rs | 5 ++++- src/trash.rs | 2 ++ 5 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/archive.rs b/src/archive.rs index 92024d8..ba11cbb 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -189,6 +189,8 @@ fn zip_extract>( if file.is_symlink() && (cfg!(unix) || cfg!(windows)) { let mut target = Vec::with_capacity(file.size() as usize); file.read_to_end(&mut target)?; + // File no longer needed, drop to allow reading target on windows + drop(file); #[cfg(unix)] { @@ -199,11 +201,15 @@ fn zip_extract>( #[cfg(windows)] { let Ok(target) = String::from_utf8(target) else { - return Err(ZipError::InvalidArchive("Invalid UTF-8 as symlink target")); + return Err(ZipError::InvalidArchive( + "Invalid UTF-8 as symlink target".into(), + )); }; - let target = target.into_boxed_str(); - let target_is_dir_from_archive = - archive.shared.files.contains_key(&target) && is_dir(&target); + let target_is_dir_from_archive = match password { + None => archive.by_name(&target), + Some(pwd) => archive.by_name_decrypt(&target, pwd.as_bytes()), + } + .map_or(false, |x| x.is_dir()); let target_path = directory.as_ref().join(OsString::from(target.to_string())); let target_is_dir = if target_is_dir_from_archive { true diff --git a/src/mime_icon.rs b/src/mime_icon.rs index 52b1a27..8d8d2e5 100644 --- a/src/mime_icon.rs +++ b/src/mime_icon.rs @@ -19,6 +19,7 @@ struct MimeIconKey { struct MimeIconCache { cache: FxHashMap>, + #[cfg(unix)] shared_mime_info: xdg_mime::SharedMimeInfo, } @@ -26,10 +27,17 @@ impl MimeIconCache { pub fn new() -> Self { Self { cache: FxHashMap::default(), + #[cfg(unix)] shared_mime_info: xdg_mime::SharedMimeInfo::new(), } } + #[cfg(not(unix))] + pub fn get(&mut self, _key: MimeIconKey) -> Option { + None + } + + #[cfg(unix)] pub fn get(&mut self, key: MimeIconKey) -> Option { self.cache .entry(key) @@ -53,6 +61,16 @@ impl MimeIconCache { static MIME_ICON_CACHE: LazyLock> = LazyLock::new(|| Mutex::new(MimeIconCache::new())); +#[cfg(not(unix))] +pub fn mime_for_path( + path: impl AsRef, + metadata_opt: Option<&fs::Metadata>, + remote: bool, +) -> Mime { + mime_guess::from_path(path).first_or_octet_stream() +} + +#[cfg(unix)] pub fn mime_for_path( path: impl AsRef, metadata_opt: Option<&fs::Metadata>, @@ -100,8 +118,13 @@ pub fn mime_icon(mime: Mime, size: u16) -> icon::Handle { } } +#[cfg(not(unix))] +pub fn parent_mime_types(_mime: &Mime) -> Option> { + None +} + +#[cfg(unix)] pub fn parent_mime_types(mime: &Mime) -> Option> { let mime_icon_cache = MIME_ICON_CACHE.lock().unwrap(); - mime_icon_cache.shared_mime_info.get_parents_aliased(mime) } diff --git a/src/tab.rs b/src/tab.rs index 82dd03d..94eacdd 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -41,6 +41,8 @@ use jiff_icu::ConvertFrom; use mime_guess::{Mime, mime}; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; +#[cfg(unix)] +use std::os::unix::fs::MetadataExt; use std::{ borrow::Cow, cell::Cell, @@ -51,7 +53,6 @@ use std::{ fs::{self, File, Metadata}, hash::Hash, io::{BufRead, BufReader}, - os::unix::fs::MetadataExt, path::{self, Path, PathBuf}, sync::{Arc, LazyLock, RwLock, atomic}, time::{Duration, Instant, SystemTime}, @@ -4339,6 +4340,7 @@ impl Tab { for item in self.items_opt().map_or(Vec::new(), |items| { items.iter().filter(|item| item.selected).collect() }) { + #[cfg(unix)] if let (Some(path), Some(mode)) = ( item.path_opt(), item.file_metadata() @@ -6356,22 +6358,23 @@ impl Tab { } else { total_size = total_size.saturating_add(metadata.len()); } - let mode = metadata.mode(); #[cfg(unix)] - user_name.insert( - uzers::get_user_by_uid(metadata.uid()) - .and_then(|user| user.name().to_str().map(ToOwned::to_owned)) - .unwrap_or_default(), - ); - mode_user.insert(get_mode_part(mode, MODE_SHIFT_USER)); - #[cfg(unix)] - group_name.insert( - uzers::get_group_by_gid(metadata.gid()) - .and_then(|group| group.name().to_str().map(ToOwned::to_owned)) - .unwrap_or_default(), - ); - mode_group.insert(get_mode_part(mode, MODE_SHIFT_GROUP)); - mode_other.insert(get_mode_part(mode, MODE_SHIFT_OTHER)); + { + let mode = metadata.mode(); + user_name.insert( + uzers::get_user_by_uid(metadata.uid()) + .and_then(|user| user.name().to_str().map(ToOwned::to_owned)) + .unwrap_or_default(), + ); + mode_user.insert(get_mode_part(mode, MODE_SHIFT_USER)); + group_name.insert( + uzers::get_group_by_gid(metadata.gid()) + .and_then(|group| group.name().to_str().map(ToOwned::to_owned)) + .unwrap_or_default(), + ); + mode_group.insert(get_mode_part(mode, MODE_SHIFT_GROUP)); + mode_other.insert(get_mode_part(mode, MODE_SHIFT_OTHER)); + } } } let mut mime_types: Vec<(String, u64)> = mime_type_counts.into_iter().collect(); diff --git a/src/thumbnail_cacher.rs b/src/thumbnail_cacher.rs index 719bfc6..e4d616e 100644 --- a/src/thumbnail_cacher.rs +++ b/src/thumbnail_cacher.rs @@ -1,11 +1,12 @@ use image::DynamicImage; use md5::{Digest, Md5}; use rustc_hash::FxHashMap; +#[cfg(unix)] +use std::os::unix::fs::PermissionsExt; use std::{ error::Error, fs::{self, File}, io::{self, BufReader, BufWriter}, - os::unix::fs::PermissionsExt, path::{Path, PathBuf}, sync::LazyLock, time::UNIX_EPOCH, @@ -93,6 +94,7 @@ impl ThumbnailCacher { } pub fn update_with_temp_file(&self, temp_file: NamedTempFile) -> Result<&Path, Box> { + #[cfg(unix)] fs::set_permissions(temp_file.path(), fs::Permissions::from_mode(0o600))?; self.update_thumbnail_text_metadata(temp_file.path())?; fs::rename(temp_file.path(), &self.thumbnail_path)?; @@ -127,6 +129,7 @@ impl ThumbnailCacher { pub fn create_fail_marker(&self) -> Result<(), Box> { if let Some(dir) = self.thumbnail_fail_marker_path.parent() { fs::create_dir_all(dir)?; + #[cfg(unix)] fs::set_permissions(dir, fs::Permissions::from_mode(0o700))?; } diff --git a/src/trash.rs b/src/trash.rs index 0262ba9..ce37c83 100644 --- a/src/trash.rs +++ b/src/trash.rs @@ -74,6 +74,8 @@ impl TrashExt for Trash { } } + // Not available on Windows only + #[cfg(not(target_os = "windows"))] fn folders() -> Result, trash::Error> { trash::os_limited::trash_folders() } From 38e4fd3ec7c5a7d97bc34cc3af7134b2549ef726 Mon Sep 17 00:00:00 2001 From: Will Sheehan Date: Fri, 24 Apr 2026 23:15:31 -0700 Subject: [PATCH 047/110] Use name for network location if available --- src/app.rs | 2 ++ src/dialog.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/app.rs b/src/app.rs index feca9c5..c13d49d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1771,6 +1771,8 @@ impl App { 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 { diff --git a/src/dialog.rs b/src/dialog.rs index cac5907..35bf7e2 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -902,6 +902,8 @@ impl App { 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 { From accf5b2ba64e3dd3da99138eda010d87690a7469 Mon Sep 17 00:00:00 2001 From: Will Sheehan Date: Sat, 25 Apr 2026 00:00:29 -0700 Subject: [PATCH 048/110] Add button to clear recents --- i18n/en/cosmic_files.ftl | 3 +++ src/app.rs | 8 ++++++++ src/tab.rs | 23 +++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 69a76c6..2c86071 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -62,6 +62,9 @@ empty-trash = Empty trash empty-trash-title = Empty trash? empty-trash-warning = Items in the Trash folder will be permanently deleted +## Clear Recents +clear-recents = Clear Recents + ## Mount Error Dialog mount-error = Unable to access drive diff --git a/src/app.rs b/src/app.rs index feca9c5..cd01780 100644 --- a/src/app.rs +++ b/src/app.rs @@ -4588,6 +4588,14 @@ impl Application for App { tab::Command::DropFiles(to, from) => { commands.push(self.update(Message::PasteContents(to, from))); } + tab::Command::ClearRecents => { + match recently_used_xbel::clear_recently_used() { + Ok(()) => {} + Err(err) => { + log::warn!("failed to clear recents history: {}", err); + } + } + } tab::Command::EmptyTrash => { return self.push_dialog( DialogPage::EmptyTrash, diff --git a/src/tab.rs b/src/tab.rs index 94eacdd..51cbd24 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1683,6 +1683,7 @@ pub enum Command { ContextMenu(Option, Option), Delete(Vec), DropFiles(PathBuf, ClipboardPaste), + ClearRecents, EmptyTrash, #[cfg(feature = "desktop")] ExecEntryAction(cosmic::desktop::DesktopEntryData, usize), @@ -1722,6 +1723,7 @@ pub enum Message { EditLocationSubmit, EditLocationTab, OpenInNewTab(PathBuf), + ClearRecents, EmptyTrash, #[cfg(feature = "desktop")] ExecEntryAction(Option, usize), @@ -3697,6 +3699,9 @@ impl Tab { Message::OpenInNewTab(path) => { commands.push(Command::OpenInNewTab(path)); } + Message::ClearRecents => { + commands.push(Command::ClearRecents); + } Message::EmptyTrash => { commands.push(Command::EmptyTrash); } @@ -6216,6 +6221,24 @@ impl Tab { ); } } + Location::Recents | Location::Search(SearchLocation::Recents, ..) => { + if let Some(items) = self.items_opt() + && !items.is_empty() + { + tab_column = tab_column.push( + widget::layer_container(widget::row::with_children([ + widget::space::horizontal().into(), + widget::button::standard(fl!("clear-recents")) + .on_press(Message::ClearRecents) + .into(), + ])) + .padding([space_xxs, space_xs]) + .layer(cosmic_theme::Layer::Primary) + .apply(widget::container) + .padding([0, 0, 7, 0]), + ); + } + } Location::Network(uri, _display_name, _path) if uri == "network:///" => { tab_column = tab_column.push( widget::layer_container(widget::row::with_children([ From e7fa2d0fa5e1eb5352d34efff0380fc699323b47 Mon Sep 17 00:00:00 2001 From: Will Sheehan Date: Sat, 25 Apr 2026 00:11:05 -0700 Subject: [PATCH 049/110] Use existing clear-recents-history string --- i18n/en/cosmic_files.ftl | 3 --- src/tab.rs | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 2c86071..69a76c6 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -62,9 +62,6 @@ empty-trash = Empty trash empty-trash-title = Empty trash? empty-trash-warning = Items in the Trash folder will be permanently deleted -## Clear Recents -clear-recents = Clear Recents - ## Mount Error Dialog mount-error = Unable to access drive diff --git a/src/tab.rs b/src/tab.rs index 51cbd24..ccee41c 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -6228,7 +6228,7 @@ impl Tab { tab_column = tab_column.push( widget::layer_container(widget::row::with_children([ widget::space::horizontal().into(), - widget::button::standard(fl!("clear-recents")) + widget::button::standard(fl!("clear-recents-history")) .on_press(Message::ClearRecents) .into(), ])) From 93e31d433a5f388a71e661af37991233cbb29384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:42:39 +0200 Subject: [PATCH 050/110] chore: update dependencies --- Cargo.lock | 645 +++++++++++++++++++++++++++----------------------- Cargo.toml | 14 +- src/app.rs | 158 ++++++------- src/dialog.rs | 6 +- src/menu.rs | 6 +- src/tab.rs | 20 +- 6 files changed, 453 insertions(+), 396 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0084c8d..d2e592c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ dependencies = [ "accesskit_consumer", "atspi-common", "serde", - "zvariant 5.10.0", + "zvariant 5.10.1", ] [[package]] @@ -72,7 +72,7 @@ dependencies = [ "serde", "tokio", "tokio-stream", - "zbus 5.14.0", + "zbus 5.15.0", ] [[package]] @@ -109,13 +109,13 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aes" -version = "0.8.4" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8" dependencies = [ - "cfg-if", "cipher", - "cpufeatures", + "cpubits", + "cpufeatures 0.3.0", ] [[package]] @@ -179,6 +179,12 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "almost" version = "0.2.0" @@ -367,7 +373,7 @@ dependencies = [ "serde_repr", "tokio", "url", - "zbus 5.14.0", + "zbus 5.15.0", ] [[package]] @@ -387,7 +393,7 @@ dependencies = [ "wayland-backend", "wayland-client", "wayland-protocols", - "zbus 5.14.0", + "zbus 5.15.0", ] [[package]] @@ -573,11 +579,11 @@ dependencies = [ "enumflags2", "serde", "static_assertions", - "zbus 5.14.0", + "zbus 5.15.0", "zbus-lockstep", "zbus-lockstep-macros", - "zbus_names 4.3.1", - "zvariant 5.10.0", + "zbus_names 4.3.2", + "zvariant 5.10.1", ] [[package]] @@ -588,7 +594,7 @@ checksum = "2230e48787ed3eb4088996eab66a32ca20c0b67bbd4fd6cdfe79f04f1f04c9fc" dependencies = [ "atspi-common", "serde", - "zbus 5.14.0", + "zbus 5.15.0", ] [[package]] @@ -727,6 +733,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", + "zeroize", +] + [[package]] name = "block2" version = "0.5.1" @@ -900,9 +916,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.60" +version = "1.2.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" +checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" dependencies = [ "find-msvc-tools", "jobserver", @@ -959,11 +975,11 @@ dependencies = [ [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" dependencies = [ - "crypto-common", + "crypto-common 0.2.1", "inout", ] @@ -1005,6 +1021,12 @@ dependencies = [ "x11rb", ] +[[package]] +name = "cmov" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" + [[package]] name = "cocoa" version = "0.25.0" @@ -1211,6 +1233,12 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e57e3272f0190c3f1584272d613719ba5fc7df7f4942fe542e63d949cf3a649b" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "constant_time_eq" version = "0.4.2" @@ -1314,7 +1342,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1329,13 +1357,13 @@ dependencies = [ "tokio", "tracing", "xdg", - "zbus 5.14.0", + "zbus 5.15.0", ] [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "quote", "syn", @@ -1474,13 +1502,14 @@ name = "cosmic-settings-daemon" version = "0.1.0" source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" dependencies = [ - "zbus 5.14.0", + "zbus 5.15.0", ] [[package]] name = "cosmic-text" -version = "0.18.2" -source = "git+https://github.com/pop-os/cosmic-text.git#4d74f795cc771fdcc7ea0f9cacba63fcf036fad6" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be17b688510d934ce13f48a2beba700e11583e281e0fda99c22bb256a14eda73" dependencies = [ "bitflags 2.11.1", "fontdb", @@ -1503,7 +1532,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "almost", "configparser", @@ -1517,6 +1546,12 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "cpubits" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -1526,6 +1561,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -1578,7 +1622,7 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "cryoglyph" version = "0.1.0" -source = "git+https://github.com/pop-os/glyphon.git?tag=cosmic-0.14#c49de15bce4d8254ac136d1be9911960cc85ce12" +source = "git+https://github.com/iced-rs/cryoglyph.git?rev=e429a025df36ab8145708acb309080ae3deec17a#e429a025df36ab8145708acb309080ae3deec17a" dependencies = [ "cosmic-text", "etagere", @@ -1597,6 +1641,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "hybrid-array", +] + [[package]] name = "css-color" version = "0.2.8" @@ -1616,10 +1669,22 @@ dependencies = [ ] [[package]] -name = "ctor-lite" -version = "0.1.2" +name = "ctor" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e162d0c2e2068eb736b71e5597eff0b9944e6b973cd9f37b6a288ab9bf20e300" +checksum = "83cf0d42651b16c6dfe68685716d18480d18a9c39c62d76e8cf3eb6ed5d8bcbf" +dependencies = [ + "dtor", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] [[package]] name = "cursor-icon" @@ -1747,9 +1812,21 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "crypto-common", - "subtle", + "block-buffer 0.10.4", + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +dependencies = [ + "block-buffer 0.12.0", + "const-oid", + "crypto-common 0.2.1", + "ctutils", + "zeroize", ] [[package]] @@ -1918,6 +1995,12 @@ dependencies = [ "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" version = "1.0.20" @@ -2089,23 +2172,9 @@ checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "fax" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" -dependencies = [ - "fax_derive", -] - -[[package]] -name = "fax_derive" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a" [[package]] name = "fdeflate" @@ -2733,35 +2802,18 @@ dependencies = [ "system-deps", ] -[[package]] -name = "gpu-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" -dependencies = [ - "bitflags 2.11.1", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" -dependencies = [ - "bitflags 2.11.1", -] - [[package]] name = "gpu-allocator" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795" dependencies = [ + "ash", + "hashbrown 0.16.1", "log", "presser", - "thiserror 1.0.69", - "windows 0.58.0", + "thiserror 2.0.18", + "windows 0.62.2", ] [[package]] @@ -2786,9 +2838,9 @@ dependencies = [ [[package]] name = "grid" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e2d4c0a8296178d8802098410ca05d86b17a10bb5ab559b3fb404c1f948220" +checksum = "b40ca9252762c466af32d0b1002e91e4e1bc5398f77455e55474deb466355ff5" [[package]] name = "guillotiere" @@ -2846,6 +2898,8 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ + "allocator-api2", + "equivalent", "foldhash 0.2.0", ] @@ -2887,11 +2941,20 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest", + "digest 0.11.2", +] + +[[package]] +name = "hybrid-array" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" +dependencies = [ + "typenum", ] [[package]] @@ -2988,7 +3051,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "dnd", "iced_accessibility", @@ -3009,7 +3072,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "accesskit", "accesskit_winit", @@ -3018,7 +3081,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "bitflags 2.11.1", "bytes", @@ -3042,7 +3105,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "iced_core", "iced_futures", @@ -3052,7 +3115,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "futures", "iced_core", @@ -3066,7 +3129,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -3087,7 +3150,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "iced_graphics", "iced_runtime", @@ -3096,7 +3159,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3108,7 +3171,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3123,7 +3186,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "bytemuck", "cosmic-text", @@ -3140,7 +3203,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.1", @@ -3171,7 +3234,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3189,7 +3252,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3642,9 +3705,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -3775,11 +3838,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -3814,9 +3877,9 @@ dependencies = [ [[package]] name = "io-uring" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd7bddefd0a8833b88a4b68f90dae22c7450d11b354198baee3874fd811b344" +checksum = "4d09b98f7eace8982db770e4408e7470b028ce513ac28fecdc6bf4c30fe92b62" dependencies = [ "bitflags 2.11.1", "cfg-if", @@ -3882,9 +3945,9 @@ checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1" [[package]] name = "jiff" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" +checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" dependencies = [ "jiff-static", "jiff-tzdb-platform", @@ -3908,9 +3971,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" +checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" dependencies = [ "proc-macro2", "quote", @@ -4002,9 +4065,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" dependencies = [ "cfg-if", "futures-util", @@ -4304,14 +4367,14 @@ checksum = "b3a6a8c165077efc8f3a971534c50ea6a1a18b329ef4a66e897a7e3a1494565f" [[package]] name = "libc" -version = "0.2.185" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#c423ad1bfc25057922406c687f2ddc75ead5ab67" +source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" dependencies = [ "apply", "ashpd 0.12.3", @@ -4358,7 +4421,7 @@ dependencies = [ "tracing", "unicode-segmentation", "url", - "zbus 5.14.0", + "zbus 5.15.0", ] [[package]] @@ -4609,7 +4672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if", - "digest", + "digest 0.10.7", ] [[package]] @@ -4647,9 +4710,9 @@ dependencies = [ [[package]] name = "metal" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" +checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15" dependencies = [ "bitflags 2.11.1", "block", @@ -4730,9 +4793,9 @@ checksum = "13d2233c9842d08cfe13f9eac96e207ca6a2ea10b80259ebe8ad0268be27d2af" [[package]] name = "naga" -version = "27.0.3" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8" +checksum = "618f667225063219ddfc61251087db8a9aec3c3f0950c916b614e403486f1135" dependencies = [ "arrayvec", "bit-set", @@ -4870,16 +4933,16 @@ dependencies = [ [[package]] name = "notify-rust" -version = "4.15.0" +version = "4.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8146c105ae33d744e2d645f684d063b01176a99daf5986556266777b428816" +checksum = "5e551a9f0db223eaf3eb156906f99f46897fd951ee66dd1cb0be14db4d36d2fa" dependencies = [ "futures-lite", "log", "mac-notification-sys", "serde", "tauri-winrt-notification", - "zbus 5.14.0", + "zbus 5.15.0", ] [[package]] @@ -5212,9 +5275,9 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "open" -version = "5.3.3" +version = "5.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bb73a7fa3799b198970490a51174027ba0d4ec504b03cd08caf513d40024bc" +checksum = "9f3bab717c29a857abf75fcef718d441ec7cb2725f937343c734740a985d37fd" dependencies = [ "is-wsl", "libc", @@ -5229,9 +5292,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" -version = "0.3.51" +version = "0.3.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59aed3b33578edcfa1bc96a321d590d31832b6ad55a26f0313362ce687e9abd6" +checksum = "12c6933ddbbd16539a7672e697bb8d41ac3a4e99ac43eeb40c07236bd7fcb2dd" dependencies = [ "libc", "libredox", @@ -5384,11 +5447,11 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pbkdf2" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +checksum = "112d82ceb8c5bf524d9af484d4e4970c9fd5a0cc15ba14ad93dccd28873b0629" dependencies = [ - "digest", + "digest 0.11.2", "hmac", ] @@ -5798,7 +5861,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" dependencies = [ "memchr", - "serde", ] [[package]] @@ -5808,6 +5870,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" dependencies = [ "memchr", + "serde", ] [[package]] @@ -6460,8 +6523,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.2", ] [[package]] @@ -6471,8 +6545,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", ] [[package]] @@ -6641,7 +6715,7 @@ dependencies = [ [[package]] name = "softbuffer" version = "0.4.1" -source = "git+https://github.com/pop-os/softbuffer?tag=cosmic-4.0#a3f77e251e7422803f693df6e3fc313c010c4dcb" +source = "git+https://github.com/pop-os/softbuffer?tag=cosmic-4.0#c2b2c19ddb38ff17495643699f97cb1f2064a1be" dependencies = [ "as-raw-xcb-connection", "bytemuck", @@ -6713,12 +6787,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - [[package]] name = "svg_fmt" version = "0.4.5" @@ -6871,9 +6939,9 @@ dependencies = [ [[package]] name = "test-log" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d53ac171c92a39e4769491c4b4dde7022c60042254b5fc044ae409d34a24d4" +checksum = "2f46bf474f0a4afebf92f076d54fd5e63423d9438b8c278a3d2ccb0f47f7cdb3" dependencies = [ "env_logger", "test-log-macros", @@ -6881,16 +6949,26 @@ dependencies = [ ] [[package]] -name = "test-log-macros" -version = "0.2.19" +name = "test-log-core" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be35209fd0781c5401458ab66e4f98accf63553e8fae7425503e92fdd319783b" +checksum = "37d4d41320b48bc4a211a9021678fcc0c99569b594ea31c93735b8e517102b4c" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "test-log-macros" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9beb9249a81e430dffd42400a49019bcf548444f1968ff23080a625de0d4d320" +dependencies = [ + "syn", + "test-log-core", +] + [[package]] name = "thin-cell" version = "0.1.2" @@ -7040,12 +7118,12 @@ dependencies = [ [[package]] name = "tiny-xlib" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0324504befd01cab6e0c994f34b2ffa257849ee019d3fb3b64fb2c858887d89e" +checksum = "a90a0ca3ee6a69f2ad28fd11621a4c3f03b371f366be500b64df260c4ffbafb4" dependencies = [ "as-raw-xcb-connection", - "ctor-lite", + "ctor", "libloading", "pkg-config", "tracing", @@ -7137,7 +7215,7 @@ dependencies = [ "toml_datetime", "toml_parser", "toml_writer", - "winnow 1.0.1", + "winnow", ] [[package]] @@ -7158,7 +7236,7 @@ dependencies = [ "indexmap 2.14.0", "toml_datetime", "toml_parser", - "winnow 1.0.1", + "winnow", ] [[package]] @@ -7167,7 +7245,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.1", + "winnow", ] [[package]] @@ -7287,9 +7365,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "uds_windows" @@ -7534,11 +7612,11 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.57.1", ] [[package]] @@ -7547,14 +7625,14 @@ version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.51.0", ] [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" dependencies = [ "cfg-if", "once_cell", @@ -7565,9 +7643,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.68" +version = "0.4.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084" dependencies = [ "js-sys", "wasm-bindgen", @@ -7575,9 +7653,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7585,9 +7663,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" dependencies = [ "bumpalo", "proc-macro2", @@ -7598,9 +7676,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" dependencies = [ "unicode-ident", ] @@ -7805,9 +7883,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.95" +version = "0.3.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +checksum = "2eadbac71025cd7b0834f20d1fe8472e8495821b4e9801eb0a60bd1f19827602" dependencies = [ "js-sys", "wasm-bindgen", @@ -7831,12 +7909,13 @@ checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] name = "wgpu" -version = "27.0.1" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77" +checksum = "f9cb534d5ffd109c7d1135f34cdae29e60eab94855a625dcfe1705f8bc7ad79f" dependencies = [ "arrayvec", "bitflags 2.11.1", + "bytemuck", "cfg-if", "cfg_aliases", "document-features", @@ -7860,9 +7939,9 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "27.0.3" +version = "28.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27a75de515543b1897b26119f93731b385a19aea165a1ec5f0e3acecc229cae7" +checksum = "d23f4642f53f666adcfd2d3218ab174d1e6681101aef18696b90cbe64d1c10f9" dependencies = [ "arrayvec", "bit-set", @@ -7892,36 +7971,36 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0772ae958e9be0c729561d5e3fd9a19679bcdfb945b8b1a1969d9bfe8056d233" +checksum = "87b7b696b918f337c486bf93142454080a32a37832ba8a31e4f48221890047da" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06ac3444a95b0813ecfd81ddb2774b66220b264b3e2031152a4a29fda4da6b5" +checksum = "34b251c331f84feac147de3c4aa3aa45112622a95dd7ee1b74384fa0458dbd79" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71197027d61a71748e4120f05a9242b2ad142e3c01f8c1b47707945a879a03c3" +checksum = "68ca976e72b2c9964eb243e281f6ce7f14a514e409920920dcda12ae40febaae" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-hal" -version = "27.0.4" +version = "28.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b21cb61c57ee198bc4aff71aeadff4cbb80b927beb912506af9c780d64313ce" +checksum = "44d6cb474beb218824dcc9e1ce679d973f719262789bfb27407da560cac20eeb" dependencies = [ "android_system_properties", "arrayvec", @@ -7935,7 +8014,6 @@ dependencies = [ "core-graphics-types 0.2.0", "glow", "glutin_wgl_sys", - "gpu-alloc", "gpu-allocator", "gpu-descriptor", "hashbrown 0.16.1", @@ -7962,21 +8040,20 @@ dependencies = [ "wasm-bindgen", "web-sys", "wgpu-types", - "windows 0.58.0", - "windows-core 0.58.0", + "windows 0.62.2", + "windows-core 0.62.2", ] [[package]] name = "wgpu-types" -version = "27.0.1" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb" +checksum = "e18308757e594ed2cd27dddbb16a139c42a683819d32a2e0b1b0167552f5840c" dependencies = [ "bitflags 2.11.1", "bytemuck", "js-sys", "log", - "thiserror 2.0.18", "web-sys", ] @@ -8042,27 +8119,29 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows" version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ - "windows-collections", + "windows-collections 0.2.0", "windows-core 0.61.2", - "windows-future", + "windows-future 0.2.1", "windows-link 0.1.3", - "windows-numerics", + "windows-numerics 0.2.0", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections 0.3.2", + "windows-core 0.62.2", + "windows-future 0.3.2", + "windows-numerics 0.3.1", ] [[package]] @@ -8074,6 +8153,15 @@ dependencies = [ "windows-core 0.61.2", ] +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", +] + [[package]] name = "windows-core" version = "0.56.0" @@ -8086,19 +8174,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-core" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" -dependencies = [ - "windows-implement 0.58.0", - "windows-interface 0.58.0", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows-core" version = "0.61.2" @@ -8133,7 +8208,18 @@ checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core 0.61.2", "windows-link 0.1.3", - "windows-threading", + "windows-threading 0.1.0", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", + "windows-threading 0.2.1", ] [[package]] @@ -8147,17 +8233,6 @@ dependencies = [ "syn", ] -[[package]] -name = "windows-implement" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-implement" version = "0.60.2" @@ -8180,17 +8255,6 @@ dependencies = [ "syn", ] -[[package]] -name = "windows-interface" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-interface" version = "0.59.3" @@ -8225,19 +8289,20 @@ dependencies = [ ] [[package]] -name = "windows-result" -version = "0.1.2" +name = "windows-numerics" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ - "windows-targets 0.52.6", + "windows-core 0.62.2", + "windows-link 0.2.1", ] [[package]] name = "windows-result" -version = "0.2.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" dependencies = [ "windows-targets 0.52.6", ] @@ -8260,16 +8325,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows-strings" version = "0.4.2" @@ -8390,6 +8445,15 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-version" version = "0.1.7" @@ -8754,18 +8818,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.15" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" dependencies = [ "memchr", ] @@ -8779,6 +8834,12 @@ dependencies = [ "wit-bindgen-rust-macro", ] +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + [[package]] name = "wit-bindgen-core" version = "0.51.0" @@ -9112,7 +9173,7 @@ dependencies = [ "rand 0.8.6", "serde", "serde_repr", - "sha1", + "sha1 0.10.6", "static_assertions", "tracing", "uds_windows", @@ -9125,9 +9186,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.14.0" +version = "5.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca82f95dbd3943a40a53cfded6c2d0a2ca26192011846a1810c4256ef92c60bc" +checksum = "c3bcbf15c8708d7fc1be0c993622e0a5cbd5e8b52bfa40afa4c3e0cd8d724ac1" dependencies = [ "async-broadcast", "async-executor", @@ -9153,10 +9214,10 @@ dependencies = [ "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow 0.7.15", - "zbus_macros 5.14.0", - "zbus_names 4.3.1", - "zvariant 5.10.0", + "winnow", + "zbus_macros 5.15.0", + "zbus_names 4.3.2", + "zvariant 5.10.1", ] [[package]] @@ -9166,7 +9227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6998de05217a084b7578728a9443d04ea4cd80f2a0839b8d78770b76ccd45863" dependencies = [ "zbus_xml", - "zvariant 5.10.0", + "zvariant 5.10.1", ] [[package]] @@ -9180,7 +9241,7 @@ dependencies = [ "syn", "zbus-lockstep", "zbus_xml", - "zvariant 5.10.0", + "zvariant 5.10.1", ] [[package]] @@ -9198,17 +9259,17 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.14.0" +version = "5.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897e79616e84aac4b2c46e9132a4f63b93105d54fe8c0e8f6bffc21fa8d49222" +checksum = "51fa5406ad9175a8c825a931f8cf347116b531b3634fcb0b627c290f1f2516ff" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", "syn", - "zbus_names 4.3.1", - "zvariant 5.10.0", - "zvariant_utils 3.3.0", + "zbus_names 4.3.2", + "zvariant 5.10.1", + "zvariant_utils 3.3.1", ] [[package]] @@ -9224,25 +9285,25 @@ dependencies = [ [[package]] name = "zbus_names" -version = "4.3.1" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" +checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d" dependencies = [ "serde", - "winnow 0.7.15", - "zvariant 5.10.0", + "winnow", + "zvariant 5.10.1", ] [[package]] name = "zbus_xml" -version = "5.1.0" +version = "5.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "441a0064125265655bccc3a6af6bef56814d9277ac83fce48b1cd7e160b80eac" +checksum = "a8067892e940ed1727dea64690378601603b31d62dfde019a5335fbb7c0e0ed9" dependencies = [ - "quick-xml 0.38.4", + "quick-xml 0.39.2", "serde", - "zbus_names 4.3.1", - "zvariant 5.10.0", + "zbus_names 4.3.2", + "zvariant 5.10.1", ] [[package]] @@ -9335,9 +9396,9 @@ dependencies = [ [[package]] name = "zip" -version = "8.5.1" +version = "8.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcab981e19633ebcf0b001ddd37dd802996098bc1864f90b7c5d970ce76c1d59" +checksum = "2d04a6b5381502aa6087c94c669499eb1602eb9c5e8198e534de571f7154809b" dependencies = [ "aes", "bzip2", @@ -9352,7 +9413,7 @@ dependencies = [ "memchr", "pbkdf2", "ppmd-rust", - "sha1", + "sha1 0.11.0", "time", "typed-path", "zeroize", @@ -9466,17 +9527,17 @@ dependencies = [ [[package]] name = "zvariant" -version = "5.10.0" +version = "5.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5708299b21903bbe348e94729f22c49c55d04720a004aa350f1f9c122fd2540b" +checksum = "c4db0ecb8987cf5e92653c57c098f7f0e39a03112edb796f4fe089fb7eaa14ff" dependencies = [ "endi", "enumflags2", "serde", "url", - "winnow 0.7.15", - "zvariant_derive 5.10.0", - "zvariant_utils 3.3.0", + "winnow", + "zvariant_derive 5.10.1", + "zvariant_utils 3.3.1", ] [[package]] @@ -9494,15 +9555,15 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "5.10.0" +version = "5.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b59b012ebe9c46656f9cc08d8da8b4c726510aef12559da3e5f1bf72780752c" +checksum = "5b949b639ab1b4bed763aa7481ba0e368af68d8b55532f8ed4bec86a59f2ca98" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", "syn", - "zvariant_utils 3.3.0", + "zvariant_utils 3.3.1", ] [[package]] @@ -9518,13 +9579,13 @@ dependencies = [ [[package]] name = "zvariant_utils" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" +checksum = "6d464f5733ffa07a3164d656f18533caace9d0638596721355d73256a410d691" dependencies = [ "proc-macro2", "quote", "serde", "syn", - "winnow 0.7.15", + "winnow", ] diff --git a/Cargo.toml b/Cargo.toml index c1b75ae..0ccd0d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,13 +4,13 @@ version = "1.0.11" authors = ["Jeremy Soller "] edition = "2024" license = "GPL-3.0-only" -rust-version = "1.90" +rust-version = "1.93" [dependencies] anyhow = "1" jiff = "0.2" jiff-icu = "0.2" -icu = { version = "2.1.1", features = ["compiled_data"] } +icu = { version = "2.2.0", features = ["compiled_data"] } cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "160b086", optional = true } cosmic-mime-apps = { git = "https://github.com/pop-os/cosmic-mime-apps.git", optional = true } dirs = "6.0.0" @@ -24,7 +24,7 @@ log = "0.4" mime_guess = "2" notify-debouncer-full = "0.7" notify-rust = { version = "4", optional = true } -open = "5.3.3" +open = "5.3.4" paste = "1.0" regex = "1" rustc-hash = "2.1" @@ -36,15 +36,15 @@ tokio = { version = "1", features = ["process", "sync"] } trash = { git = "https://github.com/jackpot51/trash-rs.git", branch = "cosmic" } url = "2.5" walkdir = "2.5.0" -wayland-client = { version = "0.31.13", optional = true } +wayland-client = { version = "0.31.14", optional = true } xdg = { version = "3.0", optional = true } xdg-mime = { git = "https://github.com/ebassi/xdg-mime-rs" } # Compression bzip2 = { version = "0.6", optional = true } #TODO: replace with pure Rust crate flate2 = "1.1" -tar = "0.4.44" +tar = "0.4.45" lzma-rust2 = { version = "0.16", optional = true } -ordermap = { version = "1.1.0", features = ["serde"] } +ordermap = { version = "1.2.0", features = ["serde"] } # Internationalization i18n-embed = { version = "0.16", features = [ "fluent-system", @@ -61,7 +61,7 @@ jxl-oxide = { version = "0.12.5", features = ["image"] } num_cpus = "1.17.0" filetime = "0.2" tracing = "0.1.44" -tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } +tracing-subscriber = { version = "0.3.23", features = ["env-filter"] } thiserror = "2.0.18" atomic_float = "1.1.0" num_enum = "0.7.6" diff --git a/src/app.rs b/src/app.rs index feca9c5..4157a70 100644 --- a/src/app.rs +++ b/src/app.rs @@ -41,7 +41,7 @@ use cosmic::{ icon, menu::{action::MenuAction, key_bind::KeyBind}, segmented_button::{self, Entity, ReorderEvent}, - space, + settings, space, }, }; use mime_guess::Mime; @@ -1946,7 +1946,7 @@ impl App { fn network_drive(&self) -> Element<'_, Message> { let cosmic_theme::Spacing { space_xxs, space_m, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let mut table = widget::column::with_capacity(8); for (i, line) in fl!("network-drive-schemes").lines().enumerate() { let mut row = widget::row::with_capacity(2); @@ -1977,25 +1977,23 @@ impl App { fn desktop_view_options(&self) -> Element<'_, Message> { let cosmic_theme::Spacing { space_m, space_l, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let config = self.config.desktop; - let mut column = widget::column::with_capacity(2); - - let mut section = widget::settings::section().title(fl!("show-on-desktop")); - section = section.add( - widget::settings::item::builder(fl!("desktop-folder-content")).toggler( - config.show_content, - move |show_content| { - Message::DesktopConfig(DesktopConfig { - show_content, - ..config - }) - }, - ), - ); - section = section.add( - widget::settings::item::builder(fl!("mounted-drives")).toggler( + let show_on_desktop = settings::section() + .title(fl!("show-on-desktop")) + .add( + settings::item::builder(fl!("desktop-folder-content")).toggler( + config.show_content, + move |show_content| { + Message::DesktopConfig(DesktopConfig { + show_content, + ..config + }) + }, + ), + ) + .add(settings::item::builder(fl!("mounted-drives")).toggler( config.show_mounted_drives, move |show_mounted_drives| { Message::DesktopConfig(DesktopConfig { @@ -2003,10 +2001,8 @@ impl App { ..config }) }, - ), - ); - section = section.add( - widget::settings::item::builder(fl!("trash-folder-icon")).toggler( + )) + .add(settings::item::builder(fl!("trash-folder-icon")).toggler( config.show_trash, move |show_trash| { Message::DesktopConfig(DesktopConfig { @@ -2014,50 +2010,49 @@ impl App { ..config }) }, - ), - ); - column = column.push(section); + )); - let mut section = widget::settings::section().title(fl!("icon-size-and-spacing")); let icon_size = config.icon_size; - section = section.add( - widget::settings::item::builder(fl!("icon-size")) - .description(format!("{icon_size}%")) - .control( - widget::slider(50..=500, icon_size.get(), move |new_value| { - Message::DesktopConfig(DesktopConfig { - icon_size: NonZeroU16::new(new_value).unwrap_or(icon_size), - ..config - }) - }) - .step(25u16), - ), - ); - let grid_spacing = config.grid_spacing; - section = section.add( - widget::settings::item::builder(fl!("grid-spacing")) - .description(format!("{grid_spacing}%")) - .control( - widget::slider(50..=500, grid_spacing.get(), move |new_value| { - Message::DesktopConfig(DesktopConfig { - grid_spacing: NonZeroU16::new(new_value).unwrap_or(grid_spacing), - ..config + let icon_size_and_spacing = settings::section() + .title(fl!("icon-size-and-spacing")) + .add( + settings::item::builder(fl!("icon-size")) + .description(format!("{icon_size}%")) + .control( + widget::slider(50..=500, icon_size.get(), move |new_value| { + Message::DesktopConfig(DesktopConfig { + icon_size: NonZeroU16::new(new_value).unwrap_or(icon_size), + ..config + }) }) - }) - .step(25u16), - ), - ); - column = column.push(section); + .step(25u16), + ), + ) + .add( + settings::item::builder(fl!("grid-spacing")) + .description(format!("{grid_spacing}%")) + .control( + widget::slider(50..=500, grid_spacing.get(), move |new_value| { + Message::DesktopConfig(DesktopConfig { + grid_spacing: NonZeroU16::new(new_value).unwrap_or(grid_spacing), + ..config + }) + }) + .step(25u16), + ), + ); - column + widget::column::with_capacity(2) .padding([0, space_l, space_l, space_l]) .spacing(space_m) + .push(show_on_desktop) + .push(icon_size_and_spacing) .into() } fn edit_history(&self) -> Element<'_, Message> { - let cosmic_theme::Spacing { space_m, .. } = theme::active().cosmic().spacing; + let cosmic_theme::Spacing { space_m, .. } = theme::spacing(); let mut children = Vec::new(); @@ -2149,7 +2144,7 @@ impl App { kind: &'a PreviewKind, context_drawer: bool, ) -> Element<'a, tab::Message> { - let cosmic_theme::Spacing { space_l, .. } = theme::active().cosmic().spacing; + let cosmic_theme::Spacing { space_l, .. } = theme::spacing(); let mut children = Vec::with_capacity(1); let entity = entity_opt.unwrap_or_else(|| self.tab_model.active()); @@ -2219,8 +2214,8 @@ impl App { let tab_config = self.config.tab; // TODO: Should dialog be updated here too? - widget::settings::view_column(vec![ - widget::settings::section() + settings::view_column(vec![ + settings::section() .title(fl!("appearance")) .add({ let app_theme_selected = match self.config.app_theme { @@ -2228,7 +2223,7 @@ impl App { AppTheme::Light => 2, AppTheme::System => 0, }; - widget::settings::item::builder(fl!("theme")).control(widget::dropdown( + settings::item::builder(fl!("theme")).control(widget::dropdown( &self.app_themes, Some(app_theme_selected), move |index| { @@ -2241,31 +2236,32 @@ impl App { )) }) .into(), - widget::settings::section() + settings::section() .title(fl!("type-to-search")) - .add(widget::radio( - widget::text::body(fl!("type-to-search-recursive")), - TypeToSearch::Recursive, - Some(self.config.type_to_search), - Message::SetTypeToSearch, - )) - .add(widget::radio( - widget::text::body(fl!("type-to-search-enter-path")), - TypeToSearch::EnterPath, - Some(self.config.type_to_search), - Message::SetTypeToSearch, - )) - .add(widget::radio( - widget::text::body(fl!("type-to-search-select")), + .add( + settings::item::builder(fl!("type-to-search-recursive")).radio( + TypeToSearch::Recursive, + Some(self.config.type_to_search), + Message::SetTypeToSearch, + ), + ) + .add( + settings::item::builder(fl!("type-to-search-enter-path")).radio( + TypeToSearch::EnterPath, + Some(self.config.type_to_search), + Message::SetTypeToSearch, + ), + ) + .add(settings::item::builder(fl!("type-to-search-select")).radio( TypeToSearch::SelectByPrefix, Some(self.config.type_to_search), Message::SetTypeToSearch, )) .into(), - widget::settings::section() + settings::section() .title(fl!("other")) .add({ - widget::settings::item::builder(fl!("single-click")).toggler( + settings::item::builder(fl!("single-click")).toggler( tab_config.single_click, move |single_click| { Message::TabConfig(TabConfig { @@ -2276,7 +2272,7 @@ impl App { ) }) .add({ - widget::settings::item::builder(fl!("show-recents")) + settings::item::builder(fl!("show-recents")) .toggler(self.config.show_recents, Message::SetShowRecents) }) .into(), @@ -5526,7 +5522,7 @@ impl Application for App { let cosmic_theme::Spacing { space_xxs, space_s, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let dialog = match dialog_page { DialogPage::Compress { @@ -6288,7 +6284,7 @@ impl Application for App { let cosmic_theme::Spacing { space_xs, space_s, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let mut title = String::new(); let mut total_progress = 0.0; @@ -6445,7 +6441,7 @@ impl Application for App { fn view(&self) -> Element<'_, Self::Message> { let cosmic_theme::Spacing { space_xxs, space_s, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let mut tab_column = widget::column::with_capacity(4); diff --git a/src/dialog.rs b/src/dialog.rs index cac5907..976caf4 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -587,7 +587,7 @@ impl App { space_s, space_l, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let is_condensed = self.core().is_condensed(); let mut col = widget::column::with_capacity(2).spacing(space_xxs); @@ -1125,7 +1125,7 @@ impl Application for App { } fn dialog(&self) -> Option> { - let cosmic_theme::Spacing { space_xxs, .. } = theme::active().cosmic().spacing; + let cosmic_theme::Spacing { space_xxs, .. } = theme::spacing(); //TODO: should gallery view just be a dialog? if self.tab.gallery { @@ -2017,7 +2017,7 @@ impl Application for App { /// Creates a view after each update. fn view(&self) -> Element<'_, Message> { - let cosmic_theme::Spacing { space_xxs, .. } = theme::active().cosmic().spacing; + let cosmic_theme::Spacing { space_xxs, .. } = theme::spacing(); let mut col = widget::column::with_capacity(2); diff --git a/src/menu.rs b/src/menu.rs index 89e4a02..b9c735a 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -38,7 +38,7 @@ macro_rules! menu_button { .height(Length::Fixed(24.0)) .align_y(Alignment::Center) ) - .padding([theme::active().cosmic().spacing.space_xxs, 16]) + .padding([theme::spacing().space_xxs, 16]) .width(Length::Fill) .class(theme::Button::MenuItem) ); @@ -579,7 +579,7 @@ pub fn dialog_menu( ]) .item_height(ItemHeight::Dynamic(40)) .item_width(ItemWidth::Uniform(360)) - .spacing(theme::active().cosmic().spacing.space_xxxs.into()) + .spacing(theme::spacing().space_xxxs.into()) .into() } @@ -634,7 +634,7 @@ pub fn menu_bar<'a>( responsive_menu_bar() .item_height(ItemHeight::Dynamic(40)) .item_width(ItemWidth::Uniform(360)) - .spacing(theme::active().cosmic().spacing.space_xxxs.into()) + .spacing(theme::spacing().space_xxxs.into()) .into_element( core, key_binds, diff --git a/src/tab.rs b/src/tab.rs index 94eacdd..58b2dee 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2278,7 +2278,7 @@ impl Item { } fn preview(&self) -> Element<'_, Message> { - let spacing = cosmic::theme::active().cosmic().spacing; + let spacing = cosmic::theme::spacing(); // This loads the image only if thumbnailing worked let icon = widget::icon::icon(self.icon_handle_grid.clone()) .content_fit(ContentFit::Contain) @@ -2339,7 +2339,7 @@ impl Item { space_xxxs, space_m, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let mut column = widget::column::with_capacity(4).spacing(space_m); @@ -2517,7 +2517,7 @@ impl Item { } pub fn replace_view(&self, heading: String, military_time: bool) -> Element<'_, Message> { - let cosmic_theme::Spacing { space_xxxs, .. } = theme::active().cosmic().spacing; + let cosmic_theme::Spacing { space_xxxs, .. } = theme::spacing(); let mut row = widget::row::with_capacity(2).spacing(space_xxxs); row = row.push(self.preview()); @@ -4765,7 +4765,7 @@ impl Tab { space_xs, space_m, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); //TODO: display error messages when image not found? let mut name_opt = None; @@ -4963,7 +4963,7 @@ impl Tab { space_s, space_m, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let size = self.size_opt.get().unwrap_or(Size::new(0.0, 0.0)); @@ -5298,7 +5298,7 @@ impl Tab { } pub fn empty_view(&self, has_hidden: bool) -> Element<'_, Message> { - let cosmic_theme::Spacing { space_xxs, .. } = theme::active().cosmic().spacing; + let cosmic_theme::Spacing { space_xxs, .. } = theme::spacing(); mouse_area::MouseArea::new(widget::column::with_children([widget::container( match self.mode { @@ -5338,7 +5338,7 @@ impl Tab { space_xxs, space_xxxs, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let TabConfig { show_hidden, @@ -5684,7 +5684,7 @@ impl Tab { ) { let cosmic_theme::Spacing { space_s, space_xxs, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let TabConfig { show_hidden, @@ -6086,7 +6086,7 @@ impl Tab { space_xxs, space_xs, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let location_view_opt = if matches!(self.mode, Mode::Desktop) { None @@ -6282,7 +6282,7 @@ impl Tab { space_xxxs, space_m, .. - } = theme::active().cosmic().spacing; + } = theme::spacing(); let mut column = widget::column::with_capacity(4).spacing(space_m); From e91a984da9a13157d8473427591a1d0a17855554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Tue, 28 Apr 2026 14:45:01 +0200 Subject: [PATCH 051/110] chore: clippy --- src/app.rs | 6 ++-- src/clipboard.rs | 2 +- src/menu.rs | 9 +++--- src/operation/recursive.rs | 12 +++---- src/tab.rs | 66 +++++++++++++++++--------------------- src/trash.rs | 2 +- 6 files changed, 45 insertions(+), 52 deletions(-) diff --git a/src/app.rs b/src/app.rs index 4157a70..e259dc2 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1401,7 +1401,7 @@ impl App { // Manually rescan any trash tabs after any operation is completed commands.push(self.rescan_trash()); - return Task::batch(commands); + Task::batch(commands) } fn handle_operation_errors(&mut self, errors: Vec<(u64, OperationError)>) -> Task { @@ -1446,7 +1446,7 @@ impl App { } // Manually rescan any trash tabs after any operation is completed tasks.push(self.rescan_trash()); - return Task::batch(tasks); + Task::batch(tasks) } fn remove_window(&mut self, id: &window::Id) { @@ -5661,7 +5661,7 @@ impl Application for App { } DialogPage::FailedOperations(ids) => { let errors: Vec = ids - .into_iter() + .iter() .filter_map(|id| match self.failed_operations.get(id) { Some((operation, _, err)) => Some(format!("{operation:#?}\n{err}")), _ => None, diff --git a/src/clipboard.rs b/src/clipboard.rs index 5892071..7e21276 100644 --- a/src/clipboard.rs +++ b/src/clipboard.rs @@ -132,7 +132,7 @@ impl TryFrom<(Vec, String)> for ClipboardPaste { match mime.as_str() { "text/uri-list" => { let text = str::from_utf8(&data)?; - let lines = text.lines(); + let _lines = text.lines(); for line in text.lines() { let url = Url::parse(line)?; diff --git a/src/menu.rs b/src/menu.rs index b9c735a..9f3f158 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -143,12 +143,11 @@ pub fn context_menu<'a>( Some(Location::Trash) | Some(Location::Search(SearchLocation::Trash, ..)) => { selected_trash_only = true } - Some(Location::Path(path)) => { + Some(Location::Path(path)) if selected == 1 - && path.extension().and_then(|s| s.to_str()) == Some("desktop") - { - selected_desktop_entry = Some(&**path); - } + && path.extension().and_then(|s| s.to_str()) == Some("desktop") => + { + selected_desktop_entry = Some(&**path); } _ => (), } diff --git a/src/operation/recursive.rs b/src/operation/recursive.rs index 9a33ebd..047d09b 100644 --- a/src/operation/recursive.rs +++ b/src/operation/recursive.rs @@ -473,12 +473,12 @@ impl Op { progress.total_bytes = metadata.as_ref().map(|m| m.len()); (ctx.on_progress)(self, &progress); - if let Some(metadata) = metadata.as_ref() { - if let Err(why) = to_file.set_permissions(metadata.permissions()).await { - // This error is not propagated upwards as some filesystems do not support setting permissions - if !matches!(why.kind(), std::io::ErrorKind::Unsupported) { - tracing::warn!(?why, "failed to set permissions for {}", self.to.display(),); - } + if let Some(metadata) = metadata.as_ref() + && let Err(why) = to_file.set_permissions(metadata.permissions()).await + { + // This error is not propagated upwards as some filesystems do not support setting permissions + if !matches!(why.kind(), std::io::ErrorKind::Unsupported) { + tracing::warn!(?why, "failed to set permissions for {}", self.to.display(),); } } diff --git a/src/tab.rs b/src/tab.rs index 58b2dee..91164c8 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2991,10 +2991,10 @@ impl Tab { return None; }; let search_items = after - .into_iter() + .iter_mut() .enumerate() .map(|(i, item)| (i + start, item)) - .chain(until.into_iter().enumerate()); + .chain(until.iter_mut().enumerate()); if forward { Self::select_first_prefix_match(prefix_lower, search_items) @@ -3011,7 +3011,7 @@ impl Tab { items: impl Iterator, ) -> Option { for (i, item) in items { - if item.name.to_lowercase().starts_with(&prefix) { + if item.name.to_lowercase().starts_with(prefix) { item.selected = true; return Some(i); } @@ -4332,7 +4332,7 @@ impl Tab { Message::ShiftPermissions(path_mode_opt, shift, bits) => match path_mode_opt { Some((path, mode)) => commands.push(Command::SetPermissions( path, - set_mode_part(mode, shift, bits.try_into().unwrap()), + set_mode_part(mode, shift, bits), )), // Shift permissions on all selected items None => { @@ -4343,13 +4343,9 @@ impl Tab { #[cfg(unix)] if let (Some(path), Some(mode)) = ( item.path_opt(), - item.file_metadata() - .and_then(|metadata| Some(metadata.mode())), + item.file_metadata().map(|metadata| metadata.mode()), ) { - permissions.push(( - path.clone(), - set_mode_part(mode, shift, bits.try_into().unwrap()), - )); + permissions.push((path.clone(), set_mode_part(mode, shift, bits))); } } commands.push(Command::SetMultiplePermissions(permissions)); @@ -6415,33 +6411,31 @@ impl Tab { let mut settings = Vec::new(); // Only allow modifying open-with if all mime types are the same - if mime_types.len() == 1 { - if let Some(mime) = mime_types - .get(0) + if mime_types.len() == 1 + && let Some(mime) = mime_types + .first() .and_then(|(mime, _)| mime.parse::().ok()) - { - if let Some(mime_app_cache) = mime_app_cache_opt { - let mime_apps = mime_app_cache.get(&mime); - if !mime_apps.is_empty() { - let mime_closure = mime.clone(); - settings.push( - widget::settings::item::builder(fl!("open-with")).control( - Element::from( - widget::dropdown( - mime_apps, - mime_apps.iter().position(|x| x.is_default), - move |index| (index, mime_closure.clone()), - ) - .icons(Cow::Borrowed(mime_app_cache.icons(&mime))), - ) - .map(|(index, mime)| { - let mime_app = &mime_apps[index]; - Message::SetOpenWith(mime, mime_app.id.clone()) - }), - ), - ); - } - } + && let Some(mime_app_cache) = mime_app_cache_opt + { + let mime_apps = mime_app_cache.get(&mime); + if !mime_apps.is_empty() { + let mime_closure = mime.clone(); + settings.push( + widget::settings::item::builder(fl!("open-with")).control( + Element::from( + widget::dropdown( + mime_apps, + mime_apps.iter().position(|x| x.is_default), + move |index| (index, mime_closure.clone()), + ) + .icons(Cow::Borrowed(mime_app_cache.icons(&mime))), + ) + .map(|(index, mime)| { + let mime_app = &mime_apps[index]; + Message::SetOpenWith(mime, mime_app.id.clone()) + }), + ), + ); } } diff --git a/src/trash.rs b/src/trash.rs index ce37c83..f46bc48 100644 --- a/src/trash.rs +++ b/src/trash.rs @@ -27,7 +27,7 @@ pub trait TrashExt { Vec::new() } - fn scan_search bool + Sync>(callback: F, regex: &Regex) {} + fn scan_search bool + Sync>(_callback: F, _regex: &Regex) {} fn icon(icon_size: u16) -> widget::icon::Handle { widget::icon::from_name(if Self::is_empty() { From d5dbcc76776b3e014b99945f7ca0c069f72aac68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:05:08 +0200 Subject: [PATCH 052/110] chore: add rustfmt config Also adds a Zed editor config for automatic formatting with nightly. --- .zed/settings.json | 15 ++++ build.rs | 3 +- examples/copy.rs | 8 +- examples/dialog.rs | 13 ++-- rustfmt.toml | 1 + src/app.rs | 154 ++++++++++++++++--------------------- src/archive.rs | 25 +++--- src/channel.rs | 10 +-- src/clipboard.rs | 10 +-- src/config.rs | 22 +++--- src/context_action.rs | 3 +- src/dialog.rs | 80 ++++++++----------- src/key_bind.rs | 11 ++- src/large_image.rs | 6 +- src/lib.rs | 17 ++-- src/load_image.rs | 9 +-- src/localize.rs | 13 ++-- src/menu.rs | 37 ++++----- src/mime_app.rs | 13 ++-- src/mime_icon.rs | 8 +- src/mounter/gvfs.rs | 26 ++++--- src/mounter/mod.rs | 16 ++-- src/mouse_area.rs | 24 +++--- src/operation/mod.rs | 54 ++++++------- src/operation/reader.rs | 3 +- src/operation/recursive.rs | 9 ++- src/tab.rs | 139 +++++++++++++++------------------ src/thumbnail_cacher.rs | 14 ++-- src/thumbnailer.rs | 11 +-- src/trash.rs | 12 +-- src/zoom.rs | 3 +- 31 files changed, 349 insertions(+), 420 deletions(-) create mode 100644 .zed/settings.json create mode 100644 rustfmt.toml diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 0000000..2cc7b98 --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,15 @@ +{ + "format_on_save": "on", + "lsp": { + "rust-analyzer": { + "initialization_options": { + "check": { + "command": "clippy", + }, + "rustfmt": { + "extraArgs": ["+nightly"], + }, + }, + }, + }, +} diff --git a/build.rs b/build.rs index 5edc53b..206e897 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,5 @@ -use std::{env, fs, path::PathBuf}; +use std::path::PathBuf; +use std::{env, fs}; use xdgen::{App, Context, FluentString}; fn main() { diff --git a/examples/copy.rs b/examples/copy.rs index 6396209..7f37abd 100644 --- a/examples/copy.rs +++ b/examples/copy.rs @@ -1,6 +1,8 @@ -use cosmic_files::operation::recursive::Method; -use cosmic_files::operation::{Controller, ReplaceResult, recursive::Context}; -use std::{error::Error, io, path::PathBuf}; +use cosmic_files::operation::recursive::{Context, Method}; +use cosmic_files::operation::{Controller, ReplaceResult}; +use std::error::Error; +use std::io; +use std::path::PathBuf; #[compio::main] async fn main() -> Result<(), Box> { diff --git a/examples/dialog.rs b/examples/dialog.rs index be93576..df77069 100644 --- a/examples/dialog.rs +++ b/examples/dialog.rs @@ -1,15 +1,12 @@ -use cosmic::{ - Application, Element, - app::{self, Core, Settings, Task}, - executor, - iced::{Subscription, window}, - widget, -}; +use cosmic::app::{self, Core, Settings, Task}; +use cosmic::iced::{Subscription, window}; +use cosmic::{Application, Element, executor, widget}; use cosmic_files::dialog::{ Dialog, DialogChoice, DialogChoiceOption, DialogFilter, DialogFilterPattern, DialogKind, DialogMessage, DialogResult, DialogSettings, }; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; fn main() -> Result<(), Box> { let log_format = tracing_subscriber::fmt::format() diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..c1578aa --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +imports_granularity = "Module" diff --git a/src/app.rs b/src/app.rs index e259dc2..fcc411f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,8 +1,23 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only +use cosmic::app::{self, Core, Task, context_drawer}; +use cosmic::cosmic_config::{self, ConfigSet}; +use cosmic::iced::clipboard::dnd::DndAction; +use cosmic::iced::core::SmolStr; +use cosmic::iced::core::widget::operation::focusable::unfocus; +use cosmic::iced::futures::{self, SinkExt}; +use cosmic::iced::keyboard::{Event as KeyEvent, Key, Modifiers}; #[cfg(all(feature = "wayland", feature = "desktop-applet"))] use cosmic::iced::platform_specific::shell::wayland::commands::overlap_notify::overlap_notify; +use cosmic::iced::runtime::{clipboard, task}; +use cosmic::iced::widget::button::focus; +use cosmic::iced::widget::scrollable; +use cosmic::iced::widget::scrollable::AbsoluteOffset; +use cosmic::iced::window::{self, Event as WindowEvent, Id as WindowId}; +use cosmic::iced::{ + self, Alignment, Event, Length, Rectangle, Size, Subscription, event, mouse, stream, +}; #[cfg(all(feature = "wayland", feature = "desktop-applet"))] use cosmic::iced::{ Limits, Point, @@ -14,92 +29,59 @@ use cosmic::iced::{ Anchor, KeyboardInteractivity, Layer, destroy_layer_surface, get_layer_surface, }, }; -use cosmic::{ - Application, ApplicationExt, Element, - app::{self, Core, Task, context_drawer}, - cosmic_config::{self, ConfigSet}, - cosmic_theme, executor, - iced::core::widget::operation::focusable::unfocus, - iced::runtime::{clipboard, task}, - iced::widget::{button::focus, scrollable::AbsoluteOffset}, - iced::{ - self, Alignment, Event, Length, Rectangle, Size, Subscription, - clipboard::dnd::DndAction, - core::SmolStr, - event, - futures::{self, SinkExt}, - keyboard::{Event as KeyEvent, Key, Modifiers}, - mouse, stream, - widget::scrollable, - window::{self, Event as WindowEvent, Id as WindowId}, - }, - style, surface, theme, - widget::{ - self, - about::About, - dnd_destination::DragId, - icon, - menu::{action::MenuAction, key_bind::KeyBind}, - segmented_button::{self, Entity, ReorderEvent}, - settings, space, - }, -}; +use cosmic::widget::about::About; +use cosmic::widget::dnd_destination::DragId; +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 mime_guess::Mime; -use notify_debouncer_full::{ - DebouncedEvent, Debouncer, RecommendedCache, new_debouncer, - notify::{self, RecommendedWatcher}, -}; +use notify_debouncer_full::notify::{self, RecommendedWatcher}; +use notify_debouncer_full::{DebouncedEvent, Debouncer, RecommendedCache, new_debouncer}; use rustc_hash::{FxHashMap, FxHashSet}; use slotmap::Key as SlotMapKey; -use std::{ - any::TypeId, - collections::{BTreeMap, BTreeSet, HashMap, VecDeque}, - env, fmt, fs, - future::Future, - io, - num::NonZeroU16, - path::{Path, PathBuf}, - pin::Pin, - process, - sync::{Arc, LazyLock, Mutex}, - time::{self, Duration, Instant}, -}; +use std::any::TypeId; +use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque}; +use std::future::Future; +use std::num::NonZeroU16; +use std::path::{Path, PathBuf}; +use std::pin::Pin; +use std::sync::{Arc, LazyLock, Mutex}; +use std::time::{self, Duration, Instant}; +use std::{env, fmt, fs, io, process}; use tokio::sync::mpsc; use trash::TrashItem; #[cfg(all(feature = "wayland", feature = "desktop-applet"))] use wayland_client::{Proxy, protocol::wl_output::WlOutput}; -use crate::{ - FxOrderMap, - clipboard::{ - ClipboardCache, ClipboardCopy, ClipboardKind, ClipboardPaste, ClipboardPasteImage, - ClipboardPasteText, ClipboardPasteVideo, - }, - config::{ - AppTheme, Config, DesktopConfig, Favorite, IconSizes, State, TIME_CONFIG_ID, TabConfig, - TimeConfig, TypeToSearch, - }, - context_action, - dialog::{Dialog, DialogKind, DialogMessage, DialogResult, DialogSettings}, - fl, home_dir, - key_bind::key_binds, - localize::LANGUAGE_SORTER, - menu, - mime_app::{self, MimeApp, MimeAppCache}, - mime_icon, - mounter::{MOUNTERS, MounterAuth, MounterItem, MounterItems, MounterKey, MounterMessage}, - operation::{ - Controller, Operation, OperationError, OperationErrorType, OperationSelection, - ReplaceResult, copy_unique_path, - }, - spawn_detached::spawn_detached, - tab::{ - self, HOVER_DURATION, HeadingOptions, ItemMetadata, Location, SORT_OPTION_FALLBACK, - SearchLocation, Tab, - }, - trash::{Trash, TrashExt}, - zoom::{zoom_in_view, zoom_out_view, zoom_to_default}, +use crate::clipboard::{ + ClipboardCache, ClipboardCopy, ClipboardKind, ClipboardPaste, ClipboardPasteImage, + ClipboardPasteText, ClipboardPasteVideo, }; +use crate::config::{ + AppTheme, Config, DesktopConfig, Favorite, IconSizes, State, TIME_CONFIG_ID, TabConfig, + TimeConfig, TypeToSearch, +}; +use crate::dialog::{Dialog, DialogKind, DialogMessage, DialogResult, DialogSettings}; +use crate::key_bind::key_binds; +use crate::localize::LANGUAGE_SORTER; +use crate::mime_app::{self, MimeApp, MimeAppCache}; +use crate::mounter::{ + MOUNTERS, MounterAuth, MounterItem, MounterItems, MounterKey, MounterMessage, +}; +use crate::operation::{ + Controller, Operation, OperationError, OperationErrorType, OperationSelection, ReplaceResult, + copy_unique_path, +}; +use crate::spawn_detached::spawn_detached; +use crate::tab::{ + self, HOVER_DURATION, HeadingOptions, ItemMetadata, Location, SORT_OPTION_FALLBACK, + SearchLocation, Tab, +}; +use crate::trash::{Trash, TrashExt}; +use crate::zoom::{zoom_in_view, zoom_out_view, zoom_to_default}; +use crate::{FxOrderMap, context_action, fl, home_dir, menu, mime_icon}; static PERMANENT_DELETE_BUTTON_ID: LazyLock = LazyLock::new(|| widget::Id::new("permanent-delete-button")); @@ -7033,21 +7015,17 @@ impl Application for App { // Ideally, tests would use the cap-std crate which limits path traversal. #[cfg(test)] pub(crate) mod test_utils { - use std::{ - cmp::Ordering, - fs::File, - io::{self, Write}, - iter, - path::Path, - }; + use std::cmp::Ordering; + use std::fs::File; + use std::io::{self, Write}; + use std::iter; + use std::path::Path; use log::{debug, trace}; use tempfile::{TempDir, tempdir}; - use crate::{ - config::{IconSizes, TabConfig, ThumbCfg}, - tab::Item, - }; + use crate::config::{IconSizes, TabConfig, ThumbCfg}; + use crate::tab::Item; use super::*; diff --git a/src/archive.rs b/src/archive.rs index ba11cbb..cff0c1e 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -1,16 +1,14 @@ -use crate::{ - mime_icon::mime_for_path, - operation::{Controller, OpReader, OperationError, OperationErrorType, sync_to_disk}, -}; +use crate::mime_icon::mime_for_path; +use crate::operation::{Controller, OpReader, OperationError, OperationErrorType, sync_to_disk}; use cosmic::iced::futures; -use jiff::{Zoned, civil::DateTime, tz::TimeZone}; -use std::{ - collections::HashSet, - fs, - io::{self, Read, Write}, - path::{Path, PathBuf}, - time::SystemTime, -}; +use jiff::Zoned; +use jiff::civil::DateTime; +use jiff::tz::TimeZone; +use std::collections::HashSet; +use std::fs; +use std::io::{self, Read, Write}; +use std::path::{Path, PathBuf}; +use std::time::SystemTime; use zip::result::ZipError; pub const SUPPORTED_ARCHIVE_TYPES: &[&str] = &[ @@ -112,7 +110,8 @@ fn zip_extract>( password: Option<&str>, controller: Controller, ) -> zip::result::ZipResult<()> { - use std::{ffi::OsString, fs}; + use std::ffi::OsString; + use std::fs; use zip::result::ZipError; fn make_writable_dir_all>( diff --git a/src/channel.rs b/src/channel.rs index e91bc35..2a295f9 100644 --- a/src/channel.rs +++ b/src/channel.rs @@ -1,13 +1,9 @@ // Copyright 2025 System76 // SPDX-License-Identifier: MPL-2.0 -use std::{ - collections::VecDeque, - sync::{ - Arc, Mutex, - atomic::{AtomicBool, Ordering}, - }, -}; +use std::collections::VecDeque; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Mutex}; /// Create a channel backed by `tokio::sync::Notify` and a sync mutex with a vec deque. pub fn channel() -> (Sender, Receiver) { diff --git a/src/clipboard.rs b/src/clipboard.rs index 7e21276..7af2f9f 100644 --- a/src/clipboard.rs +++ b/src/clipboard.rs @@ -2,12 +2,10 @@ // SPDX-License-Identifier: GPL-3.0-only use cosmic::iced::clipboard::mime::{AllowedMimeTypes, AsMimeTypes}; -use std::{ - borrow::Cow, - error::Error, - path::{Path, PathBuf}, - str, -}; +use std::borrow::Cow; +use std::error::Error; +use std::path::{Path, PathBuf}; +use std::str; use url::Url; #[derive(Clone, Copy, Debug)] diff --git a/src/config.rs b/src/config.rs index 0ce9c22..2138d83 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,20 +1,18 @@ // SPDX-License-Identifier: GPL-3.0-only -use std::{any::TypeId, num::NonZeroU16, path::PathBuf}; +use std::any::TypeId; +use std::num::NonZeroU16; +use std::path::PathBuf; -use cosmic::{ - Application, - cosmic_config::{self, CosmicConfigEntry, cosmic_config_derive::CosmicConfigEntry}, - iced::Subscription, - theme, -}; +use cosmic::cosmic_config::cosmic_config_derive::CosmicConfigEntry; +use cosmic::cosmic_config::{self, CosmicConfigEntry}; +use cosmic::iced::Subscription; +use cosmic::{Application, theme}; use serde::{Deserialize, Serialize}; -use crate::{ - FxOrderMap, - app::App, - tab::{HeadingOptions, Location, View}, -}; +use crate::FxOrderMap; +use crate::app::App; +use crate::tab::{HeadingOptions, Location, View}; pub use crate::context_action::{ContextActionPreset, ContextActionSelection}; diff --git a/src/context_action.rs b/src/context_action.rs index 86f3bc6..639b964 100644 --- a/src/context_action.rs +++ b/src/context_action.rs @@ -4,7 +4,8 @@ use std::path::PathBuf; use serde::{Deserialize, Serialize}; -use crate::{mime_app, spawn_detached::spawn_detached}; +use crate::mime_app; +use crate::spawn_detached::spawn_detached; #[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] pub enum ContextActionSelection { diff --git a/src/dialog.rs b/src/dialog.rs index 976caf4..bca80ef 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -1,58 +1,46 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only -use cosmic::{ - Application, ApplicationExt, Element, - app::{Core, Task, context_drawer, cosmic::Cosmic}, - cosmic_config, cosmic_theme, executor, - iced::core::widget::operation, - iced::platform_specific::shell::{self as iced_winit, SurfaceIdWrapper}, - iced::widget::scrollable::AbsoluteOffset, - iced::{ - self, Alignment, Event, Length, Size, Subscription, - core::SmolStr, - event, - futures::{self, SinkExt}, - keyboard::{Event as KeyEvent, Key, Modifiers, key::Named}, - mouse, stream, - widget::scrollable, - window, - }, - theme, - widget::{ - self, Operation, - menu::{Action as MenuAction, KeyBind, key_bind::Modifier}, - segmented_button, - }, +use cosmic::app::cosmic::Cosmic; +use cosmic::app::{Core, Task, context_drawer}; +use cosmic::iced::core::SmolStr; +use cosmic::iced::core::widget::operation; +use cosmic::iced::futures::{self, SinkExt}; +use cosmic::iced::keyboard::key::Named; +use cosmic::iced::keyboard::{Event as KeyEvent, Key, Modifiers}; +use cosmic::iced::platform_specific::shell::{self as iced_winit, SurfaceIdWrapper}; +use cosmic::iced::widget::scrollable; +use cosmic::iced::widget::scrollable::AbsoluteOffset; +use cosmic::iced::{ + self, Alignment, Event, Length, Size, Subscription, event, mouse, stream, window, }; +use cosmic::widget::menu::key_bind::Modifier; +use cosmic::widget::menu::{Action as MenuAction, KeyBind}; +use cosmic::widget::{self, Operation, segmented_button}; +use cosmic::{Application, ApplicationExt, Element, cosmic_config, cosmic_theme, executor, theme}; use mime_guess::{Mime, mime}; -use notify_debouncer_full::{ - DebouncedEvent, Debouncer, RecommendedCache, new_debouncer, - notify::{self, RecommendedWatcher}, -}; +use notify_debouncer_full::notify::{self, RecommendedWatcher}; +use notify_debouncer_full::{DebouncedEvent, Debouncer, RecommendedCache, new_debouncer}; use recently_used_xbel::update_recently_used; use rustc_hash::{FxHashMap, FxHashSet}; -use std::{ - any::TypeId, - collections::{HashMap, VecDeque}, - env, fmt, fs, - path::PathBuf, - time::{self, Instant}, -}; +use std::any::TypeId; +use std::collections::{HashMap, VecDeque}; +use std::path::PathBuf; +use std::time::{self, Instant}; +use std::{env, fmt, fs}; -use crate::{ - app::{ - Action, ContextPage, Message as AppMessage, PreviewItem, PreviewKind, REPLACE_BUTTON_ID, - }, - config::{Config, DialogConfig, Favorite, TIME_CONFIG_ID, ThumbCfg, TimeConfig, TypeToSearch}, - fl, home_dir, - key_bind::key_binds, - localize::LANGUAGE_SORTER, - menu, - mounter::{MOUNTERS, MounterItem, MounterItems, MounterKey, MounterMessage}, - tab::{self, ItemMetadata, Location, SearchLocation, Tab}, - zoom::{zoom_in_view, zoom_out_view, zoom_to_default}, +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::key_bind::key_binds; +use crate::localize::LANGUAGE_SORTER; +use crate::mounter::{MOUNTERS, MounterItem, MounterItems, MounterKey, MounterMessage}; +use crate::tab::{self, ItemMetadata, Location, SearchLocation, Tab}; +use crate::zoom::{zoom_in_view, zoom_out_view, zoom_to_default}; +use crate::{fl, home_dir, menu}; #[derive(Clone, Debug)] pub struct DialogMessage(cosmic::Action); diff --git a/src/key_bind.rs b/src/key_bind.rs index 57a9dbf..f47d403 100644 --- a/src/key_bind.rs +++ b/src/key_bind.rs @@ -1,11 +1,10 @@ -use cosmic::{ - iced::core::keyboard::key::Named, - iced::keyboard::Key, - widget::menu::key_bind::{KeyBind, Modifier}, -}; +use cosmic::iced::core::keyboard::key::Named; +use cosmic::iced::keyboard::Key; +use cosmic::widget::menu::key_bind::{KeyBind, Modifier}; use std::collections::HashMap; -use crate::{app::Action, tab}; +use crate::app::Action; +use crate::tab; //TODO: load from config pub fn key_binds(mode: &tab::Mode) -> HashMap { diff --git a/src/large_image.rs b/src/large_image.rs index 8686a97..1d78bc5 100644 --- a/src/large_image.rs +++ b/src/large_image.rs @@ -1,9 +1,7 @@ use cosmic::widget; use image::ImageReader; -use std::{ - collections::{HashMap, HashSet}, - path::{Path, PathBuf}, -}; +use std::collections::{HashMap, HashSet}; +use std::path::{Path, PathBuf}; /// Bytes per pixel in RGBA format (Red, Green, Blue, Alpha = 4 bytes) pub const RGBA_BYTES_PER_PIXEL: u64 = 4; diff --git a/src/lib.rs b/src/lib.rs index 3e89861..f2d04d7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,15 +1,16 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only -use cosmic::{app::Settings, iced::Limits}; -use std::{env, fs, path::PathBuf, process}; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; +use cosmic::app::Settings; +use cosmic::iced::Limits; +use std::path::PathBuf; +use std::{env, fs, process}; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; -use crate::{ - app::{App, Flags}, - config::{Config, State}, - tab::Location, -}; +use crate::app::{App, Flags}; +use crate::config::{Config, State}; +use crate::tab::Location; pub mod app; mod archive; diff --git a/src/load_image.rs b/src/load_image.rs index d54fe7f..88ceb1b 100644 --- a/src/load_image.rs +++ b/src/load_image.rs @@ -1,11 +1,10 @@ use cosmic::iced::{core as iced_core, widget as iced_widget}; use iced_core::event::Event; -use iced_core::layout; -use iced_core::mouse; -use iced_core::overlay; -use iced_core::renderer; use iced_core::widget::{Operation, Tree}; -use iced_core::{Clipboard, Element, Layout, Length, Rectangle, Shell, Vector, Widget}; +use iced_core::{ + Clipboard, Element, Layout, Length, Rectangle, Shell, Vector, Widget, layout, mouse, overlay, + renderer, +}; pub fn loaded_image<'a, Message: 'static, Theme>( handle: ::Handle, diff --git a/src/localize.rs b/src/localize.rs index f561a42..b569807 100644 --- a/src/localize.rs +++ b/src/localize.rs @@ -1,13 +1,10 @@ // SPDX-License-Identifier: GPL-3.0-only -use i18n_embed::{ - DefaultLocalizer, LanguageLoader, Localizer, - fluent::{FluentLanguageLoader, fluent_language_loader}, -}; -use icu::collator::{ - Collator, CollatorBorrowed, CollatorPreferences, options::CollatorOptions, - preferences::CollationNumericOrdering, -}; +use i18n_embed::fluent::{FluentLanguageLoader, fluent_language_loader}; +use i18n_embed::{DefaultLocalizer, LanguageLoader, Localizer}; +use icu::collator::options::CollatorOptions; +use icu::collator::preferences::CollationNumericOrdering; +use icu::collator::{Collator, CollatorBorrowed, CollatorPreferences}; use icu::locale::Locale; use rust_embed::RustEmbed; use std::sync::LazyLock; diff --git a/src/menu.rs b/src/menu.rs index 9f3f158..4132fbf 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -1,30 +1,25 @@ // SPDX-License-Identifier: GPL-3.0-only -use cosmic::{ - Element, - app::Core, - iced::{ - Alignment, Background, Border, Length, advanced::widget::text::Style as TextStyle, - keyboard::Modifiers, - }, - theme, - widget::{ - self, Row, button, column, container, divider, - menu::{self, ItemHeight, ItemWidth, MenuBar, key_bind::KeyBind}, - responsive_menu_bar, space, text, - }, +use cosmic::app::Core; +use cosmic::iced::advanced::widget::text::Style as TextStyle; +use cosmic::iced::keyboard::Modifiers; +use cosmic::iced::{Alignment, Background, Border, Length}; +use cosmic::widget::menu::key_bind::KeyBind; +use cosmic::widget::menu::{self, ItemHeight, ItemWidth, MenuBar}; +use cosmic::widget::{ + self, Row, button, column, container, divider, responsive_menu_bar, space, text, }; +use cosmic::{Element, theme}; use i18n_embed::LanguageLoader; use mime_guess::Mime; -use std::{collections::HashMap, sync::LazyLock}; +use std::collections::HashMap; +use std::sync::LazyLock; -use crate::{ - app::{Action, Message}, - config::{Config, ContextActionPreset}, - fl, - tab::{self, HeadingOptions, Location, LocationMenuAction, SearchLocation, Tab}, - trash::{Trash, TrashExt}, -}; +use crate::app::{Action, Message}; +use crate::config::{Config, ContextActionPreset}; +use crate::fl; +use crate::tab::{self, HeadingOptions, Location, LocationMenuAction, SearchLocation, Tab}; +use crate::trash::{Trash, TrashExt}; static MENU_ID: LazyLock = LazyLock::new(|| cosmic::widget::Id::new("responsive-menu")); diff --git a/src/mime_app.rs b/src/mime_app.rs index 4a55cdf..b3b299e 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -6,14 +6,11 @@ use cosmic::desktop; use cosmic::widget; pub use mime_guess::Mime; use rustc_hash::FxHashMap; -use std::{ - cmp::Ordering, - ffi::OsStr, - fs, io, - path::{Path, PathBuf}, - process, - time::Instant, -}; +use std::cmp::Ordering; +use std::ffi::OsStr; +use std::path::{Path, PathBuf}; +use std::time::Instant; +use std::{fs, io, process}; // Supported exec key field codes const EXEC_HANDLERS: [&str; 4] = ["%f", "%F", "%u", "%U"]; diff --git a/src/mime_icon.rs b/src/mime_icon.rs index 8d8d2e5..91ec3e8 100644 --- a/src/mime_icon.rs +++ b/src/mime_icon.rs @@ -3,11 +3,9 @@ use cosmic::widget::icon; use mime_guess::Mime; use rustc_hash::FxHashMap; -use std::{ - fs, - path::Path, - sync::{LazyLock, Mutex}, -}; +use std::fs; +use std::path::Path; +use std::sync::{LazyLock, Mutex}; pub const FALLBACK_MIME_ICON: &str = "text-x-generic"; diff --git a/src/mounter/gvfs.rs b/src/mounter/gvfs.rs index d6294b6..7c28668 100644 --- a/src/mounter/gvfs.rs +++ b/src/mounter/gvfs.rs @@ -1,18 +1,20 @@ -use cosmic::{ - Task, - iced::{Subscription, futures::SinkExt, stream}, - widget, -}; -use gio::{glib, prelude::*}; -use std::{any::TypeId, cell::Cell, future::pending, hash::Hash, path::PathBuf, sync::Arc}; +use cosmic::iced::futures::SinkExt; +use cosmic::iced::{Subscription, stream}; +use cosmic::{Task, widget}; +use gio::glib; +use gio::prelude::*; +use std::any::TypeId; +use std::cell::Cell; +use std::future::pending; +use std::hash::Hash; +use std::path::PathBuf; +use std::sync::Arc; use tokio::sync::mpsc; use super::{Mounter, MounterAuth, MounterItem, MounterItems, MounterMessage}; -use crate::{ - config::IconSizes, - err_str, - tab::{self, DirSize, ItemMetadata, ItemThumbnail, Location}, -}; +use crate::config::IconSizes; +use crate::err_str; +use crate::tab::{self, DirSize, ItemMetadata, ItemThumbnail, Location}; const TARGET_URI_ATTRIBUTE: &str = "standard::target-uri"; diff --git a/src/mounter/mod.rs b/src/mounter/mod.rs index b97f32a..3171c0f 100644 --- a/src/mounter/mod.rs +++ b/src/mounter/mod.rs @@ -1,13 +1,13 @@ -use cosmic::{Task, iced::Subscription, widget}; -use std::{ - collections::BTreeMap, - fmt, - path::PathBuf, - sync::{Arc, LazyLock}, -}; +use cosmic::iced::Subscription; +use cosmic::{Task, widget}; +use std::collections::BTreeMap; +use std::fmt; +use std::path::PathBuf; +use std::sync::{Arc, LazyLock}; use tokio::sync::mpsc; -use crate::{config::IconSizes, tab}; +use crate::config::IconSizes; +use crate::tab; #[cfg(feature = "gvfs")] mod gvfs; diff --git a/src/mouse_area.rs b/src/mouse_area.rs index a57b36a..73bd710 100644 --- a/src/mouse_area.rs +++ b/src/mouse_area.rs @@ -3,21 +3,17 @@ use std::time::Instant; use crate::tab::DOUBLE_CLICK_DURATION; -use cosmic::{ - Element, Renderer, Theme, - iced::core::{ - Clipboard, Color, Layout, Length, Point, Rectangle, Shell, Size, Vector, Widget, - border::Border, - event::Event, - layout, - mouse::{self, click}, - overlay, - renderer::{self, Quad, Renderer as _}, - touch, - widget::{Operation, Tree, tree}, - }, - widget::Id, +use cosmic::iced::core::border::Border; +use cosmic::iced::core::event::Event; +use cosmic::iced::core::mouse::{self, click}; +use cosmic::iced::core::renderer::{self, Quad, Renderer as _}; +use cosmic::iced::core::widget::{Operation, Tree, tree}; +use cosmic::iced::core::{ + Clipboard, Color, Layout, Length, Point, Rectangle, Shell, Size, Vector, Widget, layout, + overlay, touch, }; +use cosmic::widget::Id; +use cosmic::{Element, Renderer, Theme}; /// Emit messages on mouse events. #[allow(missing_debug_implementations)] diff --git a/src/operation/mod.rs b/src/operation/mod.rs index b4a66e9..886055a 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -1,20 +1,15 @@ -use crate::{ - app::{ArchiveType, DialogPage, Message, REPLACE_BUTTON_ID}, - archive, - config::IconSizes, - fl, - spawn_detached::spawn_detached, - tab, -}; -use cosmic::iced::futures::{self, SinkExt, StreamExt, channel::mpsc::Sender, stream}; -use std::{ - borrow::Cow, - fmt::Formatter, - fs, - io::{self, Read, Write}, - path::{Path, PathBuf}, - sync::Arc, -}; +use crate::app::{ArchiveType, DialogPage, Message, REPLACE_BUTTON_ID}; +use crate::config::IconSizes; +use crate::spawn_detached::spawn_detached; +use crate::{archive, fl, tab}; +use cosmic::iced::futures::channel::mpsc::Sender; +use cosmic::iced::futures::{self, SinkExt, StreamExt, stream}; +use std::borrow::Cow; +use std::fmt::Formatter; +use std::fs; +use std::io::{self, Read, Write}; +use std::path::{Path, PathBuf}; +use std::sync::Arc; use tokio::sync::{Mutex as TokioMutex, mpsc}; use walkdir::WalkDir; use zip::AesMode::Aes256; @@ -1243,28 +1238,23 @@ fn wrap_compio_spawn_error(err: Box) -> OperationError #[cfg(test)] mod tests { - use std::{ - fs::{self, File}, - io, - path::PathBuf, - }; + use std::fs::{self, File}; + use std::io; + use std::path::PathBuf; - use cosmic::iced::futures::{StreamExt, channel::mpsc, future}; + use cosmic::iced::futures::channel::mpsc; + use cosmic::iced::futures::{StreamExt, future}; use log::debug; use test_log::test; use tokio::sync; use super::{Controller, Operation, OperationError, OperationSelection, ReplaceResult}; - use crate::{ - app::{ - DialogPage, Message, - test_utils::{ - NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, empty_fs, filter_dirs, - filter_files, simple_fs, - }, - }, - fl, + use crate::app::test_utils::{ + NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, empty_fs, filter_dirs, filter_files, + simple_fs, }; + use crate::app::{DialogPage, Message}; + use crate::fl; /// Simple wrapper around `[Operation::Copy]` pub async fn operation_copy( diff --git a/src/operation/reader.rs b/src/operation/reader.rs index 75088df..9f45441 100644 --- a/src/operation/reader.rs +++ b/src/operation/reader.rs @@ -1,4 +1,5 @@ -use std::{fs, io, path::Path}; +use std::path::Path; +use std::{fs, io}; use crate::operation::OperationError; diff --git a/src/operation/recursive.rs b/src/operation/recursive.rs index 047d09b..a3bd2c4 100644 --- a/src/operation/recursive.rs +++ b/src/operation/recursive.rs @@ -6,15 +6,20 @@ use crate::operation::{OperationError, sync_to_disk}; use anyhow::Context as AnyhowContext; use compio::BufResult; use compio::buf::{IntoInner, IoBuf}; -use compio::driver::{ToSharedFd, op::AsyncifyFd}; +use compio::driver::ToSharedFd; +use compio::driver::op::AsyncifyFd; use compio::io::{AsyncReadAt, AsyncWriteAt}; use cosmic::iced::futures; use futures::{FutureExt, StreamExt}; +use std::cell::Cell; +use std::error::Error; +use std::fs; use std::future::Future; +use std::ops::ControlFlow; +use std::path::PathBuf; use std::pin::Pin; use std::rc::Rc; use std::time::Instant; -use std::{cell::Cell, error::Error, fs, ops::ControlFlow, path::PathBuf}; use walkdir::WalkDir; #[cfg(feature = "gvfs")] diff --git a/src/tab.rs b/src/tab.rs index 91164c8..b80aaf4 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1,91 +1,71 @@ #[cfg(feature = "desktop")] use cosmic::desktop::fde::{DesktopEntry, get_languages_from_env}; -use cosmic::{ - Apply, Element, cosmic_theme, font, - iced::core::{mouse::ScrollDelta, widget::tree}, - iced::{ - Alignment, Border, Color, ContentFit, Length, Point, Rectangle, Size, Subscription, Vector, - advanced::{ - graphics, - text::{self, Paragraph}, - }, - alignment::Vertical, - clipboard::dnd::DndAction, - futures::{self, SinkExt}, - keyboard::Modifiers, - padding, stream, - widget::{ - rule, - scrollable::{self, AbsoluteOffset, Viewport}, - stack, - }, - window, - }, - theme, - widget::{ - self, DndDestination, DndSource, Id, RcElementWrapper, Widget, - menu::{action::MenuAction, key_bind::KeyBind}, - space, - }, +use cosmic::iced::advanced::graphics; +use cosmic::iced::advanced::text::{self, Paragraph}; +use cosmic::iced::alignment::Vertical; +use cosmic::iced::clipboard::dnd::DndAction; +use cosmic::iced::core::mouse::ScrollDelta; +use cosmic::iced::core::widget::tree; +use cosmic::iced::futures::{self, SinkExt}; +use cosmic::iced::keyboard::Modifiers; +use cosmic::iced::widget::scrollable::{self, AbsoluteOffset, Viewport}; +use cosmic::iced::widget::{rule, stack}; +use cosmic::iced::{ + Alignment, Border, Color, ContentFit, Length, Point, Rectangle, Size, Subscription, Vector, + padding, stream, window, }; +use cosmic::widget::menu::action::MenuAction; +use cosmic::widget::menu::key_bind::KeyBind; +use cosmic::widget::{self, DndDestination, DndSource, Id, RcElementWrapper, Widget, space}; +use cosmic::{Apply, Element, cosmic_theme, font, theme}; use i18n_embed::LanguageLoader; -use icu::{ - datetime::{ - DateTimeFormatter, DateTimeFormatterPreferences, fieldsets, input::DateTime, - options::TimePrecision, - }, - locale::preferences::extensions::unicode::keywords::HourCycle, -}; +use icu::datetime::input::DateTime; +use icu::datetime::options::TimePrecision; +use icu::datetime::{DateTimeFormatter, DateTimeFormatterPreferences, fieldsets}; +use icu::locale::preferences::extensions::unicode::keywords::HourCycle; use image::{DynamicImage, ImageReader}; use jiff_icu::ConvertFrom; use mime_guess::{Mime, mime}; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; +use std::borrow::Cow; +use std::cell::Cell; +use std::cmp::{Ordering, Reverse}; +use std::collections::{BTreeMap, BTreeSet, HashMap}; +use std::error::Error; +use std::fmt::{self, Display}; +use std::fs::{self, File, Metadata}; +use std::hash::Hash; +use std::io::{BufRead, BufReader}; #[cfg(unix)] use std::os::unix::fs::MetadataExt; -use std::{ - borrow::Cow, - cell::Cell, - cmp::{Ordering, Reverse}, - collections::{BTreeMap, BTreeSet, HashMap}, - error::Error, - fmt::{self, Display}, - fs::{self, File, Metadata}, - hash::Hash, - io::{BufRead, BufReader}, - path::{self, Path, PathBuf}, - sync::{Arc, LazyLock, RwLock, atomic}, - time::{Duration, Instant, SystemTime}, -}; +use std::path::{self, Path, PathBuf}; +use std::sync::{Arc, LazyLock, RwLock, atomic}; +use std::time::{Duration, Instant, SystemTime}; use tempfile::NamedTempFile; use tokio::sync::mpsc; use trash::{TrashItem, TrashItemMetadata, TrashItemSize}; use walkdir::WalkDir; -use crate::{ - FxOrderMap, - app::{Action, PreviewItem, PreviewKind}, - clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste}, - config::{ - ContextActionPreset, DesktopConfig, ICON_SCALE_MAX, ICON_SIZE_GRID, IconSizes, TabConfig, - ThumbCfg, - }, - dialog::DialogKind, - fl, - large_image::{ - LargeImageManager, decode_large_image, exceeds_memory_limit, should_use_dedicated_worker, - should_use_tiling, - }, - localize::{LANGUAGE_SORTER, LOCALE}, - menu, mime_app, - mime_icon::{mime_for_path, mime_icon}, - mounter::MOUNTERS, - mouse_area, - operation::{Controller, OperationError}, - thumbnail_cacher::{CachedThumbnail, ThumbnailCacher, ThumbnailSize}, - thumbnailer::thumbnailer, - trash::{Trash, TrashExt}, +use crate::app::{Action, PreviewItem, PreviewKind}; +use crate::clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste}; +use crate::config::{ + ContextActionPreset, DesktopConfig, ICON_SCALE_MAX, ICON_SIZE_GRID, IconSizes, TabConfig, + ThumbCfg, }; +use crate::dialog::DialogKind; +use crate::large_image::{ + LargeImageManager, decode_large_image, exceeds_memory_limit, should_use_dedicated_worker, + should_use_tiling, +}; +use crate::localize::{LANGUAGE_SORTER, LOCALE}; +use crate::mime_icon::{mime_for_path, mime_icon}; +use crate::mounter::MOUNTERS; +use crate::operation::{Controller, OperationError}; +use crate::thumbnail_cacher::{CachedThumbnail, ThumbnailCacher, ThumbnailSize}; +use crate::thumbnailer::thumbnailer; +use crate::trash::{Trash, TrashExt}; +use crate::{FxOrderMap, fl, menu, mime_app, mouse_area}; pub const DOUBLE_CLICK_DURATION: Duration = Duration::from_millis(500); pub const HOVER_DURATION: Duration = Duration::from_millis(1600); @@ -7040,21 +7020,22 @@ fn text_editor_class( #[cfg(test)] mod tests { - use std::{fs, io, path::PathBuf}; + use std::path::PathBuf; + use std::{fs, io}; - use cosmic::{iced::mouse::ScrollDelta, iced::runtime::keyboard::Modifiers, widget}; + use cosmic::iced::mouse::ScrollDelta; + use cosmic::iced::runtime::keyboard::Modifiers; + use cosmic::widget; use log::{debug, trace}; use tempfile::TempDir; use test_log::test; use super::{Location, Message, Tab, respond_to_scroll_direction, scan_path}; - use crate::{ - app::test_utils::{ - NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, assert_eq_tab_path, empty_fs, - eq_path_item, filter_dirs, read_dir_sorted, simple_fs, tab_click_new, - }, - config::{IconSizes, TabConfig, ThumbCfg}, + use crate::app::test_utils::{ + NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, assert_eq_tab_path, empty_fs, + eq_path_item, filter_dirs, read_dir_sorted, simple_fs, tab_click_new, }; + use crate::config::{IconSizes, TabConfig, ThumbCfg}; // Boilerplate for tab tests. Checks if simulated clicks selected items. fn tab_selects_item( diff --git a/src/thumbnail_cacher.rs b/src/thumbnail_cacher.rs index e4d616e..e42d343 100644 --- a/src/thumbnail_cacher.rs +++ b/src/thumbnail_cacher.rs @@ -1,16 +1,14 @@ use image::DynamicImage; use md5::{Digest, Md5}; use rustc_hash::FxHashMap; +use std::error::Error; +use std::fs::{self, File}; +use std::io::{self, BufReader, BufWriter}; #[cfg(unix)] use std::os::unix::fs::PermissionsExt; -use std::{ - error::Error, - fs::{self, File}, - io::{self, BufReader, BufWriter}, - path::{Path, PathBuf}, - sync::LazyLock, - time::UNIX_EPOCH, -}; +use std::path::{Path, PathBuf}; +use std::sync::LazyLock; +use std::time::UNIX_EPOCH; use tempfile::NamedTempFile; use url::Url; diff --git a/src/thumbnailer.rs b/src/thumbnailer.rs index f7786ed..b9de821 100644 --- a/src/thumbnailer.rs +++ b/src/thumbnailer.rs @@ -5,13 +5,10 @@ use cosmic::desktop::fde::GenericEntry; use mime_guess::Mime; use rustc_hash::FxHashMap; -use std::{ - fs, - path::Path, - process, - sync::{LazyLock, Mutex}, - time::Instant, -}; +use std::path::Path; +use std::sync::{LazyLock, Mutex}; +use std::time::Instant; +use std::{fs, process}; #[derive(Clone, Debug)] pub struct Thumbnailer { diff --git a/src/trash.rs b/src/trash.rs index f46bc48..30d140f 100644 --- a/src/trash.rs +++ b/src/trash.rs @@ -1,11 +1,10 @@ use cosmic::widget; use regex::Regex; -use std::{collections::HashSet, path::PathBuf}; +use std::collections::HashSet; +use std::path::PathBuf; -use crate::{ - config::IconSizes, - tab::{Item, SearchItem}, -}; +use crate::config::IconSizes; +use crate::tab::{Item, SearchItem}; pub trait TrashExt { fn is_empty() -> bool { @@ -81,7 +80,8 @@ impl TrashExt for Trash { } fn scan(sizes: IconSizes) -> Vec { - use crate::{localize::LANGUAGE_SORTER, tab::item_from_trash_entry}; + use crate::localize::LANGUAGE_SORTER; + use crate::tab::item_from_trash_entry; use std::cmp::Ordering; let entries = match trash::os_limited::list() { diff --git a/src/zoom.rs b/src/zoom.rs index 600d0b5..89ae5b8 100644 --- a/src/zoom.rs +++ b/src/zoom.rs @@ -1,6 +1,7 @@ use std::num::NonZeroU16; -use crate::{config::IconSizes, tab::View}; +use crate::config::IconSizes; +use crate::tab::View; static DEFAULT_ZOOM: NonZeroU16 = NonZeroU16::new(100).unwrap(); static MIN_ZOOM: NonZeroU16 = NonZeroU16::new(50).unwrap(); From d775f3e5e81021e843dd9b4f44a24bc8b76e3ca2 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Fri, 24 Apr 2026 23:27:33 +0200 Subject: [PATCH 053/110] fix: improve desktop entry field code handling - The %f and %u field codes may now be expanded within a word - Handle field code escapes (%%) - Support the %c and %k field codes This will notably fix desktop entries and context menu actions that pass files as a long argument, such as `--option=%f`. --- Cargo.lock | 1 + Cargo.toml | 1 + src/app.rs | 40 ++++--- src/context_action.rs | 2 +- src/mime_app.rs | 267 ++++++++++++++++++++++-------------------- 5 files changed, 165 insertions(+), 146 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d2e592c..f5760c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1375,6 +1375,7 @@ version = "1.0.11" dependencies = [ "anyhow", "atomic_float", + "bstr", "bzip2", "compio", "cosmic-client-toolkit", diff --git a/Cargo.toml b/Cargo.toml index 0ccd0d4..7247654 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ tracing-subscriber = { version = "0.3.23", features = ["env-filter"] } thiserror = "2.0.18" atomic_float = "1.1.0" num_enum = "0.7.6" +bstr = "1.12.1" # Completion-based IO runtime to enable io_uring / IOCP file IO support. [dependencies.compio] diff --git a/src/app.rs b/src/app.rs index fcc411f..7c0d127 100644 --- a/src/app.rs +++ b/src/app.rs @@ -884,31 +884,39 @@ impl App { #[cfg(feature = "desktop")] fn launch_desktop_entries(paths: &[impl AsRef]) { use cosmic::desktop::fde::DesktopEntry; + let locales = cosmic::desktop::fde::get_languages_from_env(); for path in paths.iter().map(AsRef::as_ref) { match DesktopEntry::from_path::<&str>(path, None) { Ok(entry) => match entry.exec() { - Some(exec) => match mime_app::exec_to_command(exec, &[] as &[&str; 0]) { - Some(commands) => { - let cwd_opt = entry.desktop_entry("Path"); + Some(exec) => { + match mime_app::exec_to_command( + exec, + entry.name(&locales).as_deref().unwrap_or_default(), + Some(path), + &[] as &[&str; 0], + ) { + Some(commands) => { + let cwd_opt = entry.desktop_entry("Path"); - for mut command in commands { - if let Some(cwd) = cwd_opt { - command.current_dir(cwd); - } + for mut command in commands { + if let Some(cwd) = cwd_opt { + command.current_dir(cwd); + } - if let Err(err) = spawn_detached(&mut command) { - log::warn!("failed to execute {}: {}", path.display(), err); + if let Err(err) = spawn_detached(&mut command) { + log::warn!("failed to execute {}: {}", path.display(), err); + } } } + None => { + log::warn!( + "failed to parse {}: invalid Desktop Entry/Exec", + path.display() + ); + } } - None => { - log::warn!( - "failed to parse {}: invalid Desktop Entry/Exec", - path.display() - ); - } - }, + } None => { log::warn!( "failed to parse {}: missing Desktop Entry/Exec", diff --git a/src/context_action.rs b/src/context_action.rs index 639b964..34dfb6e 100644 --- a/src/context_action.rs +++ b/src/context_action.rs @@ -47,7 +47,7 @@ impl ContextActionPreset { } for step in &self.steps { - let Some(commands) = mime_app::exec_to_command(step, paths) else { + let Some(commands) = mime_app::exec_to_command(step, &self.name, None, paths) else { log::warn!( "failed to parse context action {:?}: invalid Exec {:?}", self.name, diff --git a/src/mime_app.rs b/src/mime_app.rs index b3b299e..4bec78c 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -1,6 +1,7 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only +use bstr::{BString, ByteSlice, ByteVec}; #[cfg(feature = "desktop")] use cosmic::desktop; use cosmic::widget; @@ -8,145 +9,120 @@ pub use mime_guess::Mime; use rustc_hash::FxHashMap; use std::cmp::Ordering; use std::ffi::OsStr; +use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; use std::time::Instant; use std::{fs, io, process}; -// Supported exec key field codes -const EXEC_HANDLERS: [&str; 4] = ["%f", "%F", "%u", "%U"]; -// Deprecated field codes. The spec advises to ignore these handlers. -const DEPRECATED_HANDLERS: [&str; 6] = ["%d", "%D", "%n", "%N", "%v", "%m"]; - pub fn exec_to_command( exec: &str, + entry_name: &str, + entry_path: Option<&Path>, path_opt: &[impl AsRef], ) -> Option> { - let args_vec = shlex::split(exec)?; - let program = args_vec.first()?; - // Skip program to make indexing easier - let args_vec = &args_vec[1..]; + let arguments = shlex::split(exec)?; - // Base Command instance(s) - // 1. We may need to launch multiple of the same process. - // 2. Each of those processes will need to be passed args from exec. - // 3. Each of those args may appear in any order. - // 4. Arg order should be preserved. - // - // So, we'll go through exec in two passes. The first pass handles paths (%f etc) and args up - // to the field code followed by the second which passes extra, non-% args to each processes. - // - // While it'd be marginally faster to process everything in one pass, that's problematic: - // 1. path_opt may need to be cloned because it may be moved on each iteration (borrowck - // doesn't know we'll only use it once) - // 2. We have to keep track of which modifier (%f etc) we've used/seen already - // 3. We have to keep track of which processes received non-modifier args which gets messy fast - // 4. `exec` is likely small so looping over it twice is not a big deal - let field_code_pos = args_vec - .iter() - .position(|arg| EXEC_HANDLERS.contains(&arg.as_str())); - let args_handler = field_code_pos.and_then(|i| args_vec.get(i)); - // msrv - // .inspect(|handler| log::trace!("Found paths handler: {handler} for exec: {exec}")); - // Number of args before the field code. - // This won't be an off by one err below because take is not zero indexed. - let field_code_pos = field_code_pos.unwrap_or_default(); - let mut processes = match args_handler.map(String::as_str) { - Some("%f") => { - let mut processes = Vec::with_capacity(path_opt.len()); + if arguments.is_empty() { + tracing::error!("command does not contain any arguments"); + return None; + } - for path in path_opt.iter().map(AsRef::as_ref) { - // TODO: %f and %F need to handle non-file URLs (see spec) - if from_file_or_dir(path).is_none() { - log::warn!("Desktop file expects a file path instead of a URL: {path:?}"); + let mut commands = Vec::new(); + + for path in path_opt.iter().map(AsRef::as_ref) { + let mut batch_process = false; + let mut args = Vec::with_capacity(arguments.len()); + let mut field_code_used = false; + + for argument in arguments.iter().skip(1) { + let mut new_argument = BString::new(Vec::with_capacity(argument.capacity())); + let mut chars = argument.chars(); + while let Some(char) = chars.next() { + // https://specifications.freedesktop.org/desktop-entry/latest/exec-variables.html + if char == '%' { + match chars.next() { + Some('%') => new_argument.push_char(char), + Some('c') => new_argument.push_str(entry_name), + Some('k') => { + if let Some(path) = entry_path { + new_argument.push_str(path.as_os_str().as_bytes()); + } + } + + Some('f') => { + if !field_code_used { + // TODO: files on remote file systems should be copied to a temporary local file. + batch_process = true; + field_code_used = true; + new_argument.push_str(path.as_bytes()); + } + } + + Some('F') => { + if !field_code_used && new_argument.is_empty() { + field_code_used = true; + for path in path_opt + .iter() + .map(AsRef::as_ref) + .filter(|&path| from_file_or_dir(path).is_none()) + { + args.push(BString::new(path.as_bytes().to_owned())); + } + } + } + + Some('u') => { + if !field_code_used { + batch_process = true; + field_code_used = true; + new_argument.push_str(path.as_bytes()); + } + } + + Some('U') => { + if !field_code_used && new_argument.is_empty() { + field_code_used = true; + for path in path_opt.iter().map(AsRef::as_ref) { + args.push(BString::new(path.as_bytes().to_owned())); + } + } + } + + _ => (), + } + } else { + new_argument.push_char(char); } - - // Passing multiple paths to %f should open an instance per path - let mut process = process::Command::new(program); - process.args( - args_vec - .iter() - .map(AsRef::as_ref) - .take(field_code_pos) - .chain(std::iter::once(path)), - ); - processes.push(process); } - processes - } - Some("%F") => { - // TODO: %f and %F need to handle non-file URLs (see spec) - for invalid in path_opt - .iter() - .map(AsRef::as_ref) - .filter(|&path| from_file_or_dir(path).is_none()) - { - log::warn!("Desktop file expects a file path instead of a URL: {invalid:?}"); + if !new_argument.is_empty() { + args.push(new_argument); } - - // Launch one instance with all args - let mut process = process::Command::new(program); - process.args( - args_vec - .iter() - .map(OsStr::new) - .take(field_code_pos) - .chain(path_opt.iter().map(AsRef::as_ref)), - ); - - vec![process] } - Some("%u") => path_opt - .iter() - .map(|path| { - let mut process = process::Command::new(program); - process.args( - args_vec - .iter() - .map(OsStr::new) - .take(field_code_pos) - .chain(std::iter::once(path.as_ref())), - ); - process - }) - .collect(), - Some("%U") => { - let mut process = process::Command::new(program); - process.args( - args_vec - .iter() - .map(OsStr::new) - .take(field_code_pos) - .chain(path_opt.iter().map(AsRef::as_ref)), - ); - vec![process] - } - Some(invalid) => unreachable!("All valid variants were checked; got: {invalid}"), - None => vec![process::Command::new(program)], - }; - // Pass 2: Add remaining arguments that are not % to each process - for arg in args_vec.iter().skip(field_code_pos) { - match arg.as_str() { - // Consume path field codes or fail on codes we don't handle yet - field_code if arg.starts_with('%') => { - if !EXEC_HANDLERS.contains(&field_code) - && !DEPRECATED_HANDLERS.contains(&field_code) - { - log::warn!("unsupported Exec code {field_code:?} in {exec:?}"); + let mut command = process::Command::new(&arguments[0]); + + for arg in args { + match arg.to_os_str() { + Ok(arg) => { + command.arg(arg); + } + Err(_) => { + tracing::error!("invalid string encoding in command"); return None; } } - arg => { - for process in &mut processes { - process.arg(arg); - } - } + } + + commands.push(command); + + if !batch_process { + break; } } #[cfg(debug_assertions)] - for command in &processes { + for command in &commands { log::debug!( "Parsed program {} with args: {:?}", command.get_program().to_string_lossy(), @@ -154,7 +130,7 @@ pub fn exec_to_command( ); } - Some(processes) + Some(commands) } fn from_file_or_dir(path: impl AsRef) -> Option { @@ -176,7 +152,12 @@ pub struct MimeApp { impl MimeApp { //TODO: move to libcosmic, support multiple files pub fn command>(&self, path_opt: &[O]) -> Option> { - exec_to_command(self.exec.as_deref()?, path_opt) + exec_to_command( + self.exec.as_deref()?, + &self.name, + self.path.as_deref(), + path_opt, + ) } } @@ -472,11 +453,29 @@ impl Default for MimeAppCache { mod tests { use super::exec_to_command; + #[test] + fn keys_within_words() { + let exec = "/usr/bin/foo --option=%f"; + let paths = ["file1"]; + let commands = exec_to_command(exec, "keys_within_words", None, &paths) + .expect("Should parse valid exec"); + + assert_eq!(1, commands.len()); + let command = commands.first().unwrap(); + + assert_eq!("/usr/bin/foo", command.get_program().to_str().unwrap()); + assert_eq!( + "--option=file1", + command.get_args().next().unwrap().to_str().unwrap() + ); + } + #[test] fn one_path_f_field_code() { let exec = "/usr/bin/foo %f"; let paths = ["file1"]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "one_path_f_field_code", None, &paths) + .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); @@ -493,7 +492,8 @@ mod tests { fn one_path_F_field_code() { let exec = "/usr/bin/bar %F"; let paths = ["cat"]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "one_path_F_field_code", None, &paths) + .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); @@ -506,7 +506,8 @@ mod tests { fn one_path_u_field_code() { let exec = "/usr/bin/foobar %u"; let paths = ["/home/josh/krumpli"]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "one_path_u_field_code", None, &paths) + .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); @@ -523,7 +524,8 @@ mod tests { fn one_path_U_field_code() { let exec = "/usr/bin/rmrfbye %U"; let paths = ["/"]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "one_path_U_field_code", None, &paths) + .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); @@ -539,7 +541,8 @@ mod tests { "/usr/share/games/psp/miku.iso", "/usr/share/games/psp/eternia.iso", ]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "mult_path_f_field_code", None, &paths) + .expect("Should parse valid exec"); assert_eq!(paths.len(), commands.len()); for (command, path) in commands.into_iter().zip(paths.iter()) { @@ -559,7 +562,8 @@ mod tests { "/usr/share/games/doom2/hr.wad", "/usr/share/games/doom2/hrmus.wad", ]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "mult_path_F_field_code", None, &paths) + .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); @@ -581,7 +585,8 @@ mod tests { "https://redox-os.org/", "https://system76.com/", ]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "mult_path_u_field_code", None, &paths) + .expect("Should parse valid exec"); assert_eq!(paths.len(), commands.len()); for (command, path) in commands.into_iter().zip(paths.iter()) { @@ -604,7 +609,8 @@ mod tests { "frieren01.mkv", "rtmp://example.org/this/video/doesnt/exist.avi", ]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "mult_path_U_field_code", None, &paths) + .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); @@ -632,7 +638,8 @@ mod tests { "@@u", ]; let paths = ["file1.rs", "file2.rs"]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "flatpak_style_exec", None, &paths) + .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); @@ -655,7 +662,8 @@ mod tests { "file:///usr/share/games/roguelike/mods/mod1", "file:///usr/share/games/roguelike/mods/mod2", ]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "multiple_field_codes", None, &paths) + .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); @@ -688,7 +696,8 @@ mod tests { ]; let paths = ["rust_game_dev.pdf", "superhero_ferris.epub"]; let args_trailing = ["@@"]; - let commands = exec_to_command(exec, &paths).expect("Should parse valid exec"); + let commands = exec_to_command(exec, "sandwiched_field_code", None, &paths) + .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); From 1fcd0dccc84ce80ad82c660d3dfd3b2fc9abc617 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Wed, 29 Apr 2026 21:52:11 +0200 Subject: [PATCH 054/110] fix: %F and %U field code handling Fixes %F path arguments being ignored --- src/mime_app.rs | 76 ++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 49 deletions(-) diff --git a/src/mime_app.rs b/src/mime_app.rs index 4bec78c..48624fe 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -49,42 +49,19 @@ pub fn exec_to_command( } } - Some('f') => { - if !field_code_used { - // TODO: files on remote file systems should be copied to a temporary local file. - batch_process = true; - field_code_used = true; - new_argument.push_str(path.as_bytes()); - } + // %f and %u behave the same in a file manager. + Some('f' | 'u') if !field_code_used => { + // TODO: files on remote file systems should be copied to a temporary local file. + batch_process = true; + field_code_used = true; + new_argument.push_str(path.as_bytes()); } - Some('F') => { - if !field_code_used && new_argument.is_empty() { - field_code_used = true; - for path in path_opt - .iter() - .map(AsRef::as_ref) - .filter(|&path| from_file_or_dir(path).is_none()) - { - args.push(BString::new(path.as_bytes().to_owned())); - } - } - } - - Some('u') => { - if !field_code_used { - batch_process = true; - field_code_used = true; - new_argument.push_str(path.as_bytes()); - } - } - - Some('U') => { - if !field_code_used && new_argument.is_empty() { - field_code_used = true; - for path in path_opt.iter().map(AsRef::as_ref) { - args.push(BString::new(path.as_bytes().to_owned())); - } + // %F and %U behave the same in a file manager. + Some('F') | Some('U') if !field_code_used && new_argument.is_empty() => { + field_code_used = true; + for path in path_opt.iter().map(AsRef::as_ref) { + args.push(BString::new(path.as_bytes().to_owned())); } } @@ -133,12 +110,6 @@ pub fn exec_to_command( Some(commands) } -fn from_file_or_dir(path: impl AsRef) -> Option { - url::Url::from_file_path(&path) - .ok() - .or_else(|| url::Url::from_directory_path(&path).ok()) -} - #[derive(Clone, Debug)] pub struct MimeApp { pub id: String, @@ -490,33 +461,40 @@ mod tests { #[test] #[allow(non_snake_case)] fn one_path_F_field_code() { - let exec = "/usr/bin/bar %F"; - let paths = ["cat"]; + let exec = "/usr/bin/cosmic-term -w %F"; + let paths = ["/home/user"]; let commands = exec_to_command(exec, "one_path_F_field_code", None, &paths) .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); + let mut args = command.get_args(); - assert_eq!("/usr/bin/bar", command.get_program().to_str().unwrap()); - assert_eq!("cat", command.get_args().next().unwrap().to_str().unwrap()); + assert_eq!( + "/usr/bin/cosmic-term", + command.get_program().to_str().unwrap() + ); + assert_eq!("-w", args.next().unwrap().to_str().unwrap()); + assert_eq!(paths[0], args.next().unwrap().to_str().unwrap()); } #[test] fn one_path_u_field_code() { - let exec = "/usr/bin/foobar %u"; - let paths = ["/home/josh/krumpli"]; + let exec = "/usr/bin/cosmic-term -w %u"; + let paths = ["/home/user"]; let commands = exec_to_command(exec, "one_path_u_field_code", None, &paths) .expect("Should parse valid exec"); assert_eq!(1, commands.len()); let command = commands.first().unwrap(); + let mut args = command.get_args(); - assert_eq!("/usr/bin/foobar", command.get_program().to_str().unwrap()); assert_eq!( - *paths.first().unwrap(), - command.get_args().next().unwrap().to_str().unwrap() + "/usr/bin/cosmic-term", + command.get_program().to_str().unwrap() ); + assert_eq!("-w", args.next().unwrap().to_str().unwrap()); + assert_eq!(paths[0], args.next().unwrap().to_str().unwrap()); } #[test] From 37e8734e7b8e36bd86b81db5b9056eca00fce9e3 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 30 Apr 2026 00:02:12 +0200 Subject: [PATCH 055/110] fix(mime-app): handle no-path command exec --- src/mime_app.rs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/mime_app.rs b/src/mime_app.rs index 48624fe..74c5f34 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -29,7 +29,17 @@ pub fn exec_to_command( let mut commands = Vec::new(); - for path in path_opt.iter().map(AsRef::as_ref) { + let paths = path_opt + .iter() + .map(AsRef::as_ref) + .map(Some) + // Add a single `None` if no path was given. + .chain(std::iter::repeat_n( + None, + if path_opt.is_empty() { 1 } else { 0 }, + )); + + for path in paths { let mut batch_process = false; let mut args = Vec::with_capacity(arguments.len()); let mut field_code_used = false; @@ -50,7 +60,10 @@ pub fn exec_to_command( } // %f and %u behave the same in a file manager. - Some('f' | 'u') if !field_code_used => { + Some('f' | 'u') + if let Some(path) = path + && !field_code_used => + { // TODO: files on remote file systems should be copied to a temporary local file. batch_process = true; field_code_used = true; @@ -441,6 +454,20 @@ mod tests { ); } + #[test] + fn no_path_f_field_code() { + let exec = "/usr/bin/foo %f"; + let paths: [&str; 0] = []; + let commands = exec_to_command(exec, "no_path_f_field_code", None, &paths) + .expect("Should parse valid exec"); + + assert_eq!(1, commands.len()); + let command = commands.first().unwrap(); + + assert_eq!("/usr/bin/foo", command.get_program().to_str().unwrap()); + assert_eq!(0, command.get_args().len()); + } + #[test] fn one_path_f_field_code() { let exec = "/usr/bin/foo %f"; From f8323171e71a922d22b4fca1c9ea17928237ac74 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 30 Apr 2026 21:29:41 +0200 Subject: [PATCH 056/110] fix: remove match if let guards for Rust 1.93 --- src/mime_app.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/mime_app.rs b/src/mime_app.rs index 74c5f34..8695d79 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -60,21 +60,24 @@ pub fn exec_to_command( } // %f and %u behave the same in a file manager. - Some('f' | 'u') + Some('f' | 'u') => { if let Some(path) = path - && !field_code_used => - { - // TODO: files on remote file systems should be copied to a temporary local file. - batch_process = true; - field_code_used = true; - new_argument.push_str(path.as_bytes()); + && !field_code_used + { + // TODO: files on remote file systems should be copied to a temporary local file. + batch_process = true; + field_code_used = true; + new_argument.push_str(path.as_bytes()); + } } // %F and %U behave the same in a file manager. - Some('F') | Some('U') if !field_code_used && new_argument.is_empty() => { - field_code_used = true; - for path in path_opt.iter().map(AsRef::as_ref) { - args.push(BString::new(path.as_bytes().to_owned())); + Some('F') | Some('U') => { + if !field_code_used && new_argument.is_empty() { + field_code_used = true; + for path in path_opt.iter().map(AsRef::as_ref) { + args.push(BString::new(path.as_bytes().to_owned())); + } } } From 7c47cbbb29cbb536c8b30a8379a5582bfb2f26dd Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 30 Apr 2026 21:29:06 +0200 Subject: [PATCH 057/110] chore: add rust-toolchain to enforce 1.93 --- rust-toolchain.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 rust-toolchain.toml diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..fb5449a --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "1.93.0" +components = ["clippy", "rustfmt"] From 72b40aece3db5f7f6ac832b777089a296a3f7fa3 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 30 Apr 2026 21:36:24 +0200 Subject: [PATCH 058/110] perf: use `Box` with `tab::Item` to reduce message size by 800 bytes --- src/app.rs | 2 +- src/dialog.rs | 2 +- src/tab.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app.rs b/src/app.rs index 7c0d127..40c9e5a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -442,7 +442,7 @@ pub enum Message { TabRescan( Entity, Location, - Option, + Option>, Vec, Option>, ), diff --git a/src/dialog.rs b/src/dialog.rs index bca80ef..14b645a 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -475,7 +475,7 @@ enum Message { TabMessage(tab::Message), TabRescan( Location, - Option, + Option>, Vec, Option>, ), diff --git a/src/tab.rs b/src/tab.rs index b80aaf4..3fdd2fd 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1538,7 +1538,7 @@ impl Location { } } - pub fn scan(&self, sizes: IconSizes) -> (Option, Vec) { + pub fn scan(&self, sizes: IconSizes) -> (Option>, Vec) { let items = match self { Self::Desktop(path, display, desktop_config) => { scan_desktop(path, display, *desktop_config, sizes) @@ -1554,7 +1554,7 @@ impl Location { }; let parent_item_opt = match self.path_opt() { Some(path) => match item_from_path(path, sizes) { - Ok(item) => Some(item), + Ok(item) => Some(Box::new(item)), Err(err) => { log::warn!("failed to get item for {}: {}", path.display(), err); None @@ -2637,7 +2637,7 @@ pub struct Tab { pub sort_name: HeadingOptions, pub sort_direction: bool, pub gallery: bool, - pub(crate) parent_item_opt: Option, + pub(crate) parent_item_opt: Option>, pub(crate) items_opt: Option>, pub dnd_hovered: Option<(Location, Instant)>, pub(crate) scrollable_id: widget::Id, From cd48e4fa30e7ff20925e747e82ab5480ca974d11 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Fri, 1 May 2026 15:15:59 +0200 Subject: [PATCH 059/110] perf: reduce size of DialogPage enum by 1000 bytes --- src/app.rs | 8 ++++---- src/operation/mod.rs | 4 ++-- src/tab.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/app.rs b/src/app.rs index 40c9e5a..2682492 100644 --- a/src/app.rs +++ b/src/app.rs @@ -287,7 +287,7 @@ impl MenuAction for Action { } #[derive(Clone, Debug)] -pub struct PreviewItem(pub tab::Item); +pub struct PreviewItem(pub Box); impl PartialEq for PreviewItem { fn eq(&self, other: &Self) -> bool { @@ -573,8 +573,8 @@ pub enum DialogPage { dir: bool, }, Replace { - from: tab::Item, - to: tab::Item, + from: Box, + to: Box, multiple: bool, apply_to_all: bool, conflict_count: usize, @@ -5205,7 +5205,7 @@ impl Application for App { Ok(item) => { self.context_page = ContextPage::Preview( None, - PreviewKind::Custom(PreviewItem(item)), + PreviewKind::Custom(PreviewItem(Box::new(item))), ); self.set_show_context(true); } diff --git a/src/operation/mod.rs b/src/operation/mod.rs index 886055a..c490655 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -34,7 +34,7 @@ async fn handle_replace( conflict_count: usize, ) -> ReplaceResult { let item_from = match tab::item_from_path(file_from, IconSizes::default()) { - Ok(ok) => ok, + Ok(ok) => Box::new(ok), Err(err) => { log::warn!("{err}"); return ReplaceResult::Cancel; @@ -42,7 +42,7 @@ async fn handle_replace( }; let item_to = match tab::item_from_path(file_to, IconSizes::default()) { - Ok(ok) => ok, + Ok(ok) => Box::new(ok), Err(err) => { log::warn!("{err}"); return ReplaceResult::Cancel; diff --git a/src/tab.rs b/src/tab.rs index 3fdd2fd..659aa6d 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -3587,7 +3587,7 @@ impl Tab { match item_from_path(&path, IconSizes::default()) { Ok(item) => { commands.push(Command::Preview(PreviewKind::Custom( - PreviewItem(item), + PreviewItem(Box::new(item)), ))); } Err(err) => { From 750c92c8412acc6a8082bf01c0c4256acd971013 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 5 May 2026 10:24:20 -0600 Subject: [PATCH 060/110] Epoch 1.0.12 version update Generated by cosmic-epoch scripts/version-update.sh --- Cargo.lock | 156 ++++++++++++++++----------------- Cargo.toml | 2 +- cosmic-files-applet/Cargo.toml | 2 +- debian/changelog | 6 ++ 4 files changed, 86 insertions(+), 80 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5760c4..57ff41b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ dependencies = [ "accesskit_consumer", "atspi-common", "serde", - "zvariant 5.10.1", + "zvariant 5.11.0", ] [[package]] @@ -583,7 +583,7 @@ dependencies = [ "zbus-lockstep", "zbus-lockstep-macros", "zbus_names 4.3.2", - "zvariant 5.10.1", + "zvariant 5.11.0", ] [[package]] @@ -1342,7 +1342,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1363,7 +1363,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "quote", "syn", @@ -1371,7 +1371,7 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.0.11" +version = "1.0.12" dependencies = [ "anyhow", "atomic_float", @@ -1439,7 +1439,7 @@ dependencies = [ [[package]] name = "cosmic-files-applet" -version = "1.0.11" +version = "1.0.12" dependencies = [ "cosmic-files", "log", @@ -1533,7 +1533,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "almost", "configparser", @@ -1549,9 +1549,9 @@ dependencies = [ [[package]] name = "cpubits" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" [[package]] name = "cpufeatures" @@ -1819,9 +1819,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.0", "const-oid", @@ -2946,7 +2946,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -3052,7 +3052,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "dnd", "iced_accessibility", @@ -3073,7 +3073,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "accesskit", "accesskit_winit", @@ -3082,7 +3082,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "bitflags 2.11.1", "bytes", @@ -3106,7 +3106,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "iced_core", "iced_futures", @@ -3116,7 +3116,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "futures", "iced_core", @@ -3130,7 +3130,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -3151,7 +3151,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "iced_graphics", "iced_runtime", @@ -3160,7 +3160,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3172,7 +3172,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3187,7 +3187,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "bytemuck", "cosmic-text", @@ -3204,7 +3204,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.1", @@ -3235,7 +3235,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3253,7 +3253,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3756,9 +3756,9 @@ dependencies = [ [[package]] name = "image-extras" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d29ba92ef6970a2685cc758b455d190842b8b9e96c865ffd31cdb9954b7548" +checksum = "60d02eb2c9ccbbab470538fce34c7bc3be7b4e59268e65a3171367b296cdb842" dependencies = [ "image", ] @@ -3781,9 +3781,9 @@ checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" [[package]] name = "imgref" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" +checksum = "40fac9d56ed6437b198fddba683305e8e2d651aa42647f00f5ae542e7f5c94a2" [[package]] name = "indexmap" @@ -4313,11 +4313,11 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +checksum = "a7b65860415f949f23fa882e669f2dbd4a0f0eeb1acdd56790b30494afd7da2f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.11.1", "libc", ] @@ -4375,7 +4375,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#564ef834cec33a948dc10c9b401cf29db5d18373" +source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" dependencies = [ "apply", "ashpd 0.12.3", @@ -4460,7 +4460,7 @@ dependencies = [ "bitflags 2.11.1", "libc", "plain", - "redox_syscall 0.7.4", + "redox_syscall 0.7.5", ] [[package]] @@ -4577,9 +4577,9 @@ dependencies = [ [[package]] name = "lyon_algorithms" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9815fac08e6fd96733a11dce4f9d15a3f338e96a2e2311ee21e1b738efc2bc0f" +checksum = "8575c0d003ae459399623c4def180c63b77f343b1a7fee64f249b349e7699a31" dependencies = [ "lyon_path", "num-traits", @@ -4869,9 +4869,9 @@ dependencies = [ [[package]] name = "no_std_io2" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b51ed7824b6e07d354605f4abb3d9d300350701299da96642ee084f5ce631550" +checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003" dependencies = [ "memchr", ] @@ -4934,9 +4934,9 @@ dependencies = [ [[package]] name = "notify-rust" -version = "4.16.0" +version = "4.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e551a9f0db223eaf3eb156906f99f46897fd951ee66dd1cb0be14db4d36d2fa" +checksum = "50ff2e74231b72c832d82982193b417f230945be6bdb5575b251d941d31adb00" dependencies = [ "futures-lite", "log", @@ -5293,9 +5293,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" -version = "0.3.53" +version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12c6933ddbbd16539a7672e697bb8d41ac3a4e99ac43eeb40c07236bd7fcb2dd" +checksum = "a570f6bca41d29acb2139229a7c873ec99bc9a313bd10804081d89bfac8ff329" dependencies = [ "libc", "libredox", @@ -5452,7 +5452,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112d82ceb8c5bf524d9af484d4e4970c9fd5a0cc15ba14ad93dccd28873b0629" dependencies = [ - "digest 0.11.2", + "digest 0.11.3", "hmac", ] @@ -5557,18 +5557,18 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "cbf0d9e68100b3a7989b4901972f265cd542e560a3a8a724e1e20322f4d06ce9" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "a990e22f43e84855daf260dded30524ef4a9021cc7541c26540500a50b624389" dependencies = [ "proc-macro2", "quote", @@ -5798,18 +5798,18 @@ dependencies = [ [[package]] name = "profiling" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" +checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb" dependencies = [ "quote", "syn", @@ -5866,9 +5866,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.39.2" +version = "0.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" +checksum = "721da970c312655cde9b4ffe0547f20a8494866a4af5ff51f18b7c633d0c870b" dependencies = [ "memchr", "serde", @@ -6080,9 +6080,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" +checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" dependencies = [ "bitflags 2.11.1", ] @@ -6488,9 +6488,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.18.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" +checksum = "f05839ce67618e14a09b286535c0d9c94e85ef25469b0e13cb4f844e5593eb19" dependencies = [ "base64", "chrono", @@ -6507,9 +6507,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.18.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" +checksum = "cf2ebbe86054f9b45bc3881e865683ccfaccce97b9b4cb53f3039d67f355a334" dependencies = [ "darling 0.23.0", "proc-macro2", @@ -6536,7 +6536,7 @@ checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" dependencies = [ "cfg-if", "cpufeatures 0.3.0", - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -6617,9 +6617,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "skrifa" @@ -7158,9 +7158,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "110a78583f19d5cdb2c5ccf321d1290344e71313c6c37d43520d386027d18386" dependencies = [ "bytes", "libc", @@ -7853,7 +7853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a" dependencies = [ "proc-macro2", - "quick-xml 0.39.2", + "quick-xml 0.39.3", "quote", ] @@ -8704,7 +8704,7 @@ dependencies = [ "libredox", "orbclient", "raw-window-handle", - "redox_syscall 0.7.4", + "redox_syscall 0.7.5", "smol_str", "tracing", "winit-core", @@ -9218,7 +9218,7 @@ dependencies = [ "winnow", "zbus_macros 5.15.0", "zbus_names 4.3.2", - "zvariant 5.10.1", + "zvariant 5.11.0", ] [[package]] @@ -9228,7 +9228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6998de05217a084b7578728a9443d04ea4cd80f2a0839b8d78770b76ccd45863" dependencies = [ "zbus_xml", - "zvariant 5.10.1", + "zvariant 5.11.0", ] [[package]] @@ -9242,7 +9242,7 @@ dependencies = [ "syn", "zbus-lockstep", "zbus_xml", - "zvariant 5.10.1", + "zvariant 5.11.0", ] [[package]] @@ -9269,7 +9269,7 @@ dependencies = [ "quote", "syn", "zbus_names 4.3.2", - "zvariant 5.10.1", + "zvariant 5.11.0", "zvariant_utils 3.3.1", ] @@ -9292,7 +9292,7 @@ checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d" dependencies = [ "serde", "winnow", - "zvariant 5.10.1", + "zvariant 5.11.0", ] [[package]] @@ -9301,10 +9301,10 @@ version = "5.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8067892e940ed1727dea64690378601603b31d62dfde019a5335fbb7c0e0ed9" dependencies = [ - "quick-xml 0.39.2", + "quick-xml 0.39.3", "serde", "zbus_names 4.3.2", - "zvariant 5.10.1", + "zvariant 5.11.0", ] [[package]] @@ -9528,16 +9528,16 @@ dependencies = [ [[package]] name = "zvariant" -version = "5.10.1" +version = "5.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db0ecb8987cf5e92653c57c098f7f0e39a03112edb796f4fe089fb7eaa14ff" +checksum = "1c1567a6ec68df868cbbfde844cfc6d81649fe5109a62b116b19fabd53e618ee" dependencies = [ "endi", "enumflags2", "serde", "url", "winnow", - "zvariant_derive 5.10.1", + "zvariant_derive 5.11.0", "zvariant_utils 3.3.1", ] @@ -9556,9 +9556,9 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "5.10.1" +version = "5.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b949b639ab1b4bed763aa7481ba0e368af68d8b55532f8ed4bec86a59f2ca98" +checksum = "c7d5b780599bbde114e39d9a0799577fad1ced5105d38515745f7b3099d8ceda" dependencies = [ "proc-macro-crate", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index 7247654..b14c8be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.0.11" +version = "1.0.12" 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 b20226b..282146e 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files-applet" -version = "1.0.11" +version = "1.0.12" edition = "2024" [dependencies] diff --git a/debian/changelog b/debian/changelog index bea1aee..f9db4ff 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-files (1.0.12) noble; urgency=medium + + * Epoch 1.0.12 version update + + -- Jeremy Soller Tue, 05 May 2026 10:23:57 -0600 + cosmic-files (1.0.11) noble; urgency=medium * Epoch 1.0.11 version update From 6946e95c88984dee75669d881cfdce47bfde9930 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 5 May 2026 14:47:34 +0200 Subject: [PATCH 061/110] fix: prefer SVG file icons --- src/mime_icon.rs | 7 +++++-- src/tab.rs | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/mime_icon.rs b/src/mime_icon.rs index 91ec3e8..64f007f 100644 --- a/src/mime_icon.rs +++ b/src/mime_icon.rs @@ -45,7 +45,7 @@ impl MimeIconCache { return None; } let icon_name = icon_names.remove(0); - let mut named = icon::from_name(icon_name).size(key.size); + let mut named = icon::from_name(icon_name).prefer_svg(true).size(key.size); if !icon_names.is_empty() { let fallback_names = icon_names.into_iter().map(std::borrow::Cow::from).collect(); @@ -112,7 +112,10 @@ pub fn mime_icon(mime: Mime, size: u16) -> icon::Handle { let mut mime_icon_cache = MIME_ICON_CACHE.lock().unwrap(); match mime_icon_cache.get(MimeIconKey { mime, size }) { Some(handle) => handle, - None => icon::from_name(FALLBACK_MIME_ICON).size(size).handle(), + None => icon::from_name(FALLBACK_MIME_ICON) + .prefer_svg(true) + .size(size) + .handle(), } } diff --git a/src/tab.rs b/src/tab.rs index 659aa6d..ba3764f 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -269,6 +269,7 @@ fn button_style( pub fn folder_icon(path: &PathBuf, icon_size: u16) -> widget::icon::Handle { widget::icon::from_name(SPECIAL_DIRS.get(path).map_or("folder", |x| *x)) + .prefer_svg(true) .size(icon_size) .handle() } @@ -581,7 +582,10 @@ fn desktop_icon_handle(icon: &str, size: u16) -> widget::icon::Handle { if icon_path.is_absolute() && icon_path.exists() { widget::icon::from_path(icon_path.to_path_buf()) } else { - widget::icon::from_name(icon).size(size).handle() + widget::icon::from_name(icon) + .prefer_svg(true) + .size(size) + .handle() } } From 095940e9a9e00a800d441582df68f03e3721652f Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 5 May 2026 14:48:15 +0200 Subject: [PATCH 062/110] fix: small grid file icons --- src/tab.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tab.rs b/src/tab.rs index ba3764f..cade53d 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -5428,8 +5428,7 @@ impl Tab { widget::button::custom( widget::icon::icon(item.icon_handle_grid.clone()) .content_fit(ContentFit::Contain) - .size(icon_sizes.grid()) - .width(Length::Shrink), + .size(icon_sizes.grid()), ) .padding(space_xxxs) .class(button_style( From 55c8a54f28d5ed603b6f7a2441a970a4280a7795 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 11 May 2026 12:23:52 +0200 Subject: [PATCH 063/110] i18n: translation updates from weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Adolfo Jayme Barrientos Co-authored-by: Aindriú Mac Giolla Eoin Co-authored-by: Arve Eriksson <031299870@telia.com> Co-authored-by: Baurzhan Muftakhidinov Co-authored-by: BoneNI Co-authored-by: Dan Co-authored-by: David Carvalho Co-authored-by: Ettore Atalan Co-authored-by: Fedorov Alexei Co-authored-by: Feike Donia Co-authored-by: Geeson Wan Co-authored-by: Hosted Weblate Co-authored-by: Hugo Carvalho Co-authored-by: Isaac Subirana Co-authored-by: Jim Spentzos Co-authored-by: Jiri Grönroos Co-authored-by: Julien Brouillard Co-authored-by: Nara Díaz Viñolas Co-authored-by: Tadas Misiūnas Co-authored-by: VandaL Co-authored-by: Vilius Paliokas Co-authored-by: Walter William Beckerleg Bruckman Co-authored-by: Zahid Rizky Fakhri Co-authored-by: bittin1ddc447d824349b2 Co-authored-by: jonnysemon Co-authored-by: lorduskordus Co-authored-by: therealmate Co-authored-by: Димко Co-authored-by: Марко М. Костић Co-authored-by: 麋麓 BigELK176 Co-authored-by: 김유빈 Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ar/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ca/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/cs/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/de/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/el/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/fi/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/fr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ga/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/id/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/kk/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ko/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/lt/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/pl/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/pt/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ru/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/sr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/sv/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/uk/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/zh_Hant/ Translation: Pop OS/COSMIC Files --- i18n/ar/cosmic_files.ftl | 11 ++ i18n/ca/cosmic_files.ftl | 3 +- i18n/cs/cosmic_files.ftl | 17 +- i18n/de/cosmic_files.ftl | 8 + i18n/el/cosmic_files.ftl | 330 +++++++++++++++++++++++++++++++++++- i18n/fi/cosmic_files.ftl | 9 + i18n/fr/cosmic_files.ftl | 8 + i18n/ga/cosmic_files.ftl | 8 + i18n/hu/cosmic_files.ftl | 8 + i18n/id/cosmic_files.ftl | 8 + i18n/kk/cosmic_files.ftl | 8 + i18n/ko/cosmic_files.ftl | 1 + i18n/lo/cosmic_files.ftl | 0 i18n/lt/cosmic_files.ftl | 19 ++- i18n/pl/cosmic_files.ftl | 8 + i18n/pt-BR/cosmic_files.ftl | 8 + i18n/pt/cosmic_files.ftl | 2 + i18n/ru/cosmic_files.ftl | 8 + i18n/sr/cosmic_files.ftl | 329 +++++++++++++++++++++++++++++++++++ i18n/sv/cosmic_files.ftl | 8 + i18n/uk/cosmic_files.ftl | 44 +++-- i18n/zh-CN/cosmic_files.ftl | 12 +- i18n/zh-TW/cosmic_files.ftl | 12 +- 23 files changed, 829 insertions(+), 40 deletions(-) create mode 100644 i18n/lo/cosmic_files.ftl diff --git a/i18n/ar/cosmic_files.ftl b/i18n/ar/cosmic_files.ftl index 867e83c..c4e3292 100644 --- a/i18n/ar/cosmic_files.ftl +++ b/i18n/ar/cosmic_files.ftl @@ -372,3 +372,14 @@ show-recents = مجلد الحديثة في الشريط الجانبي clear-recents-history = امحُ التأريخ الحديث copy-path = انسخ المسار mixed = مختلط +context-action = إجراء السياق +context-action-confirm-title = شغِّل "{ $name }"؟ +context-action-confirm-warning = + سيُشغِّل هذا على { $items } { $items -> + [one] عنصر + [two] عنصرين + [few] عناصر + [many] عنصرًا + *[other] عنصر + }. +run = شغِّل diff --git a/i18n/ca/cosmic_files.ftl b/i18n/ca/cosmic_files.ftl index 010ddb0..48e7033 100644 --- a/i18n/ca/cosmic_files.ftl +++ b/i18n/ca/cosmic_files.ftl @@ -74,7 +74,7 @@ name-no-slashes = El nom no pot contenir barres. ## Open/Save Dialog -cancel = Cancel·la +cancel = Cancel·lar create = Crea open = Obre open-file = Obre el fixer @@ -352,3 +352,4 @@ sort-newest-first = Primer més recents sort-oldest-first = Primer més antics sort-smallest-to-largest = De petit a gran sort-largest-to-smallest = De gran a petit +run = Executa diff --git a/i18n/cs/cosmic_files.ftl b/i18n/cs/cosmic_files.ftl index 54b9e10..29814ba 100644 --- a/i18n/cs/cosmic_files.ftl +++ b/i18n/cs/cosmic_files.ftl @@ -17,7 +17,7 @@ size = Velikost ## Empty Trash Dialog -empty-trash = Vysypat koš +empty-trash = Vyprázdnit koš empty-trash-warning = Položky v koši budou trvale smazány ## New File/Folder Dialog @@ -195,8 +195,8 @@ deleted = [few] položky *[other] položek } z koše -emptying-trash = Vysypávání koše ({ $progress })... -emptied-trash = Koš vysypán +emptying-trash = Vyprazdňování koše ({ $progress })... +emptied-trash = Koš vyprázdněn restoring = Obnovování { $items } { $items -> [one] položky @@ -403,7 +403,7 @@ sort-largest-to-smallest = Od největšího po nejmenší gallery-preview = Náhled galerie sort = Řazení sort-a-z = A-Z -empty-trash-title = Vysypat koš? +empty-trash-title = Vyprázdnit koš? type-to-search-select = Vybere první shodující se soubor nebo složku pasted-image = Vložený obrázek pasted-text = Vložený text @@ -418,3 +418,12 @@ show-recents = Složka „Nedávné“ v postranním panelu copy-path = Kopírovat cestu clear-recents-history = Vymazat historii „Nedávné“ mixed = Různé +context-action = Kontextová akce +context-action-confirm-title = Spustit „{ $name }“? +context-action-confirm-warning = + Tato akce se spustí pro { $items } { $items -> + [one] položku + [few] položky + *[other] položek + }. +run = Spustit diff --git a/i18n/de/cosmic_files.ftl b/i18n/de/cosmic_files.ftl index 98d2f1b..993af2d 100644 --- a/i18n/de/cosmic_files.ftl +++ b/i18n/de/cosmic_files.ftl @@ -429,3 +429,11 @@ remove-from-recents = Aus den zuletzt verwendeten Elementen entfernen move-to = Verschieben nach... copy-path = Pfad kopieren mixed = Gemischt +context-action = Kontextaktion +context-action-confirm-title = „{ $name }“ ausführen? +context-action-confirm-warning = + Dies wird ausgeführt auf { $items } { $items -> + [one] Element + *[other] Elementen + }. +run = Ausführen diff --git a/i18n/el/cosmic_files.ftl b/i18n/el/cosmic_files.ftl index b28272c..7471630 100644 --- a/i18n/el/cosmic_files.ftl +++ b/i18n/el/cosmic_files.ftl @@ -1,15 +1,329 @@ empty-folder = Άδειος φάκελος no-results = Δεν βρέθηκαν αποτελέσματα -trash = Κάδος Ανακύκλωσης +trash = Απορρίμματα recents = Πρόσφατα -cosmic-files = COSMIC Αρχεία -empty-folder-hidden = Άδειος φάκελος (περιέχει κρυφά αντικείμενα) +cosmic-files = Αρχεία COSMIC +empty-folder-hidden = Άδειος φάκελος (περιέχει κρυφά στοιχεία) filesystem = Σύστημα αρχείων home = Προσωπικός φάκελος -networks = Δίκτυο -comment = Αρχεία για το COSMIC περιβάλλον -keywords = Φάκελος;Διαχειριστής; +networks = Δίκτυα +comment = Διαχείριση αρχείων για το περιβάλλον επιφάνειας εργασίας COSMIC +keywords = Αρχείο;Φάκελος;Διαχείριση;Folder;Manager; rename = Μετονομασία... close-tab = Κλείσιμο καρτέλας -light = Φωτεινό -dark = Σκοτεινό +light = Ανοιχτόχρωμο +dark = Σκουρόχρωμο +connect = Σύνδεση +dismiss = Απόρριψη μηνύματος +copy_noun = Αντιγραφή +open-file = Άνοιγμα αρχείου +save = Αποθήκευση +password = Κωδικός πρόσβασης +remove = Αφαίρεση +create = Δημιουργία +pause = Παύση +quit = Έξοδος +calculating = Υπολογισμός... +keep = Διατήρηση +edit = Επεξεργασία +connecting = Σύνδεση... +copy = Αντιγραφή +theme = Θέμα +appearance = Εμφάνιση +name = Όνομα +resume = Συνέχιση +username = Όνομα χρήστη +delete = Διαγραφή +repository = Αποθετήριο +support = Υποστήριξη +eject = Εξαγωγή +group = Ομάδα +skip = Παράλειψη +paste = Επικόλληση +menu-settings = Ρυθμίσεις... +view = Προβολή +undo = Αναίρεση +details = Λεπτομέρειες +sort-a-z = Α-Ω +extract-here = Αποσυμπίεση +cancel = Ακύρωση +sort-z-a = Ω-Α +open = Άνοιγμα +history = Ιστορικό +domain = Τομέας +sort = Ταξινόμηση +settings = Ρυθμίσεις +pending = Σε εκκρεμότητα +open-folder = Άνοιγμα φακέλου +replace = Αντικατάσταση +cut = Αποκοπή +file = Αρχείο +today = Σήμερα +compress = Συμπίεση... +size = Μέγεθος +related-apps = Σχετικές εφαρμογές +zoom-in = Μεγέθυνση +select-all = Επιλογή όλων +icon-size-and-spacing = Μέγεθος και απόσταση εικονιδίων +new-window = Νέο παράθυρο +zoom-out = Σμίκρυνση +default-size = Προεπιλεγμένο μέγεθος +create-archive = Δημιουργία συμπιεσμένου αρχείου +other-apps = Άλλες εφαρμογές +rename-folder = Μετονομασία φακέλου +folder-name = Όνομα φακέλου +connect-anonymously = Ανώνυμη σύνδεση +replace-with = Αντικατάσταση με +mounted-drives = Προσαρτημένες μονάδες +desktop-view-options = Επιλογές προβολής επιφάνειας εργασίας... +show-on-desktop = Εμφάνιση στην επιφάνεια εργασίας +trash-folder-icon = Εικονίδιο φακέλου απορριμμάτων +open-with = Άνοιγμα με +keep-both = Διατήρηση αμφότερων +icon-size = Μέγεθος εικονιδίων +open-with-title = Πώς θέλετε να ανοίξετε το «{ $name }»; +extract-password-required = Απαιτείται κωδικός πρόσβασης +rename-file = Μετονομασία αρχείου +file-name = Όνομα αρχείου +save-file = Αποθήκευση αρχείου +name-hidden = Τα ονόματα που ξεκινούν με «.» θα αποκρύπτονται +folder-already-exists = Υπάρχει ήδη ένας φάκελος με αυτό το όνομα +empty-trash = Άδειασμα απορριμμάτων +permanently-delete-question = Οριστική διαγραφή; +copy-to-button-label = Αντιγραφή +move-to-button-label = Μετακίνηση +run = Εκτέλεση +copy-to-title = Επιλογή προορισμού αντιγραφής +sort-newest-first = Πρώτα τα νεότερα +default-app = { $name } (προεπιλογή) +renamed = Έγινε μετονομασία από «{ $from }» σε «{ $to }» +read-execute = Ανάγνωση και εκτέλεση +deleted = + Έγινε διαγραφή { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τα { trash } +item-modified = Ημερομηνία τροποποίησης: { $modified } +list-view = Προβολή λίστας +reload-folder = Επαναφόρτωση φακέλου +favorite-path-error = Σφάλμα ανοίγματος καταλόγου +progress = { $percent }% +remove-from-sidebar = Αφαίρεση από την πλαϊνή στήλη +restoring = + Ανάκτηση { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τα { trash } ({ $progress })... +network-drive-error = Αδυναμία πρόσβασης σε μονάδα δικτύου +gallery-preview = Προεπισκόπηση συλλογής +sort-smallest-to-largest = Από τα μικρότερα στα μεγαλύτερα +removing-from-recents = + Αφαίρεση { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τα { recents } +type-to-search-enter-path = Εισέρχεται στη διαδρομή προς τον κατάλογο ή το αρχείο +emptying-trash = Άδειασμα φακέλου «{ trash }» ({ $progress })... +trashed-on = Ημερομηνία διαγραφής +compressing = + Συμπίεση { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τον φάκελο «{ $from }» στο αρχείο «{ $to }» ({ $progress })... +move-to-trash = Μετακίνηση στα απορρίμματα +menu-about = Σχετικά με τα Αρχεία COSMIC... +setting-executable-and-launching = Ορισμός του «{ $name }» ως εκτελέσιμου και εκκίνηση +open-multiple-files = Άνοιγμα πολλαπλών αρχείων +menu-open-with = Άνοιγμα με... +extracted = + Έγινε αποσυμπίεση { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από το αρχείο «{ $from }» στον φάκελο «{ $to }» +create-new-folder = Δημιουργία νέου φακέλου +original-file = Πρωτότυπο αρχείο +read-write-execute = Ανάγνωση, εγγραφή και εκτέλεση +set-permissions = Έγινε ορισμός των δικαιωμάτων για το «{ $name }» σε: { $mode } +sort-by-size = Ταξινόμηση κατά μέγεθος +item-size = Μέγεθος: { $size } +permanently-deleting = + Οριστική διαγραφή { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } +read-write = Ανάγνωση και εγγραφή +none = Κανένα +items = Στοιχεία: { $items } +type = Τύπος: { $mime } +compressed = + Έγινε συμπίεση { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τον φάκελο «{ $from }» στο αρχείο «{ $to }» +replace-warning = Θέλετε να το αντικαταστήσετε με αυτό που αποθηκεύετε; Αυτό θα οδηγήσει στην αντικατάσταση του περιεχομένου του. +new-file = Νέο αρχείο... +open-in-terminal = Άνοιγμα σε τερματικό +open-multiple-folders = Άνοιγμα πολλαπλών φακέλων +remember-password = Απομνημόνευση κωδικού πρόσβασης +show-details = Εμφάνιση λεπτομερειών +grid-spacing = Απόσταση πλέγματος +extract-to = Αποσυμπίεση σε... +add-network-drive = Προσθήκη μονάδας δικτύου +copying = + Αντιγραφή { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τον φάκελο «{ $from }» στον φάκελο «{ $to }» ({ $progress })... +sort-oldest-first = Πρώτα τα παλαιότερα +create-new-file = Δημιουργία νέου αρχείου +sort-by-trashed = Ταξινόμηση κατά ημερομηνία διαγραφής +replace-warning-operation = Θέλετε να το αντικαταστήσετε; Αυτό θα οδηγήσει στην αντικατάσταση του περιεχομένου του. +try-again = Δοκιμή ξανά +copied = + Έγινε αντιγραφή { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τον φάκελο «{ $from }» στον φάκελο «{ $to }» +other = Άλλο +open-in-new-window = Άνοιγμα σε νέο παράθυρο +sort-by-modified = Ταξινόμηση κατά ημερομηνία τροποποίησης +list-directories-first = Παράθεση των καταλόγων πρώτα +read-only = Μόνο ανάγνωση +browse-store = Περιήγηση στο { $store } +enter-server-address = Εισαγάγετε τη διεύθυνση διακομιστή +remove-from-recents = Αφαίρεση από τα πρόσφατα +apply-to-all = Εφαρμογή σε όλα +moving = + Μετακίνηση { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τον φάκελο «{ $from }» στον φάκελο «{ $to }» ({ $progress })... +change-wallpaper = Αλλαγή ταπετσαρίας... +network-drive-description = + Οι διευθύνσεις διακομιστών αποτελούνται από ένα πρόθεμα πρωτοκόλλου και μια διεύθυνση. + Παραδείγματα: ssh://192.168.0.1, ftp://[2001:db8::1] +deleting = + Διαγραφή { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τα { trash } ({ $progress })... +single-click = Μονό κλικ για άνοιγμα +setting-permissions = Ορισμός των δικαιωμάτων για το «{ $name }» σε: { $mode } +owner = Κάτοχος +creating = Δημιουργία του «{ $name }» στον φάκελο «{ $parent }» +execute-only = Μόνο εκτέλεση +open-item-location = Άνοιγμα τοποθεσίας στοιχείου +set-executable-and-launched = Έγινε ορισμός του «{ $name }» ως εκτελέσιμου και εκκινήθηκε +mount-error = Αδυναμία πρόσβασης στη μονάδα +grid-view = Προβολή πλέγματος +set-and-launch = Ορισμός και εκκίνηση +removed-from-recents = + Έγινε αφαίρεση { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τα { recents } +add-to-sidebar = Προσθήκη στην πλαϊνή στήλη +item-created = Ημερομηνία δημιουργίας: { $created } +network-drive-schemes = + Διαθέσιμα πρωτόκολλα,Πρόθεμα + AppleTalk,afp:// + File Transfer Protocol,ftp:// ή ftps:// + Network File System,nfs:// + Server Message Block,smb:// + SSH File Transfer Protocol,sftp:// ή ssh:// + WebDAV,dav:// ή davs:// +set-executable-and-launch = Ορισμός ως εκτελέσιμο και εκκίνηση +restored = + Έγινε ανάκτηση { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τα { trash } +type-to-search-recursive = Κάνει αναζήτηση στον τρέχοντα φάκελο και όλους τους υποφακέλους +progress-paused = { $percent }%, σε παύση +cancelled = Ακυρωμένες +new-folder = Νέος φάκελος... +match-desktop = Συμφωνία με την επιφάνεια εργασίας +operations-running-finished = + Εκτέλεση { $running } { $running -> + [one] διεργασίας + *[other] διεργασιών + } ({ $percent }%), { $finished } ολοκληρωμένες... +sort-by-name = Ταξινόμηση κατά όνομα +edit-history = Ιστορικό επεξεργασιών +show-hidden-files = Εμφάνιση κρυφών αρχείων +progress-failed = { $percent }%, απέτυχε +item-accessed = Ημερομηνία πρόσβασης: { $accessed } +extract-to-title = Αποσυμπίεση σε φάκελο +extracting = + Αποσυμπίεση { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από το αρχείο «{ $from }» στον φάκελο «{ $to }» ({ $progress })... +permanently-deleted = + Έγινε οριστική διαγραφή { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } +complete = Ολοκληρωμένες +write-execute = Εγγραφή και εκτέλεση +desktop-folder-content = Περιεχόμενο φακέλου επιφάνειας εργασίας +renaming = Μετονομασία από «{ $from }» σε «{ $to }» +set-executable-and-launch-description = Θέλετε να ορίσετε το «{ $name }» ως εκτελέσιμο και να το εκκινήσετε; +no-history = Δεν υπάρχουν στοιχεία στο ιστορικό. +emptied-trash = Έγινε άδειασμα του φακέλου «{ trash }» +sort-largest-to-smallest = Από τα μεγαλύτερα στα μικρότερα +restore-from-trash = Ανάκτηση από τα απορρίμματα +moved = + Έγινε μετακίνηση { $items } { $items -> + [one] στοιχείου + *[other] στοιχείων + } από τον φάκελο «{ $from }» στον φάκελο «{ $to }» +progress-cancelled = { $percent }%, ακυρώθηκε +open-in-new-tab = Άνοιγμα σε νέα καρτέλα +unknown-folder = άγνωστος φάκελος +created = Έγινε δημιουργία του «{ $name }» στον φάκελο «{ $parent }» +delete-permanently = Οριστική διαγραφή +write-only = Μόνο εγγραφή +display-settings = Ρυθμίσεις οθόνης... +new-tab = Νέα καρτέλα +failed = Αποτυχημένες +modified = Ημερομηνία τροποποίησης +desktop-appearance = Εμφάνιση επιφάνειας εργασίας... +file-already-exists = Υπάρχει ήδη ένα αρχείο με αυτό το όνομα +permanently-delete-warning = Θα διαγραφούν οριστικά τα εξής: { $target }. Δεν είναι δυνατή η αναίρεση αυτής της ενέργειας. +favorite-path-error-description = + Αδυναμία ανοίγματος του «{ $path }» + Το «{ $path }» ενδέχεται να μην υπάρχει ή να μην έχετε το δικαίωμα να το ανοίξετε + + Θέλετε να το αφαιρέσετε από την πλαϊνή στήλη; +empty-trash-warning = Τα στοιχεία του φακέλου «Απορρίμματα» θα διαγραφούν οριστικά +empty-trash-title = Άδειασμα απορριμμάτων; +type-to-search = Πληκτρολόγηση για αναζήτηση +notification-in-progress = Βρίσκονται σε εξέλιξη διεργασίες αρχείων +name-no-slashes = Το όνομα δεν μπορεί να περιέχει καθέτους +replace-title = Το «{ $filename }» υπάρχει ήδη σε αυτήν την τοποθεσία +name-invalid = Το όνομα δεν μπορεί να είναι «{ $filename }» +operations-running = + Εκτέλεση { $running } { $running -> + [one] διεργασίας + *[other] διεργασιών + } ({ $percent }%)... +context-action-confirm-title = Εκτέλεση του «{ $name }»; +pasted-image = Επικολλημένη εικόνα +pasted-text = Επικολλημένο κείμενο +pasted-video = Επικολλημένο βίντεο +show-recents = Φάκελος «Πρόσφατα» στην πλαϊνή στήλη +move-to = Μετακίνηση σε... +copy-path = Αντιγραφή διαδρομής +move-to-title = Επιλογή προορισμού μετακίνησης +selected-items = { $items } επιλεγμένα στοιχεία +context-action = Ενέργεια περιβάλλοντος +copy-to = Αντιγραφή σε... +mixed = Μικτό +type-to-search-select = Επιλέγει την πρώτη αντιστοιχία αρχείου ή φακέλου +clear-recents-history = Απαλοιφή ιστορικού πρόσφατων +context-action-confirm-warning = + Θα εκτελεστεί σε { $items } { $items -> + [one] στοιχείο + *[other] στοιχεία + }. diff --git a/i18n/fi/cosmic_files.ftl b/i18n/fi/cosmic_files.ftl index f22b7b4..f1c3c58 100644 --- a/i18n/fi/cosmic_files.ftl +++ b/i18n/fi/cosmic_files.ftl @@ -405,3 +405,12 @@ removed-from-recents = [one] kohde *[other] kohdetta } viimeaikaisista +mixed = Sekoitettu +context-action = Kontekstitoiminto +context-action-confirm-title = Suoritetaanko "{ $name }"? +context-action-confirm-warning = + Tämä suorittaa { $items } { $items -> + [one] kohteen + *[other] kohdetta + }. +run = Suorita diff --git a/i18n/fr/cosmic_files.ftl b/i18n/fr/cosmic_files.ftl index a461a9f..f1454d2 100644 --- a/i18n/fr/cosmic_files.ftl +++ b/i18n/fr/cosmic_files.ftl @@ -437,3 +437,11 @@ show-recents = Dossier Récents dans la barre latérale copy-path = Copier le chemin clear-recents-history = Effacer l'historique des Récents mixed = Mixte +context-action-confirm-title = Exécuter "{ $name }" ? +context-action-confirm-warning = + Cela exécutera sur { $items } { $items -> + [one] élément + *[other] éléments + }. +run = Exécuter +context-action = Action contextuelle diff --git a/i18n/ga/cosmic_files.ftl b/i18n/ga/cosmic_files.ftl index 5a9aa9a..04d546f 100644 --- a/i18n/ga/cosmic_files.ftl +++ b/i18n/ga/cosmic_files.ftl @@ -434,3 +434,11 @@ show-recents = Fillteán le déanaí sa bharra taoibh clear-recents-history = Glan stair na n-earraí le déanaí copy-path = Cóipeáil an chosán mixed = Measctha +context-action = Gníomh comhthéacsúil +context-action-confirm-title = Rith "{ $name }"? +context-action-confirm-warning = + Rithfidh sé seo ar { $items } { $items -> + [one] mhír + *[other] míreanna + }. +run = Rith diff --git a/i18n/hu/cosmic_files.ftl b/i18n/hu/cosmic_files.ftl index 6a87c44..2cf31e6 100644 --- a/i18n/hu/cosmic_files.ftl +++ b/i18n/hu/cosmic_files.ftl @@ -437,3 +437,11 @@ show-recents = Legutóbbiak mappa megjelenítése az oldalsávban copy-path = Útvonal másolása clear-recents-history = Legutóbbiak előzményének törlése mixed = Vegyes +context-action = Helyi művelet +context-action-confirm-title = Futtatod ezt: „{ $name }”? +context-action-confirm-warning = + Ez a művelet { $items } { $items -> + [one] elemen + *[other] elemen + } fog lefutni. +run = Futtatás diff --git a/i18n/id/cosmic_files.ftl b/i18n/id/cosmic_files.ftl index 2f1f21b..aefff98 100644 --- a/i18n/id/cosmic_files.ftl +++ b/i18n/id/cosmic_files.ftl @@ -319,3 +319,11 @@ show-recents = Map terbaru di bilah sisi clear-recents-history = Bersihkan riwayat Terbaru copy-path = Salin jalur mixed = Bercampur +context-action = Tindakan konteks +context-action-confirm-title = Jalankan "{ $name }"? +run = Jalankan +context-action-confirm-warning = + Ini akan dijalankan pada { $items } { $items -> + [one] item + *[other] item + }. diff --git a/i18n/kk/cosmic_files.ftl b/i18n/kk/cosmic_files.ftl index 3b97025..8aabf01 100644 --- a/i18n/kk/cosmic_files.ftl +++ b/i18n/kk/cosmic_files.ftl @@ -319,3 +319,11 @@ show-recents = Бүйір панеліндегі «Жуырдағы құжатт clear-recents-history = Жуырдағылар тарихын өшіру copy-path = Орналасқан жолын көшіру mixed = Аралас +context-action = Контекст әрекеті +context-action-confirm-title = "{ $name }" орындау керек пе? +context-action-confirm-warning = + Бұл { $items } орындалады { $items -> + [one] нәрсеге + *[other] нәрсеге + }. +run = Орындау diff --git a/i18n/ko/cosmic_files.ftl b/i18n/ko/cosmic_files.ftl index 3a9f2f6..5683c39 100644 --- a/i18n/ko/cosmic_files.ftl +++ b/i18n/ko/cosmic_files.ftl @@ -277,3 +277,4 @@ copy-to-button-label = 복사 move-to-button-label = 이동 clear-recents-history = 최근 기록 비우기 copy-path = 복사 경로 +move-to-title = 이동 위치 선택 diff --git a/i18n/lo/cosmic_files.ftl b/i18n/lo/cosmic_files.ftl new file mode 100644 index 0000000..e69de29 diff --git a/i18n/lt/cosmic_files.ftl b/i18n/lt/cosmic_files.ftl index acceb7c..2a8e36f 100644 --- a/i18n/lt/cosmic_files.ftl +++ b/i18n/lt/cosmic_files.ftl @@ -1,5 +1,5 @@ progress = { $percent }% -cosmic-files = Cosmic Files +cosmic-files = COSMIC Failai empty-folder = Tuščias aplankas empty-folder-hidden = Tuščias aplankas (turi paslėptų failų) no-results = Rezultatų nėra @@ -76,7 +76,7 @@ delete = Ištrinti permanently-delete-warning = { $target } bus ištrintas visam laikui. Šis veiksmas yra negrįžtamas. rename-file = Pervadinti failą rename-folder = Pervadinti aplanką -replace = Pakeisti +replace = Keisti replace-title = „{ $filename }“ jau egzistuoja šioje vietoje replace-warning = Ar norite pakeisti tai su tuo, kas yra įrašoma? Keičiant bus pakeistas turinys. replace-warning-operation = Ar norite pakeisti tai? Pakeičiant bus keičiamas turinys. @@ -244,7 +244,7 @@ item-created = Sukurtas: { $created } item-modified = Modifikuota: { $modified } item-accessed = Paskutinė prieiga: { $accessed } calculating = Skaičiuojama... -settings = Nustatymai +settings = Nuostatos single-click = Vieno paspaudimo atidarymas appearance = Išvaizda match-desktop = Pagal darbalaukio temą @@ -280,18 +280,18 @@ quit = Išeiti edit = Redaguoti cut = Iškirpti copy = Kopijuoti -paste = Įklijuoti -select-all = Pažymėti viską -zoom-in = Priartinti +paste = Įdėti +select-all = Žymėti viską +zoom-in = Artinti default-size = Numatytas dydis -zoom-out = Nutolinti +zoom-out = Tolinti view = Rodymas grid-view = Tinklelio išdėstymas list-view = Sąrašo išdėstymas show-hidden-files = Rodyti paslėptus failus list-directories-first = Pirmiau pateikti aplankus gallery-preview = Galerijos peržiūra -menu-settings = Nustatymai... +menu-settings = Nuostatos... menu-about = Apie COSMIC Files... sort = Rikiuoti sort-a-z = A-Ž @@ -302,7 +302,7 @@ sort-smallest-to-largest = Nuo mažiausio iki didžiausio sort-largest-to-smallest = Nuo didžiausio iki mažiausio dark = Tamsus light = Šviesus -comment = COSMIC desktop failų tvarkyklė +comment = COSMIC aplinkos failų tvarkyklė keywords = Aplankas;Tvarkyklė; copy-to-title = Pasirinkti kopijavimo vietą copy-to-button-label = Kopijuoti @@ -317,3 +317,4 @@ clear-recents-history = Išvalyti Neseniai naudotų istoriją copy-to = Kopijuoti į... move-to = Perkeltiį į... copy-path = Kopijuoti kelią +theme = Stilius diff --git a/i18n/pl/cosmic_files.ftl b/i18n/pl/cosmic_files.ftl index b0bc7a8..9af6027 100644 --- a/i18n/pl/cosmic_files.ftl +++ b/i18n/pl/cosmic_files.ftl @@ -438,3 +438,11 @@ show-recents = Ostatnie katalogi w panelu bocznym clear-recents-history = Wyczyść bierzącą historię copy-path = Skopiuj ścieżkę mixed = Mieszane +context-action = Akcja sytuacyjna +context-action-confirm-title = Uruchomić "{ $name }"? +context-action-confirm-warning = + Zostanie uruchomionych { $items } { $items -> + [one] element + *[other] elementów + }. +run = Uruchom diff --git a/i18n/pt-BR/cosmic_files.ftl b/i18n/pt-BR/cosmic_files.ftl index 86ebd88..6d33279 100644 --- a/i18n/pt-BR/cosmic_files.ftl +++ b/i18n/pt-BR/cosmic_files.ftl @@ -437,3 +437,11 @@ show-recents = Pasta de recentes na barra lateral clear-recents-history = Limpar histórico de recentes copy-path = Copiar caminho mixed = Misto +context-action = Ação de contexto +context-action-confirm-title = Executar "{ $name }"? +context-action-confirm-warning = + Isso será executado em { $items } { $items -> + [one] item + *[other] itens + }. +run = Executar diff --git a/i18n/pt/cosmic_files.ftl b/i18n/pt/cosmic_files.ftl index 33921f1..211b094 100644 --- a/i18n/pt/cosmic_files.ftl +++ b/i18n/pt/cosmic_files.ftl @@ -352,3 +352,5 @@ sort-newest-first = Mais recentes primeiro sort-oldest-first = Mais antigos primeiro sort-smallest-to-largest = Do menor para o maior sort-largest-to-smallest = Do maior para o menor +context-action-confirm-title = Executar "{ $name }"? +run = Executar diff --git a/i18n/ru/cosmic_files.ftl b/i18n/ru/cosmic_files.ftl index e9673f1..f8e76c1 100644 --- a/i18n/ru/cosmic_files.ftl +++ b/i18n/ru/cosmic_files.ftl @@ -381,3 +381,11 @@ show-recents = «Недавние документы» в бок. панели clear-recents-history = Очистить историю недавних copy-path = Копировать путь mixed = Смешанные +context-action = Контекстная команда +context-action-confirm-title = Выполнить «{ $name }»? +context-action-confirm-warning = + Команда затронет { $items } { $items -> + [one] элемент + *[other] элем. + }. +run = Выполнить diff --git a/i18n/sr/cosmic_files.ftl b/i18n/sr/cosmic_files.ftl index e69de29..b71afe5 100644 --- a/i18n/sr/cosmic_files.ftl +++ b/i18n/sr/cosmic_files.ftl @@ -0,0 +1,329 @@ +open-file = Отвори датотеку +quit = Изађи +cancel = Откажи +open = Отвори +run = Покрени +connect = Повежи +save = Сачувај +password = Лозинка +remove = Уклони +appearance = Изглед +username = Корисничко име +light = Светла +dark = Тамна +settings = Подешавања +replace = Замени +size = Величина +sort-newest-first = Најновије прво +default-app = { $name } (подразумевано) +renamed = Преименована „{ $from }“ у „{ $to }“ +read-execute = Читање и извршавање +deleted = + Обрисано је { $items } { $items -> + [one] ставка + *[other] ставки + } из { trash } +item-modified = Измењено: { $modified } +dismiss = Одбаци поруку +list-view = Преглед у виду списака +reload-folder = Поново учитај фасциклу +copy_noun = Копија +favorite-path-error = Грешка при отварању директоријума +progress = { $percent }% +remove-from-sidebar = Уклони из бочне траке +related-apps = Повезани програми +restoring = + Враћање { $items } { $items -> + [one] ставке + *[other] ставки + } из { trash } ({ $progress })... +network-drive-error = Немогуће приступити мрежном уређају +gallery-preview = Преглед галерије +sort-smallest-to-largest = Од најмање до највеће +zoom-in = Увећајте приказ +select-all = Означи све +icon-size-and-spacing = Величина и размак иконица +removing-from-recents = + Уклањање { $items } { $items -> + [one] ставке + *[other] ставки + } из { recents } +cosmic-files = Космик датотеке +type-to-search-enter-path = Уноси путању до директоријума или датотеке +trash = Смеће +emptying-trash = Пражњење { trash } ({ $progress })... +trashed-on = Премештено у смеће +new-window = Нови прозор +zoom-out = Умањите приказ +compressing = + Сажимање { $items } { $items -> + [one] ставке + *[other] ставки + } из „{ $from }“ у „{ $to }“ ({ $progress })... +move-to-trash = Премести у смеће +menu-about = О програму Космик Датотеке... +setting-executable-and-launching = Подешавање „{ $name }“ као извршне датотеке и покретање +open-multiple-files = Отвори више датотека +default-size = Подразумевана величина +menu-open-with = Отвори програмом... +extracted = + Извлачено { $items } { $items -> + [one] ставка + *[other] ставки + } из „{ $from }“ у „{ $to }“ +create-new-folder = Направи нову фасциклу +original-file = Изворна датотека +create = Направи +create-archive = Направи архиву +read-write-execute = Читање, уписивање и извршавање +other-apps = Остали програми +set-permissions = Овлашћења за „{ $name }“ су постављена на { $mode } +pause = Паузирај +calculating = Израчунавам… +sort-by-size = Поређај по величини +rename = Преименуј... +empty-folder-hidden = Празна фасцикла (има сакривених ставки) +keep = Задржи +item-size = Величина: { $size } +permanently-deleting = + Трајно брисање { $items } { $items -> + [one] ставке + *[other] ставки + } +edit = Уреди +connecting = Повезујем се... +read-write = Читање и уписивање +copy = Умножи +none = Ништа +items = Ставки: { $items } +no-results = Нису пронађени резултати +theme = Тема +type = Врста: { $mime } +compressed = + Сажето { $items } { $items -> + [one] ставка + *[other] ставки + } из „{ $from }“ у „{ $to }“ +replace-warning = Да ли желите да га замените оним који снимате? Замена ће преписати његов садржај. +rename-folder = Преименуј фасциклу +new-file = Нова датотека... +close-tab = Затвори језичак +name = Назив +open-in-terminal = Отвори у терминалу +resume = Настави +open-multiple-folders = Отвори више фасцикла +remember-password = Запамти лозинку +show-details = Прикажи детаље +grid-spacing = Размак мреже +extract-to = Распакуј у... +add-network-drive = Додај мрежни уређај +copying = + Умножавање { $items } { $items -> + [one] ставке + *[other] ставки + } из „{ $from }“ у „{ $to }“ ({ $progress })... +delete = Обриши +sort-oldest-first = Најстарије прво +repository = Ризница +create-new-file = Направи нову датотеку +sort-by-trashed = Поређај по времену брисања +replace-warning-operation = Да ли желите да га замените? Замена ће преписати његов садржај. +support = Подршка +try-again = Покушај поново +eject = Избаци +copied = + Умножено { $items } { $items -> + [one] ставке + *[other] ставки + } из „{ $from }“ у „{ $to }“ +other = Друго +open-in-new-window = Отвори у новом прозору +empty-folder = Празна фасцикла +sort-by-modified = Поређај по датуму измене +list-directories-first = Прикажи директоријуме прво +read-only = Само за читање +folder-name = Назив фасцикле +browse-store = Разгледај { $store } +enter-server-address = Унесите адресу сервера +remove-from-recents = Уклони из недавних +connect-anonymously = Повежи се анонимно +group = Група +apply-to-all = Примени на све +skip = Прескочи +paste = Залепи +menu-settings = Подешавања... +moving = + Премештање { $items } { $items -> + [one] датотеке + *[other] датотека + } из „{ $from }“ у „{ $to }“ ({ $progress })... +replace-with = Замени са +recents = Недавно +change-wallpaper = Промени позадину... +network-drive-description = + Адресе сервера укључују префикс протокола и адресу. + Примери: ssh://192.168.0.1, ftp://[2001:db8::1] +deleting = + Брише се { $items } { $items -> + [one] ставка + *[other] ставки + } из { trash } ({ $progress })... +single-click = Један клик за отварање +view = Преглед +undo = Опозови +setting-permissions = Подешавање овлашћења за „{ $name }“ на { $mode } +owner = Власник +creating = Правим „{ $name }“ у „{ $parent }“ +execute-only = Само извршавање +open-item-location = Отвори локацију ставке +details = Детаљи +set-executable-and-launched = Постављено „{ $name }“ као извршну датотеку и покренуто +mounted-drives = Прикључени дискови +sort-a-z = А-Ш +mount-error = Немогуће приступити уређају +extract-here = Извуци +grid-view = Преглед у виду мреже +filesystem = Систем датотека +set-and-launch = Подеси и покрени +removed-from-recents = + Уклоњено { $items } { $items -> + [one] ставке + *[other] ставки + } из { recents } +add-to-sidebar = Додај у страничник +item-created = Направљено: { $created } +network-drive-schemes = + Доступни протоколи,Префикс + ЕплТок,afp:// + Протокол за пренос датотека,ftp:// или ftps:// + Мрежни систем датотека,nfs:// + Серверски блок порука,smb:// + SSH протокол за пренос датотека,sftp:// или ssh:// + ВебДАВ,dav:// или davs:// +home = Лична +set-executable-and-launch = Постави као извршну и покрени +restored = + Враћено { $items } { $items -> + [one] ставка + *[other] ставки + } из { trash } +sort-z-a = Ш-А +type-to-search-recursive = Претражује тренутну фасциклу и све подфасцикле +history = Историјат +progress-paused = { $percent }%, паузирано +desktop-view-options = Могућности приказа радне површине... +show-on-desktop = Прикажи на радној површини +cancelled = Отказано +new-folder = Нова фасцикла... +match-desktop = Прати радну површину +domain = Домен +operations-running-finished = + { $running } { $running -> + [one] радња покренута + *[other] радње покренуте + } ({ $percent }%), { $finished } завршено... +sort-by-name = Поређај по називу +edit-history = Историјат уређивања +sort = Поређај +show-hidden-files = Прикажи скривене датотеке +progress-failed = { $percent }%, није успело +trash-folder-icon = Иконица фасцикле Смеће +item-accessed = Приступљено: { $accessed } +extract-to-title = Распакуј у фасциклу +open-with = Отвори помоћу +keep-both = Задржи оба +icon-size = Величина иконице +open-with-title = Како желите да отворите „{ $name }“? +extracting = + Извлачење { $items } { $items -> + [one] ставке + *[other] ставки + } из „{ $from }“ у „{ $to }“ ({ $progress })... +permanently-deleted = + Трајно обрисано { $items } { $items -> + [one] ставке + *[other] ставки + } +complete = Завршено +write-execute = Писање и извршавање +extract-password-required = Потребна је лозинка +pending = У току +desktop-folder-content = Садржај фасцикле радне површине +renaming = Преименовање „{ $from }“ у „{ $to }“ +set-executable-and-launch-description = Да ли желите да поставите „{ $name }“ као извршну и покренете је? +no-history = Нема ставки у историјату. +open-folder = Отвори фасциклу +emptied-trash = Опражњено { trash } +rename-file = Преименуј датотеку +sort-largest-to-smallest = Од највеће до најмање +restore-from-trash = Врати из смећа +cut = Исеци +moved = + Премештено { $items } { $items -> + [one] датотеке + *[other] датотека + } из „{ $from }“ у „{ $to }“ +progress-cancelled = { $percent }%, отказано +open-in-new-tab = Отвори у новом језичку +unknown-folder = непозната фасцикла +file = Датотека +file-name = Назив датотеке +save-file = Сачувај датотеку +created = Направљено „{ $name }“ у „{ $parent }“ +delete-permanently = Трајно обриши +networks = Мреже +write-only = Само писање +today = Данас +display-settings = Подешавања екрана... +new-tab = Нови језичак +failed = Неуспешно +modified = Измењено +desktop-appearance = Изглед радне површине... +file-already-exists = Датотека са овим називом већ постоји +name-hidden = Називи који почињу тачком „.“ ће бити сакривени +folder-already-exists = Фасцикла са овим називом већ постоји +permanently-delete-warning = { $target } ће бити трајно обрисано. Ова радња се не може поништити. +favorite-path-error-description = + Не можемо да отворимо „{ $path }“ + „{ $path }“ можда не постоји или немате дозволу за његово отварање + + Желите ли да га уклоните из бочне површи? +empty-trash-warning = Ставке у смећу биће трајно обрисане +empty-trash = Испразни смеће +empty-trash-title = Испразнити смеће? +type-to-search = Куцајте за претрагу +notification-in-progress = Радње са датотекама су у току +name-no-slashes = Назив не може садржати косе црте +permanently-delete-question = Трајно обриши? +replace-title = „{ $filename }“ већ постоји на овој локацији +name-invalid = Назив не може бити „{ $filename }“ +operations-running = + { $running } { $running -> + [one] радња покренута + *[other] радње покренуте + } ({ $percent }%)... +comment = Управник датотека за Космик радну површину +keywords = Folder;Manager;Фасцикла;Управник;fascikla;upravnik; +copy-to-title = Изабери одредиште умножавања +copy-to-button-label = Умножи +move-to-title = Изабери одредиште премештања +move-to-button-label = Помери +context-action = Контекстна радња +context-action-confirm-title = Покрени „{ $name }“? +context-action-confirm-warning = + Ово ће се извршити на { $items } { $items -> + [one] ставку + *[other] ставки + }. +selected-items = Изабраних { $items } ставки +mixed = Помешано +pasted-image = Убачена слика +pasted-text = Убачен текст +pasted-video = Убачен видео +show-recents = Недавна фасцикла у бочној површи +type-to-search-select = Обира прву подударајућу датотеку или фасциклу +clear-recents-history = Очисти историју недавних +compress = Сажми... +copy-to = Умножи у... +move-to = Помери у... +copy-path = Умножи путању diff --git a/i18n/sv/cosmic_files.ftl b/i18n/sv/cosmic_files.ftl index cbd28dd..974c7dc 100644 --- a/i18n/sv/cosmic_files.ftl +++ b/i18n/sv/cosmic_files.ftl @@ -410,3 +410,11 @@ move-to = Flytta till... show-recents = Mapp för senast använda filer i sidofältet clear-recents-history = Töm historik för Senaste copy-path = Kopiera sökväg +context-action = Kontextåtgärd +context-action-confirm-title = Kör "{ $name }"? +context-action-confirm-warning = + Detta kommer att köras på { $items } { $items -> + [one] objekt + *[other] objekt + }. +run = Kör diff --git a/i18n/uk/cosmic_files.ftl b/i18n/uk/cosmic_files.ftl index 611c2b1..7299a7d 100644 --- a/i18n/uk/cosmic_files.ftl +++ b/i18n/uk/cosmic_files.ftl @@ -5,7 +5,7 @@ filesystem = Файлова система home = Домівка trash = Смітник recents = Нещодавні -undo = Відмінити +undo = Скасувати # List view name = Назва modified = Змінено @@ -86,6 +86,7 @@ copying = copied = Скопійовано { $items } { $items -> [one] елемент + [few] елементи *[other] елеменів } з «{ $from }» в «{ $to }» emptying-trash = Спорожнення { trash } ({ $progress })... @@ -98,7 +99,8 @@ moving = moved = Переміщено { $items } { $items -> [one] елемент - *[other] елементи + [few] елементи + *[other] елементів } з «{ $from }» в «{ $to }» renaming = Перейменування «{ $from }» на «{ $to }» renamed = Перейменовано «{ $from }» на «{ $to }» @@ -110,7 +112,8 @@ restoring = restored = Відновлено { $items } { $items -> [one] елемент - *[other] елементи + [few] елементи + *[other] елементів } з { trash } unknown-folder = невідома тека @@ -223,7 +226,7 @@ permanently-delete-question = Остаточно видалити? delete = Видалити permanently-delete-warning = { $target } буде остаточно видалено. Цю дію не можна скасувати. set-executable-and-launch = Зробити виконуваним і запустити -set-executable-and-launch-description = Бажаєте зробити "{ $name }" виконуваним і запустити його? +set-executable-and-launch-description = Бажаєте зробити «{ $name }» виконуваним і запустити його? set-and-launch = Зробити і запустити open-with = Відкрити за допомогою owner = Власник @@ -245,7 +248,7 @@ favorite-path-error-description = Вилучити з бічної панелі? keep = Залишити add-network-drive = Додати мережевий диск -connect = З'єднати +connect = З’єднати connect-anonymously = З'єднатись анонімно connecting = З'єднання… domain = Домен @@ -274,12 +277,13 @@ compressing = Стиснення { $items } { $items -> [one] елемента *[other] елементів - } з "{ $from }" до "{ $to }" ({ $progress })... + } з «{ $from }» до «{ $to }» ({ $progress })... compressed = Стиснуто { $items } { $items -> [one] елемент - *[other] елементи - } з "{ $from }" до "{ $to }" + [few] елементи + *[other] елементів + } з «{ $from }» до «{ $to }» deleting = Видалення { $items } { $items -> [one] елемента @@ -288,6 +292,7 @@ deleting = deleted = Видалено { $items } { $items -> [one] елемент + [few] елементи *[other] елементи } з { trash } extracting = @@ -298,7 +303,8 @@ extracting = extracted = Видобуто { $items } { $items -> [one] елемент - *[other] елементи + [few] елементи + *[other] елементів } з «{ $from }» в «{ $to }» setting-executable-and-launching = Надання «{ $name }» прав на виконання та запуск set-executable-and-launched = «{ $name }» надано права на виконання і відкрито @@ -343,7 +349,8 @@ permanently-deleting = permanently-deleted = Остаточно вилучено { $items } { $items -> [one] елемент - *[other] елементи + [few] елементи + *[other] елементів } removing-from-recents = Вилучення { $items } { $items -> @@ -353,13 +360,14 @@ removing-from-recents = removed-from-recents = Вилучено { $items } { $items -> [one] елемент - *[other] елементи + [few] елементи + *[other] елементів } з { recents } empty-trash-title = Спорожити смітник? type-to-search-select = Вибирає перший відповідний файл або папку -pasted-image = Вставлене Зображення -pasted-text = Вставлений Текст -pasted-video = Вставлене Видиво +pasted-image = Вставлене зображення +pasted-text = Вставлений текст +pasted-video = Вставлене відео copy-to-button-label = Копіювати move-to-button-label = Перемістити copy-to = Копіювати до… @@ -371,3 +379,11 @@ keywords = Тека;Папка;Провідник;Менеджер;Катало show-recents = Тека «Нещодавні» на бічній панелі copy-path = Копіювати шлях clear-recents-history = Очистити нещодавні +context-action-confirm-title = Запустити «{ $name }»? +run = Виконати +context-action-confirm-warning = + Запуститься для { $items } { $items -> + [one] елемента + *[other] елементів + }. +context-action = Контекстна дія diff --git a/i18n/zh-CN/cosmic_files.ftl b/i18n/zh-CN/cosmic_files.ftl index 11441d1..abc8fda 100644 --- a/i18n/zh-CN/cosmic_files.ftl +++ b/i18n/zh-CN/cosmic_files.ftl @@ -167,7 +167,7 @@ read-write-execute = 读取、写入和执行 ## Favorite Path Error Dialog -favorite-path-error = 打开路径时出错 +favorite-path-error = 打开目录时出错 favorite-path-error-description = 无法打开 "{ $path }" 。 "{ $path }" 可能不存在或您没有权限打开它。 @@ -348,7 +348,7 @@ light = 亮色模式 type-to-search = 输入即可搜索 type-to-search-recursive = 搜索当前文件夹及其所有子文件夹 -type-to-search-enter-path = 输入文件夹或文件路径 +type-to-search-enter-path = 输入文件夹或文件目录 # Context menu add-to-sidebar = 加入侧边栏 compress = 压缩… @@ -437,3 +437,11 @@ clear-recents-history = 清除最近访问历史 copy-path = 复制文件路径 show-recents = 侧边栏中的最近访问 mixed = 混合 +context-action-confirm-title = 运行 “{ $name }” ? +run = 运行 +context-action-confirm-warning = + 该行动将会在 { $items } { $items -> + [one] 项目 + *[other] 项目 + } 上运行。 +context-action = 环境行动 diff --git a/i18n/zh-TW/cosmic_files.ftl b/i18n/zh-TW/cosmic_files.ftl index 2bf8e5b..b356db3 100644 --- a/i18n/zh-TW/cosmic_files.ftl +++ b/i18n/zh-TW/cosmic_files.ftl @@ -42,7 +42,7 @@ name-no-slashes = 名稱不能包含斜線 ## Open/Save Dialog cancel = 取消 -create = 創作 +create = 建立 open = 開啟 open-file = 開啟檔案 open-folder = 開啟資料夾 @@ -358,7 +358,7 @@ calculating = 計算中... single-click = 點按以開啟 type-to-search = 輸入進行搜尋 type-to-search-recursive = 搜尋目前資料夾及全部子資料夾 -type-to-search-enter-path = 輸入目錄或檔案的路徑 +type-to-search-enter-path = 輸入目錄或檔案的目錄 delete-permanently = 永久刪除 eject = 彈出 remove-from-recents = 從最近項目中移除 @@ -384,3 +384,11 @@ set-executable-and-launched = 設定「{ $name }」為可以執行並已經啟 setting-permissions = 設定「{ $name }」的權限至 { $mode } set-permissions = 設定「{ $name }」的權限至 { $mode } mixed = 混合 +context-action = 環境行動 +context-action-confirm-title = 執行「{ $name }」嗎? +context-action-confirm-warning = + 該行動將會在 { $items } { $items -> + [one] 項目 + *[other] 項目 + } 上執行。 +run = 執行 From 4b5c6d2c1b12de3b7d23d087bbaa0f6d92f14ae4 Mon Sep 17 00:00:00 2001 From: lorduskordus Date: Sat, 11 Apr 2026 11:39:52 +0200 Subject: [PATCH 064/110] fix(i18n): use separate 'rename' keys for menu and dialog confirm button --- i18n/en/cosmic_files.ftl | 1 + src/app.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 69a76c6..45965ef 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -116,6 +116,7 @@ permanently-delete-warning = {$target} will be permanently deleted. This action ## Rename Dialog rename-file = Rename file rename-folder = Rename folder +rename-confirm = Rename ## Replace Dialog replace = Replace diff --git a/src/app.rs b/src/app.rs index 2185241..bc0f08b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -6140,7 +6140,7 @@ impl Application for App { dialog .primary_action( - widget::button::suggested(fl!("rename")) + widget::button::suggested(fl!("rename-confirm")) .on_press_maybe(complete_maybe.clone()), ) .secondary_action( From b4df354585f72b508ee6086e37f2a8715d233677 Mon Sep 17 00:00:00 2001 From: Rrogntudju Date: Mon, 11 May 2026 19:53:42 -0400 Subject: [PATCH 065/110] don't overwrite military time --- src/app.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index bc0f08b..cc3e5c0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2949,10 +2949,12 @@ impl Application for App { Message::Config(config) => { if config != self.config { log::info!("update config"); - // Show details is preserved for existing instances + // Show details and military time are preserved for existing instances let show_details = self.config.show_details; + let military_time = self.config.tab.military_time; self.config = config; self.config.show_details = show_details; + self.config.tab.military_time = military_time; return self.update_config(); } } From f9b215dbd4e317deee0d3383e075e796459286d6 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 12 May 2026 09:39:19 -0600 Subject: [PATCH 066/110] Epoch 1.0.13 version update Generated by cosmic-epoch scripts/version-update.sh --- Cargo.lock | 143 ++++++++++++++++++--------------- Cargo.toml | 2 +- cosmic-files-applet/Cargo.toml | 2 +- debian/changelog | 6 ++ 4 files changed, 84 insertions(+), 69 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57ff41b..56ebce6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -651,9 +651,9 @@ dependencies = [ [[package]] name = "avif-serialize" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375082f007bd67184fb9c0374614b29f9aaa604ec301635f72338bb65386a53d" +checksum = "e7178fe5f7d460b13895ebb9dcb28a3a6216d2df2574a0806cb51b555d297f38" dependencies = [ "arrayvec", ] @@ -794,6 +794,15 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "bstr" version = "1.12.1" @@ -916,9 +925,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.61" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "jobserver", @@ -1342,7 +1351,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1363,7 +1372,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "quote", "syn", @@ -1371,7 +1380,7 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.0.12" +version = "1.0.13" dependencies = [ "anyhow", "atomic_float", @@ -1439,7 +1448,7 @@ dependencies = [ [[package]] name = "cosmic-files-applet" -version = "1.0.12" +version = "1.0.13" dependencies = [ "cosmic-files", "log", @@ -1533,7 +1542,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "almost", "configparser", @@ -2197,13 +2206,12 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.27" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +checksum = "2d5b2eef6fafbf69f877e55509ce5b11a760690ac9700a2921be067aa6afaef6" dependencies = [ "cfg-if", "libc", - "libredox", ] [[package]] @@ -2906,9 +2914,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -2951,9 +2959,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" dependencies = [ "typenum", ] @@ -3052,7 +3060,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "dnd", "iced_accessibility", @@ -3073,7 +3081,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "accesskit", "accesskit_winit", @@ -3082,7 +3090,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "bitflags 2.11.1", "bytes", @@ -3106,7 +3114,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "iced_core", "iced_futures", @@ -3116,7 +3124,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "futures", "iced_core", @@ -3130,7 +3138,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -3151,7 +3159,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "iced_graphics", "iced_runtime", @@ -3160,7 +3168,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3172,7 +3180,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3187,7 +3195,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "bytemuck", "cosmic-text", @@ -3204,7 +3212,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.1", @@ -3235,7 +3243,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3253,7 +3261,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3803,7 +3811,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -4066,9 +4074,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.97" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ "cfg-if", "futures-util", @@ -4313,9 +4321,9 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7b65860415f949f23fa882e669f2dbd4a0f0eeb1acdd56790b30494afd7da2f" +checksum = "285efcf12ef41bec907b3000d5ffaeb54191d4d9d83c0d6157e6cbc2db255e64" dependencies = [ "bitflags 2.11.1", "libc", @@ -4362,9 +4370,9 @@ checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" [[package]] name = "libbz2-rs-sys" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a6a8c165077efc8f3a971534c50ea6a1a18b329ef4a66e897a7e3a1494565f" +checksum = "f8fc329e1457d97a9d58a4e2ca49e3be572431a7e096008efc2e3a3c19d428f4" [[package]] name = "libc" @@ -4375,7 +4383,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#0e0960f3c79138b445ae84f7ac6f91d4db36e8b4" +source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" dependencies = [ "apply", "ashpd 0.12.3", @@ -5276,9 +5284,9 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "open" -version = "5.3.4" +version = "5.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3bab717c29a857abf75fcef718d441ec7cb2725f937343c734740a985d37fd" +checksum = "2fbaa89d2ddc8473c78a3adf69eea8cffa28c483b8e02a971ef31527cd0fc92c" dependencies = [ "is-wsl", "libc", @@ -5866,9 +5874,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.39.3" +version = "0.39.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721da970c312655cde9b4ffe0547f20a8494866a4af5ff51f18b7c633d0c870b" +checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" dependencies = [ "memchr", "serde", @@ -6488,11 +6496,12 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.19.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05839ce67618e14a09b286535c0d9c94e85ef25469b0e13cb4f844e5593eb19" +checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" dependencies = [ "base64", + "bs58", "chrono", "hex", "indexmap 1.9.3", @@ -6507,9 +6516,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.19.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2ebbe86054f9b45bc3881e865683ccfaccce97b9b4cb53f3039d67f355a334" +checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" dependencies = [ "darling 0.23.0", "proc-macro2", @@ -6828,9 +6837,9 @@ dependencies = [ [[package]] name = "synchrony" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c174d82fd56da8214ec095cfe4568e59e5ccb49d060e70c2f98e3ba352b23e45" +checksum = "416090a4d8f6358526df5f9f65dfe28750b8b7bfd1fd8a5620f483fc4a75722c" dependencies = [ "futures-util", "loom", @@ -7158,9 +7167,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.52.2" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "110a78583f19d5cdb2c5ccf321d1290344e71313c6c37d43520d386027d18386" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -7631,9 +7640,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.120" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if", "once_cell", @@ -7644,9 +7653,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.70" +version = "0.4.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084" +checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" dependencies = [ "js-sys", "wasm-bindgen", @@ -7654,9 +7663,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.120" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7664,9 +7673,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.120" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", @@ -7677,9 +7686,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.120" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] @@ -7853,7 +7862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a" dependencies = [ "proc-macro2", - "quick-xml 0.39.3", + "quick-xml 0.39.4", "quote", ] @@ -7884,9 +7893,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.97" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eadbac71025cd7b0834f20d1fe8472e8495821b4e9801eb0a60bd1f19827602" +checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" dependencies = [ "js-sys", "wasm-bindgen", @@ -9081,9 +9090,9 @@ dependencies = [ [[package]] name = "xml" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8aa498d22c9bbaf482329839bc5620c46be275a19a812e9a22a2b07529a642a" +checksum = "636f85e5ca6488e96401b61eb7de54f4e44755c988af0f52cf90230c312a1a89" [[package]] name = "xml-rs" @@ -9301,7 +9310,7 @@ version = "5.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8067892e940ed1727dea64690378601603b31d62dfde019a5335fbb7c0e0ed9" dependencies = [ - "quick-xml 0.39.3", + "quick-xml 0.39.4", "serde", "zbus_names 4.3.2", "zvariant 5.11.0", @@ -9335,9 +9344,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] diff --git a/Cargo.toml b/Cargo.toml index b14c8be..9059e13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.0.12" +version = "1.0.13" 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 282146e..8fcf2bd 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files-applet" -version = "1.0.12" +version = "1.0.13" edition = "2024" [dependencies] diff --git a/debian/changelog b/debian/changelog index f9db4ff..e4697d2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-files (1.0.13) noble; urgency=medium + + * Epoch 1.0.13 version update + + -- Jeremy Soller Tue, 12 May 2026 09:39:14 -0600 + cosmic-files (1.0.12) noble; urgency=medium * Epoch 1.0.12 version update From 03e537abade4a99923a8d1b2d32e7e20c4254033 Mon Sep 17 00:00:00 2001 From: Oleg Bespalov Date: Sun, 8 Mar 2026 13:42:55 +0100 Subject: [PATCH 067/110] feat: add text preview for thumbnails and gallery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Preview text files (≤8 MiB) in grid and gallery: read up to 256 KiB, handle invalid UTF-8, skip empty files. Add unit tests. Lets users peek at .txt without opening; size caps avoid blocking the UI. --- src/tab.rs | 132 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 121 insertions(+), 11 deletions(-) diff --git a/src/tab.rs b/src/tab.rs index ea784c6..25d271b 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -36,7 +36,7 @@ use std::error::Error; use std::fmt::{self, Display}; use std::fs::{self, File, Metadata}; use std::hash::Hash; -use std::io::{BufRead, BufReader}; +use std::io::{BufRead, BufReader, Read}; #[cfg(unix)] use std::os::unix::fs::MetadataExt; use std::path::{self, Path, PathBuf}; @@ -75,6 +75,11 @@ const MAX_SEARCH_LATENCY: Duration = Duration::from_millis(20); const MAX_SEARCH_RESULTS: usize = 200; //TODO: configurable thumbnail size? const THUMBNAIL_SIZE: u32 = (ICON_SIZE_GRID as u32) * (ICON_SCALE_MAX as u32); +/// Maximum bytes of text to pass to the editor for preview; caps shaping work to avoid blocking. +/// Files larger than this get a truncated preview (first N bytes only). +const TEXT_PREVIEW_MAX_BYTES: usize = 256 * 1024; // 256 KiB +/// Maximum file size (bytes) to attempt text preview; files larger than this are skipped entirely. +const TEXT_PREVIEW_MAX_FILE_BYTES: u64 = 8 * 1000 * 1000; // 8 MiB // Thumbnail generation semaphore - limits parallel thumbnail workers // Uses 4 workers for balanced throughput and memory usage @@ -2070,17 +2075,37 @@ impl ItemThumbnail { log::warn!("failed to read {}: {}", path.display(), err); } } - } else if mime.type_() == mime::TEXT && check_size("text", 8 * 1000 * 1000) { - /*TODO: fix performance issues, widget::text_editor::Content::with_text forces all text to shape, which blocks rendering - match fs::read_to_string(&path) { - Ok(data) => { - return ItemThumbnail::Text(widget::text_editor::Content::with_text(&data)); - } - Err(err) => { - log::warn!("failed to read {}: {}", path.display(), err); + } else if mime.type_() == mime::TEXT && check_size("text", TEXT_PREVIEW_MAX_FILE_BYTES) { + tried_supported_file = true; + if size > 0 { + // Reuse size from metadata above; cap allocation and read + let read_cap = (size.min(TEXT_PREVIEW_MAX_BYTES as u64)) as usize; + let mut buf = vec![0u8; read_cap]; + match File::open(path).and_then(|f| { + let n = Read::read(&mut f.take(read_cap as u64), &mut buf)?; + buf.truncate(n); + Ok(()) + }) { + Ok(()) => { + let text = match std::str::from_utf8(&buf) { + Ok(s) => s.to_string(), + Err(e) => { + // Use only the valid UTF-8 prefix (slice is guaranteed valid by valid_up_to()) + std::str::from_utf8(&buf[..e.valid_up_to()]) + .unwrap_or("") + .to_string() + } + }; + if !text.is_empty() { + return Self::Text(widget::text_editor::Content::with_text(&text)); + } + } + Err(err) => { + log::warn!("failed to read {}: {}", path.display(), err); + } } } - */ + // size == 0: empty file or unknown size; skip read and allocation } // If we weren't able to create a thumbnail, but we should have @@ -7053,10 +7078,13 @@ mod tests { use cosmic::iced::runtime::keyboard::Modifiers; use cosmic::widget; use log::{debug, trace}; + use mime_guess::mime; use tempfile::TempDir; use test_log::test; - use super::{Location, Message, Tab, respond_to_scroll_direction, scan_path}; + use super::{ + ItemMetadata, ItemThumbnail, Location, Message, Tab, respond_to_scroll_direction, scan_path, + }; use crate::app::test_utils::{ NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED, assert_eq_tab_path, empty_fs, eq_path_item, filter_dirs, read_dir_sorted, simple_fs, tab_click_new, @@ -7474,4 +7502,86 @@ mod tests { } } } + + #[test] + fn item_thumbnail_text_preview_small_utf8_returns_text() -> io::Result<()> { + let dir = TempDir::new()?; + let path = dir.path().join("preview.txt"); + fs::write(&path, "Hello, world!")?; + let metadata = fs::metadata(&path)?; + let item_metadata = ItemMetadata::Path { + metadata, + children_opt: None, + }; + let thumb = ItemThumbnail::new( + &path, + item_metadata, + mime::TEXT_PLAIN, + 128, + 100 * 1024 * 1024, + 1, + 8, + ); + assert!( + matches!(thumb, ItemThumbnail::Text(_)), + "small text file should produce Text thumbnail" + ); + Ok(()) + } + + #[test] + fn item_thumbnail_text_preview_empty_file_returns_not_image() -> io::Result<()> { + let dir = TempDir::new()?; + let path = dir.path().join("empty.txt"); + fs::File::create(&path)?; + let metadata = fs::metadata(&path)?; + let item_metadata = ItemMetadata::Path { + metadata, + children_opt: None, + }; + let thumb = ItemThumbnail::new( + &path, + item_metadata, + mime::TEXT_PLAIN, + 128, + 100 * 1024 * 1024, + 1, + 8, + ); + assert!( + matches!(thumb, ItemThumbnail::NotImage), + "empty text file should produce NotImage (no read)" + ); + Ok(()) + } + + #[test] + fn item_thumbnail_text_preview_invalid_utf8_uses_valid_prefix() -> io::Result<()> { + let dir = TempDir::new()?; + let path = dir.path().join("invalid_utf8.txt"); + // Valid UTF-8 "ab" then invalid byte sequence then "c" + fs::write(&path, b"ab\xff\xfe\xfdc")?; + let metadata = fs::metadata(&path)?; + let item_metadata = ItemMetadata::Path { + metadata, + children_opt: None, + }; + let thumb = ItemThumbnail::new( + &path, + item_metadata, + mime::TEXT_PLAIN, + 128, + 100 * 1024 * 1024, + 1, + 8, + ); + match &thumb { + ItemThumbnail::Text(content) => { + // Text editor content may add a trailing newline + assert_eq!(content.text().trim_end(), "ab"); + } + _ => panic!("expected Text thumbnail with valid prefix only, got {:?}", thumb), + } + Ok(()) + } } From 784200a25309d60bda6c375c1de56b27f2c6b320 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 18 May 2026 13:57:04 -0400 Subject: [PATCH 068/110] Fix 24h time format in file dialog (#1812) * Assign parameter config the proper way * Don't overwrite military time --------- Co-authored-by: Rrogntudju --- src/dialog.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dialog.rs b/src/dialog.rs index 9041670..69714f9 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -825,9 +825,10 @@ impl App { fn update_config(&mut self) -> Task { self.core.window.show_context = self.flags.config.dialog.show_details; - self.tab.config = self.flags.config.dialog_tab(); + let config = self.flags.config.dialog_tab(); + self.tab.config.view = config.view; self.update_nav_model(); - self.update(Message::TabMessage(tab::Message::Config(self.tab.config))) + self.update(Message::TabMessage(tab::Message::Config(config))) } fn with_dialog_config(&mut self, f: F) -> Task { @@ -1393,7 +1394,10 @@ impl Application for App { Message::Config(config) => { if config != self.flags.config { log::info!("update config"); + // Don't overwrite military time + let military_time = self.flags.config.tab.military_time; self.flags.config = config; + self.flags.config.tab.military_time = military_time; return self.update_config(); } } From 5d1c056bed8c122f20a3b24053c51a951c484cdf Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 25 May 2026 21:11:35 +0200 Subject: [PATCH 069/110] i18n: translation updates from weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Aindriú Mac Giolla Eoin Co-authored-by: Dan Co-authored-by: Fedorov Alexei Co-authored-by: Hosted Weblate Co-authored-by: Hugo Carvalho Co-authored-by: Jim Spentzos Co-authored-by: Jiri Grönroos Co-authored-by: Julien Brouillard Co-authored-by: Mattias Eriksson Co-authored-by: Thomas Worofsky Co-authored-by: VandaL Co-authored-by: Walter William Beckerleg Bruckman Co-authored-by: lorduskordus Co-authored-by: oddib <60390653+oddib@users.noreply.github.com> Co-authored-by: therealmate Co-authored-by: Димко Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/cs/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/de/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/el/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/fi/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/fr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ga/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/nb_NO/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/pl/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/pt/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ru/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/sv/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/uk/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/zh_Hant/ Translation: Pop OS/COSMIC Files --- i18n/cs/cosmic_files.ftl | 1 + i18n/de/cosmic_files.ftl | 1 + i18n/el/cosmic_files.ftl | 1 + i18n/fi/cosmic_files.ftl | 1 + i18n/fr/cosmic_files.ftl | 1 + i18n/ga/cosmic_files.ftl | 1 + i18n/hu/cosmic_files.ftl | 37 +++++++++++++++++++------------------ i18n/nb-NO/cosmic_files.ftl | 8 ++++---- i18n/pl/cosmic_files.ftl | 1 + i18n/pt-BR/cosmic_files.ftl | 1 + i18n/pt/cosmic_files.ftl | 1 + i18n/ru/cosmic_files.ftl | 1 + i18n/sv/cosmic_files.ftl | 1 + i18n/uk/cosmic_files.ftl | 11 ++++++----- i18n/zh-CN/cosmic_files.ftl | 1 + i18n/zh-TW/cosmic_files.ftl | 1 + 16 files changed, 42 insertions(+), 27 deletions(-) diff --git a/i18n/cs/cosmic_files.ftl b/i18n/cs/cosmic_files.ftl index 29814ba..fac1794 100644 --- a/i18n/cs/cosmic_files.ftl +++ b/i18n/cs/cosmic_files.ftl @@ -427,3 +427,4 @@ context-action-confirm-warning = *[other] položek }. run = Spustit +rename-confirm = Přejmenovat diff --git a/i18n/de/cosmic_files.ftl b/i18n/de/cosmic_files.ftl index 993af2d..65a5ebf 100644 --- a/i18n/de/cosmic_files.ftl +++ b/i18n/de/cosmic_files.ftl @@ -437,3 +437,4 @@ context-action-confirm-warning = *[other] Elementen }. run = Ausführen +rename-confirm = Umbenennen diff --git a/i18n/el/cosmic_files.ftl b/i18n/el/cosmic_files.ftl index 7471630..c75e419 100644 --- a/i18n/el/cosmic_files.ftl +++ b/i18n/el/cosmic_files.ftl @@ -327,3 +327,4 @@ context-action-confirm-warning = [one] στοιχείο *[other] στοιχεία }. +rename-confirm = Μετονομασία diff --git a/i18n/fi/cosmic_files.ftl b/i18n/fi/cosmic_files.ftl index f1c3c58..6000bc7 100644 --- a/i18n/fi/cosmic_files.ftl +++ b/i18n/fi/cosmic_files.ftl @@ -414,3 +414,4 @@ context-action-confirm-warning = *[other] kohdetta }. run = Suorita +rename-confirm = Nimeä uudelleen diff --git a/i18n/fr/cosmic_files.ftl b/i18n/fr/cosmic_files.ftl index f1454d2..7301596 100644 --- a/i18n/fr/cosmic_files.ftl +++ b/i18n/fr/cosmic_files.ftl @@ -445,3 +445,4 @@ context-action-confirm-warning = }. run = Exécuter context-action = Action contextuelle +rename-confirm = Renommer diff --git a/i18n/ga/cosmic_files.ftl b/i18n/ga/cosmic_files.ftl index 04d546f..773c2fa 100644 --- a/i18n/ga/cosmic_files.ftl +++ b/i18n/ga/cosmic_files.ftl @@ -442,3 +442,4 @@ context-action-confirm-warning = *[other] míreanna }. run = Rith +rename-confirm = Athainmnigh diff --git a/i18n/hu/cosmic_files.ftl b/i18n/hu/cosmic_files.ftl index 2cf31e6..c81703b 100644 --- a/i18n/hu/cosmic_files.ftl +++ b/i18n/hu/cosmic_files.ftl @@ -2,7 +2,7 @@ cosmic-files = COSMIC Fájlok comment = Fájlkezelő a COSMIC asztali környezethez keywords = mappa;fájl;kezelő; empty-folder = Üres mappa -empty-folder-hidden = Üres mappa (Rejtett elemeket tartalmaz) +empty-folder-hidden = Üres mappa (rejtett elemeket tartalmaz) no-results = Nincs találat filesystem = Fájlrendszer home = Saját mappa @@ -47,13 +47,13 @@ resume = Folytatás ## Compress Dialog -create-archive = Tömörített fájl létrehozása +create-archive = Archívum létrehozása ## Extract Dialog extract-password-required = Jelszó szükséges extract-to = Kibontás ide… -extract-to-title = Kibontás mappába +extract-to-title = Kibontási cél kiválasztása ## Empty Trash Dialog @@ -93,7 +93,7 @@ save-file = Fájl mentése ## Open With Dialog -open-with-title = Hogyan szeretnéd megnyitni a következőt: „{ $name }”? +open-with-title = Hogyan szeretnéd megnyitni a(z) „{ $name }” fájlt? browse-store = { $store } böngészése other-apps = Egyéb alkalmazások related-apps = Hasonló alkalmazások @@ -113,7 +113,7 @@ rename-folder = Mappa átnevezése ## Replace Dialog replace = Csere -replace-title = „{ $filename }” már létezik +replace-title = „{ $filename }” már létezik ezen a helyen replace-warning = Szeretnéd lecserélni a meglévő fájlt a mentendő fájllal? A cserével felülírod annak tartalmát. replace-warning-operation = Szeretnéd lecserélni? A csere felülírja annak tartalmát. original-file = Eredeti fájl @@ -133,7 +133,7 @@ set-and-launch = Beállítás és indítás open-with = Megnyitás ezzel owner = Tulajdonos group = Csoport -other = Többi +other = Mások ### Mode 0 @@ -172,7 +172,7 @@ read-write-execute = Olvasás, írás és végrehajtás favorite-path-error = Hiba a könyvtár megnyitásakor favorite-path-error-description = Nem sikerült megnyitni ezt: „{ $path }” - „{ $path }” lehet nem létezik, vagy nincs jogosultságod a megnyitásához + A(z) „{ $path }” útvonal lehet, hogy nem létezik, vagy nincs jogosultságod a megnyitásához Szeretnéd eltávolítani az oldalsávról? remove = Eltávolítás @@ -187,9 +187,9 @@ keep = Megtartás ## Add Network Drive add-network-drive = Hálózati meghajtó hozzáadása -connect = Csatlakozás -connect-anonymously = Csatlakozás névtelenül -connecting = Csatlakozás… +connect = Kapcsolódás +connect-anonymously = Kapcsolódás névtelenül +connecting = Kapcsolódás… domain = Tartomány enter-server-address = Add meg a kiszolgáló címét network-drive-description = @@ -209,7 +209,7 @@ network-drive-schemes = network-drive-error = Nem érhető el a hálózati meghajtó password = Jelszó remember-password = Jelszó megjegyzése -try-again = Újra +try-again = Próbáld újra username = Felhasználónév ## Operations @@ -217,7 +217,7 @@ username = Felhasználónév cancelled = Megszakítva edit-history = Fájlműveleti előzmények history = Előzmények -no-history = Nem találhatók elemek az előzményekben +no-history = Nem találhatók elemek az előzményekben. pending = Függőben progress = { $percent }% progress-cancelled = { $percent }%, megszakítva @@ -330,7 +330,7 @@ items = Elemek: { $items } item-size = Méret: { $size } item-created = Létrehozva: { $created } item-modified = Módosítva: { $modified } -item-accessed = Hozzáférve: { $accessed } +item-accessed = Utolsó hozzáférés: { $accessed } calculating = Számítás… ## Settings @@ -350,7 +350,7 @@ light = Világos type-to-search = Gépeléssel keresés type-to-search-recursive = Keresés a jelenlegi mappában és almappákban -type-to-search-enter-path = Elérési út megadása +type-to-search-enter-path = Elérési út megnyitása # Context menu add-to-sidebar = Hozzáadás az oldalsávhoz compress = Tömörítés… @@ -373,7 +373,7 @@ remove-from-recents = Eltávolítás a legutóbbiak közül change-wallpaper = Háttérkép cseréje… desktop-appearance = Asztali megjelenés… -display-settings = Képernyő-beállítások… +display-settings = Kijelzőbeállítások… # Menu @@ -406,7 +406,7 @@ grid-view = Rácsnézet list-view = Listanézet show-hidden-files = Rejtett fájlok megjelenítése list-directories-first = Könyvtárak listázása először -gallery-preview = Galéria előnézet +gallery-preview = Galéria-előnézet menu-settings = Beállítások… menu-about = A COSMIC Fájlok névjegye… @@ -415,8 +415,8 @@ menu-about = A COSMIC Fájlok névjegye… sort = Rendezés sort-a-z = A-Z sort-z-a = Z-A -sort-newest-first = Legújabb előre -sort-oldest-first = Legrégibb előre +sort-newest-first = Legújabb elöl +sort-oldest-first = Legrégibb elöl sort-smallest-to-largest = Legkisebbtől a legnagyobbig sort-largest-to-smallest = Legnagyobbtól a legkisebbig repository = Tároló @@ -445,3 +445,4 @@ context-action-confirm-warning = *[other] elemen } fog lefutni. run = Futtatás +rename-confirm = Átnevezés diff --git a/i18n/nb-NO/cosmic_files.ftl b/i18n/nb-NO/cosmic_files.ftl index e0fb82c..cae2b5b 100644 --- a/i18n/nb-NO/cosmic_files.ftl +++ b/i18n/nb-NO/cosmic_files.ftl @@ -98,7 +98,7 @@ permanently-delete-question = Slett permanent permanently-delete-warning = Er du sukker på om du vil permanent slette { $target }? Dette kan ikke angres. rename-file = Endre filnavn rename-folder = Endre mappenavn -replace-title = "{ $filename }" finnes allerede på denne plasseringen. +replace-title = «{ $filename }» finnes allerede på denne plasseringen replace-warning = Vil du bytte den ut med filen du lagrer? Dette vil overskrive innholdet. replace-warning-operation = Vil du erstatte den? Dette vil overskrive innholdet. original-file = Orginalfil @@ -122,8 +122,8 @@ read-write = Kun skrive- og lesbar read-write-execute = Lesbar, skrivbar og kjørbar favorite-path-error = Feil ved åpning av mappen favorite-path-error-description = - Kunne ikke åpne "{ $path }". - Den kan ikke eksistere eller så har du ikke tilgang til å åpne den. + Klarte ikke åpne «{ $path }». + «{ $path }» finnes ikke eller så har du ikke tilgang til å åpne den. Vil du fjerne den fra sidepanelet? keep = Behold @@ -140,7 +140,7 @@ zoom-out = Zoom ut cut = Klipp ut set-and-launch = Still inn og start domain = Domene -enter-server-address = Angi serveradresse +enter-server-address = Angi tjeneradresse network-drive-description = Serveradresser inkluderer ett protokollprefiks og en addresse. Examples: ssh://192.168.0.1, ftp://[2001:db8::1] diff --git a/i18n/pl/cosmic_files.ftl b/i18n/pl/cosmic_files.ftl index 9af6027..2f58d64 100644 --- a/i18n/pl/cosmic_files.ftl +++ b/i18n/pl/cosmic_files.ftl @@ -446,3 +446,4 @@ context-action-confirm-warning = *[other] elementów }. run = Uruchom +rename-confirm = Zmień nazwę diff --git a/i18n/pt-BR/cosmic_files.ftl b/i18n/pt-BR/cosmic_files.ftl index 6d33279..6309e46 100644 --- a/i18n/pt-BR/cosmic_files.ftl +++ b/i18n/pt-BR/cosmic_files.ftl @@ -445,3 +445,4 @@ context-action-confirm-warning = *[other] itens }. run = Executar +rename-confirm = Renomear diff --git a/i18n/pt/cosmic_files.ftl b/i18n/pt/cosmic_files.ftl index 211b094..447487e 100644 --- a/i18n/pt/cosmic_files.ftl +++ b/i18n/pt/cosmic_files.ftl @@ -354,3 +354,4 @@ sort-smallest-to-largest = Do menor para o maior sort-largest-to-smallest = Do maior para o menor context-action-confirm-title = Executar "{ $name }"? run = Executar +rename-confirm = Renomear diff --git a/i18n/ru/cosmic_files.ftl b/i18n/ru/cosmic_files.ftl index f8e76c1..f34a377 100644 --- a/i18n/ru/cosmic_files.ftl +++ b/i18n/ru/cosmic_files.ftl @@ -389,3 +389,4 @@ context-action-confirm-warning = *[other] элем. }. run = Выполнить +rename-confirm = Переименовать diff --git a/i18n/sv/cosmic_files.ftl b/i18n/sv/cosmic_files.ftl index 974c7dc..506be0b 100644 --- a/i18n/sv/cosmic_files.ftl +++ b/i18n/sv/cosmic_files.ftl @@ -418,3 +418,4 @@ context-action-confirm-warning = *[other] objekt }. run = Kör +rename-confirm = Byt namn diff --git a/i18n/uk/cosmic_files.ftl b/i18n/uk/cosmic_files.ftl index 7299a7d..9f23949 100644 --- a/i18n/uk/cosmic_files.ftl +++ b/i18n/uk/cosmic_files.ftl @@ -82,7 +82,7 @@ copying = Копіювання { $items } { $items -> [one] елемента *[other] елементів - } з «{ $from }» в «{ $to }» ({ $progress })... + } з «{ $from }» до «{ $to }» ({ $progress })... copied = Скопійовано { $items } { $items -> [one] елемент @@ -95,7 +95,7 @@ moving = Переміщення { $items } { $items -> [one] елемента *[other] елементів - } з «{ $from }» в «{ $to }» ({ $progress })... + } з «{ $from }» до «{ $to }» ({ $progress })... moved = Переміщено { $items } { $items -> [one] елемент @@ -299,7 +299,7 @@ extracting = Видобування { $items } { $items -> [one] елемента *[other] елементів - } з «{ $from }» в «{ $to }» ({ $progress })... + } з «{ $from }» до «{ $to }» ({ $progress })... extracted = Видобуто { $items } { $items -> [one] елемент @@ -364,10 +364,10 @@ removed-from-recents = *[other] елементів } з { recents } empty-trash-title = Спорожити смітник? -type-to-search-select = Вибирає перший відповідний файл або папку +type-to-search-select = Вибирає перший відповідний файл або теку pasted-image = Вставлене зображення pasted-text = Вставлений текст -pasted-video = Вставлене відео +pasted-video = Вставлене видиво copy-to-button-label = Копіювати move-to-button-label = Перемістити copy-to = Копіювати до… @@ -387,3 +387,4 @@ context-action-confirm-warning = *[other] елементів }. context-action = Контекстна дія +rename-confirm = Перейменувати diff --git a/i18n/zh-CN/cosmic_files.ftl b/i18n/zh-CN/cosmic_files.ftl index abc8fda..4807c4a 100644 --- a/i18n/zh-CN/cosmic_files.ftl +++ b/i18n/zh-CN/cosmic_files.ftl @@ -445,3 +445,4 @@ context-action-confirm-warning = *[other] 项目 } 上运行。 context-action = 环境行动 +rename-confirm = 重命名 diff --git a/i18n/zh-TW/cosmic_files.ftl b/i18n/zh-TW/cosmic_files.ftl index b356db3..294ed2a 100644 --- a/i18n/zh-TW/cosmic_files.ftl +++ b/i18n/zh-TW/cosmic_files.ftl @@ -392,3 +392,4 @@ context-action-confirm-warning = *[other] 項目 } 上執行。 run = 執行 +rename-confirm = 重新命名 From cdec335ac734235b8e6b5a128c82bd58aa78b7fc Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 26 May 2026 08:31:04 -0600 Subject: [PATCH 070/110] Epoch 1.0.14 version update Generated by cosmic-epoch scripts/version-update.sh --- Cargo.lock | 215 +++++++++++++++++++-------------- Cargo.toml | 2 +- cosmic-files-applet/Cargo.toml | 2 +- debian/changelog | 6 + 4 files changed, 135 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56ebce6..fd9a283 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,9 +611,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "av-scenechange" @@ -825,15 +825,15 @@ dependencies = [ [[package]] name = "built" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" +checksum = "5c0e531d93d39c34eef561e929e8a7f86d77a5af08aac4f6d6e39976c51858e9" [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "by_address" @@ -984,11 +984,11 @@ dependencies = [ [[package]] name = "cipher" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ - "crypto-common 0.2.1", + "crypto-common 0.2.2", "inout", ] @@ -1341,7 +1341,20 @@ version = "0.2.0" source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38" dependencies = [ "bitflags 2.11.1", - "cosmic-protocols", + "cosmic-protocols 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=160b086)", + "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=c253ec1#c253ec1d6804afbcdf250f5cc37ae1194bba7bd2" +dependencies = [ + "bitflags 2.11.1", + "cosmic-protocols 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", "libc", "smithay-client-toolkit", "wayland-client", @@ -1351,7 +1364,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1372,7 +1385,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "quote", "syn", @@ -1380,14 +1393,14 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.0.13" +version = "1.0.14" dependencies = [ "anyhow", "atomic_float", "bstr", "bzip2", "compio", - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=160b086)", "cosmic-mime-apps", "dirs 6.0.0", "fastrand", @@ -1448,7 +1461,7 @@ dependencies = [ [[package]] name = "cosmic-files-applet" -version = "1.0.13" +version = "1.0.14" dependencies = [ "cosmic-files", "log", @@ -1458,7 +1471,7 @@ dependencies = [ [[package]] name = "cosmic-freedesktop-icons" version = "0.4.0" -source = "git+https://github.com/pop-os/freedesktop-icons#9c562fe3ecf03241a46a60c0078cd6ea10bd75ce" +source = "git+https://github.com/pop-os/freedesktop-icons#739e266210d471c09af61d529d8f41dccd815b90" dependencies = [ "bstr", "btoi", @@ -1494,10 +1507,24 @@ dependencies = [ "wayland-server", ] +[[package]] +name = "cosmic-protocols" +version = "0.2.0" +source = "git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1#c253ec1d6804afbcdf250f5cc37ae1194bba7bd2" +dependencies = [ + "bitflags 2.11.1", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "wayland-server", +] + [[package]] name = "cosmic-settings-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#716da6d6af0b252e2f78aba2ad72ee19ae0241e0" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#fa82bdf9fe7b5f5bd6008f32f393efd5e7a71c47" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1542,7 +1569,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "almost", "configparser", @@ -1653,9 +1680,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ "hybrid-array", ] @@ -1834,7 +1861,7 @@ checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.0", "const-oid", - "crypto-common 0.2.1", + "crypto-common 0.2.2", "ctutils", "zeroize", ] @@ -2019,9 +2046,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "endi" @@ -2206,9 +2233,9 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.28" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5b2eef6fafbf69f877e55509ce5b11a760690ac9700a2921be067aa6afaef6" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", @@ -3060,7 +3087,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "dnd", "iced_accessibility", @@ -3081,7 +3108,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "accesskit", "accesskit_winit", @@ -3090,11 +3117,11 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "bitflags 2.11.1", "bytes", - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", "dnd", "glam", "lilt", @@ -3107,6 +3134,7 @@ dependencies = [ "serde", "smol_str", "thiserror 2.0.18", + "unicode-segmentation", "web-time", "window_clipboard", ] @@ -3114,7 +3142,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "iced_core", "iced_futures", @@ -3124,7 +3152,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "futures", "iced_core", @@ -3138,7 +3166,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -3159,7 +3187,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "iced_graphics", "iced_runtime", @@ -3168,7 +3196,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3180,10 +3208,10 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "bytes", - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", "dnd", "iced_core", "iced_futures", @@ -3195,7 +3223,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "bytemuck", "cosmic-text", @@ -3212,12 +3240,12 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.1", "bytemuck", - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", "cryoglyph", "futures", "glam", @@ -3243,9 +3271,9 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", "dnd", "iced_renderer", "iced_runtime", @@ -3261,9 +3289,9 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", "cursor-icon", "dnd", "iced_debug", @@ -3954,9 +3982,9 @@ checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1" [[package]] name = "jiff" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" +checksum = "392c70591e8749fe235ddaf513e6f58b26bce3dcc16524cecc8936f75afa161e" dependencies = [ "jiff-static", "jiff-tzdb-platform", @@ -3964,7 +3992,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.61.2", + "windows-link 0.2.1", ] [[package]] @@ -3980,9 +4008,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" +checksum = "47b605b0c050d845fc355bb11eb3f9a8deddc218ea60c76e61aa1f2adfb2c96a" dependencies = [ "proc-macro2", "quote", @@ -4074,9 +4102,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ "cfg-if", "futures-util", @@ -4321,9 +4349,9 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "285efcf12ef41bec907b3000d5ffaeb54191d4d9d83c0d6157e6cbc2db255e64" +checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ "bitflags 2.11.1", "libc", @@ -4370,9 +4398,9 @@ checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" [[package]] name = "libbz2-rs-sys" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fc329e1457d97a9d58a4e2ca49e3be572431a7e096008efc2e3a3c19d428f4" +checksum = "34b357333733e8260735ba5894eb928c02ecc69c78715f01a8019e7fa7f2db4c" [[package]] name = "libc" @@ -4383,12 +4411,12 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#4fab6c777dbd1a023440f08fb2b729c86492366c" +source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "apply", "ashpd 0.12.3", "auto_enums", - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", "cosmic-config", "cosmic-freedesktop-icons", "cosmic-settings-config", @@ -4540,9 +4568,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" [[package]] name = "loom" @@ -4627,11 +4655,11 @@ dependencies = [ [[package]] name = "lzma-rust2" -version = "0.16.2" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47bb1e988e6fb779cf720ad431242d3f03167c1b3f2b1aae7f1a94b2495b36ae" +checksum = "5e9ceaec84b54518262de7cf06b8b43e83c808349960f1610b21b0bfc9640f20" dependencies = [ - "sha2", + "sha2 0.11.0", ] [[package]] @@ -4984,9 +5012,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-derive" @@ -5301,9 +5329,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" -version = "0.3.54" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a570f6bca41d29acb2139229a7c873ec99bc9a313bd10804081d89bfac8ff329" +checksum = "5df339f526ea9a60e371768d50efc2f2508c7203290731565d1f7a6f71d21747" dependencies = [ "libc", "libredox", @@ -5565,18 +5593,18 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.12" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf0d9e68100b3a7989b4901972f265cd542e560a3a8a724e1e20322f4d06ce9" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.12" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a990e22f43e84855daf260dded30524ef4a9021cc7541c26540500a50b624389" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -6285,7 +6313,7 @@ version = "8.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" dependencies = [ - "sha2", + "sha2 0.10.9", "walkdir", ] @@ -6462,9 +6490,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "indexmap 2.14.0", "itoa", @@ -6559,6 +6587,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -6892,9 +6931,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.45" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" dependencies = [ "filetime", "libc", @@ -7640,9 +7679,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -7653,9 +7692,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.71" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ "js-sys", "wasm-bindgen", @@ -7663,9 +7702,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7673,9 +7712,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -7686,9 +7725,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] @@ -7893,9 +7932,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.98" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", @@ -8828,9 +8867,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 9059e13..5d96135 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.0.13" +version = "1.0.14" 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 8fcf2bd..b802913 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files-applet" -version = "1.0.13" +version = "1.0.14" edition = "2024" [dependencies] diff --git a/debian/changelog b/debian/changelog index e4697d2..347d255 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-files (1.0.14) noble; urgency=medium + + * Epoch 1.0.14 version update + + -- Jeremy Soller Tue, 26 May 2026 08:30:59 -0600 + cosmic-files (1.0.13) noble; urgency=medium * Epoch 1.0.13 version update From 355423a02780dfa62926897c21f9120fe9422370 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Tue, 26 May 2026 10:51:59 -0600 Subject: [PATCH 071/110] chore: fixes after libcosmic update --- src/app.rs | 12 ++++++++---- src/dialog.rs | 15 +++++++++------ src/menu.rs | 2 ++ src/tab.rs | 5 ++++- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/app.rs b/src/app.rs index cc3e5c0..7edc5db 100644 --- a/src/app.rs +++ b/src/app.rs @@ -7,6 +7,7 @@ use cosmic::iced::clipboard::dnd::DndAction; use cosmic::iced::core::SmolStr; use cosmic::iced::core::widget::operation::focusable::unfocus; use cosmic::iced::futures::{self, SinkExt}; +use cosmic::iced::keyboard::key::Physical; use cosmic::iced::keyboard::{Event as KeyEvent, Key, Modifiers}; #[cfg(all(feature = "wayland", feature = "desktop-applet"))] use cosmic::iced::platform_specific::shell::wayland::commands::overlap_notify::overlap_notify; @@ -355,7 +356,7 @@ pub enum Message { ExtractToResult(DialogResult), #[cfg(all(feature = "wayland", feature = "desktop-applet"))] Focused(window::Id), - Key(window::Id, Modifiers, Key, Option), + Key(window::Id, Modifiers, Key, Physical, Option), LaunchUrl(String), MaybeExit, ModifiersChanged(window::Id, Modifiers), @@ -3351,7 +3352,7 @@ impl Application for App { return dialog.update(dialog_message); } } - Message::Key(window_id, modifiers, key, text) => { + Message::Key(window_id, modifiers, key, physical_key, text) => { #[cfg(all(feature = "wayland", feature = "desktop-applet"))] let in_surface_ids = self.surface_ids.values().any(|id| *id == window_id); #[cfg(not(all(feature = "wayland", feature = "desktop-applet")))] @@ -3359,7 +3360,7 @@ impl Application for App { if self.core.main_window_id() == Some(window_id) || in_surface_ids { let entity = self.tab_model.active(); for (key_bind, action) in &self.key_binds { - if key_bind.matches(modifiers, &key) { + if key_bind.matches(modifiers, &key, Some(&physical_key)) { return self.update(action.message(Some(entity))); } } @@ -6633,11 +6634,14 @@ impl Application for App { }, Event::Keyboard(KeyEvent::KeyPressed { key, + physical_key, modifiers, text, .. }) => match status { - event::Status::Ignored => Some(Message::Key(window_id, modifiers, key, text)), + event::Status::Ignored => { + Some(Message::Key(window_id, modifiers, key, physical_key, text)) + } event::Status::Captured => None, }, Event::Keyboard(KeyEvent::ModifiersChanged(modifiers)) => { diff --git a/src/dialog.rs b/src/dialog.rs index 69714f9..0623da0 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -6,7 +6,7 @@ use cosmic::app::{Core, Task, context_drawer}; use cosmic::iced::core::SmolStr; use cosmic::iced::core::widget::operation; use cosmic::iced::futures::{self, SinkExt}; -use cosmic::iced::keyboard::key::Named; +use cosmic::iced::keyboard::key::{Named, Physical}; use cosmic::iced::keyboard::{Event as KeyEvent, Key, Modifiers}; use cosmic::iced::platform_specific::shell::{self as iced_winit, SurfaceIdWrapper}; use cosmic::iced::widget::scrollable; @@ -456,7 +456,7 @@ enum Message { Escape, Filename(String), Filter(usize), - Key(Modifiers, Key, Option), + Key(Modifiers, Key, Physical, Option), ModifiersChanged(Modifiers), MounterItems(MounterKey, MounterItems), Mouse(window::Id, mouse::Button), @@ -1450,16 +1450,16 @@ impl Application for App { } return self.rescan_tab(None); } - Message::Key(modifiers, key, text) => { + Message::Key(modifiers, key, physical_key, text) => { for (key_bind, action) in &self.key_binds { - if key_bind.matches(modifiers, &key) { + if key_bind.matches(modifiers, &key, Some(&physical_key)) { return self.update(Message::from(action.message())); } } // Check key binds from accept label if let Some(key_bind) = &self.accept_label.key_bind_opt - && key_bind.matches(modifiers, &key) + && key_bind.matches(modifiers, &key, Some(&physical_key)) { return self.update(if self.flags.kind.save() { Message::Save(false) @@ -2050,11 +2050,14 @@ impl Application for App { }, Event::Keyboard(KeyEvent::KeyPressed { key, + physical_key, modifiers, text, .. }) => match status { - event::Status::Ignored => Some(Message::Key(modifiers, key, text)), + event::Status::Ignored => { + Some(Message::Key(modifiers, key, physical_key, text)) + } event::Status::Captured => { if key == Key::Named(Named::Escape) { Some(Message::Escape) diff --git a/src/menu.rs b/src/menu.rs index 4132fbf..d8c13ba 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -71,6 +71,7 @@ pub fn context_menu<'a>( color.alpha *= 0.75; TextStyle { color: Some(color.into()), + ..Default::default() } } fn disabled_style(theme: &cosmic::Theme) -> TextStyle { @@ -78,6 +79,7 @@ pub fn context_menu<'a>( color.alpha *= 0.5; TextStyle { color: Some(color.into()), + ..Default::default() } } diff --git a/src/tab.rs b/src/tab.rs index 25d271b..7d0c8fd 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -7580,7 +7580,10 @@ mod tests { // Text editor content may add a trailing newline assert_eq!(content.text().trim_end(), "ab"); } - _ => panic!("expected Text thumbnail with valid prefix only, got {:?}", thumb), + _ => panic!( + "expected Text thumbnail with valid prefix only, got {:?}", + thumb + ), } Ok(()) } From 18eb41930a5ec7844387e48fe4fd111335f5d36b Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Tue, 26 May 2026 15:17:08 -0400 Subject: [PATCH 072/110] fix: cosmic-protocols --- Cargo.lock | 43 ++++++++----------------------------------- Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd9a283..8d0cf5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1335,26 +1335,13 @@ dependencies = [ "libm", ] -[[package]] -name = "cosmic-client-toolkit" -version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38" -dependencies = [ - "bitflags 2.11.1", - "cosmic-protocols 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=160b086)", - "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=c253ec1#c253ec1d6804afbcdf250f5cc37ae1194bba7bd2" dependencies = [ "bitflags 2.11.1", - "cosmic-protocols 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", + "cosmic-protocols", "libc", "smithay-client-toolkit", "wayland-client", @@ -1400,7 +1387,7 @@ dependencies = [ "bstr", "bzip2", "compio", - "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=160b086)", + "cosmic-client-toolkit", "cosmic-mime-apps", "dirs 6.0.0", "fastrand", @@ -1493,20 +1480,6 @@ dependencies = [ "xdg", ] -[[package]] -name = "cosmic-protocols" -version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38" -dependencies = [ - "bitflags 2.11.1", - "wayland-backend", - "wayland-client", - "wayland-protocols", - "wayland-protocols-wlr", - "wayland-scanner", - "wayland-server", -] - [[package]] name = "cosmic-protocols" version = "0.2.0" @@ -3121,7 +3094,7 @@ source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf84 dependencies = [ "bitflags 2.11.1", "bytes", - "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", + "cosmic-client-toolkit", "dnd", "glam", "lilt", @@ -3211,7 +3184,7 @@ version = "0.14.0" source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ "bytes", - "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", + "cosmic-client-toolkit", "dnd", "iced_core", "iced_futures", @@ -3245,7 +3218,7 @@ dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.1", "bytemuck", - "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", + "cosmic-client-toolkit", "cryoglyph", "futures", "glam", @@ -3273,7 +3246,7 @@ name = "iced_widget" version = "0.14.2" source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ - "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", + "cosmic-client-toolkit", "dnd", "iced_renderer", "iced_runtime", @@ -3291,7 +3264,7 @@ name = "iced_winit" version = "0.14.0" source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" dependencies = [ - "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", + "cosmic-client-toolkit", "cursor-icon", "dnd", "iced_debug", @@ -4416,7 +4389,7 @@ dependencies = [ "apply", "ashpd 0.12.3", "auto_enums", - "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", + "cosmic-client-toolkit", "cosmic-config", "cosmic-freedesktop-icons", "cosmic-settings-config", diff --git a/Cargo.toml b/Cargo.toml index 5d96135..2739b9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ anyhow = "1" jiff = "0.2" jiff-icu = "0.2" icu = { version = "2.2.0", features = ["compiled_data"] } -cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "160b086", optional = true } +cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "c253ec1", optional = true } cosmic-mime-apps = { git = "https://github.com/pop-os/cosmic-mime-apps.git", optional = true } dirs = "6.0.0" gio = { version = "0.21", optional = true } From bf01bb31a318dcb7bb4eb59c86095259ae676f9d Mon Sep 17 00:00:00 2001 From: Hojjat Date: Wed, 27 May 2026 17:25:09 -0600 Subject: [PATCH 073/110] chore: update libcosmic to fix item highlight in wayland context menu --- Cargo.lock | 110 +++++++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d0cf5b..88a99cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,9 +109,9 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aes" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8" +checksum = "f1fc76eaeac4c9164506c466d4ffdd8ec9d0c5bf57ee97177c4d8eceb3a0e138" dependencies = [ "cipher", "cpubits", @@ -1351,7 +1351,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1372,7 +1372,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "quote", "syn", @@ -1458,7 +1458,7 @@ dependencies = [ [[package]] name = "cosmic-freedesktop-icons" version = "0.4.0" -source = "git+https://github.com/pop-os/freedesktop-icons#739e266210d471c09af61d529d8f41dccd815b90" +source = "git+https://github.com/pop-os/freedesktop-icons#cb0a2f299dbc443697ce1674065e0d4f82915c02" dependencies = [ "bstr", "btoi", @@ -1471,8 +1471,8 @@ dependencies = [ [[package]] name = "cosmic-mime-apps" -version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-mime-apps.git#673f3758920a7b20d307d356d586deef714df6b0" +version = "0.2.0" +source = "git+https://github.com/pop-os/cosmic-mime-apps.git#a95c8043a7b41ca3c143a1fad5b3b8a5a3411008" dependencies = [ "freedesktop-desktop-entry", "mime 0.3.17", @@ -1542,7 +1542,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "almost", "configparser", @@ -1916,9 +1916,9 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", @@ -1964,7 +1964,7 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" version = "0.1.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" [[package]] name = "drm" @@ -3060,7 +3060,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "dnd", "iced_accessibility", @@ -3081,7 +3081,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "accesskit", "accesskit_winit", @@ -3090,7 +3090,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "bitflags 2.11.1", "bytes", @@ -3115,7 +3115,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "iced_core", "iced_futures", @@ -3125,7 +3125,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "futures", "iced_core", @@ -3139,7 +3139,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -3160,7 +3160,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "iced_graphics", "iced_runtime", @@ -3169,7 +3169,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3181,7 +3181,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3196,7 +3196,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "bytemuck", "cosmic-text", @@ -3213,7 +3213,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "as-raw-xcb-connection", "bitflags 2.11.1", @@ -3244,7 +3244,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -4384,7 +4384,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#8fa6a01d049905ce99eb9adf8415b2fa73611818" +source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" dependencies = [ "apply", "ashpd 0.12.3", @@ -4462,14 +4462,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ "bitflags 2.11.1", "libc", "plain", - "redox_syscall 0.7.5", + "redox_syscall 0.8.0", ] [[package]] @@ -4687,9 +4687,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "memmap2" @@ -6078,6 +6078,16 @@ dependencies = [ "url", ] +[[package]] +name = "redox_event" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c07d0d6d291e3a951bd847b1cd4af32fc6243d64116cf7702838c02797688b7" +dependencies = [ + "bitflags 2.11.1", + "libredox", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -6089,9 +6099,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" +checksum = "7c7591fa2c6b601dfcfe5f043f65a1c39fcdf50efefcd7f1572e538c1f4b398d" dependencies = [ "bitflags 2.11.1", ] @@ -7251,9 +7261,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap 2.14.0", "toml_datetime", @@ -8626,7 +8636,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#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "cfg_aliases", @@ -8652,7 +8662,7 @@ dependencies = [ [[package]] name = "winit-android" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "android-activity", "bitflags 2.11.1", @@ -8667,7 +8677,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#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "block2 0.6.2", @@ -8689,7 +8699,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#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "memmap2 0.9.10", "objc2 0.6.4", @@ -8704,7 +8714,7 @@ dependencies = [ [[package]] name = "winit-core" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "cursor-icon", @@ -8718,14 +8728,14 @@ dependencies = [ [[package]] name = "winit-orbital" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "dpi", "libredox", "orbclient", "raw-window-handle", - "redox_syscall 0.7.5", + "redox_event", "smol_str", "tracing", "winit-core", @@ -8734,7 +8744,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#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "block2 0.6.2", @@ -8754,7 +8764,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#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "ahash", "bitflags 2.11.1", @@ -8780,7 +8790,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#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "atomic-waker", "bitflags 2.11.1", @@ -8802,7 +8812,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#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "cursor-icon", @@ -8818,7 +8828,7 @@ dependencies = [ [[package]] name = "winit-x11" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.11.1", "bytemuck", @@ -9336,18 +9346,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "bce33a6288fa3f072a8c2c7d0f2fdbb90e28298f0135c1f99b96c3db2efcc60b" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "8fd425244944f4ab65ccff928e7323354c5a018c75838362fdce749dfad2ee1e" dependencies = [ "proc-macro2", "quote", From 53cfeebe57bfd8a0d44d97c14eada450edbd2978 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Mon, 18 May 2026 17:23:43 +0200 Subject: [PATCH 074/110] feat: improve mime app detection & do it faster --- src/app.rs | 8 +- src/mime_app.rs | 209 ++++++++++++++++++++++++------------------------ src/tab.rs | 14 +++- 3 files changed, 121 insertions(+), 110 deletions(-) diff --git a/src/app.rs b/src/app.rs index 7edc5db..44f4b0c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -448,6 +448,7 @@ pub enum Message { Option>, ), TabView(Option, tab::View), + TerminalDefault(Box), TimeConfigChange(TimeConfig), ToggleContextPage(ContextPage), ToggleFoldersFirst, @@ -559,7 +560,7 @@ pub enum DialogPage { path: PathBuf, mime: mime_guess::Mime, selected: usize, - store_opt: Option, + store_opt: Option>, }, PermanentlyDelete { paths: Box<[PathBuf]>, @@ -2273,7 +2274,7 @@ impl App { .into() } - fn get_apps_for_mime(&self, mime_type: &Mime) -> Vec<(&MimeApp, MimeAppMatch)> { + fn get_apps_for_mime(&self, mime_type: &Mime) -> Vec<(&Arc, MimeAppMatch)> { let mut results = Vec::new(); let mut dedupe = FxHashSet::default(); @@ -4793,6 +4794,7 @@ impl Application for App { tab.refresh_cut(&paths); } } + Message::TerminalDefault(command) => {} Message::TimeConfigChange(time_config) => { self.config.tab.military_time = time_config.military_time; return self.update_config(); @@ -5982,7 +5984,7 @@ impl Application for App { widget::button::custom( widget::row::with_children([ icon(app.icon.clone()).size(32).into(), - if app.is_default && !displayed_default { + if app.is_default() && !displayed_default { displayed_default = true; widget::text::body(fl!( "default-app", diff --git a/src/mime_app.rs b/src/mime_app.rs index 8695d79..c830ab7 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -7,10 +7,11 @@ use cosmic::desktop; use cosmic::widget; pub use mime_guess::Mime; use rustc_hash::FxHashMap; -use std::cmp::Ordering; use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; +use std::sync::atomic::AtomicBool; +use std::sync::{Arc, atomic}; use std::time::Instant; use std::{fs, io, process}; @@ -133,7 +134,7 @@ pub struct MimeApp { pub name: String, pub exec: Option, pub icon: widget::icon::Handle, - pub is_default: bool, + is_default: Arc, } impl MimeApp { @@ -146,6 +147,10 @@ impl MimeApp { path_opt, ) } + + pub fn is_default(&self) -> bool { + self.is_default.load(atomic::Ordering::SeqCst) + } } // This allows usage of MimeApp in a dropdown @@ -169,24 +174,16 @@ impl From<&desktop::DesktopEntryData> for MimeApp { } desktop::fde::IconSource::Path(path) => widget::icon::from_path(path.clone()), }, - is_default: false, + is_default: Arc::new(AtomicBool::new(false)), } } } -#[cfg(feature = "desktop")] -fn filename_eq(path_opt: &Option, filename: &str) -> bool { - path_opt - .as_ref() - .and_then(|path| path.file_name()) - .is_some_and(|x| x == filename) -} - pub struct MimeAppCache { - apps: Vec, - cache: FxHashMap>, + apps: Vec>, + cache: FxHashMap>>, icons: FxHashMap>, - terminals: Vec, + terminals: Vec>, } impl MimeAppCache { @@ -204,10 +201,12 @@ impl MimeAppCache { #[cfg(not(feature = "desktop"))] pub fn reload(&mut self) {} - // Only available when using desktop feature of libcosmic, which only works on Unix-likes + /// Reload mime types and their known app associations and defaults. #[cfg(feature = "desktop")] pub fn reload(&mut self) { use crate::localize::LANGUAGE_SORTER; + use cosmic::desktop::fde; + use std::borrow::Cow; let start = Instant::now(); @@ -216,107 +215,111 @@ impl MimeAppCache { self.icons.clear(); self.terminals.clear(); - //TODO: get proper locale? - let locale = &[]; - - // Load desktop applications by supported mime types - //TODO: hashmap for all apps by id? - let all_apps: Box<[_]> = desktop::load_applications(locale, false, None).collect(); - for app in &all_apps { - //TODO: just collect apps that can be executed with a file argument? - if !app.mime_types.is_empty() { - self.apps.push(MimeApp::from(app)); - } - for mime in &app.mime_types { - let apps = self - .cache - .entry(mime.clone()) - .or_insert_with(|| Vec::with_capacity(1)); - if !apps.iter().any(|x| x.id == app.id) { - apps.push(MimeApp::from(app)); - } - } - for category in &app.categories { - if category == "TerminalEmulator" { - self.terminals.push(MimeApp::from(app)); - break; - } - } - } - let mut list = cosmic_mime_apps::List::default(); - let paths = cosmic_mime_apps::list_paths(); list.load_from_paths(&paths); + let locales = fde::get_languages_from_env(); + for desktop_entry in fde::Iter::new(fde::default_paths()).entries(Some(&locales)) { + let name = desktop_entry + .name(&locales) + .unwrap_or_else(|| Cow::Borrowed(desktop_entry.id())); - for (mime, filenames) in list - .added_associations - .iter() - .chain(list.default_apps.iter()) - { - for filename in filenames { - log::trace!("add {mime}={filename}"); - let apps = self - .cache - .entry(mime.clone()) - .or_insert_with(|| Vec::with_capacity(1)); - if !apps.iter().any(|x| filename_eq(&x.path, filename)) { - if let Some(app) = all_apps.iter().find(|&x| filename_eq(&x.path, filename)) { - apps.push(MimeApp::from(app)); + let app = Arc::new(MimeApp { + id: desktop_entry.appid.clone(), + path: Some(desktop_entry.path.clone()), + name: name.into(), + exec: desktop_entry.exec().map(String::from), + icon: { + let icon = desktop_entry.icon().unwrap_or_default(); + if icon.starts_with('/') { + cosmic::widget::icon::from_path(PathBuf::from(icon)) } else { - log::info!( - "failed to add association for {mime:?}: application {filename:?} not found" - ); + cosmic::widget::icon::from_name(icon).size(32).handle() + } + }, + is_default: Arc::new(AtomicBool::new(false)), + }); + + tracing::info!(target: "mime-apps", id = app.id, "detected desktop entry"); + + self.apps.push(app.clone()); + + if desktop_entry + .categories() + .into_iter() + .flatten() + .any(|c| c == "TerminalEmulator") + { + self.terminals.push(app.clone()); + } + + // Cache associations defined by the desktop entry. + let mime_types = desktop_entry.mime_type().unwrap_or_else(Vec::new); + for mime in mime_types.iter().filter_map(|m| m.parse::().ok()) { + let apps = self.cache.entry(mime.clone()).or_default(); + if apps.iter().all(|cached_app| cached_app.id != app.id) { + apps.push(app.clone()); + } + } + } + + // Cache added associations from mimeapps lists. + for (added_mime, added_apps) in &list.added_associations { + for added_app in added_apps { + if let Some(app) = self + .apps + .iter() + .find(|cached| cached.id.as_str() == added_app.as_ref()) + { + let apps = self.cache.entry(added_mime.clone()).or_default(); + if apps.iter().all(|cached_app| cached_app.id != app.id) { + apps.push(app.clone()); } } } } - for (mime, filenames) in list.removed_associations.iter() { - for filename in filenames { - log::trace!("remove {mime}={filename}"); - if let Some(apps) = self.cache.get_mut(mime) { - apps.retain(|x| !filename_eq(&x.path, filename)); + // Remove associations + for (removed_mime, removed_apps) in &list.removed_associations { + for removed_app in removed_apps { + if let Some(app) = self + .apps + .iter() + .find(|cached| cached.id.as_str() == removed_app.as_ref()) + && let Some(apps) = self.cache.get_mut(removed_mime) + { + apps.retain(|cached_app| cached_app.id != app.id); } } } - for (mime, filenames) in list.default_apps.iter() { - for filename in filenames { - log::trace!("default {mime}={filename}"); - if let Some(apps) = self.cache.get_mut(mime) { - let mut found = false; - for app in apps.iter_mut() { - if filename_eq(&app.path, filename) { - app.is_default = true; - found = true; - } else { - app.is_default = false; - } - } + // Fetch defaults and sort apps by their default precedence. + for (mime, mut apps) in std::mem::take(&mut self.cache).into_iter() { + let defaults = list.default_app_for(&mime); + let cache = self + .cache + .entry(mime.clone()) + .or_insert_with(|| Vec::with_capacity(apps.len())); + + // Sort cached apps for this mime by default precedence. + for default in defaults.into_iter().flatten() { + let default = default.strip_suffix(".desktop").unwrap_or(default.as_ref()); + apps.retain(|app| { + let found = app.id.as_str() == default; if found { - break; + app.is_default.store(true, atomic::Ordering::Relaxed); + cache.push(app.clone()); } - log::debug!( - "failed to set default for {mime:?}: application {filename:?} not found" - ); - } - } - } - // Sort apps by name - self.apps - .sort_by(|a, b| match (a.is_default, b.is_default) { - (true, false) => Ordering::Less, - (false, true) => Ordering::Greater, - _ => LANGUAGE_SORTER.compare(&a.name, &b.name), - }); - for apps in self.cache.values_mut() { - apps.sort_by(|a, b| match (a.is_default, b.is_default) { - (true, false) => Ordering::Less, - (false, true) => Ordering::Greater, - _ => LANGUAGE_SORTER.compare(&a.name, &b.name), - }); + !found + }); + } + + // Sort remaining apps by name + apps.sort_by(|a, b| LANGUAGE_SORTER.compare(&a.name, &b.name)); + cache.extend_from_slice(&apps); + + tracing::debug!(target: "mime-apps", mime = mime.essence_str(), apps = ?(cache.iter().map(|app| &*app.id).collect::>()), "mime defaults found") } // Copy icons to special cache @@ -329,14 +332,14 @@ impl MimeAppCache { })); let elapsed = start.elapsed(); - log::info!("loaded mime app cache in {elapsed:?}"); + tracing::info!(target: "mime-apps", "loaded mime app cache in {elapsed:?}"); } - pub fn apps(&self) -> &[MimeApp] { + pub fn apps(&self) -> &[Arc] { &self.apps } - pub fn get(&self, key: &Mime) -> &[MimeApp] { + pub fn get(&self, key: &Mime) -> &[Arc] { self.cache.get(key).map_or(&[], Vec::as_slice) } @@ -359,7 +362,7 @@ impl MimeAppCache { .map(|string| string.trim().replace(".desktop", "")) } - pub fn terminal(&self) -> Option<&MimeApp> { + pub fn terminal(&self) -> Option<&Arc> { //TODO: consider rules in https://github.com/Vladimir-csp/xdg-terminal-exec // The current approach works but might not adhere to the spec (yet) diff --git a/src/tab.rs b/src/tab.rs index 7d0c8fd..185a258 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2374,8 +2374,11 @@ impl Item { widget::settings::item::builder(fl!("open-with")).control( Element::from( widget::dropdown( - mime_apps, - mime_apps.iter().position(|x| x.is_default), + mime_apps + .iter() + .map(|app| Cow::Owned(app.name.clone())) + .collect::>>(), + mime_apps.iter().position(|x| x.is_default()), move |index| index, ) .icons(Cow::Borrowed(mime_app_cache.icons(&self.mime))), @@ -6455,8 +6458,11 @@ impl Tab { widget::settings::item::builder(fl!("open-with")).control( Element::from( widget::dropdown( - mime_apps, - mime_apps.iter().position(|x| x.is_default), + mime_apps + .iter() + .map(|app| Cow::Owned(app.name.clone())) + .collect::>>(), + mime_apps.iter().position(|x| x.is_default()), move |index| (index, mime_closure.clone()), ) .icons(Cow::Borrowed(mime_app_cache.icons(&mime))), From 0b3d8a9f3fbc83a01cd18750fd93c0b9010779c6 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Mon, 1 Jun 2026 17:56:32 +0200 Subject: [PATCH 075/110] build: use `cargo vendor --locked` --- justfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index 9522e98..5e8d024 100644 --- a/justfile +++ b/justfile @@ -48,7 +48,7 @@ build-debug *args: # Compiles with release profile build-release *args: (build-debug '--release' args) - + # Compiles applet with release profile build-release-applet *args: cargo build --package {{applet-name}} --release {{args}} @@ -111,7 +111,7 @@ uninstall: vendor: #!/usr/bin/env bash mkdir -p .cargo - cargo vendor --sync Cargo.toml | head -n -1 > .cargo/config.toml + cargo vendor --locked --sync Cargo.toml | head -n -1 > .cargo/config.toml echo 'directory = "vendor"' >> .cargo/config.toml echo >> .cargo/config.toml echo '[env]' >> .cargo/config.toml From bb1ae9d45827184ab7a4a8be626f2717057ae110 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Mon, 1 Jun 2026 22:11:40 +0200 Subject: [PATCH 076/110] feat: reload mime app cache when mime app config is updated --- src/app.rs | 22 +++++++++++++++++++-- src/mime_app.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/src/app.rs b/src/app.rs index 44f4b0c..b8846de 100644 --- a/src/app.rs +++ b/src/app.rs @@ -416,6 +416,7 @@ pub enum Message { PendingPauseAll(bool), PermanentlyDelete(Option), Preview(Option), + ReloadMimeAppCache, ReorderTab(ReorderEvent), RescanRecents, RescanTrash, @@ -448,7 +449,6 @@ pub enum Message { Option>, ), TabView(Option, tab::View), - TerminalDefault(Box), TimeConfigChange(TimeConfig), ToggleContextPage(ContextPage), ToggleFoldersFirst, @@ -4221,6 +4221,9 @@ impl Application for App { let paths: Box<[_]> = self.selected_paths(entity_opt).collect(); return self.operation(Operation::RemoveFromRecents { paths }); } + Message::ReloadMimeAppCache => { + self.mime_app_cache.reload(); + } Message::RescanRecents => { return self.rescan_recents(); } @@ -4794,7 +4797,6 @@ impl Application for App { tab.refresh_cut(&paths); } } - Message::TerminalDefault(command) => {} Message::TimeConfigChange(time_config) => { self.config.tab.military_time = time_config.military_time; return self.update_config(); @@ -6775,6 +6777,22 @@ impl Application for App { }, ) }), + Subscription::run(|| { + eprintln!("loading mime app watcher"); + stream::channel( + 1, + |mut output: futures::channel::mpsc::Sender| async move { + mime_app::watch(move || { + futures::executor::block_on(async { + _ = output.send(Message::ReloadMimeAppCache).await; + }) + }) + .await; + + std::future::pending().await + }, + ) + }), Subscription::run_with(TypeId::of::(), |_| { stream::channel( 1, diff --git a/src/mime_app.rs b/src/mime_app.rs index c830ab7..706c80d 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -6,15 +6,64 @@ use bstr::{BString, ByteSlice, ByteVec}; use cosmic::desktop; use cosmic::widget; pub use mime_guess::Mime; +use notify_debouncer_full::notify; use rustc_hash::FxHashMap; use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; use std::sync::atomic::AtomicBool; use std::sync::{Arc, atomic}; -use std::time::Instant; +use std::time::{self, Instant}; use std::{fs, io, process}; +pub async fn watch(mut emitter: impl FnMut() + 'static + Send) { + let watcher_result = notify_debouncer_full::new_debouncer( + time::Duration::from_millis(250), + Some(time::Duration::from_millis(250)), + move |event_res: notify_debouncer_full::DebounceEventResult| { + let Ok(events) = event_res else { + return; + }; + + if events.iter().any(|event| { + event.kind.is_create() || event.kind.is_modify() || event.kind.is_remove() + }) { + emitter(); + } + }, + ); + + if let Ok(mut watcher) = watcher_result { + let system_paths = cosmic_mime_apps::list_paths(); + let local_paths = (|| { + let base_dirs = xdg::BaseDirectories::new(); + let Some(home) = base_dirs.get_config_home() else { + return Err(std::io::Error::other("XDG config home not set")); + }; + + let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") else { + return Err(std::io::Error::other("XDG_CURRENT_DESKTOP unset")); + }; + + let default_mimeapps = home.join("mimeapps.list"); + let desktop_mimeapps = + home.join([&desktop.to_ascii_lowercase(), "-mimeapps.list"].concat()); + + Ok([desktop_mimeapps, default_mimeapps]) + })() + .ok(); + + for path in system_paths + .iter() + .chain(local_paths.as_ref().into_iter().flatten()) + { + _ = watcher.watch(path.as_path(), notify::RecursiveMode::NonRecursive); + } + + std::future::pending().await + } +} + pub fn exec_to_command( exec: &str, entry_name: &str, From fca0753781988f036f2fcbd4d12328624a1536e6 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 2 Jun 2026 00:34:14 +0200 Subject: [PATCH 077/110] fix: gate desktop features for no-default-features build --- src/app.rs | 2 +- src/mime_app.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app.rs b/src/app.rs index b8846de..a4af64b 100644 --- a/src/app.rs +++ b/src/app.rs @@ -6777,8 +6777,8 @@ impl Application for App { }, ) }), + #[cfg(feature = "desktop")] Subscription::run(|| { - eprintln!("loading mime app watcher"); stream::channel( 1, |mut output: futures::channel::mpsc::Sender| async move { diff --git a/src/mime_app.rs b/src/mime_app.rs index 706c80d..c543afa 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -6,6 +6,7 @@ use bstr::{BString, ByteSlice, ByteVec}; use cosmic::desktop; use cosmic::widget; pub use mime_guess::Mime; +#[cfg(feature = "desktop")] use notify_debouncer_full::notify; use rustc_hash::FxHashMap; use std::ffi::OsStr; @@ -16,6 +17,7 @@ use std::sync::{Arc, atomic}; use std::time::{self, Instant}; use std::{fs, io, process}; +#[cfg(feature = "desktop")] pub async fn watch(mut emitter: impl FnMut() + 'static + Send) { let watcher_result = notify_debouncer_full::new_debouncer( time::Duration::from_millis(250), From c605dbecaf70e193a98fec775f7381a943d264a2 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 2 Jun 2026 11:02:34 -0600 Subject: [PATCH 078/110] Epoch 1.0.15 version update Generated by cosmic-epoch scripts/version-update.sh --- Cargo.lock | 388 +++++++++++++++++---------------- Cargo.toml | 2 +- cosmic-files-applet/Cargo.toml | 2 +- debian/changelog | 6 + 4 files changed, 205 insertions(+), 193 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88a99cc..b78423e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,7 +35,7 @@ dependencies = [ "accesskit_consumer", "atspi-common", "serde", - "zvariant 5.11.0", + "zvariant 5.12.0", ] [[package]] @@ -72,7 +72,7 @@ dependencies = [ "serde", "tokio", "tokio-stream", - "zbus 5.15.0", + "zbus 5.16.0", ] [[package]] @@ -198,7 +198,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" dependencies = [ "android-properties", - "bitflags 2.11.1", + "bitflags 2.12.1", "cc", "jni", "libc", @@ -373,7 +373,7 @@ dependencies = [ "serde_repr", "tokio", "url", - "zbus 5.15.0", + "zbus 5.16.0", ] [[package]] @@ -393,7 +393,7 @@ dependencies = [ "wayland-backend", "wayland-client", "wayland-protocols", - "zbus 5.15.0", + "zbus 5.16.0", ] [[package]] @@ -579,11 +579,11 @@ dependencies = [ "enumflags2", "serde", "static_assertions", - "zbus 5.15.0", + "zbus 5.16.0", "zbus-lockstep", "zbus-lockstep-macros", "zbus_names 4.3.2", - "zvariant 5.11.0", + "zvariant 5.12.0", ] [[package]] @@ -594,7 +594,7 @@ checksum = "2230e48787ed3eb4088996eab66a32ca20c0b67bbd4fd6cdfe79f04f1f04c9fc" dependencies = [ "atspi-common", "serde", - "zbus 5.15.0", + "zbus 5.16.0", ] [[package]] @@ -702,9 +702,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" dependencies = [ "serde_core", ] @@ -786,9 +786,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "5.0.0" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +checksum = "5962523e1b92ce1b5e793d9169b9943eece10d39f62550bc04bb605d75b94924" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -904,7 +904,7 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "polling", "rustix 1.1.4", "slab", @@ -925,14 +925,14 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.62" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", "jobserver", "libc", - "shlex", + "shlex 2.0.1", ] [[package]] @@ -948,9 +948,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.20.7" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6b04e07d8080154ed4ac03546d9a2b303cc2fe1901ba0b35b301516e289368" +checksum = "fb693542bcafa528e198be0ebd9d3632ca5b7c93dbe7237460e199910835997c" dependencies = [ "smallvec", "target-lexicon", @@ -1032,9 +1032,9 @@ dependencies = [ [[package]] name = "cmov" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" [[package]] name = "cocoa" @@ -1116,9 +1116,9 @@ dependencies = [ [[package]] name = "compio-buf" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00d719dbd8c602ab0d25d219cbc6b517008858de7a8d6c51b4dc95aefff4dce" +checksum = "1b9478803aae4726ce02139b5510354034ae3afc99ce2496734784314664b91c" dependencies = [ "arrayvec", "bytes", @@ -1310,7 +1310,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "core-foundation 0.10.1", "libc", ] @@ -1340,7 +1340,7 @@ name = "cosmic-client-toolkit" version = "0.2.0" source = "git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1#c253ec1d6804afbcdf250f5cc37ae1194bba7bd2" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "cosmic-protocols", "libc", "smithay-client-toolkit", @@ -1351,7 +1351,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1366,13 +1366,13 @@ dependencies = [ "tokio", "tracing", "xdg", - "zbus 5.15.0", + "zbus 5.16.0", ] [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "quote", "syn", @@ -1380,7 +1380,7 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.0.14" +version = "1.0.15" dependencies = [ "anyhow", "atomic_float", @@ -1425,7 +1425,7 @@ dependencies = [ "rust-embed", "rustc-hash 2.1.2", "serde", - "shlex", + "shlex 1.3.0", "slotmap", "tar", "tempfile", @@ -1448,7 +1448,7 @@ dependencies = [ [[package]] name = "cosmic-files-applet" -version = "1.0.14" +version = "1.0.15" dependencies = [ "cosmic-files", "log", @@ -1472,7 +1472,7 @@ dependencies = [ [[package]] name = "cosmic-mime-apps" version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-mime-apps.git#a95c8043a7b41ca3c143a1fad5b3b8a5a3411008" +source = "git+https://github.com/pop-os/cosmic-mime-apps.git#8fc81e8857e46c018ea21ab985aaf30ac853c007" dependencies = [ "freedesktop-desktop-entry", "mime 0.3.17", @@ -1485,7 +1485,7 @@ name = "cosmic-protocols" version = "0.2.0" source = "git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1#c253ec1d6804afbcdf250f5cc37ae1194bba7bd2" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -1510,9 +1510,9 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#507e342c21d3ce6ae41b1d4f3fa2f0ad5ee23e75" +source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" dependencies = [ - "zbus 5.15.0", + "zbus 5.16.0", ] [[package]] @@ -1521,7 +1521,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be17b688510d934ce13f48a2beba700e11583e281e0fda99c22bb256a14eda73" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "fontdb", "harfrust", "linebender_resource_handle", @@ -1542,7 +1542,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "almost", "configparser", @@ -1908,7 +1908,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.6.2", "libc", "objc2 0.6.4", @@ -1939,7 +1939,7 @@ name = "dnd" version = "0.1.0" source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "mime 0.1.0", "raw-window-handle", "smithay-client-toolkit", @@ -1972,7 +1972,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "bytemuck", "drm-ffi", "drm-fourcc", @@ -2558,9 +2558,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" +checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" dependencies = [ "cc", "cfg-if", @@ -2722,7 +2722,7 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16de123c2e6c90ce3b573b7330de19be649080ec612033d397d72da265f1bd8b" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "futures-channel", "futures-core", "futures-executor", @@ -2831,7 +2831,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "gpu-descriptor-types", "hashbrown 0.15.5", ] @@ -2842,7 +2842,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", ] [[package]] @@ -2879,7 +2879,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9da2e5ae821f6e96664977bf974d6d6a2d6682f9ccee23e62ec1d134246845f9" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "bytemuck", "core_maths", "read-fonts", @@ -3060,7 +3060,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "dnd", "iced_accessibility", @@ -3081,7 +3081,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "accesskit", "accesskit_winit", @@ -3090,9 +3090,9 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "bytes", "cosmic-client-toolkit", "dnd", @@ -3115,7 +3115,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "iced_core", "iced_futures", @@ -3125,7 +3125,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "futures", "iced_core", @@ -3139,9 +3139,9 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "bytemuck", "cosmic-text", "half", @@ -3160,7 +3160,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "iced_graphics", "iced_runtime", @@ -3169,7 +3169,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3181,7 +3181,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3196,7 +3196,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "bytemuck", "cosmic-text", @@ -3213,10 +3213,10 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "as-raw-xcb-connection", - "bitflags 2.11.1", + "bitflags 2.12.1", "bytemuck", "cosmic-client-toolkit", "cryoglyph", @@ -3244,7 +3244,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3828,11 +3828,11 @@ dependencies = [ [[package]] name = "inotify" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5b3eaf1a28b758ac0faa5a4254e8ab2705605496f1b1f3fbbc3988ad73d199" +checksum = "533e68a5842e734946fe159fb03fc9bbbb254f590dd0d8ad321ae5ff7beca2c1" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "inotify-sys", "libc", ] @@ -3891,7 +3891,7 @@ version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d09b98f7eace8982db770e4408e7470b028ce513ac28fecdc6bf4c30fe92b62" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "cfg-if", "libc", ] @@ -3955,9 +3955,9 @@ checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1" [[package]] name = "jiff" -version = "0.2.27" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "392c70591e8749fe235ddaf513e6f58b26bce3dcc16524cecc8936f75afa161e" +checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" dependencies = [ "jiff-static", "jiff-tzdb-platform", @@ -3981,9 +3981,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.27" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b605b0c050d845fc355bb11eb3f9a8deddc218ea60c76e61aa1f2adfb2c96a" +checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" dependencies = [ "proc-macro2", "quote", @@ -4138,9 +4138,9 @@ dependencies = [ [[package]] name = "jxl-grid" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0e0ef92d5d60e76bf41098e57e985f523185e08fad54268da448637feca6989" +checksum = "01671307879a033bfa52e6e8784b941aca770b3f3a7d33830b455b6844f793fb" dependencies = [ "tracing", ] @@ -4177,9 +4177,9 @@ dependencies = [ [[package]] name = "jxl-modular" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da758b2f989aafd9eeb39489fe43d7be5a3a0d2ad61cf1bad705eb6990a6053c" +checksum = "2a2f045b24c738dd91d482be385512b512721ae08a671bd4b27bf1c47f215235" dependencies = [ "jxl-bitstream", "jxl-coding", @@ -4191,9 +4191,9 @@ dependencies = [ [[package]] name = "jxl-oxide" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8ecd2678ed70c1eda42b811ccb2e25ab836edeb18e7f1178c1f917ed36b772" +checksum = "d36c662923f47586880211f3bc7c0d83fb3a9b410d278c7bde93450748abeef3" dependencies = [ "brotli-decompressor", "bytemuck", @@ -4221,9 +4221,9 @@ dependencies = [ [[package]] name = "jxl-render" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa0c3100918bd3c41bb0f8ce1f4f1664e48f3032ff8eeab0d6a2cfc3276f462d" +checksum = "d34386bfdb6a19b5a30cc9beb4d475d537422c31ae8c39bb69640fcce3fcaf19" dependencies = [ "bytemuck", "jxl-bitstream", @@ -4280,7 +4280,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fbe853b403ae61a04233030ae8a79d94975281ed9770a1f9e246732b534b28d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "serde", ] @@ -4312,9 +4312,9 @@ dependencies = [ [[package]] name = "kqueue" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" +checksum = "273c0752728918e0ac4976f2b275b6fefb9ecd400585dec929419f3844cd87b5" dependencies = [ "kqueue-sys", "libc", @@ -4326,7 +4326,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "libc", ] @@ -4384,7 +4384,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#59bebbdffeb8ed4abd3f2577c099745b9a2f2c37" +source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" dependencies = [ "apply", "ashpd 0.12.3", @@ -4423,7 +4423,7 @@ dependencies = [ "rust-embed", "rustix 1.1.4", "serde", - "shlex", + "shlex 1.3.0", "slotmap", "taffy", "thiserror 2.0.18", @@ -4431,7 +4431,7 @@ dependencies = [ "tracing", "unicode-segmentation", "url", - "zbus 5.15.0", + "zbus 5.16.0", ] [[package]] @@ -4466,10 +4466,10 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "libc", "plain", - "redox_syscall 0.8.0", + "redox_syscall 0.8.1", ] [[package]] @@ -4541,9 +4541,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.30" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" +checksum = "113b30b4cd05f7c06868fdb2854f66a7b9fece9a48425351cd532e810d74024f" [[package]] name = "loom" @@ -4628,9 +4628,9 @@ dependencies = [ [[package]] name = "lzma-rust2" -version = "0.16.3" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9ceaec84b54518262de7cf06b8b43e83c808349960f1610b21b0bfc9640f20" +checksum = "ce716bf1a316f47a280fc76295f6495b5bea4752bca01c3b3885e101b1c23c02" dependencies = [ "sha2 0.11.0", ] @@ -4724,7 +4724,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block", "core-graphics-types 0.2.0", "foreign-types", @@ -4775,9 +4775,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "log", @@ -4809,7 +4809,7 @@ checksum = "618f667225063219ddfc61251087db8a9aec3c3f0950c916b614e403486f1135" dependencies = [ "arrayvec", "bit-set", - "bitflags 2.11.1", + "bitflags 2.12.1", "cfg-if", "cfg_aliases", "codespan-reporting", @@ -4833,7 +4833,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "jni-sys 0.3.1", "log", "ndk-sys", @@ -4869,7 +4869,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "cfg-if", "cfg_aliases", "libc", @@ -4916,7 +4916,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "fsevent-sys", "inotify", "kqueue", @@ -4952,7 +4952,7 @@ dependencies = [ "mac-notification-sys", "serde", "tauri-winrt-notification", - "zbus 5.15.0", + "zbus 5.16.0", ] [[package]] @@ -4961,7 +4961,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", ] [[package]] @@ -5113,7 +5113,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -5129,7 +5129,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.6.2", "objc2 0.6.4", "objc2-core-foundation", @@ -5142,7 +5142,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -5154,7 +5154,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.6.2", "dispatch2", "objc2 0.6.4", @@ -5166,7 +5166,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "libc", "objc2-core-foundation", ] @@ -5189,7 +5189,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "objc2-core-foundation", "objc2-core-graphics", ] @@ -5206,7 +5206,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -5218,7 +5218,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.6.2", "libc", "objc2 0.6.4", @@ -5231,7 +5231,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -5243,7 +5243,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -5256,7 +5256,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "objc2 0.6.4", "objc2-core-foundation", "objc2-foundation 0.3.2", @@ -5638,7 +5638,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "crc32fast", "fdeflate", "flate2", @@ -5787,7 +5787,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "chrono", "flate2", "procfs-core", @@ -5800,7 +5800,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "chrono", "hex", ] @@ -6084,7 +6084,7 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c07d0d6d291e3a951bd847b1cd4af32fc6243d64116cf7702838c02797688b7" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "libredox", ] @@ -6094,16 +6094,16 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", ] [[package]] name = "redox_syscall" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c7591fa2c6b601dfcfe5f043f65a1c39fcdf50efefcd7f1572e538c1f4b398d" +checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", ] [[package]] @@ -6240,7 +6240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" dependencies = [ "base64", - "bitflags 2.11.1", + "bitflags 2.12.1", "serde", "serde_derive", "unicode-ident", @@ -6252,7 +6252,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "once_cell", "serde", "serde_derive", @@ -6327,7 +6327,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "errno", "libc", "linux-raw-sys 0.4.15", @@ -6340,7 +6340,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "errno", "libc", "linux-raw-sys 0.12.1", @@ -6359,7 +6359,7 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "bytemuck", "core_maths", "log", @@ -6596,6 +6596,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "signal-hook-registry" version = "1.4.8" @@ -6689,7 +6695,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "bytemuck", "calloop", "calloop-wayland-source", @@ -6736,9 +6742,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -6789,7 +6795,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", ] [[package]] @@ -6925,9 +6931,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.3" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "tauri-winrt-notification" @@ -6971,9 +6977,9 @@ dependencies = [ [[package]] name = "test-log" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f46bf474f0a4afebf92f076d54fd5e63423d9438b8c278a3d2ccb0f47f7cdb3" +checksum = "9b9c218384242b5c89b68303ab6f6fc53a312d923f0c14dc6bb860c6aeee40f1" dependencies = [ "env_logger", "test-log-macros", @@ -6982,9 +6988,9 @@ dependencies = [ [[package]] name = "test-log-core" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d4d41320b48bc4a211a9021678fcc0c99569b594ea31c93735b8e517102b4c" +checksum = "c26ef8b00e4d382e59f6a8ddb3cd790b3a5bb29f21a358a9a69ea2f29f13f27b" dependencies = [ "proc-macro2", "quote", @@ -6993,9 +6999,9 @@ dependencies = [ [[package]] name = "test-log-macros" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9beb9249a81e430dffd42400a49019bcf548444f1968ff23080a625de0d4d320" +checksum = "944ad38adcbb71eaa682c56bceeb079e4ca82b4b3edc2a0fde5cb297b77dac8d" dependencies = [ "syn", "test-log-core", @@ -7397,9 +7403,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "uds_windows" @@ -7490,9 +7496,9 @@ checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-vo" @@ -7578,9 +7584,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.1" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" dependencies = [ "js-sys", "serde_core", @@ -7743,7 +7749,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "hashbrown 0.15.5", "indexmap 2.14.0", "semver", @@ -7783,7 +7789,7 @@ version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "rustix 1.1.4", "wayland-backend", "wayland-scanner", @@ -7795,7 +7801,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "cursor-icon", "wayland-backend", ] @@ -7817,7 +7823,7 @@ version = "0.32.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "wayland-backend", "wayland-client", "wayland-scanner", @@ -7830,7 +7836,7 @@ version = "20250721.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7843,7 +7849,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7856,7 +7862,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7869,7 +7875,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7894,7 +7900,7 @@ version = "0.31.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc1846eb04c49182e04f4a099e2a830a2b745610bbc1d61246e206f29c7000a0" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "downcast-rs", "rustix 1.1.4", "wayland-backend", @@ -7946,7 +7952,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9cb534d5ffd109c7d1135f34cdae29e60eab94855a625dcfe1705f8bc7ad79f" dependencies = [ "arrayvec", - "bitflags 2.11.1", + "bitflags 2.12.1", "bytemuck", "cfg-if", "cfg_aliases", @@ -7978,7 +7984,7 @@ dependencies = [ "arrayvec", "bit-set", "bit-vec", - "bitflags 2.11.1", + "bitflags 2.12.1", "bytemuck", "cfg_aliases", "document-features", @@ -8038,7 +8044,7 @@ dependencies = [ "arrayvec", "ash", "bit-set", - "bitflags 2.11.1", + "bitflags 2.12.1", "block", "bytemuck", "cfg-if", @@ -8082,7 +8088,7 @@ version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e18308757e594ed2cd27dddbb16a139c42a683819d32a2e0b1b0167552f5840c" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "bytemuck", "js-sys", "log", @@ -8638,7 +8644,7 @@ name = "winit" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "cfg_aliases", "cursor-icon", "dpi", @@ -8665,7 +8671,7 @@ version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "android-activity", - "bitflags 2.11.1", + "bitflags 2.12.1", "dpi", "ndk", "raw-window-handle", @@ -8679,7 +8685,7 @@ name = "winit-appkit" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.6.2", "dispatch2", "dpi", @@ -8716,7 +8722,7 @@ name = "winit-core" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "cursor-icon", "dpi", "keyboard-types", @@ -8730,7 +8736,7 @@ name = "winit-orbital" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "dpi", "libredox", "orbclient", @@ -8746,7 +8752,7 @@ name = "winit-uikit" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "block2 0.6.2", "dispatch2", "dpi", @@ -8767,7 +8773,7 @@ version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "ahash", - "bitflags 2.11.1", + "bitflags 2.12.1", "calloop", "cursor-icon", "dpi", @@ -8793,7 +8799,7 @@ version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "atomic-waker", - "bitflags 2.11.1", + "bitflags 2.12.1", "concurrent-queue", "cursor-icon", "dpi", @@ -8814,7 +8820,7 @@ name = "winit-win32" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "cursor-icon", "dpi", "raw-window-handle", @@ -8830,7 +8836,7 @@ name = "winit-x11" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "bytemuck", "calloop", "cursor-icon", @@ -8921,7 +8927,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.11.1", + "bitflags 2.12.1", "indexmap 2.14.0", "log", "serde", @@ -9094,7 +9100,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.12.1", "dlib", "log", "once_cell", @@ -9218,9 +9224,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.15.0" +version = "5.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3bcbf15c8708d7fc1be0c993622e0a5cbd5e8b52bfa40afa4c3e0cd8d724ac1" +checksum = "eee682d202a77e4a9f3b2c2bdf48a7b28af5c08c34ddf66f98c93e5e39464285" dependencies = [ "async-broadcast", "async-executor", @@ -9247,9 +9253,9 @@ dependencies = [ "uuid", "windows-sys 0.61.2", "winnow", - "zbus_macros 5.15.0", + "zbus_macros 5.16.0", "zbus_names 4.3.2", - "zvariant 5.11.0", + "zvariant 5.12.0", ] [[package]] @@ -9259,7 +9265,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6998de05217a084b7578728a9443d04ea4cd80f2a0839b8d78770b76ccd45863" dependencies = [ "zbus_xml", - "zvariant 5.11.0", + "zvariant 5.12.0", ] [[package]] @@ -9273,7 +9279,7 @@ dependencies = [ "syn", "zbus-lockstep", "zbus_xml", - "zvariant 5.11.0", + "zvariant 5.12.0", ] [[package]] @@ -9291,17 +9297,17 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.15.0" +version = "5.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51fa5406ad9175a8c825a931f8cf347116b531b3634fcb0b627c290f1f2516ff" +checksum = "adf1bd45a81a103745b1757754762a26e8cd01e4532e4d6c8ec431624b80d1d6" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", "syn", "zbus_names 4.3.2", - "zvariant 5.11.0", - "zvariant_utils 3.3.1", + "zvariant 5.12.0", + "zvariant_utils 3.4.0", ] [[package]] @@ -9323,7 +9329,7 @@ checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d" dependencies = [ "serde", "winnow", - "zvariant 5.11.0", + "zvariant 5.12.0", ] [[package]] @@ -9335,7 +9341,7 @@ dependencies = [ "quick-xml 0.39.4", "serde", "zbus_names 4.3.2", - "zvariant 5.11.0", + "zvariant 5.12.0", ] [[package]] @@ -9346,18 +9352,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.49" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bce33a6288fa3f072a8c2c7d0f2fdbb90e28298f0135c1f99b96c3db2efcc60b" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.49" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd425244944f4ab65ccff928e7323354c5a018c75838362fdce749dfad2ee1e" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" dependencies = [ "proc-macro2", "quote", @@ -9559,17 +9565,17 @@ dependencies = [ [[package]] name = "zvariant" -version = "5.11.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c1567a6ec68df868cbbfde844cfc6d81649fe5109a62b116b19fabd53e618ee" +checksum = "a192a0bde63360d77a7523c833d4b4ce6070a927e2c53246e4c540b1a3e27be0" dependencies = [ "endi", "enumflags2", "serde", "url", "winnow", - "zvariant_derive 5.11.0", - "zvariant_utils 3.3.1", + "zvariant_derive 5.12.0", + "zvariant_utils 3.4.0", ] [[package]] @@ -9587,15 +9593,15 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "5.11.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d5b780599bbde114e39d9a0799577fad1ced5105d38515745f7b3099d8ceda" +checksum = "90bc6cde9c01c511074be97f7ccb6c19d0da89e3f8662e812e999dcfd4638737" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", "syn", - "zvariant_utils 3.3.1", + "zvariant_utils 3.4.0", ] [[package]] @@ -9611,9 +9617,9 @@ dependencies = [ [[package]] name = "zvariant_utils" -version = "3.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d464f5733ffa07a3164d656f18533caace9d0638596721355d73256a410d691" +checksum = "1e8535915cfa75547e559d8c68e8139909a4aeee076831e4ef7fc59d8172c4d6" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 2739b9b..d3220e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.0.14" +version = "1.0.15" 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 b802913..9150478 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files-applet" -version = "1.0.14" +version = "1.0.15" edition = "2024" [dependencies] diff --git a/debian/changelog b/debian/changelog index 347d255..f5a35f4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-files (1.0.15) noble; urgency=medium + + * Epoch 1.0.15 version update + + -- Jeremy Soller Tue, 02 Jun 2026 11:02:29 -0600 + cosmic-files (1.0.14) noble; urgency=medium * Epoch 1.0.14 version update From fc8f2b40006c466011c54c5f246736f1bf63b47d Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Sat, 6 Jun 2026 20:09:36 +0200 Subject: [PATCH 079/110] fix: hide no-display apps in open-with select --- src/mime_app.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mime_app.rs b/src/mime_app.rs index c543afa..3b587ee 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -270,7 +270,12 @@ impl MimeAppCache { let paths = cosmic_mime_apps::list_paths(); list.load_from_paths(&paths); let locales = fde::get_languages_from_env(); - for desktop_entry in fde::Iter::new(fde::default_paths()).entries(Some(&locales)) { + + let desktop_entries = fde::Iter::new(fde::default_paths()) + .entries(Some(&locales)) + .filter(move |de| !de.no_display()); + + for desktop_entry in desktop_entries { let name = desktop_entry .name(&locales) .unwrap_or_else(|| Cow::Borrowed(desktop_entry.id())); From 7c7970d0c0f634f39820a0965a277b5637614ca3 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Sat, 6 Jun 2026 20:26:45 +0200 Subject: [PATCH 080/110] fix: hide no-display apps only in other category --- src/app.rs | 1 + src/mime_app.rs | 27 +++------------------------ 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/app.rs b/src/app.rs index a4af64b..08601c0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2306,6 +2306,7 @@ impl App { self.mime_app_cache .apps() .iter() + .filter(|mime_app| !mime_app.no_display) .filter(|&mime_app| dedupe.insert(&mime_app.id)) .map(|mime_app| (mime_app, MimeAppMatch::Other)), ); diff --git a/src/mime_app.rs b/src/mime_app.rs index 3b587ee..6bb0d8b 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -2,8 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only use bstr::{BString, ByteSlice, ByteVec}; -#[cfg(feature = "desktop")] -use cosmic::desktop; use cosmic::widget; pub use mime_guess::Mime; #[cfg(feature = "desktop")] @@ -186,6 +184,7 @@ pub struct MimeApp { pub exec: Option, pub icon: widget::icon::Handle, is_default: Arc, + pub no_display: bool, } impl MimeApp { @@ -211,25 +210,6 @@ impl AsRef for MimeApp { } } -#[cfg(feature = "desktop")] -impl From<&desktop::DesktopEntryData> for MimeApp { - fn from(app: &desktop::DesktopEntryData) -> Self { - Self { - id: app.id.clone(), - path: app.path.clone(), - name: app.name.clone(), - exec: app.exec.clone(), - icon: match &app.icon { - desktop::fde::IconSource::Name(name) => { - widget::icon::from_name(name.as_str()).size(32).handle() - } - desktop::fde::IconSource::Path(path) => widget::icon::from_path(path.clone()), - }, - is_default: Arc::new(AtomicBool::new(false)), - } - } -} - pub struct MimeAppCache { apps: Vec>, cache: FxHashMap>>, @@ -271,9 +251,7 @@ impl MimeAppCache { list.load_from_paths(&paths); let locales = fde::get_languages_from_env(); - let desktop_entries = fde::Iter::new(fde::default_paths()) - .entries(Some(&locales)) - .filter(move |de| !de.no_display()); + let desktop_entries = fde::Iter::new(fde::default_paths()).entries(Some(&locales)); for desktop_entry in desktop_entries { let name = desktop_entry @@ -294,6 +272,7 @@ impl MimeAppCache { } }, is_default: Arc::new(AtomicBool::new(false)), + no_display: desktop_entry.no_display(), }); tracing::info!(target: "mime-apps", id = app.id, "detected desktop entry"); From 814b49114bfc5dc9aa3fbfcac154acac2e342318 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Mon, 8 Jun 2026 17:30:13 +0200 Subject: [PATCH 081/110] fix: sort other apps section --- src/app.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/app.rs b/src/app.rs index 08601c0..b00f719 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2302,14 +2302,20 @@ impl App { } // Add other apps - results.extend( - self.mime_app_cache + results.extend({ + let mut apps = self + .mime_app_cache .apps() .iter() .filter(|mime_app| !mime_app.no_display) .filter(|&mime_app| dedupe.insert(&mime_app.id)) - .map(|mime_app| (mime_app, MimeAppMatch::Other)), - ); + .map(|mime_app| (mime_app, MimeAppMatch::Other)) + .collect::>(); + apps.sort_by(|(a, _), (b, _)| { + crate::localize::LANGUAGE_SORTER.compare(&a.name, &b.name) + }); + apps + }); results } From 1d88fd16d6760207daaafff7481b2ff0e2f636b6 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 9 Jun 2026 10:26:10 -0600 Subject: [PATCH 082/110] Epoch 1.0.16 version update Generated by cosmic-epoch scripts/version-update.sh --- Cargo.lock | 307 +++++++++++++++++---------------- Cargo.toml | 2 +- cosmic-files-applet/Cargo.toml | 2 +- debian/changelog | 6 + 4 files changed, 171 insertions(+), 146 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b78423e..bc95ecd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,7 +198,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" dependencies = [ "android-properties", - "bitflags 2.12.1", + "bitflags 2.13.0", "cc", "jni", "libc", @@ -702,9 +702,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" dependencies = [ "serde_core", ] @@ -904,7 +904,7 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dbf9978365bac10f54d1d4b04f7ce4427e51f71d61f2fe15e3fed5166474df7" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "polling", "rustix 1.1.4", "slab", @@ -970,9 +970,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", @@ -1238,9 +1238,9 @@ dependencies = [ [[package]] name = "configparser" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57e3272f0190c3f1584272d613719ba5fc7df7f4942fe542e63d949cf3a649b" +checksum = "b46dec724fd22199ebde05033a0cbae453bc3b1ecff11eb6a6bb3eec4b90c6a4" [[package]] name = "const-oid" @@ -1310,7 +1310,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "core-foundation 0.10.1", "libc", ] @@ -1340,7 +1340,7 @@ name = "cosmic-client-toolkit" version = "0.2.0" source = "git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1#c253ec1d6804afbcdf250f5cc37ae1194bba7bd2" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "cosmic-protocols", "libc", "smithay-client-toolkit", @@ -1351,7 +1351,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1372,7 +1372,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "quote", "syn", @@ -1380,7 +1380,7 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.0.15" +version = "1.0.16" dependencies = [ "anyhow", "atomic_float", @@ -1448,7 +1448,7 @@ dependencies = [ [[package]] name = "cosmic-files-applet" -version = "1.0.15" +version = "1.0.16" dependencies = [ "cosmic-files", "log", @@ -1485,7 +1485,7 @@ name = "cosmic-protocols" version = "0.2.0" source = "git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1#c253ec1d6804afbcdf250f5cc37ae1194bba7bd2" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -1521,7 +1521,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be17b688510d934ce13f48a2beba700e11583e281e0fda99c22bb256a14eda73" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "fontdb", "harfrust", "linebender_resource_handle", @@ -1529,7 +1529,7 @@ dependencies = [ "rangemap", "rustc-hash 2.1.2", "self_cell", - "skrifa", + "skrifa 0.40.0", "smol_str", "swash", "sys-locale", @@ -1542,7 +1542,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "almost", "configparser", @@ -1908,7 +1908,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.6.2", "libc", "objc2 0.6.4", @@ -1939,7 +1939,7 @@ name = "dnd" version = "0.1.0" source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "mime 0.1.0", "raw-window-handle", "smithay-client-toolkit", @@ -1972,7 +1972,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "bytemuck", "drm-ffi", "drm-fourcc", @@ -2722,7 +2722,7 @@ version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16de123c2e6c90ce3b573b7330de19be649080ec612033d397d72da265f1bd8b" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "futures-channel", "futures-core", "futures-executor", @@ -2831,7 +2831,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "gpu-descriptor-types", "hashbrown 0.15.5", ] @@ -2842,7 +2842,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", ] [[package]] @@ -2879,10 +2879,10 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9da2e5ae821f6e96664977bf974d6d6a2d6682f9ccee23e62ec1d134246845f9" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "bytemuck", "core_maths", - "read-fonts", + "read-fonts 0.37.0", "smallvec", ] @@ -3060,7 +3060,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "dnd", "iced_accessibility", @@ -3081,7 +3081,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "accesskit", "accesskit_winit", @@ -3090,9 +3090,9 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "bytes", "cosmic-client-toolkit", "dnd", @@ -3115,7 +3115,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "iced_core", "iced_futures", @@ -3125,7 +3125,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "futures", "iced_core", @@ -3139,9 +3139,9 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "bytemuck", "cosmic-text", "half", @@ -3160,7 +3160,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "iced_graphics", "iced_runtime", @@ -3169,7 +3169,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3181,7 +3181,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3196,7 +3196,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "bytemuck", "cosmic-text", @@ -3213,10 +3213,10 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "as-raw-xcb-connection", - "bitflags 2.12.1", + "bitflags 2.13.0", "bytemuck", "cosmic-client-toolkit", "cryoglyph", @@ -3244,7 +3244,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3725,9 +3725,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.25" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" +checksum = "b915661dd01db3f05050265b2477bcc6527b3792388e2749b41623cc592be67d" dependencies = [ "crossbeam-deque", "globset", @@ -3790,9 +3790,9 @@ checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" [[package]] name = "imgref" -version = "1.12.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40fac9d56ed6437b198fddba683305e8e2d651aa42647f00f5ae542e7f5c94a2" +checksum = "89194689a993ab15268672e99e7b0e19da2da3268ac682e8f02d29d4d1434cd7" [[package]] name = "indexmap" @@ -3832,7 +3832,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "533e68a5842e734946fe159fb03fc9bbbb254f590dd0d8ad321ae5ff7beca2c1" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "inotify-sys", "libc", ] @@ -3891,7 +3891,7 @@ version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d09b98f7eace8982db770e4408e7470b028ce513ac28fecdc6bf4c30fe92b62" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "cfg-if", "libc", ] @@ -4075,13 +4075,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.99" +version = "0.3.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +checksum = "f2025f20d7a4fa7785846e7b63d10a76d3f1cee98ee5cb79ea59703f95e42162" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -4280,7 +4279,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fbe853b403ae61a04233030ae8a79d94975281ed9770a1f9e246732b534b28d" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "serde", ] @@ -4326,7 +4325,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "libc", ] @@ -4384,7 +4383,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#f0f68933f1552857e2165fc0fa953228107bddef" +source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" dependencies = [ "apply", "ashpd 0.12.3", @@ -4436,9 +4435,9 @@ dependencies = [ [[package]] name = "libfuzzer-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12a681b7dd8ce12bff52488013ba614b869148d54dd79836ab85aafdd53f08d" +checksum = "a9fd2f41a1cba099f79a0b6b6c35656cf7c03351a7bae8ff0f28f25270f929d2" dependencies = [ "arbitrary", "cc", @@ -4466,7 +4465,7 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "libc", "plain", "redox_syscall 0.8.1", @@ -4541,9 +4540,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.31" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "113b30b4cd05f7c06868fdb2854f66a7b9fece9a48425351cd532e810d74024f" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" [[package]] name = "loom" @@ -4637,9 +4636,9 @@ dependencies = [ [[package]] name = "mac-notification-sys" -version = "0.6.12" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a16783dd1a47849b8c8133c9cd3eb2112cfbc6901670af3dba47c8bbfb07d3" +checksum = "50efa634682b3fc5a1ab6f3dd5b2bce7b848011fc485b53b063dc68f2f74feae" dependencies = [ "cc", "objc2 0.6.4", @@ -4724,7 +4723,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block", "core-graphics-types 0.2.0", "foreign-types", @@ -4809,7 +4808,7 @@ checksum = "618f667225063219ddfc61251087db8a9aec3c3f0950c916b614e403486f1135" dependencies = [ "arrayvec", "bit-set", - "bitflags 2.12.1", + "bitflags 2.13.0", "cfg-if", "cfg_aliases", "codespan-reporting", @@ -4833,7 +4832,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "jni-sys 0.3.1", "log", "ndk-sys", @@ -4869,7 +4868,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "cfg-if", "cfg_aliases", "libc", @@ -4916,7 +4915,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "fsevent-sys", "inotify", "kqueue", @@ -4961,7 +4960,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", ] [[package]] @@ -5113,7 +5112,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -5129,7 +5128,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.6.2", "objc2 0.6.4", "objc2-core-foundation", @@ -5142,7 +5141,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -5154,7 +5153,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.6.2", "dispatch2", "objc2 0.6.4", @@ -5166,7 +5165,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "libc", "objc2-core-foundation", ] @@ -5189,7 +5188,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "objc2-core-foundation", "objc2-core-graphics", ] @@ -5206,7 +5205,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.5.1", "libc", "objc2 0.5.2", @@ -5218,7 +5217,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.6.2", "libc", "objc2 0.6.4", @@ -5231,7 +5230,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -5243,7 +5242,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -5256,7 +5255,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "objc2 0.6.4", "objc2-core-foundation", "objc2-foundation 0.3.2", @@ -5638,7 +5637,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "crc32fast", "fdeflate", "flate2", @@ -5787,7 +5786,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "chrono", "flate2", "procfs-core", @@ -5800,7 +5799,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "chrono", "hex", ] @@ -6062,6 +6061,16 @@ dependencies = [ "font-types", ] +[[package]] +name = "read-fonts" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4ed38b89c2c77ff968c524145ad65fb010f38af5c7a224b53b81d47ac2daa81" +dependencies = [ + "bytemuck", + "font-types", +] + [[package]] name = "recently-used-xbel" version = "1.2.0" @@ -6084,7 +6093,7 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c07d0d6d291e3a951bd847b1cd4af32fc6243d64116cf7702838c02797688b7" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "libredox", ] @@ -6094,7 +6103,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", ] [[package]] @@ -6103,7 +6112,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", ] [[package]] @@ -6150,9 +6159,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.3" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" dependencies = [ "aho-corasick", "memchr", @@ -6173,9 +6182,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "renderdoc-sys" @@ -6240,7 +6249,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468" dependencies = [ "base64", - "bitflags 2.12.1", + "bitflags 2.13.0", "serde", "serde_derive", "unicode-ident", @@ -6252,7 +6261,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "once_cell", "serde", "serde_derive", @@ -6327,7 +6336,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -6340,7 +6349,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "errno", "libc", "linux-raw-sys 0.12.1", @@ -6359,7 +6368,7 @@ version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "bytemuck", "core_maths", "log", @@ -6507,9 +6516,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" +checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c" dependencies = [ "base64", "bs58", @@ -6527,9 +6536,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" +checksum = "84d57bc0c8b9a17920c178daa6bb924850d54a9c97ab45194bb8c17ad66bb660" dependencies = [ "darling 0.23.0", "proc-macro2", @@ -6665,7 +6674,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbdfe3d2475fbd7ddd1f3e5cf8288a30eb3e5f95832829570cd88115a7434ac" dependencies = [ "bytemuck", - "read-fonts", + "read-fonts 0.37.0", +] + +[[package]] +name = "skrifa" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c34617370ae968efb7161bb2beb517d9084659aae19e24b89e3db25b46e4564" +dependencies = [ + "bytemuck", + "read-fonts 0.39.2", ] [[package]] @@ -6695,7 +6714,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "bytemuck", "calloop", "calloop-wayland-source", @@ -6795,7 +6814,7 @@ version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", ] [[package]] @@ -6843,11 +6862,11 @@ dependencies = [ [[package]] name = "swash" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "842f3cd369c2ba38966204f983eaa5e54a8e84a7d7159ed36ade2b6c335aae64" +checksum = "d1804632b66a35ca2b1d277eb0a138e10f46cb365b9a6d297e876b69ef79de43" dependencies = [ - "skrifa", + "skrifa 0.42.1", "yazi", "zeno", ] @@ -7584,9 +7603,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.2" +version = "1.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" +checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" dependencies = [ "js-sys", "serde_core", @@ -7668,9 +7687,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.122" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +checksum = "a254a4b10c19a76f09a27640e7ffbf9bc30bf67e16a3bf28aaefa4920fe81563" dependencies = [ "cfg-if", "once_cell", @@ -7681,9 +7700,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.72" +version = "0.4.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" +checksum = "54568702fabf5d4849ce2b90fadfa64168a097eaf4b351ce9df8b687a0086aaf" dependencies = [ "js-sys", "wasm-bindgen", @@ -7691,9 +7710,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.122" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +checksum = "24a40fc75b0ec6f3746ceb10d36f53a93dcd68a93b11b6445983945d79eba0dc" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7701,9 +7720,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.122" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +checksum = "908f34bd9b9ce3d4caf07b72dfab63d61504d156856c6bd3cd87fa350cf3985b" dependencies = [ "bumpalo", "proc-macro2", @@ -7714,9 +7733,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.122" +version = "0.2.123" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +checksum = "7acbf7616c27b194bbb550bf77ed0c2c3e5b7fd1260a93082b95fb7f47959b92" dependencies = [ "unicode-ident", ] @@ -7749,7 +7768,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "hashbrown 0.15.5", "indexmap 2.14.0", "semver", @@ -7789,7 +7808,7 @@ version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "rustix 1.1.4", "wayland-backend", "wayland-scanner", @@ -7801,7 +7820,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "cursor-icon", "wayland-backend", ] @@ -7823,7 +7842,7 @@ version = "0.32.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -7836,7 +7855,7 @@ version = "20250721.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7849,7 +7868,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7862,7 +7881,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7875,7 +7894,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7900,7 +7919,7 @@ version = "0.31.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc1846eb04c49182e04f4a099e2a830a2b745610bbc1d61246e206f29c7000a0" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "downcast-rs", "rustix 1.1.4", "wayland-backend", @@ -7921,9 +7940,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.99" +version = "0.3.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" +checksum = "6e0871acf327f283dc6da28a1696cdc64fb355ba9f935d052021fa77f35cce69" dependencies = [ "js-sys", "wasm-bindgen", @@ -7952,7 +7971,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9cb534d5ffd109c7d1135f34cdae29e60eab94855a625dcfe1705f8bc7ad79f" dependencies = [ "arrayvec", - "bitflags 2.12.1", + "bitflags 2.13.0", "bytemuck", "cfg-if", "cfg_aliases", @@ -7984,7 +8003,7 @@ dependencies = [ "arrayvec", "bit-set", "bit-vec", - "bitflags 2.12.1", + "bitflags 2.13.0", "bytemuck", "cfg_aliases", "document-features", @@ -8044,7 +8063,7 @@ dependencies = [ "arrayvec", "ash", "bit-set", - "bitflags 2.12.1", + "bitflags 2.13.0", "block", "bytemuck", "cfg-if", @@ -8088,7 +8107,7 @@ version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e18308757e594ed2cd27dddbb16a139c42a683819d32a2e0b1b0167552f5840c" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "bytemuck", "js-sys", "log", @@ -8644,7 +8663,7 @@ name = "winit" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "cfg_aliases", "cursor-icon", "dpi", @@ -8671,7 +8690,7 @@ version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "android-activity", - "bitflags 2.12.1", + "bitflags 2.13.0", "dpi", "ndk", "raw-window-handle", @@ -8685,7 +8704,7 @@ name = "winit-appkit" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.6.2", "dispatch2", "dpi", @@ -8722,7 +8741,7 @@ name = "winit-core" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "cursor-icon", "dpi", "keyboard-types", @@ -8736,7 +8755,7 @@ name = "winit-orbital" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "dpi", "libredox", "orbclient", @@ -8752,7 +8771,7 @@ name = "winit-uikit" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "block2 0.6.2", "dispatch2", "dpi", @@ -8773,7 +8792,7 @@ version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "ahash", - "bitflags 2.12.1", + "bitflags 2.13.0", "calloop", "cursor-icon", "dpi", @@ -8799,7 +8818,7 @@ version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "atomic-waker", - "bitflags 2.12.1", + "bitflags 2.13.0", "concurrent-queue", "cursor-icon", "dpi", @@ -8820,7 +8839,7 @@ name = "winit-win32" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "cursor-icon", "dpi", "raw-window-handle", @@ -8836,7 +8855,7 @@ name = "winit-x11" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "bytemuck", "calloop", "cursor-icon", @@ -8927,7 +8946,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.12.1", + "bitflags 2.13.0", "indexmap 2.14.0", "log", "serde", @@ -9100,7 +9119,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.12.1", + "bitflags 2.13.0", "dlib", "log", "once_cell", @@ -9163,9 +9182,9 @@ checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ "stable_deref_trait", "yoke-derive", diff --git a/Cargo.toml b/Cargo.toml index d3220e0..188d0dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.0.15" +version = "1.0.16" 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 9150478..7414ba5 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files-applet" -version = "1.0.15" +version = "1.0.16" edition = "2024" [dependencies] diff --git a/debian/changelog b/debian/changelog index f5a35f4..251a2f8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-files (1.0.16) noble; urgency=medium + + * Epoch 1.0.16 version update + + -- Jeremy Soller Tue, 09 Jun 2026 10:26:05 -0600 + cosmic-files (1.0.15) noble; urgency=medium * Epoch 1.0.15 version update From af65a6b1c06322b5f5a79969f63df91af5dca6c1 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Tue, 9 Jun 2026 14:36:14 -0600 Subject: [PATCH 083/110] improv: use sort-icons instead of unicode arrow glyphs --- src/menu.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/menu.rs b/src/menu.rs index d8c13ba..cfc7d20 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -107,18 +107,25 @@ pub fn context_menu<'a>( let (sort_name, sort_direction, _) = tab.sort_options(); let sort_item = |label, variant| { - menu_item( - format!( - "{} {}", - label, - match (sort_name == variant, sort_direction) { - (true, true) => "\u{2B07}", - (true, false) => "\u{2B06}", - _ => "", - } - ), - Action::ToggleSort(variant), + let key = find_key(&Action::ToggleSort(variant)); + let leading: Element<'a, tab::Message> = if sort_name == variant { + let icon_name = if sort_direction { + "view-sort-ascending-symbolic" + } else { + "view-sort-descending-symbolic" + }; + widget::icon::from_name(icon_name).size(14).into() + } else { + space::horizontal().width(Length::Fixed(14.0)).into() + }; + menu_button!( + leading, + space::horizontal().width(Length::Fixed(theme::spacing().space_xxs.into())), + text::body(label), + space::horizontal(), + text::body(key).class(theme::Text::Custom(key_style)) ) + .on_press(tab::Message::ContextAction(Action::ToggleSort(variant))) .into() }; From c6c9eac97ebcb73acb848c418530d4b3abde8ce9 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Tue, 9 Jun 2026 20:03:21 +0200 Subject: [PATCH 084/110] fix: hide apps without declared mimetype support --- src/mime_app.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mime_app.rs b/src/mime_app.rs index 6bb0d8b..6038149 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -272,7 +272,9 @@ impl MimeAppCache { } }, is_default: Arc::new(AtomicBool::new(false)), - no_display: desktop_entry.no_display(), + no_display: desktop_entry + .mime_type() + .is_none_or(|supported| supported.is_empty()), }); tracing::info!(target: "mime-apps", id = app.id, "detected desktop entry"); From 4ac289f40a95398a281e1adcddddd5ebe6caa156 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Tue, 9 Jun 2026 16:34:20 -0600 Subject: [PATCH 085/110] improv: lazy load app icons for mime apps --- src/app.rs | 2 +- src/mime_app.rs | 44 +++++++++++++++++++++----------------------- src/tab.rs | 4 ++-- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/app.rs b/src/app.rs index b00f719..8996b5c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -5992,7 +5992,7 @@ impl Application for App { widget::mouse_area( widget::button::custom( widget::row::with_children([ - icon(app.icon.clone()).size(32).into(), + icon(app.icon()).size(32).into(), if app.is_default() && !displayed_default { displayed_default = true; widget::text::body(fl!( diff --git a/src/mime_app.rs b/src/mime_app.rs index 6038149..232cdff 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -182,7 +182,8 @@ pub struct MimeApp { pub path: Option, pub name: String, pub exec: Option, - pub icon: widget::icon::Handle, + icon_name: Box, + icon: std::sync::OnceLock, is_default: Arc, pub no_display: bool, } @@ -201,6 +202,19 @@ impl MimeApp { pub fn is_default(&self) -> bool { self.is_default.load(atomic::Ordering::SeqCst) } + + pub fn icon(&self) -> widget::icon::Handle { + self.icon + .get_or_init(|| { + let name = &*self.icon_name; + if name.starts_with('/') { + cosmic::widget::icon::from_path(PathBuf::from(name)) + } else { + cosmic::widget::icon::from_name(name).size(32).handle() + } + }) + .clone() + } } // This allows usage of MimeApp in a dropdown @@ -213,7 +227,6 @@ impl AsRef for MimeApp { pub struct MimeAppCache { apps: Vec>, cache: FxHashMap>>, - icons: FxHashMap>, terminals: Vec>, } @@ -222,7 +235,6 @@ impl MimeAppCache { let mut mime_app_cache = Self { apps: Vec::new(), cache: FxHashMap::default(), - icons: FxHashMap::default(), terminals: Vec::new(), }; mime_app_cache.reload(); @@ -243,7 +255,6 @@ impl MimeAppCache { self.apps.clear(); self.cache.clear(); - self.icons.clear(); self.terminals.clear(); let mut list = cosmic_mime_apps::List::default(); @@ -263,14 +274,8 @@ impl MimeAppCache { path: Some(desktop_entry.path.clone()), name: name.into(), exec: desktop_entry.exec().map(String::from), - icon: { - let icon = desktop_entry.icon().unwrap_or_default(); - if icon.starts_with('/') { - cosmic::widget::icon::from_path(PathBuf::from(icon)) - } else { - cosmic::widget::icon::from_name(icon).size(32).handle() - } - }, + icon_name: desktop_entry.icon().unwrap_or_default().into(), + icon: std::sync::OnceLock::new(), is_default: Arc::new(AtomicBool::new(false)), no_display: desktop_entry .mime_type() @@ -359,15 +364,6 @@ impl MimeAppCache { tracing::debug!(target: "mime-apps", mime = mime.essence_str(), apps = ?(cache.iter().map(|app| &*app.id).collect::>()), "mime defaults found") } - // Copy icons to special cache - //TODO: adjust dropdown API so this is no longer needed - self.icons.extend(self.cache.iter().map(|(mime, apps)| { - ( - mime.clone(), - apps.iter().map(|app| app.icon.clone()).collect(), - ) - })); - let elapsed = start.elapsed(); tracing::info!(target: "mime-apps", "loaded mime app cache in {elapsed:?}"); } @@ -380,8 +376,10 @@ impl MimeAppCache { self.cache.get(key).map_or(&[], Vec::as_slice) } - pub fn icons(&self, key: &Mime) -> &[widget::icon::Handle] { - self.icons.get(key).map_or(&[], Box::as_ref) + pub fn icons(&self, key: &Mime) -> Vec { + self.cache + .get(key) + .map_or_else(Vec::new, |apps| apps.iter().map(|app| app.icon()).collect()) } fn get_default_terminal(&self) -> Option { diff --git a/src/tab.rs b/src/tab.rs index 185a258..0aaaddc 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2381,7 +2381,7 @@ impl Item { mime_apps.iter().position(|x| x.is_default()), move |index| index, ) - .icons(Cow::Borrowed(mime_app_cache.icons(&self.mime))), + .icons(Cow::Owned(mime_app_cache.icons(&self.mime))), ) .map(|index| { let mime_app = &mime_apps[index]; @@ -6465,7 +6465,7 @@ impl Tab { mime_apps.iter().position(|x| x.is_default()), move |index| (index, mime_closure.clone()), ) - .icons(Cow::Borrowed(mime_app_cache.icons(&mime))), + .icons(Cow::Owned(mime_app_cache.icons(&mime))), ) .map(|(index, mime)| { let mime_app = &mime_apps[index]; From 42577aa4679390f8437d902ba22bd3e6dff7eda5 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Tue, 9 Jun 2026 16:50:50 -0600 Subject: [PATCH 086/110] fix: take user's Added Association into account when hiding apps --- src/app.rs | 2 +- src/mime_app.rs | 25 ++++++++++++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/app.rs b/src/app.rs index 8996b5c..292bb83 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2307,7 +2307,7 @@ impl App { .mime_app_cache .apps() .iter() - .filter(|mime_app| !mime_app.no_display) + .filter(|mime_app| !mime_app.no_display()) .filter(|&mime_app| dedupe.insert(&mime_app.id)) .map(|mime_app| (mime_app, MimeAppMatch::Other)) .collect::>(); diff --git a/src/mime_app.rs b/src/mime_app.rs index 232cdff..f1f643c 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -185,7 +185,7 @@ pub struct MimeApp { icon_name: Box, icon: std::sync::OnceLock, is_default: Arc, - pub no_display: bool, + no_display: Arc, } impl MimeApp { @@ -200,7 +200,11 @@ impl MimeApp { } pub fn is_default(&self) -> bool { - self.is_default.load(atomic::Ordering::SeqCst) + self.is_default.load(atomic::Ordering::Relaxed) + } + + pub fn no_display(&self) -> bool { + self.no_display.load(atomic::Ordering::Relaxed) } pub fn icon(&self) -> widget::icon::Handle { @@ -277,9 +281,7 @@ impl MimeAppCache { icon_name: desktop_entry.icon().unwrap_or_default().into(), icon: std::sync::OnceLock::new(), is_default: Arc::new(AtomicBool::new(false)), - no_display: desktop_entry - .mime_type() - .is_none_or(|supported| supported.is_empty()), + no_display: Arc::new(AtomicBool::new(false)), }); tracing::info!(target: "mime-apps", id = app.id, "detected desktop entry"); @@ -364,6 +366,19 @@ impl MimeAppCache { tracing::debug!(target: "mime-apps", mime = mime.essence_str(), apps = ?(cache.iter().map(|app| &*app.id).collect::>()), "mime defaults found") } + let associated: rustc_hash::FxHashSet<&str> = self + .cache + .values() + .flatten() + .map(|app| app.id.as_str()) + .collect(); + for app in &self.apps { + app.no_display.store( + !associated.contains(app.id.as_str()), + atomic::Ordering::Relaxed, + ); + } + let elapsed = start.elapsed(); tracing::info!(target: "mime-apps", "loaded mime app cache in {elapsed:?}"); } From 64998b37a1ff84a4430101e3dfb2191dc7d6f428 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 11 Jun 2026 15:52:30 +0200 Subject: [PATCH 087/110] fix: do not use `application/x-zerosize` as mime type for empty files --- src/mime_icon.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mime_icon.rs b/src/mime_icon.rs index 64f007f..847b550 100644 --- a/src/mime_icon.rs +++ b/src/mime_icon.rs @@ -78,6 +78,7 @@ pub fn mime_for_path( let mime_icon_cache = MIME_ICON_CACHE.lock().unwrap(); // Try the shared mime info cache first let mut gb = mime_icon_cache.shared_mime_info.guess_mime_type(); + gb.zero_size(false); if remote { if let Some(file_name) = path.file_name().and_then(std::ffi::OsStr::to_str) { gb.file_name(file_name); From 3cd0d0c00a867933b1eef954757400b56e391d03 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 11 Jun 2026 16:36:30 +0200 Subject: [PATCH 088/110] refactor: move mime app logic to mime_app module --- src/app.rs | 59 +++---------------------------------------------- src/mime_app.rs | 51 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 57 deletions(-) diff --git a/src/app.rs b/src/app.rs index 292bb83..10b8c76 100644 --- a/src/app.rs +++ b/src/app.rs @@ -67,7 +67,7 @@ use crate::config::{ use crate::dialog::{Dialog, DialogKind, DialogMessage, DialogResult, DialogSettings}; use crate::key_bind::key_binds; use crate::localize::LANGUAGE_SORTER; -use crate::mime_app::{self, MimeApp, MimeAppCache}; +use crate::mime_app::{self, MimeApp, MimeAppCache, MimeAppMatch}; use crate::mounter::{ MOUNTERS, MounterAuth, MounterItem, MounterItems, MounterKey, MounterMessage, }; @@ -656,13 +656,6 @@ impl DialogPages { pub struct FavoriteIndex(usize); -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -enum MimeAppMatch { - Exact, - Related, - Other, -} - pub struct MounterData(MounterKey, MounterItem); #[derive(Clone, Debug)] @@ -2274,52 +2267,6 @@ impl App { .into() } - fn get_apps_for_mime(&self, mime_type: &Mime) -> Vec<(&Arc, MimeAppMatch)> { - let mut results = Vec::new(); - - let mut dedupe = FxHashSet::default(); - - // start with exact matches - results.extend( - self.mime_app_cache - .get(mime_type) - .iter() - .filter(|&mime_app| dedupe.insert(&mime_app.id)) - .map(|mime_app| (mime_app, MimeAppMatch::Exact)), - ); - - // grab matches based off of subclass / parent mime type - if let Some(parent_types) = mime_icon::parent_mime_types(mime_type) { - for parent_type in parent_types { - results.extend( - self.mime_app_cache - .get(&parent_type) - .iter() - .filter(|&mime_app| dedupe.insert(&mime_app.id)) - .map(|mime_app| (mime_app, MimeAppMatch::Related)), - ); - } - } - - // Add other apps - results.extend({ - let mut apps = self - .mime_app_cache - .apps() - .iter() - .filter(|mime_app| !mime_app.no_display()) - .filter(|&mime_app| dedupe.insert(&mime_app.id)) - .map(|mime_app| (mime_app, MimeAppMatch::Other)) - .collect::>(); - apps.sort_by(|(a, _), (b, _)| { - crate::localize::LANGUAGE_SORTER.compare(&a.name, &b.name) - }); - apps - }); - - results - } - // Update favorites based on renaming or moving dirs. fn update_favorites(&mut self, path_changes: &[(impl AsRef, impl AsRef)]) -> bool { let mut favorites_changed = false; @@ -3233,7 +3180,7 @@ impl Application for App { selected, .. } => { - let available_apps = self.get_apps_for_mime(&mime); + let available_apps = self.mime_app_cache.get_apps_for_mime(&mime); if let Some((app, _)) = available_apps.get(selected) { if let Some(mut command) = @@ -5971,7 +5918,7 @@ impl Application for App { }; let mut column = widget::list_column(); - let available_apps = self.get_apps_for_mime(mime); + let available_apps = self.mime_app_cache.get_apps_for_mime(mime); let item_height = 32.0; let mut displayed_default = false; let mut last_kind = MimeAppMatch::Exact; diff --git a/src/mime_app.rs b/src/mime_app.rs index f1f643c..a4956f8 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -6,7 +6,7 @@ use cosmic::widget; pub use mime_guess::Mime; #[cfg(feature = "desktop")] use notify_debouncer_full::notify; -use rustc_hash::FxHashMap; +use rustc_hash::{FxHashMap, FxHashSet}; use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; @@ -176,6 +176,13 @@ pub fn exec_to_command( Some(commands) } +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum MimeAppMatch { + Exact, + Related, + Other, +} + #[derive(Clone, Debug)] pub struct MimeApp { pub id: String, @@ -245,6 +252,48 @@ impl MimeAppCache { mime_app_cache } + pub fn get_apps_for_mime(&self, mime_type: &Mime) -> Vec<(&Arc, MimeAppMatch)> { + let mut results = Vec::new(); + + let mut dedupe = FxHashSet::default(); + + // start with exact matches + results.extend( + self.get(mime_type) + .iter() + .filter(|&mime_app| dedupe.insert(&mime_app.id)) + .map(|mime_app| (mime_app, MimeAppMatch::Exact)), + ); + + // grab matches based off of subclass / parent mime type + if let Some(parent_types) = crate::mime_icon::parent_mime_types(mime_type) { + for parent_type in parent_types { + results.extend( + self.get(&parent_type) + .iter() + .filter(|&mime_app| dedupe.insert(&mime_app.id)) + .map(|mime_app| (mime_app, MimeAppMatch::Related)), + ); + } + } + + results.extend({ + let mut apps = self + .apps() + .iter() + .filter(|mime_app| !mime_app.no_display()) + .filter(|&mime_app| dedupe.insert(&mime_app.id)) + .map(|mime_app| (mime_app, MimeAppMatch::Other)) + .collect::>(); + apps.sort_by(|(a, _), (b, _)| { + crate::localize::LANGUAGE_SORTER.compare(&a.name, &b.name) + }); + apps + }); + + results + } + #[cfg(not(feature = "desktop"))] pub fn reload(&mut self) {} From 256a6cba19b2bf7667d271fe27c106449bf6c30c Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 11 Jun 2026 17:15:37 +0200 Subject: [PATCH 089/110] feat(mime_app): include video players for audio mime types --- src/mime_app.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/mime_app.rs b/src/mime_app.rs index a4956f8..e1f1ca2 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -254,7 +254,6 @@ impl MimeAppCache { pub fn get_apps_for_mime(&self, mime_type: &Mime) -> Vec<(&Arc, MimeAppMatch)> { let mut results = Vec::new(); - let mut dedupe = FxHashSet::default(); // start with exact matches @@ -265,6 +264,20 @@ impl MimeAppCache { .map(|mime_app| (mime_app, MimeAppMatch::Exact)), ); + let include_mime = match mime_type.type_().as_str() { + "audio" => Some("video/mp4".parse::().expect("video/mp4 mime")), + _ => None, + }; + + if let Some(mime) = include_mime { + results.extend( + self.get(&mime) + .iter() + .filter(|&mime_app| dedupe.insert(&mime_app.id)) + .map(|mime_app| (mime_app, MimeAppMatch::Exact)), + ); + } + // grab matches based off of subclass / parent mime type if let Some(parent_types) = crate::mime_icon::parent_mime_types(mime_type) { for parent_type in parent_types { From 6d4af69318e5a5ee5fdfd2000383d9a199247f6f Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 11 Jun 2026 17:16:26 +0200 Subject: [PATCH 090/110] feat(mime_app): include text editors for text-based mime types --- src/mime_app.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mime_app.rs b/src/mime_app.rs index e1f1ca2..a76a84c 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -266,6 +266,7 @@ impl MimeAppCache { let include_mime = match mime_type.type_().as_str() { "audio" => Some("video/mp4".parse::().expect("video/mp4 mime")), + "text" => Some(mime_guess::mime::TEXT_PLAIN), _ => None, }; From eda8291678dac99fd082e778c5260754ab26f8f6 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 11 Jun 2026 17:54:12 +0200 Subject: [PATCH 091/110] fix(mime_app): track mime type app default by mime --- src/app.rs | 2 +- src/mime_app.rs | 12 ++++++------ src/tab.rs | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/app.rs b/src/app.rs index 10b8c76..58ac81f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -5940,7 +5940,7 @@ impl Application for App { widget::button::custom( widget::row::with_children([ icon(app.icon()).size(32).into(), - if app.is_default() && !displayed_default { + if app.is_default(mime) && !displayed_default { displayed_default = true; widget::text::body(fl!( "default-app", diff --git a/src/mime_app.rs b/src/mime_app.rs index a76a84c..bb84f80 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -11,7 +11,7 @@ use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; use std::sync::atomic::AtomicBool; -use std::sync::{Arc, atomic}; +use std::sync::{Arc, RwLock, atomic}; use std::time::{self, Instant}; use std::{fs, io, process}; @@ -191,7 +191,7 @@ pub struct MimeApp { pub exec: Option, icon_name: Box, icon: std::sync::OnceLock, - is_default: Arc, + is_default: Arc>>>, no_display: Arc, } @@ -206,8 +206,8 @@ impl MimeApp { ) } - pub fn is_default(&self) -> bool { - self.is_default.load(atomic::Ordering::Relaxed) + pub fn is_default(&self, mime: &Mime) -> bool { + self.is_default.read().unwrap().contains(mime.essence_str()) } pub fn no_display(&self) -> bool { @@ -343,7 +343,7 @@ impl MimeAppCache { exec: desktop_entry.exec().map(String::from), icon_name: desktop_entry.icon().unwrap_or_default().into(), icon: std::sync::OnceLock::new(), - is_default: Arc::new(AtomicBool::new(false)), + is_default: Arc::new(RwLock::default()), no_display: Arc::new(AtomicBool::new(false)), }); @@ -414,7 +414,7 @@ impl MimeAppCache { apps.retain(|app| { let found = app.id.as_str() == default; if found { - app.is_default.store(true, atomic::Ordering::Relaxed); + app.is_default.write().unwrap().insert(default.into()); cache.push(app.clone()); } diff --git a/src/tab.rs b/src/tab.rs index 0aaaddc..d5deaaf 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2378,7 +2378,7 @@ impl Item { .iter() .map(|app| Cow::Owned(app.name.clone())) .collect::>>(), - mime_apps.iter().position(|x| x.is_default()), + mime_apps.iter().position(|x| x.is_default(&self.mime)), move |index| index, ) .icons(Cow::Owned(mime_app_cache.icons(&self.mime))), @@ -6462,7 +6462,7 @@ impl Tab { .iter() .map(|app| Cow::Owned(app.name.clone())) .collect::>>(), - mime_apps.iter().position(|x| x.is_default()), + mime_apps.iter().position(|x| x.is_default(&mime)), move |index| (index, mime_closure.clone()), ) .icons(Cow::Owned(mime_app_cache.icons(&mime))), From e8fdb28a24ab11f249a9a39b1ea04bb245924466 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Thu, 11 Jun 2026 18:45:49 +0200 Subject: [PATCH 092/110] feat(mime_app): show related apps in open with dropdown in preview --- src/app.rs | 4 ++-- src/mime_app.rs | 47 +++++++++++++++++++++++++++++++++-------------- src/tab.rs | 38 ++++++++++++++++++++------------------ 3 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/app.rs b/src/app.rs index 58ac81f..ac0996a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -3180,7 +3180,7 @@ impl Application for App { selected, .. } => { - let available_apps = self.mime_app_cache.get_apps_for_mime(&mime); + let available_apps = self.mime_app_cache.get_apps_for_mime(&mime, true); if let Some((app, _)) = available_apps.get(selected) { if let Some(mut command) = @@ -5918,7 +5918,7 @@ impl Application for App { }; let mut column = widget::list_column(); - let available_apps = self.mime_app_cache.get_apps_for_mime(mime); + let available_apps = self.mime_app_cache.get_apps_for_mime(mime, true); let item_height = 32.0; let mut displayed_default = false; let mut last_kind = MimeAppMatch::Exact; diff --git a/src/mime_app.rs b/src/mime_app.rs index bb84f80..5a3b421 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -252,7 +252,11 @@ impl MimeAppCache { mime_app_cache } - pub fn get_apps_for_mime(&self, mime_type: &Mime) -> Vec<(&Arc, MimeAppMatch)> { + pub fn get_apps_for_mime( + &self, + mime_type: &Mime, + include_other: bool, + ) -> Vec<(&Arc, MimeAppMatch)> { let mut results = Vec::new(); let mut dedupe = FxHashSet::default(); @@ -291,19 +295,21 @@ impl MimeAppCache { } } - results.extend({ - let mut apps = self - .apps() - .iter() - .filter(|mime_app| !mime_app.no_display()) - .filter(|&mime_app| dedupe.insert(&mime_app.id)) - .map(|mime_app| (mime_app, MimeAppMatch::Other)) - .collect::>(); - apps.sort_by(|(a, _), (b, _)| { - crate::localize::LANGUAGE_SORTER.compare(&a.name, &b.name) + if include_other { + results.extend({ + let mut apps = self + .apps() + .iter() + .filter(|mime_app| !mime_app.no_display()) + .filter(|&mime_app| dedupe.insert(&mime_app.id)) + .map(|mime_app| (mime_app, MimeAppMatch::Other)) + .collect::>(); + apps.sort_by(|(a, _), (b, _)| { + crate::localize::LANGUAGE_SORTER.compare(&a.name, &b.name) + }); + apps }); - apps - }); + } results } @@ -411,15 +417,28 @@ impl MimeAppCache { // Sort cached apps for this mime by default precedence. for default in defaults.into_iter().flatten() { let default = default.strip_suffix(".desktop").unwrap_or(default.as_ref()); + let mut found_any = false; apps.retain(|app| { let found = app.id.as_str() == default; if found { - app.is_default.write().unwrap().insert(default.into()); + app.is_default + .write() + .unwrap() + .insert(mime.essence_str().into()); cache.push(app.clone()); + found_any = true; } !found }); + + if !found_any && let Some(app) = self.apps.iter().find(|app| app.id == default) { + app.is_default + .write() + .unwrap() + .insert(mime.essence_str().into()); + cache.push(app.clone()); + } } // Sort remaining apps by name diff --git a/src/tab.rs b/src/tab.rs index d5deaaf..6afcfce 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2368,23 +2368,24 @@ impl Item { ))); let mut settings = Vec::new(); if let Some(mime_app_cache) = mime_app_cache_opt { - let mime_apps = mime_app_cache.get(&self.mime); + let mime_apps = mime_app_cache.get_apps_for_mime(&self.mime, false); if !mime_apps.is_empty() { + let (names, icons) = mime_apps + .iter() + .map(|(app, _)| (Cow::Owned(app.name.clone()), app.icon())) + .collect::<(Vec<_>, Vec<_>)>(); settings.push( widget::settings::item::builder(fl!("open-with")).control( Element::from( widget::dropdown( - mime_apps - .iter() - .map(|app| Cow::Owned(app.name.clone())) - .collect::>>(), - mime_apps.iter().position(|x| x.is_default(&self.mime)), + names, + mime_apps.iter().position(|(x, _)| x.is_default(&self.mime)), move |index| index, ) - .icons(Cow::Owned(mime_app_cache.icons(&self.mime))), + .icons(Cow::Owned(icons)), ) - .map(|index| { - let mime_app = &mime_apps[index]; + .map(move |index| { + let mime_app = &mime_apps[index].0; Message::SetOpenWith(self.mime.clone(), mime_app.id.clone()) }), ), @@ -6451,24 +6452,25 @@ impl Tab { .and_then(|(mime, _)| mime.parse::().ok()) && let Some(mime_app_cache) = mime_app_cache_opt { - let mime_apps = mime_app_cache.get(&mime); + let mime_apps = mime_app_cache.get_apps_for_mime(&mime, false); if !mime_apps.is_empty() { let mime_closure = mime.clone(); + let (names, icons) = mime_apps + .iter() + .map(|(app, _)| (Cow::Owned(app.name.clone()), app.icon())) + .collect::<(Vec<_>, Vec<_>)>(); settings.push( widget::settings::item::builder(fl!("open-with")).control( Element::from( widget::dropdown( - mime_apps - .iter() - .map(|app| Cow::Owned(app.name.clone())) - .collect::>>(), - mime_apps.iter().position(|x| x.is_default(&mime)), + names, + mime_apps.iter().position(|(x, _)| x.is_default(&mime)), move |index| (index, mime_closure.clone()), ) - .icons(Cow::Owned(mime_app_cache.icons(&mime))), + .icons(Cow::Owned(icons)), ) - .map(|(index, mime)| { - let mime_app = &mime_apps[index]; + .map(move |(index, mime)| { + let mime_app = &mime_apps[index].0; Message::SetOpenWith(mime, mime_app.id.clone()) }), ), From 7d3487da7bd0ea14650eb1c3c70087f3f07d6971 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Sat, 13 Jun 2026 15:28:24 +0200 Subject: [PATCH 093/110] fix(mime_app): unalias mime types when associating apps Fixes associations for `.iso`, where many apps define `application/x-cd-image` instead of `application/vnd.efi.iso`. Popsicle and GNOME Disks will now appear as exact matches for opening `.iso` files with this change. --- src/mime_app.rs | 46 +++++++++++++++++++++++++++++++++++++++++----- src/mime_icon.rs | 20 +++++++------------- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/mime_app.rs b/src/mime_app.rs index 5a3b421..fe45d39 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -321,6 +321,7 @@ impl MimeAppCache { #[cfg(feature = "desktop")] pub fn reload(&mut self) { use crate::localize::LANGUAGE_SORTER; + use crate::mime_icon; use cosmic::desktop::fde; use std::borrow::Cow; @@ -334,8 +335,10 @@ impl MimeAppCache { let paths = cosmic_mime_apps::list_paths(); list.load_from_paths(&paths); let locales = fde::get_languages_from_env(); - let desktop_entries = fde::Iter::new(fde::default_paths()).entries(Some(&locales)); + let mime_icon_cache = mime_icon::MIME_ICON_CACHE.lock().unwrap(); + let shared_mime_info = &mime_icon_cache.shared_mime_info; + let mut aliased_mimes = FxHashMap::default(); for desktop_entry in desktop_entries { let name = desktop_entry @@ -368,7 +371,18 @@ impl MimeAppCache { // Cache associations defined by the desktop entry. let mime_types = desktop_entry.mime_type().unwrap_or_else(Vec::new); - for mime in mime_types.iter().filter_map(|m| m.parse::().ok()) { + let associated_mime_types = mime_types.iter().filter_map(|m| { + m.parse::().ok().map(|mime| { + if let Some(unaliased) = shared_mime_info.unalias_mime_type(&mime) { + aliased_mimes.insert(unaliased.clone(), mime); + return unaliased; + } + + mime + }) + }); + + for mime in associated_mime_types { let apps = self.cache.entry(mime.clone()).or_default(); if apps.iter().all(|cached_app| cached_app.id != app.id) { apps.push(app.clone()); @@ -377,7 +391,14 @@ impl MimeAppCache { } // Cache added associations from mimeapps lists. - for (added_mime, added_apps) in &list.added_associations { + for (mut added_mime, added_apps) in &list.added_associations { + let _unaliased; + if let Some(unaliased) = shared_mime_info.unalias_mime_type(added_mime) { + aliased_mimes.insert(unaliased.clone(), added_mime.clone()); + _unaliased = unaliased; + added_mime = &_unaliased; + } + for added_app in added_apps { if let Some(app) = self .apps @@ -393,7 +414,14 @@ impl MimeAppCache { } // Remove associations - for (removed_mime, removed_apps) in &list.removed_associations { + for (mut removed_mime, removed_apps) in &list.removed_associations { + let _unaliased; + if let Some(unaliased) = shared_mime_info.unalias_mime_type(removed_mime) { + aliased_mimes.insert(unaliased.clone(), removed_mime.clone()); + _unaliased = unaliased; + removed_mime = &_unaliased; + } + for removed_app in removed_apps { if let Some(app) = self .apps @@ -409,13 +437,21 @@ impl MimeAppCache { // Fetch defaults and sort apps by their default precedence. for (mime, mut apps) in std::mem::take(&mut self.cache).into_iter() { let defaults = list.default_app_for(&mime); + let aliased_defaults = aliased_mimes + .get(&mime) + .and_then(|mime| list.default_app_for(mime)); + let cache = self .cache .entry(mime.clone()) .or_insert_with(|| Vec::with_capacity(apps.len())); // Sort cached apps for this mime by default precedence. - for default in defaults.into_iter().flatten() { + for default in defaults + .into_iter() + .flatten() + .chain(aliased_defaults.into_iter().flatten()) + { let default = default.strip_suffix(".desktop").unwrap_or(default.as_ref()); let mut found_any = false; apps.retain(|app| { diff --git a/src/mime_icon.rs b/src/mime_icon.rs index 847b550..1c1bf40 100644 --- a/src/mime_icon.rs +++ b/src/mime_icon.rs @@ -15,28 +15,21 @@ struct MimeIconKey { size: u16, } -struct MimeIconCache { +#[derive(Default)] +pub struct MimeIconCache { cache: FxHashMap>, #[cfg(unix)] - shared_mime_info: xdg_mime::SharedMimeInfo, + pub shared_mime_info: xdg_mime::SharedMimeInfo, } impl MimeIconCache { - pub fn new() -> Self { - Self { - cache: FxHashMap::default(), - #[cfg(unix)] - shared_mime_info: xdg_mime::SharedMimeInfo::new(), - } - } - #[cfg(not(unix))] pub fn get(&mut self, _key: MimeIconKey) -> Option { None } #[cfg(unix)] - pub fn get(&mut self, key: MimeIconKey) -> Option { + fn get(&mut self, key: MimeIconKey) -> Option { self.cache .entry(key) .or_insert_with_key(|key| { @@ -56,8 +49,9 @@ impl MimeIconCache { .clone() } } -static MIME_ICON_CACHE: LazyLock> = - LazyLock::new(|| Mutex::new(MimeIconCache::new())); + +pub static MIME_ICON_CACHE: LazyLock> = + LazyLock::new(|| Mutex::new(MimeIconCache::default())); #[cfg(not(unix))] pub fn mime_for_path( From 53a33dbe7403907a626815d9c120716dc22407a5 Mon Sep 17 00:00:00 2001 From: Gene Wood Date: Wed, 17 Jun 2026 12:33:57 -0700 Subject: [PATCH 094/110] Clear hover highlights when navigating with keyboard Keyboard navigation (arrow keys) did not clear item hover state, causing items to retain their grey hover background after the mouse left the window, resulting in multiple items appearing highlighted simultaneously. Fixes #1865 --- src/tab.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tab.rs b/src/tab.rs index 6afcfce..9c1c2e5 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -3130,6 +3130,14 @@ impl Tab { item.pos_opt.get() } + fn dehighlight_all(&mut self) { + if let Some(items) = self.items_opt.as_mut() { + for item in items.iter_mut() { + item.highlighted = false; + } + } + } + pub(crate) fn select_focus_scroll(&mut self) -> Option { let items = self.items_opt.as_ref()?; let item = items.get(self.select_focus?)?; @@ -3820,6 +3828,7 @@ impl Tab { } } Message::ItemDown => { + self.dehighlight_all(); if let Some(edit_location) = &mut self.edit_location { edit_location.select(true); } else if self.gallery { @@ -3862,6 +3871,7 @@ impl Tab { } } Message::ItemLeft => { + self.dehighlight_all(); if self.gallery { commands.append(&mut self.update(Message::GalleryPrevious, modifiers)); } else { @@ -3920,6 +3930,7 @@ impl Tab { } } Message::ItemRight => { + self.dehighlight_all(); if self.gallery { commands.append(&mut self.update(Message::GalleryNext, modifiers)); } else { @@ -3961,6 +3972,7 @@ impl Tab { } } Message::ItemUp => { + self.dehighlight_all(); if let Some(edit_location) = &mut self.edit_location { edit_location.select(false); } else if self.gallery { From 65f5f454be7ab01346ca43eecb85539548bba1ad Mon Sep 17 00:00:00 2001 From: Gene Wood Date: Mon, 22 Jun 2026 14:37:41 -0700 Subject: [PATCH 095/110] feat: add PageUp and PageDown bindings --- src/app.rs | 4 ++ src/key_bind.rs | 4 ++ src/tab.rs | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) diff --git a/src/app.rs b/src/app.rs index ac0996a..2622a24 100644 --- a/src/app.rs +++ b/src/app.rs @@ -155,6 +155,8 @@ pub enum Action { HistoryPrevious, ItemDown, ItemLeft, + ItemPageDown, + ItemPageUp, ItemRight, ItemUp, LocationUp, @@ -228,6 +230,8 @@ impl Action { Self::HistoryPrevious => Message::TabMessage(entity_opt, tab::Message::GoPrevious), Self::ItemDown => Message::TabMessage(entity_opt, tab::Message::ItemDown), Self::ItemLeft => Message::TabMessage(entity_opt, tab::Message::ItemLeft), + Self::ItemPageDown => Message::TabMessage(entity_opt, tab::Message::ItemPageDown), + Self::ItemPageUp => Message::TabMessage(entity_opt, tab::Message::ItemPageUp), Self::ItemRight => Message::TabMessage(entity_opt, tab::Message::ItemRight), Self::ItemUp => Message::TabMessage(entity_opt, tab::Message::ItemUp), Self::LocationUp => Message::TabMessage(entity_opt, tab::Message::LocationUp), diff --git a/src/key_bind.rs b/src/key_bind.rs index f47d403..d3ddd59 100644 --- a/src/key_bind.rs +++ b/src/key_bind.rs @@ -30,12 +30,16 @@ pub fn key_binds(mode: &tab::Mode) -> HashMap { bind!([], Key::Named(Named::F5), Reload); bind!([], Key::Named(Named::Home), SelectFirst); bind!([], Key::Named(Named::End), SelectLast); + bind!([], Key::Named(Named::PageDown), ItemPageDown); + bind!([], Key::Named(Named::PageUp), ItemPageUp); bind!([Shift], Key::Named(Named::ArrowDown), ItemDown); bind!([Shift], Key::Named(Named::ArrowLeft), ItemLeft); bind!([Shift], Key::Named(Named::ArrowRight), ItemRight); bind!([Shift], Key::Named(Named::ArrowUp), ItemUp); bind!([Shift], Key::Named(Named::Home), SelectFirst); bind!([Shift], Key::Named(Named::End), SelectLast); + bind!([Shift], Key::Named(Named::PageDown), ItemPageDown); + bind!([Shift], Key::Named(Named::PageUp), ItemPageUp); bind!([Ctrl, Shift], Key::Character("n".into()), NewFolder); bind!([], Key::Named(Named::Enter), Open); bind!([Ctrl], Key::Character(" ".into()), Preview); diff --git a/src/tab.rs b/src/tab.rs index 9c1c2e5..ebeaa63 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -1724,6 +1724,8 @@ pub enum Message { GoPrevious, ItemDown, ItemLeft, + ItemPageDown, + ItemPageUp, ItemRight, ItemUp, Location(Location), @@ -3173,6 +3175,23 @@ impl Tab { } } + fn rows_per_page(&self) -> usize { + let viewport_height = self + .item_view_size_opt + .get() + .map_or(0.0, |s| s.height); + let row_height = self + .select_focus + .and_then(|i| self.items_opt.as_ref()?.get(i)) + .and_then(|item| item.rect_opt.get()) + .map_or(0.0, |r| r.height); + if row_height > 0.0 && viewport_height > 0.0 { + (viewport_height / row_height).floor() as usize + } else { + 1 + } + } + fn select_range_start_pos_opt(&self) -> Option<(usize, usize)> { let items = self.items_opt.as_ref()?; let item = items.get(self.select_range.map(|r| r.0)?)?; @@ -3870,6 +3889,100 @@ impl Tab { } } } + Message::ItemPageDown => { + self.dehighlight_all(); + if let Some((row, col)) = + self.select_focus_pos_opt().or(self.select_last_pos_opt()) + { + if self.select_focus.is_none() { + self.select_position(row, col, mod_shift); + } + + let rows_per_page = self.rows_per_page().max(1); + let target_row = row.saturating_add(rows_per_page); + + if !self.select_position(target_row, col, mod_shift) { + // Fall back to the last item at or before target_row + let best = self + .items_opt + .as_ref() + .and_then(|items| { + items + .iter() + .filter_map(|item| item.pos_opt.get()) + .filter(|(r, _)| *r <= target_row) + .max() + }); + if let Some((best_row, best_col)) = best { + self.select_position(best_row, best_col, mod_shift); + } + } + } else { + self.select_position(0, 0, mod_shift); + } + if let Some(offset) = self.select_focus_scroll() { + commands.push(Command::Iced( + scrollable::scroll_to( + self.scrollable_id.clone(), + AbsoluteOffset { + x: Some(offset.x), + y: Some(offset.y), + }, + ) + .into(), + )); + } + if let Some(id) = self.select_focus_id() { + commands.push(Command::Iced(widget::button::focus(id).into())); + } + } + Message::ItemPageUp => { + self.dehighlight_all(); + if let Some((row, col)) = + self.select_focus_pos_opt().or(self.select_first_pos_opt()) + { + if self.select_focus.is_none() { + self.select_position(row, col, mod_shift); + } + + let rows_per_page = self.rows_per_page().max(1); + let target_row = row.saturating_sub(rows_per_page); + + if !self.select_position(target_row, col, mod_shift) { + // Fall back to the first item at or after target_row + let best = self + .items_opt + .as_ref() + .and_then(|items| { + items + .iter() + .filter_map(|item| item.pos_opt.get()) + .filter(|(r, _)| *r >= target_row) + .min() + }); + if let Some((best_row, best_col)) = best { + self.select_position(best_row, best_col, mod_shift); + } + } + } else { + self.select_position(0, 0, mod_shift); + } + if let Some(offset) = self.select_focus_scroll() { + commands.push(Command::Iced( + scrollable::scroll_to( + self.scrollable_id.clone(), + AbsoluteOffset { + x: Some(offset.x), + y: Some(offset.y), + }, + ) + .into(), + )); + } + if let Some(id) = self.select_focus_id() { + commands.push(Command::Iced(widget::button::focus(id).into())); + } + } Message::ItemLeft => { self.dehighlight_all(); if self.gallery { From c653b69c75f735c1559e5f8aa621977e81d8373c Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 23 Jun 2026 08:48:35 -0600 Subject: [PATCH 096/110] Epoch 1.1.0 version update Generated by cosmic-epoch scripts/version-update.sh --- Cargo.lock | 423 ++++++++++++--------------------- Cargo.toml | 2 +- cosmic-files-applet/Cargo.toml | 2 +- debian/changelog | 6 + 4 files changed, 156 insertions(+), 277 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc95ecd..2a050a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,9 +172,9 @@ checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" [[package]] name = "alloc-stdlib" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195" dependencies = [ "alloc-no-stdlib", ] @@ -330,9 +330,9 @@ checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" [[package]] name = "as-raw-xcb-connection" @@ -599,9 +599,9 @@ dependencies = [ [[package]] name = "auto_enums" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65398a2893f41bce5c9259f6e1a4f03fbae40637c1bdc755b4f387f48c613b03" +checksum = "2e4487600931c9a89f8db7ffbdf3fbdd45bb7bd85e26861f659a463cd0dff966" dependencies = [ "derive_utils", "proc-macro2", @@ -735,9 +735,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ "hybrid-array", "zeroize", @@ -776,9 +776,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" +checksum = "2f3f6da4992df95bbcd9af42a6c7dcb994498fc9048230405f3b36ff7cd3f145" dependencies = [ "bytes", "cfg_aliases", @@ -786,9 +786,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "5.0.1" +version = "5.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5962523e1b92ce1b5e793d9169b9943eece10d39f62550bc04bb605d75b94924" +checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -875,9 +875,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" [[package]] name = "bzip2" @@ -925,9 +925,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.63" +version = "1.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", "jobserver", @@ -1116,9 +1116,9 @@ dependencies = [ [[package]] name = "compio-buf" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9478803aae4726ce02139b5510354034ae3afc99ce2496734784314664b91c" +checksum = "b51a2c35873865376ed4cdb6cfeb602b6cf569815f017ddd7bd8f86ad49b34c7" dependencies = [ "arrayvec", "bytes", @@ -1351,7 +1351,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1361,7 +1361,7 @@ dependencies = [ "iced_futures", "known-folders", "notify", - "ron 0.12.1", + "ron 0.12.2", "serde", "tokio", "tracing", @@ -1372,7 +1372,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "quote", "syn", @@ -1380,7 +1380,7 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.0.16" +version = "1.1.0" dependencies = [ "anyhow", "atomic_float", @@ -1448,7 +1448,7 @@ dependencies = [ [[package]] name = "cosmic-files-applet" -version = "1.0.16" +version = "1.1.0" dependencies = [ "cosmic-files", "log", @@ -1458,12 +1458,12 @@ dependencies = [ [[package]] name = "cosmic-freedesktop-icons" version = "0.4.0" -source = "git+https://github.com/pop-os/freedesktop-icons#cb0a2f299dbc443697ce1674065e0d4f82915c02" +source = "git+https://github.com/pop-os/freedesktop-icons#ab4c57b8e416c6af9297cb04d101889896fd9a92" dependencies = [ "bstr", "btoi", "memchr", - "memmap2 0.9.10", + "memmap2 0.9.11", "thiserror 2.0.18", "tracing", "xdg", @@ -1497,7 +1497,7 @@ dependencies = [ [[package]] name = "cosmic-settings-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#fa82bdf9fe7b5f5bd6008f32f393efd5e7a71c47" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#75c0480f1315ec96ec3eb216fc939f93f57d7612" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1542,7 +1542,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "almost", "configparser", @@ -1550,7 +1550,7 @@ dependencies = [ "csscolorparser", "dirs 6.0.0", "palette", - "ron 0.12.1", + "ron 0.12.2", "serde", "serde_json", "thiserror 2.0.18", @@ -1783,13 +1783,44 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac6b926516df9c60bfa16e107b21086399f8285a44ca9711344b9e553c5146e2" +[[package]] +name = "defmt" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror 2.0.18", +] + [[package]] name = "deranged" version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ - "powerfmt", "serde_core", ] @@ -1832,7 +1863,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ - "block-buffer 0.12.0", + "block-buffer 0.12.1", "const-oid", "crypto-common 0.2.2", "ctutils", @@ -2370,7 +2401,7 @@ checksum = "457e789b3d1202543297a350643cf459f836cade38934e7a4cf6a39e7cde2905" dependencies = [ "fontconfig-parser", "log", - "memmap2 0.9.10", + "memmap2 0.9.11", "slotmap", "tinyvec", "ttf-parser", @@ -2616,16 +2647,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi 6.0.0", - "wasip2", - "wasip3", "wasm-bindgen", ] @@ -3060,7 +3089,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "dnd", "iced_accessibility", @@ -3081,7 +3110,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "accesskit", "accesskit_winit", @@ -3090,7 +3119,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "bitflags 2.13.0", "bytes", @@ -3115,7 +3144,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "iced_core", "iced_futures", @@ -3125,7 +3154,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "futures", "iced_core", @@ -3139,7 +3168,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "bitflags 2.13.0", "bytemuck", @@ -3160,7 +3189,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "iced_graphics", "iced_runtime", @@ -3169,7 +3198,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3181,7 +3210,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3196,7 +3225,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "bytemuck", "cosmic-text", @@ -3213,7 +3242,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "as-raw-xcb-connection", "bitflags 2.13.0", @@ -3244,7 +3273,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3262,7 +3291,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3690,12 +3719,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f2f8aeca682d874a5247084aa4fb7d1cef9ba45d889c21209a8818dcaaa0ec9" -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "ident_case" version = "1.0.1" @@ -3955,10 +3978,11 @@ checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1" [[package]] name = "jiff" -version = "0.2.28" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" +checksum = "34f877a98676d2fb664698d74cc6a51ce6c484ce8c770f05d0108ec9090aeb46" dependencies = [ + "defmt", "jiff-static", "jiff-tzdb-platform", "log", @@ -3981,9 +4005,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.28" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" +checksum = "0666b5ab5ecaca213fc2a85b8c0083d9004e84ee2d5f9a7e0017aaf50986f25f" dependencies = [ "proc-macro2", "quote", @@ -4075,9 +4099,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.100" +version = "0.3.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2025f20d7a4fa7785846e7b63d10a76d3f1cee98ee5cb79ea59703f95e42162" +checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" dependencies = [ "cfg-if", "futures-util", @@ -4356,12 +4380,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "lebe" version = "0.5.3" @@ -4383,7 +4401,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#bb10afd849f1ad172be6b78eeec347d548aa4fd7" +source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" dependencies = [ "apply", "ashpd 0.12.3", @@ -4540,9 +4558,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "loom" @@ -4636,14 +4654,16 @@ dependencies = [ [[package]] name = "mac-notification-sys" -version = "0.6.13" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50efa634682b3fc5a1ab6f3dd5b2bce7b848011fc485b53b063dc68f2f74feae" +checksum = "fd604973958ddcc11b561193c0fb96ba146506ef2f231ef2e7c35fd2cbc9beca" dependencies = [ "cc", + "log", "objc2 0.6.4", "objc2-foundation 0.3.2", "time", + "uuid", ] [[package]] @@ -4686,9 +4706,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "memmap2" @@ -4701,9 +4721,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] @@ -4942,9 +4962,9 @@ dependencies = [ [[package]] name = "notify-rust" -version = "4.17.0" +version = "4.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50ff2e74231b72c832d82982193b417f230945be6bdb5575b251d941d31adb00" +checksum = "c5b4c1b4f2aa9f25f63a7a49d3dd0ed567b3670da15330a66b29434be899b891" dependencies = [ "futures-lite", "log", @@ -5717,16 +5737,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro-crate" version = "3.5.0" @@ -5884,9 +5894,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -6257,9 +6267,9 @@ dependencies = [ [[package]] name = "ron" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" +checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3" dependencies = [ "bitflags 2.13.0", "once_cell", @@ -6433,7 +6443,7 @@ checksum = "1dd3accc0f3f4bbaf2c9e1957a030dc582028130c67660d44c0a0345a22ca69b" dependencies = [ "ab_glyph", "log", - "memmap2 0.9.10", + "memmap2 0.9.11", "smithay-client-toolkit", "tiny-skia", ] @@ -6704,9 +6714,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "smithay-client-toolkit" @@ -6721,7 +6731,7 @@ dependencies = [ "cursor-icon", "libc", "log", - "memmap2 0.9.10", + "memmap2 0.9.11", "pkg-config", "rustix 1.1.4", "thiserror 2.0.18", @@ -6784,7 +6794,7 @@ dependencies = [ "foreign-types", "js-sys", "log", - "memmap2 0.9.10", + "memmap2 0.9.11", "objc", "raw-window-handle", "redox_syscall 0.5.18", @@ -6862,9 +6872,9 @@ dependencies = [ [[package]] name = "swash" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1804632b66a35ca2b1d277eb0a138e10f46cb365b9a6d297e876b69ef79de43" +checksum = "0811b01ca2c4e8718760713911feaf4675c24f94e50530a015ec646cfb622f7c" dependencies = [ "skrifa 0.42.1", "yazi", @@ -6873,9 +6883,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", @@ -6979,7 +6989,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix 1.1.4", "windows-sys 0.61.2", @@ -7117,12 +7127,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "85c17d80feb7334b40c484e45ed1a5273dfd8bfda537c3be2e74a06a6686f327" dependencies = [ "deranged", - "itoa", "js-sys", "num-conv", "powerfmt", @@ -7133,15 +7142,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "dcef1a61bdb119096e153208ec5cbec23944ce8bca13be5c7f60c634f7403935" dependencies = [ "num-conv", "time-core", @@ -7531,12 +7540,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "url" version = "2.5.8" @@ -7607,6 +7610,7 @@ version = "1.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" dependencies = [ + "getrandom 0.4.3", "js-sys", "serde_core", "wasm-bindgen", @@ -7669,27 +7673,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.123" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a254a4b10c19a76f09a27640e7ffbf9bc30bf67e16a3bf28aaefa4920fe81563" +checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" dependencies = [ "cfg-if", "once_cell", @@ -7700,9 +7695,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.73" +version = "0.4.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54568702fabf5d4849ce2b90fadfa64168a097eaf4b351ce9df8b687a0086aaf" +checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280" dependencies = [ "js-sys", "wasm-bindgen", @@ -7710,9 +7705,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.123" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a40fc75b0ec6f3746ceb10d36f53a93dcd68a93b11b6445983945d79eba0dc" +checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7720,9 +7715,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.123" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "908f34bd9b9ce3d4caf07b72dfab63d61504d156856c6bd3cd87fa350cf3985b" +checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" dependencies = [ "bumpalo", "proc-macro2", @@ -7733,47 +7728,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.123" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acbf7616c27b194bbb550bf77ed0c2c3e5b7fd1260a93082b95fb7f47959b92" +checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap 2.14.0", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.13.0", - "hashbrown 0.15.5", - "indexmap 2.14.0", - "semver", -] - [[package]] name = "wasmtimer" version = "0.4.3" @@ -7838,9 +7799,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.12" +version = "0.32.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" +checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6" dependencies = [ "bitflags 2.13.0", "wayland-backend", @@ -7940,9 +7901,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.100" +version = "0.3.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0871acf327f283dc6da28a1696cdc64fb355ba9f935d052021fa77f35cce69" +checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d" dependencies = [ "js-sys", "wasm-bindgen", @@ -8726,7 +8687,7 @@ name = "winit-common" version = "0.31.0-beta.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ - "memmap2 0.9.10", + "memmap2 0.9.11", "objc2 0.6.4", "objc2-core-foundation", "smol_str", @@ -8797,7 +8758,7 @@ dependencies = [ "cursor-icon", "dpi", "libc", - "memmap2 0.9.10", + "memmap2 0.9.11", "raw-window-handle", "rustix 1.1.4", "sctk-adwaita", @@ -8882,100 +8843,12 @@ dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck 0.5.0", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck 0.5.0", - "indexmap 2.14.0", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.13.0", - "indexmap 2.14.0", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap 2.14.0", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - [[package]] name = "write16" version = "1.0.0" @@ -9098,7 +8971,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d66ca9352cbd4eecbbc40871d8a11b4ac8107cfc528a6e14d7c19c69d0e1ac9" dependencies = [ "libc", - "memmap2 0.9.10", + "memmap2 0.9.11", "xkeysym", ] @@ -9109,7 +8982,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a974f48060a14e95705c01f24ad9c3345022f4d97441b8a36beb7ed5c4a02d" dependencies = [ "libc", - "memmap2 0.9.10", + "memmap2 0.9.11", "xkeysym", ] @@ -9371,18 +9244,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.50" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.50" +version = "0.8.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" dependencies = [ "proc-macro2", "quote", @@ -9412,9 +9285,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zerotrie" @@ -9463,7 +9336,7 @@ dependencies = [ "crc32fast", "deflate64", "flate2", - "getrandom 0.4.2", + "getrandom 0.4.3", "hmac", "indexmap 2.14.0", "lzma-rust2", @@ -9480,9 +9353,9 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513" +checksum = "977347db8caa080403f6b6b7c1cda9479a8e869316f7e13a59b19076a40f94e3" [[package]] name = "zmij" diff --git a/Cargo.toml b/Cargo.toml index 188d0dc..1a0923a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.0.16" +version = "1.1.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 7414ba5..fdf7864 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files-applet" -version = "1.0.16" +version = "1.1.0" edition = "2024" [dependencies] diff --git a/debian/changelog b/debian/changelog index 251a2f8..67931a8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-files (1.1.0) noble; urgency=medium + + * Epoch 1.1.0 version update + + -- Jeremy Soller Tue, 23 Jun 2026 08:47:18 -0600 + cosmic-files (1.0.16) noble; urgency=medium * Epoch 1.0.16 version update From cd427c746c07affdbc936c1157d4fa235851f0a1 Mon Sep 17 00:00:00 2001 From: JADella94 <48160118+BoiledElectricity@users.noreply.github.com> Date: Wed, 24 Jun 2026 14:12:10 -0400 Subject: [PATCH 097/110] fix: panic when a second zip extract dialog is opened * Syncs extracted zip files on the compio executor's thread * Close the first zip extract dialog before opening a new one to fix a panic --------- Co-authored-by: James A DellaMorte --- src/app.rs | 10 +++++++++- src/archive.rs | 28 ++++++++++++++-------------- src/operation/mod.rs | 34 ++++++++++++++++++++++++++-------- 3 files changed, 49 insertions(+), 23 deletions(-) diff --git a/src/app.rs b/src/app.rs index 2622a24..e9fe8cc 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1009,6 +1009,12 @@ impl App { .and_then(|first| first.as_ref().parent()) .map(Path::to_path_buf) { + let mut tasks = Vec::new(); + if let Some(old_dialog) = self.file_dialog_opt.take() { + let old_id = old_dialog.window_id(); + self.windows.remove(&old_id); + tasks.push(window::close(old_id)); + } let (mut dialog, dialog_task) = Dialog::new( DialogSettings::new() .kind(DialogKind::OpenFolder) @@ -1025,7 +1031,9 @@ impl App { ))), ); self.file_dialog_opt = Some(dialog); - Task::batch([set_title_task, dialog_task]) + tasks.push(set_title_task); + tasks.push(dialog_task); + Task::batch(tasks) } else { Task::none() } diff --git a/src/archive.rs b/src/archive.rs index cff0c1e..d51b01b 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -1,5 +1,5 @@ use crate::mime_icon::mime_for_path; -use crate::operation::{Controller, OpReader, OperationError, OperationErrorType, sync_to_disk}; +use crate::operation::{Controller, OpReader, OperationError, OperationErrorType}; use cosmic::iced::futures; use jiff::Zoned; use jiff::civil::DateTime; @@ -45,7 +45,7 @@ pub fn extract( new_dir: &Path, password: &Option, controller: &Controller, -) -> Result<(), OperationError> { +) -> Result<(Vec, HashSet), OperationError> { let mime = mime_for_path(path, None, false); let password = password.as_deref(); match mime.essence_str() { @@ -55,13 +55,15 @@ pub fn extract( .map(flate2::read::GzDecoder::new) .map(tar::Archive::new) .and_then(|mut archive| archive.unpack(new_dir)) - .map_err(|e| OperationError::from_err(e, controller))?; + .map_err(|e| OperationError::from_err(e, controller)) + .map(|_| Default::default()) } "application/x-tar" => OpReader::new(path, controller.clone()) .map(io::BufReader::new) .map(tar::Archive::new) .and_then(|mut archive| archive.unpack(new_dir)) - .map_err(|e| OperationError::from_err(e, controller))?, + .map_err(|e| OperationError::from_err(e, controller)) + .map(|_| Default::default()), "application/zip" => fs::File::open(path) .map(io::BufReader::new) .map(zip::ZipArchive::new) @@ -75,7 +77,7 @@ pub fn extract( OperationError::from_kind(OperationErrorType::PasswordRequired, controller) } _ => OperationError::from_err(e, controller), - })?, + }), #[cfg(feature = "bzip2")] "application/x-bzip" | "application/x-bzip-compressed-tar" @@ -85,7 +87,8 @@ pub fn extract( .map(bzip2::read::BzDecoder::new) .map(tar::Archive::new) .and_then(|mut archive| archive.unpack(new_dir)) - .map_err(|e| OperationError::from_err(e, controller))?, + .map_err(|e| OperationError::from_err(e, controller)) + .map(|_| Default::default()), #[cfg(feature = "lzma-rust2")] "application/x-xz" | "application/x-xz-compressed-tar" => { OpReader::new(path, controller.clone()) @@ -93,14 +96,14 @@ pub fn extract( .map(|reader| lzma_rust2::XzReader::new(reader, true)) .map(tar::Archive::new) .and_then(|mut archive| archive.unpack(new_dir)) - .map_err(|e| OperationError::from_err(e, controller))?; + .map_err(|e| OperationError::from_err(e, controller)) + .map(|_| Default::default()) } _ => Err(OperationError::from_err( format!("unsupported mime type {mime:?}"), controller, - ))?, + )), } - Ok(()) } // From https://docs.rs/zip/latest/zip/read/struct.ZipArchive.html#method.extract, with cancellation and progress added @@ -109,7 +112,7 @@ fn zip_extract>( directory: P, password: Option<&str>, controller: Controller, -) -> zip::result::ZipResult<()> { +) -> zip::result::ZipResult<(Vec, HashSet)> { use std::ffi::OsString; use std::fs; use zip::result::ZipError; @@ -282,10 +285,7 @@ fn zip_extract>( } } - // Flush files to disk - futures::executor::block_on(async { sync_to_disk(written_files, target_dirs).await }); - - Ok(()) + Ok((written_files, target_dirs)) } fn zip_date_time_to_system_time(date_time: zip::DateTime) -> Option { diff --git a/src/operation/mod.rs b/src/operation/mod.rs index c490655..7a84656 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -967,11 +967,13 @@ impl Operation { password, } => { let controller_clone = controller.clone(); - compio::runtime::spawn_blocking( - move || -> Result { + compio::runtime::spawn(async move { + let extracted = compio::runtime::spawn_blocking(move || { let controller = controller_clone; let total_paths = paths.len(); let mut op_sel = OperationSelection::default(); + let mut written_files = Vec::new(); + let mut target_dirs = std::collections::HashSet::new(); for (i, path) in paths.iter().enumerate() { futures::executor::block_on(async { controller @@ -995,16 +997,32 @@ impl Operation { op_sel.ignored.push(path.clone()); op_sel.selected.push(new_dir.clone()); - crate::archive::extract(path, &new_dir, &password, &controller)?; + let (files, dirs) = crate::archive::extract( + path, + &new_dir, + &password, + &controller, + )?; + written_files.extend(files); + target_dirs.extend(dirs); } } - Ok(op_sel) - }, - ) + Ok::<_, OperationError>((op_sel, written_files, target_dirs)) + }) + .await + .map_err(wrap_compio_spawn_error)??; + + let (op_sel, written_files, target_dirs) = extracted; + if !written_files.is_empty() || !target_dirs.is_empty() { + sync_to_disk(written_files, target_dirs).await; + } + + Ok::<_, OperationError>(op_sel) + }) + .await + .map_err(wrap_compio_spawn_error)? } - .await - .map_err(wrap_compio_spawn_error)?, Self::Move { paths, to, From 4d6788c9fd432cbd7980fb2f04d2de6079053f9a Mon Sep 17 00:00:00 2001 From: Fred Date: Fri, 26 Jun 2026 16:57:13 +0200 Subject: [PATCH 098/110] feat: add SHA256 checksums to file properties --- Cargo.lock | 1 + Cargo.toml | 1 + i18n/en/cosmic_files.ftl | 3 + src/mounter/gvfs.rs | 3 +- src/tab.rs | 189 +++++++++++++++++++++++++++++++++------ 5 files changed, 170 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a050a6..d15d360 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1425,6 +1425,7 @@ dependencies = [ "rust-embed", "rustc-hash 2.1.2", "serde", + "sha2 0.10.9", "shlex 1.3.0", "slotmap", "tar", diff --git a/Cargo.toml b/Cargo.toml index 1a0923a..a186bfc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ slotmap = "1.1.1" recently-used-xbel = "1.2.0" zip = "8" md-5 = "0.10.6" +sha2 = "0.10" png = "0.18" jxl-oxide = { version = "0.12.5", features = ["image"] } num_cpus = "1.17.0" diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 45965ef..44ff788 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -303,6 +303,9 @@ item-created = Created: {$created} item-modified = Modified: {$modified} item-accessed = Accessed: {$accessed} calculating = Calculating... +checksum = {$kind} checksum +calculate = Calculate +error = Error ## Settings settings = Settings diff --git a/src/mounter/gvfs.rs b/src/mounter/gvfs.rs index 7c28668..e2c6ba1 100644 --- a/src/mounter/gvfs.rs +++ b/src/mounter/gvfs.rs @@ -14,7 +14,7 @@ use tokio::sync::mpsc; use super::{Mounter, MounterAuth, MounterItem, MounterItems, MounterMessage}; use crate::config::IconSizes; use crate::err_str; -use crate::tab::{self, DirSize, ItemMetadata, ItemThumbnail, Location}; +use crate::tab::{self, ChecksumState, DirSize, ItemMetadata, ItemThumbnail, Location}; const TARGET_URI_ATTRIBUTE: &str = "standard::target-uri"; @@ -216,6 +216,7 @@ fn network_scan(uri: &str, sizes: IconSizes) -> Result, String> { //TODO: scan directory size on gvfs mounts? dir_size: DirSize::NotDirectory, cut: false, + checksums: ChecksumState::default(), }); } Ok(items) diff --git a/src/tab.rs b/src/tab.rs index ebeaa63..55b038d 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -28,6 +28,7 @@ use jiff_icu::ConvertFrom; use mime_guess::{Mime, mime}; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; use std::borrow::Cow; use std::cell::Cell; use std::cmp::{Ordering, Reverse}; @@ -731,6 +732,7 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS overlaps_drag_rect: false, dir_size, cut: false, + checksums: ChecksumState::default(), } } @@ -862,6 +864,7 @@ pub fn item_from_entry( overlaps_drag_rect: false, dir_size, cut: false, + checksums: ChecksumState::default(), } } @@ -918,6 +921,7 @@ pub fn item_from_trash_entry( overlaps_drag_rect: false, dir_size: DirSize::NotDirectory, cut: false, + checksums: ChecksumState::default(), } } @@ -1341,6 +1345,7 @@ pub fn scan_desktop( overlaps_drag_rect: false, dir_size: DirSize::NotDirectory, cut: false, + checksums: ChecksumState::default(), }); } @@ -1762,6 +1767,9 @@ pub enum Message { HighlightDeactivate(usize), HighlightActivate(usize), DirectorySize(PathBuf, DirSize), + Checksums(PathBuf, ChecksumState), + CalculateChecksums(PathBuf), + CopyChecksum(String), ImageDecoded(PathBuf, u32, u32, Vec, Option<(u32, u32)>, u64), // path, width, height, pixels, display_size, generation } @@ -1789,6 +1797,23 @@ pub enum DirSize { Error(String), } +/// Checksums computed for a file. Only SHA256 is currently exposed; see +/// [`calculate_checksums`] for how to add more. +#[derive(Clone, Debug, Default)] +pub struct FileChecksums { + pub sha256: String, +} + +/// State of checksum computation for a file. +#[derive(Clone, Debug, Default)] +pub enum ChecksumState { + #[default] + NotCalculated, + Calculating, + Calculated(FileChecksums), + Error(String), +} + #[derive(Clone, Debug)] pub enum ItemMetadata { Path { @@ -2240,6 +2265,7 @@ pub struct Item { pub cut: bool, pub overlaps_drag_rect: bool, pub dir_size: DirSize, + pub checksums: ChecksumState, } impl Item { @@ -2516,6 +2542,55 @@ impl Item { } column = column.push(details); + if let Some(metadata) = self.file_metadata() + && !metadata.is_dir() + && let Some(path) = self.path_opt() + { + let control: Element<'_, Message> = match &self.checksums { + ChecksumState::NotCalculated => widget::button::standard(fl!("calculate")) + .on_press(Message::CalculateChecksums(path.clone())) + .into(), + ChecksumState::Calculating => widget::row::with_capacity(2) + .align_y(Alignment::Center) + .spacing(space_xxxs) + .push(widget::indeterminate_circular().size(16.0)) + .push(widget::text::body(fl!("calculating"))) + .into(), + ChecksumState::Calculated(checksums) => { + let value = checksums.sha256.clone(); + // Middle-ellipsize the digest to fit, full value on hover. + let value_text = widget::tooltip( + widget::text::body(value.clone()) + .font(cosmic::font::mono()) + .width(Length::Fill) + .wrapping(text::Wrapping::None) + .ellipsize(text::Ellipsize::Middle(text::EllipsizeHeightLimit::Lines( + 1, + ))), + widget::text::body(value.clone()), + widget::tooltip::Position::Bottom, + ); + let copy_button = widget::button::icon( + widget::icon::from_name("edit-copy-symbolic").size(16), + ) + .on_press(Message::CopyChecksum(value.clone())) + .tooltip(fl!("copy")); + widget::row::with_capacity(2) + .align_y(Alignment::Center) + .spacing(space_xxxs) + .push(value_text) + .push(copy_button) + .into() + } + ChecksumState::Error(err) => { + widget::text::body(format!("{}: {}", fl!("error"), err)).into() + } + }; + settings.push( + widget::settings::item::builder(fl!("checksum", kind = "SHA256")).control(control), + ); + } + if let Some(path) = self.path_opt() && self.selected { @@ -2713,6 +2788,32 @@ async fn calculate_dir_size(path: &Path, controller: Controller) -> Result Result { + let path = path.to_path_buf(); + tokio::task::spawn_blocking(move || { + let mut file = File::open(&path).map_err(|e| e.to_string())?; + let mut sha256_hasher = Sha256::new(); + + let mut buffer = [0u8; 8192]; + loop { + let bytes_read = file.read(&mut buffer).map_err(|e| e.to_string())?; + if bytes_read == 0 { + break; + } + sha256_hasher.update(&buffer[..bytes_read]); + } + + Ok(FileChecksums { + sha256: format!("{:x}", sha256_hasher.finalize()), + }) + }) + .await + .map_err(|e| e.to_string())? +} + fn folder_name>(path: P) -> (String, bool) { let path = path.as_ref(); let mut found_home = false; @@ -3176,10 +3277,7 @@ impl Tab { } fn rows_per_page(&self) -> usize { - let viewport_height = self - .item_view_size_opt - .get() - .map_or(0.0, |s| s.height); + let viewport_height = self.item_view_size_opt.get().map_or(0.0, |s| s.height); let row_height = self .select_focus .and_then(|i| self.items_opt.as_ref()?.get(i)) @@ -3891,8 +3989,7 @@ impl Tab { } Message::ItemPageDown => { self.dehighlight_all(); - if let Some((row, col)) = - self.select_focus_pos_opt().or(self.select_last_pos_opt()) + if let Some((row, col)) = self.select_focus_pos_opt().or(self.select_last_pos_opt()) { if self.select_focus.is_none() { self.select_position(row, col, mod_shift); @@ -3903,16 +4000,13 @@ impl Tab { if !self.select_position(target_row, col, mod_shift) { // Fall back to the last item at or before target_row - let best = self - .items_opt - .as_ref() - .and_then(|items| { - items - .iter() - .filter_map(|item| item.pos_opt.get()) - .filter(|(r, _)| *r <= target_row) - .max() - }); + let best = self.items_opt.as_ref().and_then(|items| { + items + .iter() + .filter_map(|item| item.pos_opt.get()) + .filter(|(r, _)| *r <= target_row) + .max() + }); if let Some((best_row, best_col)) = best { self.select_position(best_row, best_col, mod_shift); } @@ -3950,16 +4044,13 @@ impl Tab { if !self.select_position(target_row, col, mod_shift) { // Fall back to the first item at or after target_row - let best = self - .items_opt - .as_ref() - .and_then(|items| { - items - .iter() - .filter_map(|item| item.pos_opt.get()) - .filter(|(r, _)| *r >= target_row) - .min() - }); + let best = self.items_opt.as_ref().and_then(|items| { + items + .iter() + .filter_map(|item| item.pos_opt.get()) + .filter(|(r, _)| *r >= target_row) + .min() + }); if let Some((best_row, best_col)) = best { self.select_position(best_row, best_col, mod_shift); } @@ -4662,6 +4753,52 @@ impl Tab { } } } + Message::Checksums(path, checksum_state) => { + let location = Location::Path(path); + if let Some(ref mut item) = self.parent_item_opt + && item.location_opt.as_ref() == Some(&location) + { + item.checksums = checksum_state.clone(); + } + if let Some(ref mut items) = self.items_opt { + for item in items.iter_mut() { + if item.location_opt.as_ref() == Some(&location) { + item.checksums = checksum_state; + break; + } + } + } + } + Message::CalculateChecksums(path) => { + let location = Location::Path(path.clone()); + if let Some(ref mut item) = self.parent_item_opt + && item.location_opt.as_ref() == Some(&location) + { + item.checksums = ChecksumState::Calculating; + } + if let Some(ref mut items) = self.items_opt { + for item in items.iter_mut() { + if item.location_opt.as_ref() == Some(&location) { + item.checksums = ChecksumState::Calculating; + break; + } + } + } + commands.push(Command::Iced( + cosmic::Task::future(async move { + match calculate_checksums(&path).await { + Ok(checksums) => { + Message::Checksums(path, ChecksumState::Calculated(checksums)) + } + Err(err) => Message::Checksums(path, ChecksumState::Error(err)), + } + }) + .into(), + )); + } + Message::CopyChecksum(value) => { + commands.push(Command::Iced(cosmic::iced::clipboard::write(value).into())); + } } // Scroll to top if needed From 8883d7cd6459b649ba4cda27f5846ca8b34b6d03 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 26 Jun 2026 18:01:42 +0200 Subject: [PATCH 099/110] i18n: translation updates from weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Baurzhan Muftakhidinov Co-authored-by: CYAXXX <85353920+CYAXXX@users.noreply.github.com> Co-authored-by: Hosted Weblate Co-authored-by: Hugo Carvalho Co-authored-by: Isaac Subirana Co-authored-by: Nara Díaz Viñolas Co-authored-by: Sami BABAT Co-authored-by: Zahid Rizky Fakhri Co-authored-by: therealmate Co-authored-by: Димко Co-authored-by: Марко М. Костић Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/ca/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/hu/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/id/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/kk/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/kmr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/pt/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/sr/ Translate-URL: https://hosted.weblate.org/projects/pop-os/cosmic-files/uk/ Translation: Pop OS/COSMIC Files --- i18n/ca/cosmic_files.ftl | 32 ++-- i18n/hu/cosmic_files.ftl | 28 ++-- i18n/id/cosmic_files.ftl | 1 + i18n/kk/cosmic_files.ftl | 1 + i18n/kmr/cosmic_files.ftl | 330 ++++++++++++++++++++++++++++++++++++++ i18n/pt/cosmic_files.ftl | 6 +- i18n/sr/cosmic_files.ftl | 1 + i18n/uk/cosmic_files.ftl | 1 + 8 files changed, 372 insertions(+), 28 deletions(-) diff --git a/i18n/ca/cosmic_files.ftl b/i18n/ca/cosmic_files.ftl index 48e7033..f37cc18 100644 --- a/i18n/ca/cosmic_files.ftl +++ b/i18n/ca/cosmic_files.ftl @@ -1,11 +1,11 @@ cosmic-files = Fitxers del COSMIC empty-folder = Carpeta buida -empty-folder-hidden = Carpeta buida (té elements ocults) +empty-folder-hidden = Carpeta buida (conté elements ocults) no-results = No s'ha trobat cap resultat filesystem = Sistema de fitxers home = Inici networks = Xarxes -notification-in-progress = Hi ha operacions amb fitxers en curs. +notification-in-progress = Operacions de fitxers en curs trash = Paperera recents = Recents undo = Desfés @@ -29,14 +29,14 @@ details = Detalls dismiss = Descarta el missatge operations-running = { $running } { $running -> - [one] operacion + [one] operació *[other] operacions } en curs ({ $percent }%)... operations-running-finished = { $running }{ $running -> - [one] operacion + [one] operació *[other] operacions - } en curs ({ $percent }%), { $finished } acabat... + } en curs ({ $percent }%), { $finished } acabada/es... pause = Pausa resume = Reprèn @@ -54,7 +54,7 @@ extract-password-required = Cal una contrasenya ## Empty Trash Dialog empty-trash = Buida la paperera -empty-trash-warning = Voleu suprimir permanentment tots els fitxers de la paperera? +empty-trash-warning = Els elements dins la Paperera s'eliminaran permanentment ## Mount Error Dialog @@ -64,12 +64,12 @@ mount-error = No es pot accedir a la unitat create-new-file = Crea un nou fitxer create-new-folder = Crea una nova carpeta -file-name = Nom del fixer +file-name = Nom del fitxer folder-name = Nom de la carpeta -file-already-exists = Ja existeix un fitxer amb aquest nom. -folder-already-exists = Ja existeix una carpeta amb aquest nom. -name-hidden = Els noms que comencin amb "." seran ocults. -name-invalid = El nom no pot ser "{ $filename }". +file-already-exists = Ja existeix un fitxer amb aquest nom +folder-already-exists = Ja existeix una carpeta amb aquest nom +name-hidden = Els noms que comencin amb "." s'ocultaran. +name-invalid = El nom no pot ser "{ $filename }" name-no-slashes = El nom no pot contenir barres. ## Open/Save Dialog @@ -353,3 +353,13 @@ sort-oldest-first = Primer més antics sort-smallest-to-largest = De petit a gran sort-largest-to-smallest = De gran a petit run = Executa +extract-to-title = Extreu a una carpeta +empty-trash-title = Voleu buidar la paperera? +extract-to = Extreu a... +delete = Suprimeix +comment = Gestor de fitxers de l'escriptori COSMIC +copy-to-title = Escolliu el destí de la còpia +copy-to-button-label = Copia +move-to-title = Escolliu el destí del trasllat +move-to-button-label = Mou +keywords = Carpeta;Fitxers;Arxius;Gestor;Explorador; diff --git a/i18n/hu/cosmic_files.ftl b/i18n/hu/cosmic_files.ftl index c81703b..dfdbf44 100644 --- a/i18n/hu/cosmic_files.ftl +++ b/i18n/hu/cosmic_files.ftl @@ -17,7 +17,7 @@ desktop-view-options = Asztali nézet beállításai… show-on-desktop = Megjelenítés az asztalon desktop-folder-content = Asztal mappa tartalma mounted-drives = Csatolt meghajtók -trash-folder-icon = Kuka ikonja +trash-folder-icon = Kuka ikon icon-size-and-spacing = Ikonméret és távolság icon-size = Ikonméret grid-spacing = Rácsköz @@ -57,8 +57,8 @@ extract-to-title = Kibontási cél kiválasztása ## Empty Trash Dialog -empty-trash = Kuka ürítése -empty-trash-warning = A kukában lévő összes elem véglegesen törölve lesz +empty-trash = A Kuka ürítése +empty-trash-warning = A Kukában lévő összes elem véglegesen törölve lesz ## Mount Error Dialog @@ -103,7 +103,7 @@ related-apps = Hasonló alkalmazások selected-items = A(z) { $items } kijelölt elem permanently-delete-question = Végleges törlés? delete = Törlés -permanently-delete-warning = { $target } véglegesen törölve lesz. A művelet nem visszavonható. +permanently-delete-warning = { $target } véglegesen törölve lesz. A művelet nem vonható vissza. ## Rename Dialog @@ -251,13 +251,13 @@ deleting = { $items } { $items -> [one] elem *[other] elem - } törlése a kukából ({ $progress })… + } törlése a Kukából ({ $progress })… deleted = { $items } { $items -> [one] elem *[other] elem - } törölve a kukából -emptying-trash = { trash } kiürítése ({ $progress })… + } törölve a Kukából +emptying-trash = { trash } ürítése ({ $progress })… emptied-trash = { trash } kiürítve extracting = { $items } { $items -> @@ -309,12 +309,12 @@ restoring = { $items } { $items -> [one] elem *[other] elem - } visszaállítása a kukából ({ $progress })… + } visszaállítása a Kukából ({ $progress })… restored = { $items } { $items -> [one] elem *[other] elem - } visszaállítva a kukából + } visszaállítva a Kukából unknown-folder = ismeretlen mappa ## Open with @@ -349,7 +349,7 @@ light = Világos ### Type to Search type-to-search = Gépeléssel keresés -type-to-search-recursive = Keresés a jelenlegi mappában és almappákban +type-to-search-recursive = Keresés a jelenlegi mappában és az almappákban type-to-search-enter-path = Elérési út megnyitása # Context menu add-to-sidebar = Hozzáadás az oldalsávhoz @@ -360,8 +360,8 @@ extract-here = Kibontás new-file = Új fájl… new-folder = Új mappa… open-in-terminal = Megnyitás a terminálban -move-to-trash = Kukába helyezés -restore-from-trash = Visszaállítás a kukából +move-to-trash = Áthelyezés a Kukába +restore-from-trash = Visszaállítás a Kukából remove-from-sidebar = Eltávolítás az oldalsávról sort-by-name = Név szerinti rendezés sort-by-modified = Módosítás szerinti rendezés @@ -372,7 +372,7 @@ remove-from-recents = Eltávolítás a legutóbbiak közül ## Desktop change-wallpaper = Háttérkép cseréje… -desktop-appearance = Asztali megjelenés… +desktop-appearance = Asztal megjelenése… display-settings = Kijelzőbeállítások… # Menu @@ -422,7 +422,7 @@ sort-largest-to-smallest = Legnagyobbtól a legkisebbig repository = Tároló support = Támogatás progress-failed = { $percent }%, sikertelen -empty-trash-title = Kuka ürítése? +empty-trash-title = Kiüríted a Kukát? type-to-search-select = Kijelöli az első egyező fájlt vagy mappát pasted-image = Beillesztett kép pasted-text = Beillesztett szöveg diff --git a/i18n/id/cosmic_files.ftl b/i18n/id/cosmic_files.ftl index aefff98..3300d25 100644 --- a/i18n/id/cosmic_files.ftl +++ b/i18n/id/cosmic_files.ftl @@ -327,3 +327,4 @@ context-action-confirm-warning = [one] item *[other] item }. +rename-confirm = Ganti nama diff --git a/i18n/kk/cosmic_files.ftl b/i18n/kk/cosmic_files.ftl index 8aabf01..0ee3ffe 100644 --- a/i18n/kk/cosmic_files.ftl +++ b/i18n/kk/cosmic_files.ftl @@ -327,3 +327,4 @@ context-action-confirm-warning = *[other] нәрсеге }. run = Орындау +rename-confirm = Атын өзгерту diff --git a/i18n/kmr/cosmic_files.ftl b/i18n/kmr/cosmic_files.ftl index e69de29..6c08bd0 100644 --- a/i18n/kmr/cosmic_files.ftl +++ b/i18n/kmr/cosmic_files.ftl @@ -0,0 +1,330 @@ +sort-newest-first = Pêşî ya herî nû +connect = Girê bide +deleted = + { $items } hat jêbirin{ $items -> + [one] hêman + *[other] hêman + } ji { trash } +dismiss = Peyamê paşguh bike +list-view = Dîtina lîsteyê +copy_noun = Jê bigire +favorite-path-error = Şaşetiya vekirina rêgehê +progress = { $percent }% +open-file = Pelê veke +remove-from-sidebar = Ji benda kêlekê rake +related-apps = Bernameyên têkildar +network-drive-error = Nikaribû bigihêje ajokarê torê +gallery-preview = Pêşdîtina galeriyê +sort-smallest-to-largest = Biçûktir bo mezintir +zoom-in = Nêzîk bike +select-all = Hemûyan hilbijêre +removing-from-recents = + { $items } tê rakirin { $items -> + [one] hêman + *[other] hêman + } ji { recents } +password = Borînpeyv +cosmic-files = Pelên COSMIC +emptying-trash = { trash } tê valakirin({ $progress })... +new-window = Çarçoveya nû +remove = Rake +zoom-out = Dûr bike +compressing = + { $items } tê guvaştin { $items -> + [one] hêman + *[other] hêman + } ji "{ $from }" bo "{ $to }" ({ $progress })... +move-to-trash = Bilivîne bo jêbirdankê +menu-about = Derbarê Pelên COSMIC... +file-already-exists = Pelek bi heman navî jixwe heye +setting-executable-and-launching = "{ $name }" wekî pelê xebitandinê tê sazkirin û xebitandin +open-multiple-files = Gelek pelan veke +default-size = Mezinahiya berdest +name-hidden = Navên ku bi "." tê destpêkirin wê werin veşartin +extracted = + { $items } hate derxistin { $items -> + [one] hêman + *[other] hêman + } ji "{ $from }" bo "{ $to }" +create-new-folder = Peldanka nû biafrîne +folder-already-exists = Peldankek bi heman navî jixwe heye +create-archive = Erşîvê biafrîne +permanently-delete-warning = { $target } wê bi mayînde were jêbirin û nayê vegerandin. +favorite-path-error-description = + Nikaribû "{ $path }" veke. + "{ $path }" dibe ku tune be yan jî mafê te yê + vekirina wê tune be. + Tu dixwazî wê ji benda kêlekê rakî? +empty-trash-warning = Hêmanên di jêbirdankê de wê bi mayînde werin jêbirin +other-apps = Bernameyên din +set-permissions = Maf hatine sazkirin ji bo "{ $name }" bo { $mode } +quit = Biqedîne +sort-by-size = Li gorî mezinahiyê rêz bike +rename = Navê biguhêrîne... +empty-folder-hidden = Peldanka vala (tiştên veşartî tê de hene) +keep = Bihêle +operations-running = + { $running } { $running -> + [one] pêvajo + *[other] pêvajo + } dixebite ({ $percent }%)... +permanently-deleting = + { $items } bi mayînde tê jêbirin { $items -> + [one] hêman + *[other] hêman + } +edit = Biguhêrîne +copy = Jê bigire +none = Ne yek +no-results = Tu encam nehatin dîtin +theme = Rûkar +compressed = + { $items } hate guvaştin{ $items -> + [one] hêman + *[other] hêman + } ji "{ $from }" bo "{ $to }" +appearance = Xuyang +rename-folder = Navê peldankê biguherîne +new-file = Pela nû... +close-tab = Rûgerê bigire +open-in-terminal = Di termînalê de veke +open-multiple-folders = Gelek peldankan veke +remember-password = Borînpeyvê bi bîr bîne +username = Navê bikarhêner +light = Ronî +extract-to = Derxîne bo... +add-network-drive = Ajokarê torê tevlî bike +copying = + { $items } tê jêgirtin{ $items -> + [one] hêman + *[other] hêman + } ji "{ $from }" bo "{ $to }" ({ $progress })... +create-new-file = Pelê nû biafrîne +sort-by-trashed = Li gorî demê rêz bike +support = Piştgirî +try-again = Dîsa hewl bide +eject = Biavêje +copied = + { $items } hate jêgirtin { $items -> + [one] hêman + *[other] hêman + } ji "{ $from }" bo "{ $to }" +open-in-new-window = Di çarçoveyeke nû de veke +empty-folder = Peldanka vala +empty-trash = Jêbirdankê vala bike +sort-by-modified = Li gorî guhertinê rêz bike +list-directories-first = Pêşî rêgehan lîste bike +folder-name = Navê peldankê +browse-store = { $store } bigere +remove-from-recents = Ji dawiyê rake +paste = Pêve bike +empty-trash-title = Jêbirdankê vala bike? +menu-settings = Sazkarî... +moving = + { $items } tê livandin{ $items -> + [one] hêman + *[other] hêman + } ji "{ $from }" bo "{ $to }" ({ $progress })... +change-wallpaper = Wêneyê dîwêr biguhêrîne... +network-drive-description = + Di nav navnîşanên rajekarê de pêşgira protokolekê û navnîşanek heye. + Mînak: ssh://192.168.0.1, ftp://[2001:db8::1] +deleting = + { $items } tê jêbirin { $items -> + [one] hêman + *[other] hêman + } ji { trash } ({ $progress })... +single-click = Tikandina yekane bo vekriinê +view = Dîtin +setting-permissions = Maf tên sazkirin ji bo "{ $name }" bo { $mode } +creating = "{ $name }" tê afirandin di "{ $parent }" de +execute-only = Tenê xebitandin +open-item-location = Cihê hêmanê veke +type-to-search = Bo lêgerînê binivîse +set-executable-and-launched = "{ $name }" wekî pelê xebitandinê hat sazkirin û xebitandin +mounted-drives = Ajokarên siwarkirî +sort-a-z = A-Z +mount-error = Nikare bigihêje ajokerê +extract-here = Derxîne +grid-view = Dîtina torê +add-to-sidebar = Tevlî benda kêlekê bike +dark = Tarî +notification-in-progress = Pêvajoyên pelê didome +home = Rûpela sereke +sort-z-a = Z-A +type-to-search-recursive = Di peldank û binpeldankên heyî de digere +history = Dîrok +progress-paused = { $percent }%, hate rawestandin +desktop-view-options = Vebijêrkên dîtina sermaseyê... +show-on-desktop = Li ser sermaseyê nîşan bide +cancelled = Têkbirî +new-folder = Peldankan nû... +match-desktop = Li gorî sermaseyê +name-no-slashes = Nav nabe ku "/" tê de hebe +operations-running-finished = + { $running } { $running -> + [one] pêvajo + *[other] pêvajo + } dixebite ({ $percent }%), { $finished } qediya... +sort-by-name = Li gorî navê rêz bike +edit-history = Dîrokê biguhêrînê +show-hidden-files = Pelên veşartî nîşan bide +progress-failed = { $percent }%, têk çû +trash-folder-icon = Îkona peldanka jêbirdankê +extract-to-title = Derxîne bo peldankê +icon-size = Mezinahiya îkonê +open-with-title = Tu çawa dixwazî "{ $name }" vekî? +extracting = + { $items } tê derxistin { $items -> + [one] hêman + *[other] hêman + } ji "{ $from }" bo"{ $to }" ({ $progress })... +settings = Sazkarî +complete = Qediya +permanently-delete-question = Bi mayînde jê bibe? +extract-password-required = Borînpeyv pêdivî ye +pending = Li bendê ye +desktop-folder-content = Naveroka peldanka sermaseyê +no-history = Tu hêman di dîrok de tune ne. +open-folder = Peldankê veke +emptied-trash = { trash } hate valakirin +rename-file = Navê pelê biguherîne +sort-largest-to-smallest = Mezintir bo biçûktir +restore-from-trash = Ji jêbirdankê vegerîne +cut = Jê bike +moved = + { $items } hate livandin { $items -> + [one] hêman + *[other] hêman + } ji "{ $from }" bo "{ $to }" +progress-cancelled = { $percent }%, hat têkbirin +open-in-new-tab = Di rûgerê nû de veke +file = Pel +file-name = Navê pelê +save-file = Pelê tomar bike +created = "{ $name }" hate afirandin di "{ $parent }" de +delete-permanently = Bi mayînde jê bibe +display-settings = Sazkariyên dîmenderê... +new-tab = Rûgera nû +failed = Têk çû +name-invalid = Nav nabe ku \"{ $filename }\" be +desktop-appearance = Xuyanga sermaseyê... +comment = Rêveberê pelê ji bo sermaseya COSMIC +keywords = Rêveber;Peldank; +filesystem = Pergala pelê +networks = Tor +recents = Dawî +open = Veke +cancel = Têk bibe +trash = Jêbirdank +undo = Vegerîne +today = Îro +name = Nav +modified = Guhertî +size = Mezinahî +details = Hûrgilî +pause = Rawestîne +resume = Bidomîne +copy-to-title = Rêgeha jêgirtinê hilbijêre +copy-to-button-label = Jê bigire +move-to-title = Rêgeha livandinê hilbijêre +move-to-button-label = Bilivîne +create = Biafrîne +save = Tomar bike +context-action = Çalakiya naverokê +context-action-confirm-title = "{ $name }" bixebtîne? +context-action-confirm-warning = + Ev ê li ser { $items } { $items -> + [one] hêman + *[other] hêman + } bixebite. +run = Bixebitîne +selected-items = { $items } hêmanên hilbijartî +delete = Jê bibe +rename-confirm = Navê biguherîne +pasted-image = Wêneya pêvekirî +pasted-text = Nivîsa pêvekirî +pasted-video = Vîdiyoya pêvekirî +copy-path = Rêgehê jê bigire +show-recents = Peldanka dawî di benda kêlekê de +clear-recents-history = Dîroka dawî pak bike +compress = Biguvşîne... +copy-to = Jê bigire bo... +move-to = Bilivîne bo... +default-app = { $name } (berdest) +renamed = Nav hate guhertin ji "{ $from }" bo "{ $to }" +read-execute = Xwendin û xebitandin +item-modified = Guhertin: { $modified } +reload-folder = Peldankê ji nû ve bar bike +restoring = + { $items } tê vegerandin { $items -> + [one] hêman + *[other] hêman + } ji { trash } ({ $progress })... +icon-size-and-spacing = Mezinahiya îkonan û valahiya di navbera wan de +type-to-search-enter-path = Riya rêgehê yan jî pelê têdixîne +menu-open-with = Veke bi... +original-file = Pelê resen +read-write-execute = Xwendin, nivîsandin û xebitandin +calculating = Tê jimartin... +item-size = Mezinahî: { $size } +connecting = Tê girêdan... +read-write = Xwendin û nivîsandin +items = Hêman: { $items } +type = Cûre: { $mime } +replace-warning = Tu dixwazî bi ya ku tu niha tomar dikî biguhêrînî? Naveroka berê wê were jêbirin. +show-details = Hûrgiliyan nîşan bide +grid-spacing = Valahiya torê +sort-oldest-first = Pêşî ya herî kevn +repository = Embar +replace-warning-operation = Tu dixwazî biguherînî? Naveroka berê wê were jêbirin. +other = Ên din +read-only = Tenê xwendin +enter-server-address = Navnîşana rajekarê têxîne +connect-anonymously = Bi awayekî anonîm girê bide +group = Kom +apply-to-all = Bo hemûyan bisepîne +skip = Derbas bike +replace-with = Biguhêrîne bi +owner = Xwedî +set-and-launch = Saz bike û dest pê bike +removed-from-recents = + { $items } hate rakirin { $items -> + [one] hêman + *[other] hêman + } ji { recents } +item-created = Afirandin:{ $created } +network-drive-schemes = + Protokolên berdest,pêşgirê + AppleTalk,afp:// + Protokola şandina pelê,ftp:// an ftps:// + Pergala pelê torê,nfs:// + Astengiya peyama rajekarê,smb:// + SSH protokola şandina pelê,sftp:// an ssh:// + WebDAV, dav:// an davs:// +set-executable-and-launch = Wekî pelê xebitandinê saz bike û bixebitîne +restored = + { $items } hate vegerandin { $items -> + [one] hêman + *[other] hêman + } ji { trash } +domain = Navper +sort = Rêz bike +item-accessed = Gihîştin: { $accessed } +open-with = Veke bi +keep-both = Herduyan bihêle +permanently-deleted = + { $items } bi mayînde hate jêbirin{ $items -> + [one] hêman + *[other] hêman + } +write-execute = Nivîsandin û xebitandin +renaming = Navê ji "{ $from }" biguhêrîne bo "{ $to }" +set-executable-and-launch-description = Tu dixwazî "{ $name }" wekî pelê xebitandinê saz bikî û bixebtînî? +replace = Biguhêrîne +replace-title = "{ $filename }" jixwe di vê cihê de heye +unknown-folder = Peldanka nenas +write-only = Tenê nivîsandin +trashed-on = Li Jêbirdankê hatiye avêtin +mixed = Tevlihev +type-to-search-select = Pel an peldanka yekem a lihevhatî hildibijêre diff --git a/i18n/pt/cosmic_files.ftl b/i18n/pt/cosmic_files.ftl index 447487e..b0c7e30 100644 --- a/i18n/pt/cosmic_files.ftl +++ b/i18n/pt/cosmic_files.ftl @@ -1,12 +1,12 @@ cosmic-files = Ficheiros COSMIC comment = Gerenciador de arquivos do COSMIC -keywords = Pastas;Gerenciador;Arquivos;Gestor;Explorer; +keywords = Pasta;Gestor; empty-folder = Pasta vazia empty-folder-hidden = Pasta vazia (tem ficheiros ocultos) no-results = Nenhum resultado encontrado filesystem = Sistema de ficheiros home = Pasta Pessoal -notification-in-progress = Operações em curso. +notification-in-progress = Operações em curso trash = Lixo undo = Anular # List view @@ -204,7 +204,7 @@ desktop-view-options = Opções de visualização da área de trabalho... show-on-desktop = Mostrar na área de trabalho desktop-folder-content = Conteúdo da pasta da área de trabalho mounted-drives = Dispositivos montados -trash-folder-icon = Ícone do lixo +trash-folder-icon = Ícone da pasta lixo icon-size-and-spacing = Tamanho e espaçamento do ícone icon-size = Tamanho do ícone grid-spacing = Espaçamento entre ícones diff --git a/i18n/sr/cosmic_files.ftl b/i18n/sr/cosmic_files.ftl index b71afe5..98a9e35 100644 --- a/i18n/sr/cosmic_files.ftl +++ b/i18n/sr/cosmic_files.ftl @@ -327,3 +327,4 @@ compress = Сажми... copy-to = Умножи у... move-to = Помери у... copy-path = Умножи путању +rename-confirm = Преименуј diff --git a/i18n/uk/cosmic_files.ftl b/i18n/uk/cosmic_files.ftl index 9f23949..31b4103 100644 --- a/i18n/uk/cosmic_files.ftl +++ b/i18n/uk/cosmic_files.ftl @@ -388,3 +388,4 @@ context-action-confirm-warning = }. context-action = Контекстна дія rename-confirm = Перейменувати +mixed = Змішано From 49107187a422344569f1580680e9ca815cbb22bf Mon Sep 17 00:00:00 2001 From: ZlordHUN <137647604+ZlordHUN@users.noreply.github.com> Date: Mon, 29 Jun 2026 18:39:12 +0200 Subject: [PATCH 100/110] feat: view folder's content in trash - [x] I have disclosed use of any AI generated code in my commit messages. - If you are using an LLM, and do not fully understand the changes it is making to the code base, do not create a PR. - In our experience, AI generated code often results in overly complex code that lacks enough context for a proper fix or feature inclusion. This results in considerably longer code reviews. Due to this, AI authored or partially authored PRs may be closed without comment. - [x] I understand these changes in full and will be able to respond to review comments. - [x] My change is accurately described in the commit message. - [x] My contribution is tested and working as described. - [x] I have read the [Developer Certificate of Origin](https://developercertificate.org/) and certify my contribution under its conditions. --- Cargo.lock | 9 ++++--- Cargo.toml | 2 +- src/menu.rs | 51 ++++++++++++++++++++++++------------ src/operation/mod.rs | 24 ++++++++++++++--- src/tab.rs | 36 ++++++++++++++++++++++++-- src/trash.rs | 61 +++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 154 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d15d360..4166c58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7385,14 +7385,15 @@ dependencies = [ [[package]] name = "trash" -version = "5.2.2" -source = "git+https://github.com/jackpot51/trash-rs.git?branch=cosmic#a225f753a88e722aeeb27bb2fb00144739911035" +version = "5.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7602e0c7d66ec2d92a8c917219fbc7894039efa2063b9064260110828a356f46" dependencies = [ "chrono", "libc", "log", - "objc2 0.5.2", - "objc2-foundation 0.2.2", + "objc2 0.6.4", + "objc2-foundation 0.3.2", "once_cell", "percent-encoding", "scopeguard", diff --git a/Cargo.toml b/Cargo.toml index a186bfc..579636c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ shlex = { version = "1.3" } tempfile = "3" tikv-jemallocator = { version = "0.6", optional = true } tokio = { version = "1", features = ["process", "sync"] } -trash = { git = "https://github.com/jackpot51/trash-rs.git", branch = "cosmic" } +trash = "5.2.6" url = "2.5" walkdir = "2.5.0" wayland-client = { version = "0.31.14", optional = true } diff --git a/src/menu.rs b/src/menu.rs index cfc7d20..4708826 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -18,7 +18,9 @@ use std::sync::LazyLock; use crate::app::{Action, Message}; use crate::config::{Config, ContextActionPreset}; use crate::fl; -use crate::tab::{self, HeadingOptions, Location, LocationMenuAction, SearchLocation, Tab}; +use crate::tab::{ + self, HeadingOptions, ItemMetadata, Location, LocationMenuAction, SearchLocation, Tab, +}; use crate::trash::{Trash, TrashExt}; static MENU_ID: LazyLock = @@ -135,6 +137,7 @@ pub fn context_menu<'a>( let mut selected_desktop_entry = None; let mut selected_types: Vec = vec![]; let mut selected_mount_point = 0; + let mut any_trash_item = false; if let Some(items) = tab.items_opt() { for item in items { if item.selected { @@ -155,6 +158,9 @@ pub fn context_menu<'a>( } _ => (), } + if matches!(&item.metadata, ItemMetadata::Trash { .. }) { + any_trash_item = true; + } selected_types.push(item.mime.clone()); } } @@ -276,27 +282,38 @@ pub fn context_menu<'a>( //TODO: Print? children.push(menu_item(fl!("show-details"), Action::Preview).into()); - if matches!(tab.mode, tab::Mode::App) { + if any_trash_item { children.push(divider::horizontal::light().into()); - children.push(menu_item(fl!("add-to-sidebar"), Action::AddToSidebar).into()); - } - children.push(divider::horizontal::light().into()); - if tab.location.is_recents() { children.push( - menu_item(fl!("remove-from-recents"), Action::RemoveFromRecents).into(), + menu_item(fl!("restore-from-trash"), Action::RestoreFromTrash).into(), ); children.push(divider::horizontal::light().into()); - } - if selected_mount_point == 0 { - if modifiers.shift() && !modifiers.control() { - children.push( - menu_item(fl!("delete-permanently"), Action::PermanentlyDelete).into(), - ); - } else { - children.push(menu_item(fl!("move-to-trash"), Action::Delete).into()); + children.push(menu_item(fl!("delete-permanently"), Action::Delete).into()); + } else { + if matches!(tab.mode, tab::Mode::App) { + children.push(divider::horizontal::light().into()); + children + .push(menu_item(fl!("add-to-sidebar"), Action::AddToSidebar).into()); + } + children.push(divider::horizontal::light().into()); + if tab.location.is_recents() { + children.push( + menu_item(fl!("remove-from-recents"), Action::RemoveFromRecents).into(), + ); + children.push(divider::horizontal::light().into()); + } + if selected_mount_point == 0 { + if modifiers.shift() && !modifiers.control() { + children.push( + menu_item(fl!("delete-permanently"), Action::PermanentlyDelete) + .into(), + ); + } else { + children.push(menu_item(fl!("move-to-trash"), Action::Delete).into()); + } + } else if selected == 1 { + children.push(menu_item(fl!("eject"), Action::Eject).into()); } - } else if selected == 1 { - children.push(menu_item(fl!("eject"), Action::Eject).into()); } } else { //TODO: need better designs for menu with no selection diff --git a/src/operation/mod.rs b/src/operation/mod.rs index 7a84656..62dbba6 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -1156,10 +1156,26 @@ impl Operation { paths.push(item.original_path()); - compio::runtime::spawn_blocking(|| trash::os_limited::restore_all([item])) - .await - .map_err(wrap_compio_spawn_error)? - .map_err(|e| OperationError::from_err(e, &controller))?; + // Items with .trashinfo id use standard restore; sub-items use manual move + if item + .id + .to_str() + .map_or(false, |s| s.ends_with(".trashinfo")) + { + compio::runtime::spawn_blocking(|| trash::os_limited::restore_all([item])) + .await + .map_err(wrap_compio_spawn_error)? + .map_err(|e| OperationError::from_err(e, &controller))?; + } else { + let from = PathBuf::from(&item.id); + let to = item.original_path(); + if let Some(parent) = to.parent() { + std::fs::create_dir_all(parent) + .map_err(|e| OperationError::from_err(e, &controller))?; + } + std::fs::rename(&from, &to) + .map_err(|e| OperationError::from_err(e, &controller))?; + } } Ok(OperationSelection { ignored: Vec::new(), diff --git a/src/tab.rs b/src/tab.rs index 55b038d..26a7ea7 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -877,6 +877,8 @@ pub fn item_from_trash_entry( let name = entry.name.to_string_lossy().into_owned(); let display_name = Item::display_name(&name); + let location = crate::trash::trash_item_path(&entry).map(Location::Path); + let (mime, icon_handle_grid, icon_handle_list, icon_handle_list_condensed) = match metadata.size { trash::TrashItemSize::Entries(_) => ( @@ -904,7 +906,7 @@ pub fn item_from_trash_entry( is_mount_point: false, metadata: ItemMetadata::Trash { metadata, entry }, hidden: false, - location_opt: None, + location_opt: location, image_dimensions: (mime.type_() == mime::IMAGE) .then(|| image::image_dimensions(&original_path).ok()) .flatten(), @@ -925,6 +927,31 @@ pub fn item_from_trash_entry( } } +fn item_from_trash_child( + path: PathBuf, + name: String, + metadata: fs::Metadata, + sizes: IconSizes, +) -> Option { + let original_path = crate::trash::original_path_for_trash_child(&path)?; + let entry = trash::TrashItem { + id: path.as_os_str().to_os_string(), + name: std::ffi::OsString::from(&name), + original_parent: original_path.parent()?.to_path_buf(), + time_deleted: 0, + }; + let size = if metadata.is_dir() { + trash::TrashItemSize::Entries(0) + } else { + trash::TrashItemSize::Bytes(metadata.len()) + }; + Some(item_from_trash_entry( + entry, + trash::TrashItemMetadata { size }, + sizes, + )) +} + fn get_filename_from_path(path: &Path) -> Result { Ok(match path.file_name() { Some(name_os) => name_os @@ -1040,7 +1067,12 @@ pub fn scan_path(tab_path: &PathBuf, sizes: IconSizes) -> Vec { }) .ok()?; - Some(item_from_entry(path, name, metadata, sizes)) + let trash = crate::trash::is_trash_path(tab_path); + if trash { + item_from_trash_child(path, name, metadata, sizes) + } else { + Some(item_from_entry(path, name, metadata, sizes)) + } }) .collect(); } diff --git a/src/trash.rs b/src/trash.rs index 30d140f..d8bccca 100644 --- a/src/trash.rs +++ b/src/trash.rs @@ -1,11 +1,30 @@ use cosmic::widget; use regex::Regex; use std::collections::HashSet; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use crate::config::IconSizes; use crate::tab::{Item, SearchItem}; +fn percent_decode(s: &str) -> Option { + let (mut r, mut b) = (String::with_capacity(s.len()), s.bytes()); + while let Some(c) = b.next() { + if c == b'%' { + let (hi, lo) = (b.next()?, b.next()?); + let h = |x: u8| match x { + b'0'..=b'9' => Some(x - b'0'), + b'a'..=b'f' => Some(x - b'a' + 10), + b'A'..=b'F' => Some(x - b'A' + 10), + _ => None, + }; + r.push((h(hi)? << 4 | h(lo)?) as char); + } else { + r.push(c as char); + } + } + Some(r) +} + pub trait TrashExt { fn is_empty() -> bool { true @@ -49,6 +68,46 @@ pub trait TrashExt { } } +/// Derive the actual filesystem path of a trashed item from its .trashinfo path +/// (or return the id directly if it's already a filesystem path). +pub fn trash_item_path(item: &trash::TrashItem) -> Option { + let id_path = Path::new(&item.id); + if id_path.extension().map_or(false, |e| e == "trashinfo") { + let trash_root = id_path.parent()?.parent()?; + let file_name = id_path.file_stem()?; + Some(trash_root.join("files").join(file_name)) + } else { + Some(PathBuf::from(&item.id)) + } +} + +/// For a path inside a trash `files/` directory, reconstruct the original path +/// by reading the parent `.trashinfo` file. +/// +/// Given `~/.local/share/Trash/files/folder/sub/file.txt`: +/// - The top-level trashed item is `folder` +/// - Read `~/.local/share/Trash/info/folder.trashinfo` to get the original path +/// - Compute: `/sub/file.txt` +pub fn original_path_for_trash_child(p: &Path) -> Option { + let files = p.ancestors().find(|a| a.ends_with("files"))?; + let root = files.parent()?; + let top = p.strip_prefix(files).ok()?.components().next()?; + let info = + std::fs::read_to_string(root.join("info").join(top).with_extension("trashinfo")).ok()?; + let orig = percent_decode(info.lines().find_map(|l| l.strip_prefix("Path="))?.trim())?; + let rel = p.strip_prefix(files.join(top)).ok()?; + let mut result = PathBuf::from(&orig); + if !rel.as_os_str().is_empty() { + result.push(rel); + } + Some(result) +} + +/// Check whether a path is inside any trash `files/` directory. +pub fn is_trash_path(path: &Path) -> bool { + path.ancestors().any(|a| a.ends_with("files")) +} + pub struct Trash; // This config statement is from trash::os_limited From 3ef7913abdcbadf13af0884a76287f19052a4469 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 30 Jun 2026 12:21:13 -0600 Subject: [PATCH 101/110] Epoch 1.2.0 version update Generated by cosmic-epoch scripts/version-update.sh --- Cargo.lock | 134 ++++++++++++++++----------------- Cargo.toml | 2 +- cosmic-files-applet/Cargo.toml | 2 +- debian/changelog | 6 ++ 4 files changed, 72 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4166c58..0508920 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -277,9 +277,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "apply" @@ -304,9 +304,9 @@ checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "arc-swap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" dependencies = [ "rustversion", ] @@ -805,13 +805,13 @@ dependencies = [ [[package]] name = "bstr" -version = "1.12.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79" dependencies = [ "memchr", "regex-automata", - "serde", + "serde_core", ] [[package]] @@ -1351,7 +1351,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1372,7 +1372,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "quote", "syn", @@ -1380,7 +1380,7 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.1.0" +version = "1.2.0" dependencies = [ "anyhow", "atomic_float", @@ -1449,7 +1449,7 @@ dependencies = [ [[package]] name = "cosmic-files-applet" -version = "1.1.0" +version = "1.2.0" dependencies = [ "cosmic-files", "log", @@ -1498,7 +1498,7 @@ dependencies = [ [[package]] name = "cosmic-settings-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#75c0480f1315ec96ec3eb216fc939f93f57d7612" +source = "git+https://github.com/pop-os/cosmic-settings-daemon#276fef9834b05c57b67e8ba36b74bea1ba690cee" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1543,7 +1543,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "almost", "configparser", @@ -2084,18 +2084,19 @@ dependencies = [ [[package]] name = "env_filter" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" dependencies = [ "log", + "regex", ] [[package]] name = "env_logger" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" dependencies = [ "anstream", "anstyle", @@ -2989,9 +2990,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" dependencies = [ "typenum", ] @@ -3090,7 +3091,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "dnd", "iced_accessibility", @@ -3111,7 +3112,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "accesskit", "accesskit_winit", @@ -3120,7 +3121,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "bitflags 2.13.0", "bytes", @@ -3145,7 +3146,7 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "iced_core", "iced_futures", @@ -3155,7 +3156,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "futures", "iced_core", @@ -3169,7 +3170,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "bitflags 2.13.0", "bytemuck", @@ -3190,7 +3191,7 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "iced_graphics", "iced_runtime", @@ -3199,7 +3200,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3211,7 +3212,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "bytes", "cosmic-client-toolkit", @@ -3226,7 +3227,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "bytemuck", "cosmic-text", @@ -3243,7 +3244,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "as-raw-xcb-connection", "bitflags 2.13.0", @@ -3274,7 +3275,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.2" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "cosmic-client-toolkit", "dnd", @@ -3292,7 +3293,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "cosmic-client-toolkit", "cursor-icon", @@ -3393,9 +3394,9 @@ checksum = "846b0857ca091204be3c874bc93daaf89d4777e8d2d20b0d3ffe8f671d98014b" [[package]] name = "icu_collator" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b521b92a2666061ddda902769d8a4cf730b5c9529a845cc1b69770b12a6c9a71" +checksum = "8bbdf98e5e0aa827770acee171ebb568aaab975a36b56afdb5fd0e2f525750bb" dependencies = [ "icu_collator_data", "icu_collections", @@ -3911,9 +3912,9 @@ dependencies = [ [[package]] name = "io-uring" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d09b98f7eace8982db770e4408e7470b028ce513ac28fecdc6bf4c30fe92b62" +checksum = "9080b15e63775b9a2ac7dca720f7050a8b955e092ea0f6020a4a80f69998cdc0" dependencies = [ "bitflags 2.13.0", "cfg-if", @@ -3979,9 +3980,9 @@ checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1" [[package]] name = "jiff" -version = "0.2.29" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f877a98676d2fb664698d74cc6a51ce6c484ce8c770f05d0108ec9090aeb46" +checksum = "ccfe6121cbe750cf81efa362d85c0bde7ea298ec43092d3a193baca59cdbd634" dependencies = [ "defmt", "jiff-static", @@ -4006,9 +4007,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.29" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0666b5ab5ecaca213fc2a85b8c0083d9004e84ee2d5f9a7e0017aaf50986f25f" +checksum = "e165e897f662d428f3cd3828a919dbe067c2d42bb1031eede74ef9d27ecdedd2" dependencies = [ "proc-macro2", "quote", @@ -4100,9 +4101,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.102" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", @@ -4402,7 +4403,7 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcosmic" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#e7f278d17f0cf8275173ab127a9b47fdd7440d9a" +source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "apply", "ashpd 0.12.3", @@ -5305,13 +5306,12 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "open" -version = "5.3.5" +version = "5.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fbaa89d2ddc8473c78a3adf69eea8cffa28c483b8e02a971ef31527cd0fc92c" +checksum = "cd8d3b65c44123a56e0133d2cd06ce4361bd3ca99d41198b2f25e3c3db9b8b4a" dependencies = [ "is-wsl", "libc", - "pathdiff", ] [[package]] @@ -5469,12 +5469,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" -[[package]] -name = "pathdiff" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" - [[package]] name = "pbkdf2" version = "0.13.0" @@ -7128,9 +7122,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.51" +version = "0.3.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c17d80feb7334b40c484e45ed1a5273dfd8bfda537c3be2e74a06a6686f327" +checksum = "0e48db7b415311b615f910b3dcaa4557bcd4bf1982379c95c223fd8c2a20e210" dependencies = [ "deranged", "js-sys", @@ -7149,9 +7143,9 @@ checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.30" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcef1a61bdb119096e153208ec5cbec23944ce8bca13be5c7f60c634f7403935" +checksum = "c431b87111666e491a90baa837f914fb45cd5dc3c268591b0220ff5057f2085f" dependencies = [ "num-conv", "time-core", @@ -7608,9 +7602,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.3" +version = "1.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ "getrandom 0.4.3", "js-sys", @@ -7684,9 +7678,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -7697,9 +7691,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.75" +version = "0.4.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" dependencies = [ "js-sys", "wasm-bindgen", @@ -7707,9 +7701,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7717,9 +7711,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", @@ -7730,9 +7724,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] @@ -7903,9 +7897,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.102" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 579636c..da030fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.1.0" +version = "1.2.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 fdf7864..b4f5bcc 100644 --- a/cosmic-files-applet/Cargo.toml +++ b/cosmic-files-applet/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files-applet" -version = "1.1.0" +version = "1.2.0" edition = "2024" [dependencies] diff --git a/debian/changelog b/debian/changelog index 67931a8..0dbce82 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +cosmic-files (1.2.0) noble; urgency=medium + + * Epoch 1.2.0 version update + + -- Jeremy Soller Tue, 30 Jun 2026 12:21:07 -0600 + cosmic-files (1.1.0) noble; urgency=medium * Epoch 1.1.0 version update From 43a4228ca4901e19c943bb7a6c4f508ba76477e4 Mon Sep 17 00:00:00 2001 From: norepro <30921834+norepro@users.noreply.github.com> Date: Thu, 2 Jul 2026 08:52:14 -0700 Subject: [PATCH 102/110] feat: support MIME subclasses in file chooser dialog --- src/dialog.rs | 4 +++- src/mime_icon.rs | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/dialog.rs b/src/dialog.rs index 0623da0..7b47b7a 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -40,7 +40,7 @@ use crate::localize::LANGUAGE_SORTER; use crate::mounter::{MOUNTERS, MounterItem, MounterItems, MounterKey, MounterMessage}; use crate::tab::{self, ItemMetadata, Location, SearchLocation, Tab}; use crate::zoom::{zoom_in_view, zoom_out_view, zoom_to_default}; -use crate::{fl, home_dir, menu}; +use crate::{fl, home_dir, menu, mime_icon}; #[derive(Clone, Debug)] pub struct DialogMessage(cosmic::Action); @@ -1919,11 +1919,13 @@ impl Application for App { items.retain(|item| { // Directories are always shown item.metadata.is_dir() + // Check for mime type match (first because it is faster) || mimes.iter().any(|filter_mime| { if filter_mime.subtype() == mime::STAR { filter_mime.type_() == item.mime.type_() } else { *filter_mime == item.mime + || mime_icon::is_mime_subclass_of(&item.mime, filter_mime) } }) // Check for glob match (last because it is slower) diff --git a/src/mime_icon.rs b/src/mime_icon.rs index 1c1bf40..26d899d 100644 --- a/src/mime_icon.rs +++ b/src/mime_icon.rs @@ -124,3 +124,11 @@ pub fn parent_mime_types(mime: &Mime) -> Option> { let mime_icon_cache = MIME_ICON_CACHE.lock().unwrap(); mime_icon_cache.shared_mime_info.get_parents_aliased(mime) } + +pub fn is_mime_subclass_of(mime_type: &Mime, base: &Mime) -> bool { + let mime_icon_cache = MIME_ICON_CACHE.lock().unwrap(); + + mime_icon_cache + .shared_mime_info + .mime_type_subclass(mime_type, base) +} From 17fc1cabbb8be85ae4012c59641fed6cdbf64e4b Mon Sep 17 00:00:00 2001 From: Leyoda Date: Sun, 24 May 2026 21:16:14 +0200 Subject: [PATCH 103/110] yoda: cosmic-files customizations (squashed 21 commits) This commit squashes the 21 local commits that customize cosmic-files for the yoda stack, to allow a clean rebase on upstream/master. Original commits (chronological): - 9bcfe7a Cargo.toml: patch libcosmic via local path for dev builds - 04abd13 yoda: depend on libcosmic-yoda (path) instead of upstream libcosmic - 02adcc3 lockfile: libcosmic-yoda 0.1.0-yoda -> 0.1.0-yoda.2 - a025fd6 yoda: prefer cosmic-yoterm over upstream cosmic-term in terminal fallback - e8d62ae yoda: add "Always use this app" toggle to OpenWith dialog - 8fb2b15 yoda wayland-v5: redirect window_clipboard + cosmic-text to local forks - 0595296 yoda: Dolphin-style quick actions toolbar under the headerbar - 4b6d345 yoda: fix missing rename icon in toolbar - 8b51af1 yoda: use pencil-symbolic for the Rename toolbar button - 33a5c8f yoda: phase 2 - customizable toolbar (settings toggles per button) - 1cf17dc yoda: phase 3 - drag-drop toolbar editor in Settings - 11d4357 yoda: add up/down buttons next to drag handle in toolbar editor - af843d2 yoda: direct drag-drop reorder on the toolbar itself - 94c3e6c yoda: toolbar as segmented_button for working drag reorder - f053819 yoda: toolbar icon-only + clean visual (Control style, 32px squares) - 338354c Improve initial directory listing latency - d080bc8 Resolve cosmic-files warnings without masking - 69c35ab yoda: switch window_clipboard patch to public Forgejo fork - 35e115f yoda: switch cosmic-text patch to public Forgejo fork - 6f3adcd chore: clean feature-gated warnings - 57ab1ec fix: clean files warnings for terminal build Original tip preserved as tag backup/pre-rebase-upstream-20260524. --- Cargo.toml | 41 +- docs/local-performance-and-portal-notes.md | 78 ++++ i18n/en/cosmic_files.ftl | 6 + i18n/fr/cosmic_files.ftl | 6 + src/app.rs | 492 +++++++++++++++++++-- src/clipboard.rs | 6 +- src/config.rs | 91 ++++ src/dialog.rs | 8 +- src/lib.rs | 1 + src/menu.rs | 5 +- src/mime_app.rs | 7 +- src/mounter/mod.rs | 5 +- src/operation/recursive.rs | 1 + src/tab.rs | 83 ++-- src/thumbnailer.rs | 11 +- src/trash.rs | 10 +- 16 files changed, 758 insertions(+), 93 deletions(-) create mode 100644 docs/local-performance-and-portal-notes.md diff --git a/Cargo.toml b/Cargo.toml index da030fc..18973c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -74,8 +74,9 @@ version = "0.18" default-features = false features = ["fs", "io", "macros", "polling", "runtime"] -[dependencies.libcosmic] -git = "https://github.com/pop-os/libcosmic.git" +# Yoda fork — depend on libcosmic-yoda directly by path (no git/no patch). +[dependencies.libcosmic-yoda] +path = "../libcosmic" default-features = false #TODO: a11y feature crashes features = [ @@ -84,7 +85,7 @@ features = [ "autosize", "multi-window", "tokio", - "winit", + "wayland", "surface-message", ] @@ -112,15 +113,15 @@ default = [ "wayland", "wgpu", ] -dbus-config = ["libcosmic/dbus-config"] -desktop = ["libcosmic/desktop", "dep:cosmic-mime-apps", "dep:xdg"] +dbus-config = ["libcosmic-yoda/dbus-config"] +desktop = ["libcosmic-yoda/desktop", "dep:cosmic-mime-apps", "dep:xdg"] desktop-applet = [] gvfs = ["dep:gio", "dep:glib"] io-uring = ["compio/io-uring"] jemalloc = ["dep:tikv-jemallocator"] notify = ["dep:notify-rust"] -wayland = ["libcosmic/wayland", "dep:cctk", "dep:wayland-client"] -wgpu = ["libcosmic/wgpu"] +wayland = ["libcosmic-yoda/wayland", "dep:cctk", "dep:wayland-client"] +wgpu = ["libcosmic-yoda/wgpu"] [profile.dev] opt-level = 1 @@ -146,20 +147,22 @@ fastrand = "2" test-log = "0.2" tokio = { version = "1", features = ["rt", "macros"] } -# [patch.'https://github.com/pop-os/cosmic-text'] -# cosmic-text = { path = "../cosmic-text" } +# Yoda fork — libcosmic dep is now a direct path dep (libcosmic-yoda above), +# no [patch] block needed anymore. Keeping the block below would be a no-op +# since nothing in the dep graph still asks for pop-os/libcosmic.git. -# [patch.'https://github.com/pop-os/libcosmic'] -# libcosmic = { path = "../libcosmic" } -# cosmic-config = { path = "../libcosmic/cosmic-config" } -# cosmic-theme = { path = "../libcosmic/cosmic-theme" } -# libcosmic = { git = "https://github.com/pop-os/libcosmic//", branch = "iced-rebase" } -# cosmic-config = { git = "https://github.com/pop-os/libcosmic//", branch = "iced-rebase" } -# cosmic-theme = { git = "https://github.com/pop-os/libcosmic//", branch = "iced-rebase" } +# Yoda wayland cut: redirect window_clipboard (x11 gated behind opt-in +# feature) and cosmic-text (PR#503: EAW monospace width fix) to our public +# Forgejo forks. The window_clipboard patch is needed to consolidate the +# upstream pop-os/libcosmic chain (pulled by cosmic-settings-daemon) onto +# the same fork iced uses, otherwise cargo compiles two versions. +[patch.'https://github.com/pop-os/window_clipboard.git'] +window_clipboard = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } +dnd = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } +mime = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } - -# [patch.'https://github.com/pop-os/smithay-clipboard'] -# smithay-clipboard = { path = "../smithay-clipboard" } +[patch.'https://github.com/pop-os/cosmic-text.git'] +cosmic-text = { git = "https://forge.aditua.com/leyoda/cosmic-text.git", branch = "local/pr-503" } [workspace] members = ["cosmic-files-applet"] diff --git a/docs/local-performance-and-portal-notes.md b/docs/local-performance-and-portal-notes.md new file mode 100644 index 0000000..a3dabbe --- /dev/null +++ b/docs/local-performance-and-portal-notes.md @@ -0,0 +1,78 @@ +# Local performance and portal notes + +Date: 2026-05-05 + +This repository carries a local patch aimed at improving initial directory +display latency in large folders, plus a system-level workaround for a COSMIC +portal FileChooser crash observed with Firefox and Chromium. + +## Directory listing latency + +The slow path was the initial construction of `Item` values in `src/tab.rs`. +On a test folder with about 2000 entries, raw filesystem enumeration and stat +calls completed in a few milliseconds, while COSMIC Files took multiple seconds +before showing the directory. + +The local patch keeps initial item construction cheap: + +- directory child counts are no longer computed synchronously in + `item_from_entry` and `item_from_gvfs_info`; +- initial MIME detection uses extension-based `mime_guess`; +- regular files use a generic file icon during the initial scan instead of + resolving the full MIME icon immediately. + +This keeps folders and `.desktop` files special-cased, while avoiding expensive +per-file work for ordinary files during first paint. + +Measured locally during investigation: + +- before the MIME/icon changes: about 3.1 seconds for `~/Téléchargements`; +- after avoiding full MIME icon resolution during scan: below the temporary + 100 ms perf-log threshold for the same folder. + +## File chooser portal workaround + +Firefox and Chromium were failing to open `Save As` on the first attempt because +`xdg-desktop-portal-cosmic` crashed while handling `FileChooser`. + +Logs showed: + +```text +Backend call failed: Remote peer disconnected +xdg-desktop-portal-cosmic ... status=11/SEGV +``` + +The working local system workaround is to remove +`org.freedesktop.impl.portal.FileChooser` from: + +```text +/usr/share/xdg-desktop-portal/portals/cosmic.portal +``` + +so the file chooser falls back to GTK. The resulting local `cosmic.portal` +keeps COSMIC for the other interfaces: + +```ini +[portal] +DBusName=org.freedesktop.impl.portal.desktop.cosmic +Interfaces=org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Settings;org.freedesktop.impl.portal.ScreenCast +UseIn=COSMIC +``` + +Backups created locally: + +```text +/usr/share/xdg-desktop-portal/portals/cosmic.portal.bak-codex-20260505-filechooser +/usr/share/xdg-desktop-portal/cosmic-portals.conf.bak-codex-20260505 +/usr/share/xdg-desktop-portal/cosmic-portals.conf.bak-codex-20260505-2 +``` + +After editing portal files, restart: + +```sh +systemctl --user restart xdg-desktop-portal.service xdg-desktop-portal-gtk.service +``` + +Package updates may overwrite `/usr/share/xdg-desktop-portal/portals/cosmic.portal`. +If `Save As` starts needing two attempts again, re-check that `FileChooser` has +not been reintroduced in `cosmic.portal`. diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 44ff788..129e6f9 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -96,6 +96,7 @@ save-file = Save file ## Open With Dialog open-with-title = How do you want to open "{$name}"? +open-with-set-default = Always use this app for this file type browse-store = Browse {$store} other-apps = Other applications related-apps = Related applications @@ -139,6 +140,11 @@ open-with = Open with owner = Owner group = Group other = Other +toolbar = Toolbar +toolbar-available = Available +toolbar-empty-hint = No buttons. Drag or add from below. +toolbar-reset = Reset to defaults +parent-directory = Parent directory mixed = Mixed ### Mode 0 none = None diff --git a/i18n/fr/cosmic_files.ftl b/i18n/fr/cosmic_files.ftl index 7301596..e85a1f6 100644 --- a/i18n/fr/cosmic_files.ftl +++ b/i18n/fr/cosmic_files.ftl @@ -92,6 +92,7 @@ save-file = Enregistrer fichier ## Open With Dialog open-with-title = Comment souhaitez-vous ouvrir "{ $name }" ? +open-with-set-default = Toujours utiliser cette application pour ce type de fichier browse-store = Parcourir { $store } ## Permanently delete Dialog @@ -130,6 +131,11 @@ open-with = Ouvrir avec owner = Propriétaire group = Groupe other = Autre +toolbar = Barre d'outils +toolbar-available = Disponibles +toolbar-empty-hint = Aucun bouton. Glisser-déposer ou ajouter depuis la liste ci-dessous. +toolbar-reset = Rétablir par défaut +parent-directory = Dossier parent ### Mode 0 diff --git a/src/app.rs b/src/app.rs index e9fe8cc..6eab0a5 100644 --- a/src/app.rs +++ b/src/app.rs @@ -42,15 +42,21 @@ use notify_debouncer_full::notify::{self, RecommendedWatcher}; use notify_debouncer_full::{DebouncedEvent, Debouncer, RecommendedCache, new_debouncer}; use rustc_hash::{FxHashMap, FxHashSet}; use slotmap::Key as SlotMapKey; -use std::any::TypeId; -use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque}; -use std::future::Future; -use std::num::NonZeroU16; -use std::path::{Path, PathBuf}; -use std::pin::Pin; -use std::sync::{Arc, LazyLock, Mutex}; -use std::time::{self, Duration, Instant}; -use std::{env, fmt, fs, io, process}; +#[cfg(feature = "notify")] +use std::sync::Mutex; +use std::{ + any::TypeId, + collections::{BTreeMap, BTreeSet, HashMap, VecDeque}, + env, fmt, fs, + future::Future, + io, + num::NonZeroU16, + path::{Path, PathBuf}, + pin::Pin, + process, + sync::{Arc, LazyLock}, + time::{self, Duration, Instant}, +}; use tokio::sync::mpsc; use trash::TrashItem; #[cfg(all(feature = "wayland", feature = "desktop-applet"))] @@ -62,7 +68,7 @@ use crate::clipboard::{ }; use crate::config::{ AppTheme, Config, DesktopConfig, Favorite, IconSizes, State, TIME_CONFIG_ID, TabConfig, - TimeConfig, TypeToSearch, + TimeConfig, ToolbarAction, TypeToSearch, default_toolbar, }; use crate::dialog::{Dialog, DialogKind, DialogMessage, DialogResult, DialogSettings}; use crate::key_bind::key_binds; @@ -128,6 +134,105 @@ pub struct Flags { pub uris: Vec, } +/// Yoda phase 3: MIME for the DnD payload carried when a user drags a +/// toolbar row in the Settings editor. A single byte = ToolbarAction +/// discriminant (see `ToolbarAction::to_u8`). +const TOOLBAR_MIME: &str = "application/x-cosmic-files-toolbar-action"; + +/// Yoda phase 3: DnD payload wrapping a ToolbarAction discriminant. +#[derive(Clone, Debug)] +pub struct ToolbarActionPayload(pub u8); + +impl cosmic::iced::clipboard::mime::AsMimeTypes for ToolbarActionPayload { + fn available(&self) -> std::borrow::Cow<'static, [String]> { + std::borrow::Cow::Owned(vec![TOOLBAR_MIME.to_owned()]) + } + fn as_bytes(&self, mime_type: &str) -> Option> { + if mime_type == TOOLBAR_MIME { + Some(std::borrow::Cow::Owned(vec![self.0])) + } else { + None + } + } +} + +impl cosmic::iced::clipboard::mime::AllowedMimeTypes for ToolbarActionPayload { + fn allowed() -> std::borrow::Cow<'static, [String]> { + std::borrow::Cow::Owned(vec![TOOLBAR_MIME.to_owned()]) + } +} + +impl TryFrom<(Vec, String)> for ToolbarActionPayload { + type Error = (); + fn try_from((data, _mime): (Vec, String)) -> Result { + if data.len() == 1 { + Ok(Self(data[0])) + } else { + Err(()) + } + } +} + +/// Yoda phase 3 helper: map a ToolbarAction to its button UI (icon name, +/// localized label, app Message). Shared by the toolbar renderer in +/// `view()` and by the Settings page row renderer so the two stay in +/// sync. +fn toolbar_action_ui(a: ToolbarAction) -> (&'static str, String, Message) { + match a { + ToolbarAction::LocationUp => ( + "go-up-symbolic", + fl!("parent-directory"), + Action::LocationUp.message(None), + ), + ToolbarAction::Reload => ( + "view-refresh-symbolic", + fl!("reload-folder"), + Action::Reload.message(None), + ), + ToolbarAction::NewFolder => ( + "folder-new-symbolic", + fl!("new-folder"), + Action::NewFolder.message(None), + ), + ToolbarAction::NewFile => ( + "document-new-symbolic", + fl!("new-file"), + Action::NewFile.message(None), + ), + ToolbarAction::Rename => ( + "pencil-symbolic", + fl!("rename"), + Action::Rename.message(None), + ), + ToolbarAction::Delete => ( + "edit-delete-symbolic", + fl!("delete"), + Action::Delete.message(None), + ), + ToolbarAction::Cut => ("edit-cut-symbolic", fl!("cut"), Action::Cut.message(None)), + ToolbarAction::Copy => ( + "edit-copy-symbolic", + fl!("copy"), + Action::Copy.message(None), + ), + ToolbarAction::Paste => ( + "edit-paste-symbolic", + fl!("paste"), + Action::Paste.message(None), + ), + ToolbarAction::ToggleShowHidden => ( + "view-reveal-symbolic", + fl!("show-hidden-files"), + Action::ToggleShowHidden.message(None), + ), + ToolbarAction::OpenTerminal => ( + "utilities-terminal-symbolic", + fl!("open-in-terminal"), + Action::OpenTerminal.message(None), + ), + } +} + #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Action { About, @@ -394,6 +499,7 @@ pub enum Message { OpenWithBrowse, OpenWithDialog(Option), OpenWithSelection(usize), + OpenWithToggleDefault(bool), #[cfg(all(feature = "wayland", feature = "desktop-applet"))] Overlap(window::Id, OverlapNotifyEvent), Paste(Option), @@ -435,6 +541,22 @@ pub enum Message { SearchInput(String), SetShowDetails(bool), SetShowRecents(bool), + /// Yoda phase 3 — toolbar editing messages. + ToolbarAdd(ToolbarAction), + ToolbarRemove(ToolbarAction), + ToolbarReorder { + src: ToolbarAction, + target: ToolbarAction, + }, + /// Move one step up (toward index 0) inside the enabled toolbar list. + ToolbarMoveUp(ToolbarAction), + /// Move one step down (toward the end) inside the enabled toolbar list. + ToolbarMoveDown(ToolbarAction), + ToolbarReset, + /// Click on a toolbar button (via segmented_button activation). + ToolbarTabActivate(segmented_button::Entity), + /// Drag-reorder inside the toolbar (via segmented_button drag). + ToolbarTabReorder(segmented_button::ReorderEvent), SetTypeToSearch(TypeToSearch), SystemThemeModeChange, Size(window::Id, Size), @@ -565,6 +687,9 @@ pub enum DialogPage { mime: mime_guess::Mime, selected: usize, store_opt: Option>, + /// When true, the chosen app is written to mimeapps.list as the + /// default handler for `mime` after it spawns. + set_default: bool, }, PermanentlyDelete { paths: Box<[PathBuf]>, @@ -715,6 +840,11 @@ pub struct App { nav_bar_context_id: segmented_button::Entity, nav_model: segmented_button::SingleSelectModel, tab_model: segmented_button::Model, + /// Yoda phase 3: segmented_button model mirroring config.toolbar so the + /// toolbar row gets free drag-reorder + click activation (same widget + /// that powers the tab bar, its reorder is proven to work in this + /// setup unlike the generic dnd_source/dnd_destination wrappers). + toolbar_model: segmented_button::Model, config_handler: Option, state_handler: Option, config: Config, @@ -1078,7 +1208,7 @@ impl App { .sort_by(|a, b| (b.1.width * b.1.height).total_cmp(&(a.1.width * b.1.height))); for (w_id, overlap) in sorted_overlaps { - let Some((bl, br, tl, tr, mut size)) = self.layer_sizes.get(w_id).map(|s| { + let Some((bl, br, tl, tr, size)) = self.layer_sizes.get(w_id).map(|s| { ( Rectangle::new( Point::new(0., s.height / 2.), @@ -1128,30 +1258,18 @@ impl App { if tl && !(tr || bl) { *top += min_dim.1; *left += min_dim.0; - - size.height -= min_dim.1; - size.width -= min_dim.0; } if tr && !(tl || br) { *top += min_dim.1; *right += min_dim.0; - - size.height -= min_dim.1; - size.width -= min_dim.0; } if bl && !(br || tl) { *bottom += min_dim.1; *left += min_dim.0; - - size.height -= min_dim.1; - size.width -= min_dim.0; } if br && !(bl || tr) { *bottom += min_dim.1; *right += min_dim.0; - - size.height -= min_dim.1; - size.width -= min_dim.0; } } self.margin = overlaps; @@ -1510,12 +1628,18 @@ impl App { ) -> Task { log::info!("rescan_tab {entity:?} {location:?} {selection_paths:?}"); let icon_sizes = self.config.tab.icon_sizes; + #[cfg(feature = "gvfs")] let mounter_items = self.mounter_items.clone(); Task::future(async move { let location2 = location.clone(); match tokio::task::spawn_blocking(move || location2.scan(icon_sizes)).await { - Ok((parent_item_opt, mut items)) => { + Ok((parent_item_opt, items)) => { + #[cfg(feature = "gvfs")] + let mut items = items; + #[cfg(not(feature = "gvfs"))] + let items = items; + #[cfg(feature = "gvfs")] { let mounter_paths: Box<[_]> = mounter_items @@ -1685,6 +1809,7 @@ impl App { fn update_config(&mut self) -> Task { self.update_nav_model(); + self.rebuild_toolbar_model(); // Tabs are collected first to placate the borrowck let tabs: Box<[_]> = self.tab_model.iter().collect(); // Update main conf and each tab with the new config @@ -1698,6 +1823,52 @@ impl App { Task::batch(commands) } + /// Yoda phase 3: rebuild `toolbar_model` so it matches `config.toolbar`. + /// Called on init and on every config update. Each entity carries the + /// associated `ToolbarAction` as data so click/reorder handlers can + /// round-trip Entity → ToolbarAction without maintaining a side map. + /// + /// We insert ONLY the icon (no `.text()`) so the toolbar renders as a + /// clean icon row — user-visible labels stay in Settings/tooltips on + /// other surfaces. + fn rebuild_toolbar_model(&mut self) { + self.toolbar_model.clear(); + for action in self.config.toolbar.iter().copied() { + let (icon_name, _label, _msg) = toolbar_action_ui(action); + self.toolbar_model + .insert() + .icon(widget::icon::from_name(icon_name).size(16).icon()) + .data::(action); + } + } + + /// Yoda phase 3: after a drag-reorder, sync `config.toolbar` with the + /// new entity order in `toolbar_model`. Inlines what `config_set!` + /// would do (the macro lives inside update()). + fn sync_toolbar_config_from_model(&mut self) -> Task { + let new_toolbar: Vec = self + .toolbar_model + .iter() + .filter_map(|e| self.toolbar_model.data::(e).copied()) + .collect(); + if new_toolbar == self.config.toolbar { + return Task::none(); + } + match self.config_handler.as_ref() { + Some(h) => { + if let Err(err) = self.config.set_toolbar(h, new_toolbar) { + log::warn!("failed to save toolbar order: {err}"); + } + } + None => self.config.toolbar = new_toolbar, + } + // Don't call update_config() — that would rebuild the + // toolbar_model from config and undo the reorder the user just + // made. The model already has the new order; config is just + // catching up for persistence. + Task::none() + } + fn update_desktop(&mut self) -> Task { let needs_reload: Box<[_]> = (self.tab_model.iter()) .filter_map(|entity| { @@ -2275,10 +2446,134 @@ impl App { .toggler(self.config.show_recents, Message::SetShowRecents) }) .into(), + // Yoda phase 3: toolbar editor. Two stacked lists: + // - top: enabled buttons in their current order (drag to reorder) + // - bottom: available (not-yet-enabled) buttons + // Each row's toggle adds/removes; enabled rows are also + // drag sources + drop targets. + self.toolbar_settings_section(), ]) .into() } + /// Yoda phase 3: build the Toolbar settings section. + fn toolbar_settings_section(&self) -> Element<'_, Message> { + use iced::clipboard::dnd::DndAction; + let enabled = &self.config.toolbar; + let disabled: Vec = ToolbarAction::ALL + .iter() + .copied() + .filter(|a| !enabled.contains(a)) + .collect(); + + let space_xxs = theme::active().cosmic().spacing.space_xxs; + + let drag_icon = |size: u16| -> Element<'static, Message> { + widget::icon::from_name("list-drag-handle-symbolic") + .size(size) + .into() + }; + + let row_enabled = + |action: ToolbarAction, pos: usize, last: usize| -> Element<'_, Message> { + let (icon, label, _msg) = toolbar_action_ui(action); + let up_btn = + widget::button::icon(widget::icon::from_name("go-up-symbolic").size(14)); + let up_btn = if pos > 0 { + up_btn.on_press(Message::ToolbarMoveUp(action)) + } else { + up_btn + }; + let down_btn = + widget::button::icon(widget::icon::from_name("go-down-symbolic").size(14)); + let down_btn = if pos < last { + down_btn.on_press(Message::ToolbarMoveDown(action)) + } else { + down_btn + }; + + let row_content: Element<_> = widget::row::with_children(vec![ + drag_icon(14), + widget::icon::from_name(icon).size(16).into(), + widget::text::body(label).width(Length::Fill).into(), + up_btn.into(), + down_btn.into(), + widget::button::icon(widget::icon::from_name("list-remove-symbolic").size(14)) + .on_press(Message::ToolbarRemove(action)) + .into(), + ]) + .spacing(space_xxs) + .align_y(Alignment::Center) + .into(); + + let row_container = widget::container(row_content) + .width(Length::Fill) + .padding(space_xxs); + + // Wrap as DnD source (drags itself) + DnD destination (accepts + // drops from other enabled rows; on drop, move the src before + // this row). + let source = widget::dnd_source::(row_container) + .drag_content(move || ToolbarActionPayload(action.to_u8())); + widget::dnd_destination(source, vec![std::borrow::Cow::Borrowed(TOOLBAR_MIME)]) + .data_received_for::( + move |payload: Option| { + match payload.and_then(|p| ToolbarAction::from_u8(p.0)) { + Some(src) if src != action => Message::ToolbarReorder { + src, + target: action, + }, + // No-op if payload missing / malformed / same row. + _ => Message::ToolbarReorder { + src: action, + target: action, + }, + } + }, + ) + .action(DndAction::Move) + .into() + }; + + let row_disabled = |action: ToolbarAction| -> Element<'_, Message> { + let (icon, label, _msg) = toolbar_action_ui(action); + widget::row::with_children(vec![ + widget::icon::from_name(icon).size(16).into(), + widget::text::body(label).width(Length::Fill).into(), + widget::button::icon(widget::icon::from_name("list-add-symbolic").size(14)) + .on_press(Message::ToolbarAdd(action)) + .into(), + ]) + .spacing(space_xxs) + .align_y(Alignment::Center) + .padding(space_xxs) + .into() + }; + + let mut section = widget::settings::section().title(fl!("toolbar")); + if enabled.is_empty() { + section = section.add(widget::text::body(fl!("toolbar-empty-hint"))); + } else { + let last = enabled.len() - 1; + for (pos, a) in enabled.iter().copied().enumerate() { + section = section.add(row_enabled(a, pos, last)); + } + } + + let mut col = widget::column::with_capacity(3).spacing(space_xxs); + col = col.push(section); + if !disabled.is_empty() { + let mut avail = widget::settings::section().title(fl!("toolbar-available")); + for a in disabled { + avail = avail.add(row_disabled(a)); + } + col = col.push(avail); + } + col = col + .push(widget::button::standard(fl!("toolbar-reset")).on_press(Message::ToolbarReset)); + col.into() + } + // Update favorites based on renaming or moving dirs. fn update_favorites(&mut self, path_changes: &[(impl AsRef, impl AsRef)]) -> bool { let mut favorites_changed = false; @@ -2411,6 +2706,7 @@ impl Application for App { nav_bar_context_id: segmented_button::Entity::null(), nav_model: segmented_button::ModelBuilder::default().build(), tab_model: segmented_button::ModelBuilder::default().build(), + toolbar_model: segmented_button::ModelBuilder::default().build(), config_handler: flags.config_handler, state_handler: flags.state_handler, config: flags.config, @@ -3190,6 +3486,7 @@ impl Application for App { path, mime, selected, + set_default, .. } => { let available_apps = self.mime_app_cache.get_apps_for_mime(&mime, true); @@ -3208,6 +3505,11 @@ impl Application for App { None, ); } + // Yoda: persist as default if the user asked for it. + if set_default { + self.mime_app_cache + .set_default(mime.clone(), app.id.clone()); + } } Err(err) => { log::warn!( @@ -3830,6 +4132,7 @@ impl Application for App { .and_then(|mime| { self.mime_app_cache.get(&mime).first().cloned() }), + set_default: false, }, Some(CONFIRM_OPEN_WITH_BUTTON_ID.clone()), ); @@ -3841,6 +4144,13 @@ impl Application for App { *selected = index; } } + Message::OpenWithToggleDefault(enabled) => { + if let Some(DialogPage::OpenWith { set_default, .. }) = + self.dialog_pages.front_mut() + { + *set_default = enabled; + } + } 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) @@ -4320,6 +4630,86 @@ impl Application for App { config_set!(show_recents, show_recents); return self.update_config(); } + Message::ToolbarAdd(action) => { + let mut tb = self.config.toolbar.clone(); + if !tb.contains(&action) { + tb.push(action); + } + config_set!(toolbar, tb); + return self.update_config(); + } + Message::ToolbarRemove(action) => { + let mut tb = self.config.toolbar.clone(); + tb.retain(|a| a != &action); + config_set!(toolbar, tb); + return self.update_config(); + } + Message::ToolbarReorder { src, target } => { + let mut tb = self.config.toolbar.clone(); + if let (Some(src_idx), Some(tgt_idx)) = ( + tb.iter().position(|a| a == &src), + tb.iter().position(|a| a == &target), + ) && src_idx != tgt_idx + { + // Pull src out, then insert before the target's new position. + let item = tb.remove(src_idx); + let new_tgt = if src_idx < tgt_idx { + tgt_idx - 1 + } else { + tgt_idx + }; + tb.insert(new_tgt, item); + config_set!(toolbar, tb); + return self.update_config(); + } + return Task::none(); + } + Message::ToolbarMoveUp(action) => { + let mut tb = self.config.toolbar.clone(); + if let Some(i) = tb.iter().position(|a| a == &action) + && i > 0 + { + tb.swap(i, i - 1); + config_set!(toolbar, tb); + return self.update_config(); + } + return Task::none(); + } + Message::ToolbarMoveDown(action) => { + let mut tb = self.config.toolbar.clone(); + if let Some(i) = tb.iter().position(|a| a == &action) + && i + 1 < tb.len() + { + tb.swap(i, i + 1); + config_set!(toolbar, tb); + return self.update_config(); + } + return Task::none(); + } + Message::ToolbarReset => { + config_set!(toolbar, default_toolbar()); + return self.update_config(); + } + Message::ToolbarTabActivate(entity) => { + // Dispatch the stored ToolbarAction's message, then clear + // the "active" selection so the button doesn't stay + // highlighted after a click (we use segmented_button for + // layout/drag but toolbar buttons are action-firing, not + // a mutual-exclusive choice). + let action = self.toolbar_model.data::(entity).copied(); + self.toolbar_model.deactivate(); + if let Some(action) = action { + let (_, _, msg) = toolbar_action_ui(action); + return self.update(msg); + } + return Task::none(); + } + Message::ToolbarTabReorder(event) => { + let _ = self + .toolbar_model + .reorder(event.dragged, event.target, event.position); + return self.sync_toolbar_config_from_model(); + } Message::SetTypeToSearch(type_to_search) => { config_set!(type_to_search, type_to_search); return self.update_config(); @@ -5079,6 +5469,7 @@ impl Application for App { .and_then(|mime| { self.mime_app_cache.get(&mime).first().cloned() }), + set_default: false, }, None, ); @@ -5922,7 +6313,7 @@ impl Application for App { mime, selected, store_opt, - .. + set_default, } => { let name = match path.file_name() { Some(file_name) => file_name.to_str(), @@ -6007,7 +6398,21 @@ impl Application for App { } else { Length::Shrink } - })); + })) + // Yoda: let the user make this choice stick. A plain row + // instead of settings::item::builder because the latter + // returns a section Item, not an Element usable in .control(). + .control( + widget::row::with_children([ + widget::text::body(fl!("open-with-set-default")).into(), + widget::space::horizontal().into(), + widget::toggler(*set_default) + .on_toggle(Message::OpenWithToggleDefault) + .into(), + ]) + .spacing(space_s) + .align_y(Alignment::Center), + ); if let Some(app) = store_opt { dialog = dialog.tertiary_action( @@ -6413,7 +6818,10 @@ impl Application for App { /// Creates a view after each update. fn view(&self) -> Element<'_, Self::Message> { let cosmic_theme::Spacing { - space_xxs, space_s, .. + space_xxs, + space_xs, + space_s, + .. } = theme::spacing(); let mut tab_column = widget::column::with_capacity(4); @@ -6457,6 +6865,36 @@ impl Application for App { ); } + // Yoda phase 3: Dolphin-style quick actions toolbar via + // segmented_button::horizontal — the same widget that powers the + // tab bar, so its built-in drag reorder works reliably (unlike the + // generic dnd_source+dnd_destination pairing we tried earlier). + // Short click = action (ToolbarTabActivate → dispatch the stored + // ToolbarAction's message). Drag past threshold = reorder + // (ToolbarTabReorder → model.reorder + sync to config). + if !self.config.toolbar.is_empty() { + // Use Control style (no TabBar underline, no bottom border) + // and let each button shrink to its icon. Spacing = space_xs + // keeps the buttons visually separated so it looks like an + // icon toolbar rather than a conjoined segmented control. + let toolbar = widget::segmented_button::horizontal(&self.toolbar_model) + .style(theme::SegmentedButton::Control) + .button_height(32) + .button_spacing(space_xs) + .button_alignment(Alignment::Center) + .minimum_button_width(32) + .maximum_button_width(32) + .enable_tab_drag(String::from("x-cosmic-files/toolbar-dnd")) + .on_reorder(Message::ToolbarTabReorder) + .tab_drag_threshold(8.) + .on_activate(Message::ToolbarTabActivate); + tab_column = tab_column.push( + widget::container(toolbar) + .width(Length::Shrink) + .padding([space_xxs, space_s]), + ); + } + let entity = self.tab_model.active(); if let Some(tab) = self.tab_model.data::(entity) { let tab_view = tab diff --git a/src/clipboard.rs b/src/clipboard.rs index 7af2f9f..7d06be5 100644 --- a/src/clipboard.rs +++ b/src/clipboard.rs @@ -130,9 +130,11 @@ impl TryFrom<(Vec, String)> for ClipboardPaste { match mime.as_str() { "text/uri-list" => { let text = str::from_utf8(&data)?; - let _lines = text.lines(); - for line in text.lines() { + for line in text.lines().filter(|line| { + let line = line.trim(); + !line.is_empty() && !line.starts_with('#') + }) { let url = Url::parse(line)?; match url.to_file_path() { Ok(path) => paths.push(path), diff --git a/src/config.rs b/src/config.rs index 2138d83..8f493c0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -170,6 +170,11 @@ pub struct Config { pub show_details: bool, pub show_recents: bool, pub tab: TabConfig, + /// Yoda phase 3: Dolphin-style quick actions toolbar. An ordered list + /// of enabled buttons — position in the vec drives the toolbar order. + /// Reorder in Settings via drag-drop; items not in the vec are + /// hidden. Default = the minimal-6 set from phase 1. + pub toolbar: Vec, pub type_to_search: TypeToSearch, } @@ -234,11 +239,97 @@ impl Default for Config { show_details: false, show_recents: true, tab: TabConfig::default(), + toolbar: default_toolbar(), type_to_search: TypeToSearch::Recursive, } } } +/// Yoda phase 3: ordered enum of quick-action toolbar buttons. +/// The Config stores `Vec` so the user can pick BOTH +/// visibility (just include/exclude the variant) AND order (position in +/// the vec). Drag-drop reorder in the Settings page moves items around. +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] +pub enum ToolbarAction { + LocationUp, + Reload, + NewFolder, + NewFile, + Rename, + Delete, + Cut, + Copy, + Paste, + ToggleShowHidden, + OpenTerminal, +} + +impl ToolbarAction { + /// Stable list of every supported action. Ordered roughly by logical + /// grouping (location → create/edit → clipboard → view/misc) so that + /// the default enabled set follows a sensible shape and the Settings + /// row for a not-yet-enabled action lands in a predictable spot. + pub const ALL: &'static [Self] = &[ + Self::LocationUp, + Self::Reload, + Self::NewFolder, + Self::NewFile, + Self::Rename, + Self::Delete, + Self::Cut, + Self::Copy, + Self::Paste, + Self::ToggleShowHidden, + Self::OpenTerminal, + ]; + + /// u8 discriminant used to carry the action over a DnD mime payload. + pub const fn to_u8(self) -> u8 { + match self { + Self::LocationUp => 0, + Self::Reload => 1, + Self::NewFolder => 2, + Self::NewFile => 3, + Self::Rename => 4, + Self::Delete => 5, + Self::Cut => 6, + Self::Copy => 7, + Self::Paste => 8, + Self::ToggleShowHidden => 9, + Self::OpenTerminal => 10, + } + } + + pub const fn from_u8(v: u8) -> Option { + match v { + 0 => Some(Self::LocationUp), + 1 => Some(Self::Reload), + 2 => Some(Self::NewFolder), + 3 => Some(Self::NewFile), + 4 => Some(Self::Rename), + 5 => Some(Self::Delete), + 6 => Some(Self::Cut), + 7 => Some(Self::Copy), + 8 => Some(Self::Paste), + 9 => Some(Self::ToggleShowHidden), + 10 => Some(Self::OpenTerminal), + _ => None, + } + } +} + +/// Default set shown on a fresh install — same "minimal 6" as phase 1/2. +pub fn default_toolbar() -> Vec { + vec![ + ToolbarAction::NewFolder, + ToolbarAction::Rename, + ToolbarAction::Delete, + ToolbarAction::Cut, + ToolbarAction::Copy, + ToolbarAction::Paste, + ] +} + #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, CosmicConfigEntry, Deserialize, Serialize)] #[serde(default)] pub struct DesktopConfig { diff --git a/src/dialog.rs b/src/dialog.rs index 7b47b7a..b8d592a 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -732,11 +732,17 @@ impl App { fn rescan_tab(&self, selection_paths: Option>) -> Task { let location = self.tab.location.clone(); let icon_sizes = self.tab.config.icon_sizes; + #[cfg(feature = "gvfs")] let mounter_items = self.mounter_items.clone(); Task::future(async move { let location2 = location.clone(); match tokio::task::spawn_blocking(move || location2.scan(icon_sizes)).await { - Ok((parent_item_opt, mut items)) => { + Ok((parent_item_opt, items)) => { + #[cfg(feature = "gvfs")] + let mut items = items; + #[cfg(not(feature = "gvfs"))] + let items = items; + #[cfg(feature = "gvfs")] { let mounter_paths: Box<[_]> = mounter_items diff --git a/src/lib.rs b/src/lib.rs index f2d04d7..44b87f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,6 +38,7 @@ mod zoom; pub(crate) type FxOrderMap = ordermap::OrderMap; +#[cfg(feature = "gvfs")] pub(crate) fn err_str(err: T) -> String { err.to_string() } diff --git a/src/menu.rs b/src/menu.rs index 4708826..6e29b6b 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -10,6 +10,7 @@ use cosmic::widget::{ self, Row, button, column, container, divider, responsive_menu_bar, space, text, }; use cosmic::{Element, theme}; +#[cfg(feature = "desktop")] use i18n_embed::LanguageLoader; use mime_guess::Mime; use std::collections::HashMap; @@ -205,11 +206,11 @@ pub fn context_menu<'a>( if !Trash::is_empty() { children.push(menu_item(fl!("empty-trash"), Action::EmptyTrash).into()); } - } else if let Some(entry) = selected_desktop_entry { + } else if let Some(_entry) = selected_desktop_entry { children.push(menu_item(fl!("open"), Action::Open).into()); #[cfg(feature = "desktop")] { - children.extend(entry.desktop_actions.into_iter().enumerate().map( + children.extend(_entry.desktop_actions.into_iter().enumerate().map( |(i, action)| menu_item(action.name, Action::ExecEntryAction(i)).into(), )); } diff --git a/src/mime_app.rs b/src/mime_app.rs index fe45d39..8fd8a60 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -537,7 +537,12 @@ impl MimeAppCache { // Look for and return preferred terminals //TODO: fallback order beyond cosmic-term? - let mut preference_order = vec!["com.system76.CosmicTerm".to_string()]; + // Yoda: cosmic-yoterm (our fork) wins over upstream cosmic-term if both + // are installed — useful when xdg-mime default is not set. + let mut preference_order = vec![ + "com.aditua.CosmicYoterm".to_string(), + "com.system76.CosmicTerm".to_string(), + ]; if let Some(id) = self.get_default_terminal() { preference_order.insert(0, id); diff --git a/src/mounter/mod.rs b/src/mounter/mod.rs index 3171c0f..a5ee75a 100644 --- a/src/mounter/mod.rs +++ b/src/mounter/mod.rs @@ -75,10 +75,10 @@ impl MounterItem { } } - pub fn icon(&self, symbolic: bool) -> Option { + pub fn icon(&self, _symbolic: bool) -> Option { match self { #[cfg(feature = "gvfs")] - Self::Gvfs(item) => item.icon(symbolic), + Self::Gvfs(item) => item.icon(_symbolic), Self::None => unreachable!(), } } @@ -103,6 +103,7 @@ impl MounterItem { pub type MounterItems = Vec; #[derive(Clone, Debug)] +#[allow(dead_code)] pub enum MounterMessage { Items(MounterItems), MountResult(MounterItem, Result), diff --git a/src/operation/recursive.rs b/src/operation/recursive.rs index a3bd2c4..0f09bd6 100644 --- a/src/operation/recursive.rs +++ b/src/operation/recursive.rs @@ -10,6 +10,7 @@ use compio::driver::ToSharedFd; use compio::driver::op::AsyncifyFd; use compio::io::{AsyncReadAt, AsyncWriteAt}; use cosmic::iced::futures; +#[cfg(feature = "gvfs")] use futures::{FutureExt, StreamExt}; use std::cell::Cell; use std::error::Error; diff --git a/src/tab.rs b/src/tab.rs index 26a7ea7..82055eb 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -18,6 +18,7 @@ use cosmic::widget::menu::action::MenuAction; use cosmic::widget::menu::key_bind::KeyBind; use cosmic::widget::{self, DndDestination, DndSource, Id, RcElementWrapper, Widget, space}; use cosmic::{Apply, Element, cosmic_theme, font, theme}; +#[cfg(feature = "desktop")] use i18n_embed::LanguageLoader; use icu::datetime::input::DateTime; use icu::datetime::options::TimePrecision; @@ -289,6 +290,26 @@ pub fn folder_icon_symbolic(path: &PathBuf, icon_size: u16) -> widget::icon::Han .handle() } +fn generic_file_icons( + sizes: IconSizes, +) -> ( + widget::icon::Handle, + widget::icon::Handle, + widget::icon::Handle, +) { + ( + widget::icon::from_name("text-x-generic") + .size(sizes.grid()) + .handle(), + widget::icon::from_name("text-x-generic") + .size(sizes.list()) + .handle(), + widget::icon::from_name("text-x-generic") + .size(sizes.list_condensed()) + .handle(), + ) +} + //TODO: replace with Path::has_trailing_sep when stable fn has_trailing_sep(path: &Path) -> bool { path.as_os_str() @@ -545,7 +566,7 @@ pub fn fs_kind(_metadata: &Metadata) -> FsKind { } #[cfg(not(feature = "desktop"))] -fn get_desktop_file_display_name(path: &Path) -> Option { +fn get_desktop_file_display_name(_path: &Path) -> Option { None } @@ -564,7 +585,7 @@ fn get_desktop_file_display_name(path: &Path) -> Option { } #[cfg(not(feature = "desktop"))] -fn get_desktop_file_icon(path: &Path) -> Option { +fn get_desktop_file_icon(_path: &Path) -> Option { None } @@ -655,9 +676,9 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS folder_icon(&path, sizes.list_condensed()), ) } else { - // ALWAYS assume we're remote for mime guessing here, since gvfs reading can be expensive - // @todo - expose this as a config option? - let mime = mime_for_path(&path, None, true); + // Keep the initial directory scan cheap. Opening files still + // recalculates MIME from the real path before launching apps. + let mime = mime_guess::from_path(&path).first_or_octet_stream(); //TODO: clean this up, implement for trash let icon_name_opt = if mime == "application/x-desktop" { @@ -674,28 +695,21 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS desktop_icon_handle(&icon_name, sizes.list_condensed()), ) } else { + let (icon_handle_grid, icon_handle_list, icon_handle_list_condensed) = + generic_file_icons(sizes); ( - mime.clone(), - mime_icon(mime.clone(), sizes.grid()), - mime_icon(mime.clone(), sizes.list()), - mime_icon(mime, sizes.list_condensed()), + mime, + icon_handle_grid, + icon_handle_list, + icon_handle_list_condensed, ) } }; - let mut children_opt = None; + let children_opt = None; let mut dir_size = DirSize::NotDirectory; if is_dir && !remote { dir_size = DirSize::Calculating(Controller::default()); - //TODO: calculate children in the background (and make it cancellable?) - match fs::read_dir(&path) { - Ok(entries) => { - children_opt = Some(entries.count()); - } - Err(err) => { - log::warn!("failed to read directory {}: {}", path.display(), err); - } - } } let display_name = display_name_for_file(&path, &file_info.display_name(), false, is_desktop); @@ -750,7 +764,10 @@ pub fn item_from_entry( sizes: IconSizes, ) -> Item { let mut is_desktop = false; + #[cfg(feature = "gvfs")] let mut is_gvfs = false; + #[cfg(not(feature = "gvfs"))] + let is_gvfs = false; let hidden = name.starts_with('.') || hidden_attribute(&metadata); @@ -798,7 +815,9 @@ pub fn item_from_entry( folder_icon(&path, sizes.list_condensed()), ) } else { - let mime = mime_for_path(&path, Some(&metadata), remote); + // Keep the initial directory scan cheap. Opening files still + // recalculates MIME from the real path before launching apps. + let mime = mime_guess::from_path(&path).first_or_octet_stream(); //TODO: clean this up, implement for trash let icon_name_opt = if mime == "application/x-desktop" { is_desktop = true; @@ -814,28 +833,21 @@ pub fn item_from_entry( desktop_icon_handle(&icon_name, sizes.list_condensed()), ) } else { + let (icon_handle_grid, icon_handle_list, icon_handle_list_condensed) = + generic_file_icons(sizes); ( - mime.clone(), - mime_icon(mime.clone(), sizes.grid()), - mime_icon(mime.clone(), sizes.list()), - mime_icon(mime, sizes.list_condensed()), + mime, + icon_handle_grid, + icon_handle_list, + icon_handle_list_condensed, ) } }; - let mut children_opt = None; + let children_opt = None; let mut dir_size = DirSize::NotDirectory; if metadata.is_dir() && !remote { dir_size = DirSize::Calculating(Controller::default()); - //TODO: calculate children in the background (and make it cancellable?) - match fs::read_dir(&path) { - Ok(entries) => { - children_opt = Some(entries.count()); - } - Err(err) => { - log::warn!("failed to read directory {}: {}", path.display(), err); - } - } } let display_name = display_name_for_file(&path, &name, is_gvfs, is_desktop); @@ -978,7 +990,10 @@ pub fn item_from_path>(path: P, sizes: IconSizes) -> Result Vec { let mut items = Vec::new(); let mut hidden_files = Box::from([]); + #[cfg(feature = "gvfs")] let mut remote_scannable = false; + #[cfg(not(feature = "gvfs"))] + let remote_scannable = false; #[cfg(feature = "gvfs")] { diff --git a/src/thumbnailer.rs b/src/thumbnailer.rs index b9de821..8e61447 100644 --- a/src/thumbnailer.rs +++ b/src/thumbnailer.rs @@ -5,10 +5,13 @@ use cosmic::desktop::fde::GenericEntry; use mime_guess::Mime; use rustc_hash::FxHashMap; -use std::path::Path; -use std::sync::{LazyLock, Mutex}; -use std::time::Instant; -use std::{fs, process}; +#[cfg(feature = "desktop")] +use std::{fs, time::Instant}; +use std::{ + path::Path, + process, + sync::{LazyLock, Mutex}, +}; #[derive(Clone, Debug)] pub struct Thumbnailer { diff --git a/src/trash.rs b/src/trash.rs index d8bccca..c0b3548 100644 --- a/src/trash.rs +++ b/src/trash.rs @@ -201,4 +201,12 @@ impl TrashExt for Trash { not(target_os = "android") ) )))] -impl TrashExt for Trash {} +impl TrashExt for Trash { + fn scan_search bool + Sync>(callback: F, regex: &Regex) { + log::warn!( + "searching trash not supported on this platform for pattern {:?}", + regex.as_str() + ); + drop(callback); + } +} From 2a74748083e248c1634a769918c13a31d4633a50 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 11:34:38 +0200 Subject: [PATCH 104/110] chore: use local cosmic-text checkout --- Cargo.toml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 18973c6..a6b6dde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -152,8 +152,9 @@ tokio = { version = "1", features = ["rt", "macros"] } # since nothing in the dep graph still asks for pop-os/libcosmic.git. # Yoda wayland cut: redirect window_clipboard (x11 gated behind opt-in -# feature) and cosmic-text (PR#503: EAW monospace width fix) to our public -# Forgejo forks. The window_clipboard patch is needed to consolidate the +# feature) to our public Forgejo fork and cosmic-text to the local checkout +# carrying PR#503 plus the EAW monospace width fix. The window_clipboard patch +# is needed to consolidate the # upstream pop-os/libcosmic chain (pulled by cosmic-settings-daemon) onto # the same fork iced uses, otherwise cargo compiles two versions. [patch.'https://github.com/pop-os/window_clipboard.git'] @@ -162,7 +163,7 @@ dnd = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = " mime = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } [patch.'https://github.com/pop-os/cosmic-text.git'] -cosmic-text = { git = "https://forge.aditua.com/leyoda/cosmic-text.git", branch = "local/pr-503" } +cosmic-text = { path = "../cosmic-text" } [workspace] members = ["cosmic-files-applet"] From fd4a2ba610df3dfb49107fbcef8d0284984eeb11 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Fri, 3 Jul 2026 13:01:18 +0200 Subject: [PATCH 105/110] fix: absorb libcosmic theme-v2 API (nav_context_menu, app_popup LiveSettings) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Leyoda 2026 – GPLv3 --- src/app.rs | 5 +++-- src/dialog.rs | 1 + src/menu.rs | 8 ++++---- src/tab.rs | 6 +++--- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/app.rs b/src/app.rs index 6eab0a5..0e572a0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2817,7 +2817,7 @@ impl Application for App { .on_middle_press(|entity| { cosmic::Action::App(Message::NavMenuAction(NavMenuAction::OpenInNewTab(entity))) }) - .context_menu(self.nav_context_menu(self.nav_bar_context_id)) + .context_menu(self.nav_context_menu()) .close_icon(icon::from_name("media-eject-symbolic").size(16).icon()) .into_container(); @@ -2832,8 +2832,8 @@ impl Application for App { fn nav_context_menu( &self, - entity: widget::nav_bar::Id, ) -> Option>>> { + let entity = self.nav_bar_context_id; let favorite_index_opt = self.nav_model.data::(entity); let location_opt = self.nav_model.data::(entity); @@ -4885,6 +4885,7 @@ impl Application for App { commands.push(self.update(Message::CheckClipboard)); commands.push(self.update(Message::Surface( cosmic::surface::action::app_popup( + |_: &Self| cosmic::surface::action::LiveSettings::default(), move |app: &mut Self| -> SctkPopupSettings { let anchor_rect = Rectangle { x: point.x as i32, diff --git a/src/dialog.rs b/src/dialog.rs index b8d592a..c760472 100644 --- a/src/dialog.rs +++ b/src/dialog.rs @@ -1801,6 +1801,7 @@ impl Application for App { let autosize_id = widget::Id::unique(); commands.push(self.update(Message::Surface( cosmic::surface::action::app_popup( + |_: &Self| cosmic::surface::action::LiveSettings::default(), move |app: &mut Self| -> SctkPopupSettings { let anchor_rect = Rectangle { x: point.x as i32, diff --git a/src/menu.rs b/src/menu.rs index 6e29b6b..0937595 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -70,7 +70,7 @@ pub fn context_menu<'a>( String::new() }; fn key_style(theme: &cosmic::Theme) -> TextStyle { - let mut color = theme.cosmic().background.component.on; + let mut color = theme.cosmic().background(false).component.on; color.alpha *= 0.75; TextStyle { color: Some(color.into()), @@ -78,7 +78,7 @@ pub fn context_menu<'a>( } } fn disabled_style(theme: &cosmic::Theme) -> TextStyle { - let mut color = theme.cosmic().background.component.on; + let mut color = theme.cosmic().background(false).component.on; color.alpha *= 0.5; TextStyle { color: Some(color.into()), @@ -442,7 +442,7 @@ pub fn context_menu<'a>( //TODO: move style to libcosmic .style(|theme| { let cosmic = theme.cosmic(); - let component = &cosmic.background.component; + let component = &cosmic.background(false).component; container::Style { icon_color: Some(component.on.into()), text_color: Some(component.on.into()), @@ -836,7 +836,7 @@ pub fn location_context_menu<'a>(ancestor_index: usize) -> Element<'a, tab::Mess .padding(1) .style(|theme| { let cosmic = theme.cosmic(); - let component = &cosmic.background.component; + let component = &cosmic.background(false).component; container::Style { icon_color: Some(component.on.into()), text_color: Some(component.on.into()), diff --git a/src/tab.rs b/src/tab.rs index 82055eb..dc3d925 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -181,7 +181,7 @@ fn button_appearance( appearance.icon_color = Some(Color::from(cosmic.on_bg_component_color())); appearance.text_color = Some(Color::from(cosmic.on_bg_component_color())); if cut { - appearance.text_color = Some(Color::from(cosmic.background.component.on_disabled)); + appearance.text_color = Some(Color::from(cosmic.background(false).component.on_disabled)); } else { appearance.text_color = Some(Color::from(cosmic.on_bg_component_color())); } @@ -192,12 +192,12 @@ fn button_appearance( appearance.background = Some(Color::from(cosmic.bg_color()).into()); appearance.icon_color = Some(Color::from(cosmic.on_bg_color())); if cut { - appearance.text_color = Some(Color::from(cosmic.background.component.disabled)); + appearance.text_color = Some(Color::from(cosmic.background(false).component.disabled)); } else { appearance.text_color = Some(Color::from(cosmic.on_bg_color())); } } else if cut { - appearance.text_color = Some(Color::from(cosmic.background.component.on_disabled)); + appearance.text_color = Some(Color::from(cosmic.background(false).component.on_disabled)); } if focused && accent { appearance.outline_width = 1.0; From d6e157261113c74c6d78988a3e7508e8fb705ee5 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Fri, 3 Jul 2026 15:28:40 +0200 Subject: [PATCH 106/110] chore: refresh lockfile post-1.2.0 rebase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Leyoda 2026 – GPLv3 --- Cargo.lock | 287 +++++++++++++---------------------------------------- 1 file changed, 70 insertions(+), 217 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0508920..2936ed4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -334,12 +334,6 @@ version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" -[[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" @@ -1004,7 +998,6 @@ 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,22 +1007,12 @@ 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" @@ -1335,13 +1318,25 @@ dependencies = [ "libm", ] +[[package]] +name = "cosmic-client-toolkit" +version = "0.2.0" +dependencies = [ + "bitflags 2.13.0", + "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=c253ec1#c253ec1d6804afbcdf250f5cc37ae1194bba7bd2" dependencies = [ "bitflags 2.13.0", - "cosmic-protocols", + "cosmic-protocols 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", "libc", "smithay-client-toolkit", "wayland-client", @@ -1351,7 +1346,6 @@ dependencies = [ [[package]] name = "cosmic-config" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1372,7 +1366,6 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "quote", "syn", @@ -1387,7 +1380,7 @@ dependencies = [ "bstr", "bzip2", "compio", - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0 (git+https://github.com/pop-os/cosmic-protocols?rev=c253ec1)", "cosmic-mime-apps", "dirs 6.0.0", "fastrand", @@ -1406,7 +1399,7 @@ dependencies = [ "jiff-icu", "jxl-oxide", "libc", - "libcosmic", + "libcosmic-yoda", "log", "lzma-rust2", "md-5", @@ -1459,7 +1452,6 @@ dependencies = [ [[package]] name = "cosmic-freedesktop-icons" version = "0.4.0" -source = "git+https://github.com/pop-os/freedesktop-icons#ab4c57b8e416c6af9297cb04d101889896fd9a92" dependencies = [ "bstr", "btoi", @@ -1481,6 +1473,19 @@ dependencies = [ "xdg", ] +[[package]] +name = "cosmic-protocols" +version = "0.2.0" +dependencies = [ + "bitflags 2.13.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "wayland-server", +] + [[package]] name = "cosmic-protocols" version = "0.2.0" @@ -1498,7 +1503,6 @@ dependencies = [ [[package]] name = "cosmic-settings-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-settings-daemon#276fef9834b05c57b67e8ba36b74bea1ba690cee" dependencies = [ "cosmic-config", "ron 0.11.0", @@ -1510,8 +1514,7 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon" -version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#eed01dd3609e90e3c8cd043656734c500956c793" +version = "0.1.1-yoda.1" dependencies = [ "zbus 5.16.0", ] @@ -1519,8 +1522,6 @@ 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.0", "fontdb", @@ -1538,18 +1539,19 @@ 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#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "almost", "configparser", "cosmic-config", "csscolorparser", "dirs 6.0.0", + "hex_color", "palette", "ron 0.12.2", "serde", @@ -1633,7 +1635,6 @@ 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", @@ -1679,15 +1680,6 @@ 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" @@ -1969,7 +1961,6 @@ 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.0", "mime 0.1.0", @@ -1996,52 +1987,6 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" version = "0.1.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" - -[[package]] -name = "drm" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" -dependencies = [ - "bitflags 2.13.0", - "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" @@ -2614,16 +2559,6 @@ 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" @@ -2973,6 +2908,17 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex_color" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d37f101bf4c633f7ca2e4b5e136050314503dd198e78e325ea602c327c484ef0" +dependencies = [ + "arrayvec", + "rand 0.8.6", + "serde", +] + [[package]] name = "hexf-parse" version = "0.2.1" @@ -3091,7 +3037,6 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "dnd", "iced_accessibility", @@ -3112,7 +3057,6 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "accesskit", "accesskit_winit", @@ -3121,11 +3065,10 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "bitflags 2.13.0", "bytes", - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0", "dnd", "glam", "lilt", @@ -3146,7 +3089,6 @@ dependencies = [ [[package]] name = "iced_debug" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "iced_core", "iced_futures", @@ -3156,7 +3098,6 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "futures", "iced_core", @@ -3170,7 +3111,6 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "bitflags 2.13.0", "bytemuck", @@ -3191,7 +3131,6 @@ dependencies = [ [[package]] name = "iced_program" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "iced_graphics", "iced_runtime", @@ -3200,7 +3139,6 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3212,10 +3150,9 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "bytes", - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0", "dnd", "iced_core", "iced_futures", @@ -3227,7 +3164,6 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ "bytemuck", "cosmic-text", @@ -3244,12 +3180,10 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ - "as-raw-xcb-connection", "bitflags 2.13.0", "bytemuck", - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0", "cryoglyph", "futures", "glam", @@ -3263,21 +3197,18 @@ dependencies = [ "rustc-hash 2.1.2", "rustix 0.38.44", "thiserror 2.0.18", - "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#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0", "dnd", "iced_renderer", "iced_runtime", @@ -3293,9 +3224,8 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" dependencies = [ - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0", "cursor-icon", "dnd", "iced_debug", @@ -4401,14 +4331,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] -name = "libcosmic" -version = "1.0.0" -source = "git+https://github.com/pop-os/libcosmic.git#18a7a75e3316b1f4855777af677d989467f2da74" +name = "libcosmic-yoda" +version = "0.1.0-yoda.2" dependencies = [ "apply", "ashpd 0.12.3", "auto_enums", - "cosmic-client-toolkit", + "cosmic-client-toolkit 0.2.0", "cosmic-config", "cosmic-freedesktop-icons", "cosmic-settings-config", @@ -4416,6 +4345,7 @@ dependencies = [ "cosmic-theme", "css-color", "derive_setters", + "enumflags2", "float-cmp 0.10.0", "freedesktop-desktop-entry", "futures", @@ -4512,12 +4442,6 @@ 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" @@ -4757,7 +4681,6 @@ 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", ] @@ -6746,7 +6669,6 @@ 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", @@ -6777,14 +6699,11 @@ 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", @@ -6794,14 +6713,12 @@ dependencies = [ "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]] @@ -7177,19 +7094,6 @@ 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.3" @@ -8111,12 +8015,10 @@ 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", @@ -8618,7 +8520,6 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.13.0", "cfg_aliases", @@ -8638,13 +8539,11 @@ 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#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "android-activity", "bitflags 2.13.0", @@ -8659,7 +8558,6 @@ dependencies = [ [[package]] name = "winit-appkit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.13.0", "block2 0.6.2", @@ -8681,7 +8579,6 @@ dependencies = [ [[package]] name = "winit-common" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "memmap2 0.9.11", "objc2 0.6.4", @@ -8689,14 +8586,12 @@ 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#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.13.0", "cursor-icon", @@ -8710,7 +8605,6 @@ dependencies = [ [[package]] name = "winit-orbital" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.13.0", "dpi", @@ -8726,7 +8620,6 @@ dependencies = [ [[package]] name = "winit-uikit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.13.0", "block2 0.6.2", @@ -8746,7 +8639,6 @@ dependencies = [ [[package]] name = "winit-wayland" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "ahash", "bitflags 2.13.0", @@ -8772,7 +8664,6 @@ dependencies = [ [[package]] name = "winit-web" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "atomic-waker", "bitflags 2.13.0", @@ -8794,7 +8685,6 @@ dependencies = [ [[package]] name = "winit-win32" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#f737f1f5900b3399b56951305b0f155afc9c9ee5" dependencies = [ "bitflags 2.13.0", "cursor-icon", @@ -8807,29 +8697,6 @@ 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#f737f1f5900b3399b56951305b0f155afc9c9ee5" -dependencies = [ - "bitflags 2.13.0", - "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.3" @@ -8860,39 +8727,6 @@ 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" @@ -9515,3 +9349,22 @@ dependencies = [ "syn", "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" From 8234e11ff381271f63eef8ce8378b59d6e6c068e Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Wed, 22 Jul 2026 15:56:59 +0200 Subject: [PATCH 107/110] chore: bump version to 1.3.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a6b6dde..eae37a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cosmic-files" -version = "1.2.0" +version = "1.3.0" authors = ["Jeremy Soller "] edition = "2024" license = "GPL-3.0-only" From 542657b557cbbf8e051cbead3a9bc24b86a17e5f Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Sat, 25 Jul 2026 22:20:51 +0200 Subject: [PATCH 108/110] chore: refresh Cargo.lock after version bump to 1.3.0 --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2936ed4..f39c221 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1373,7 +1373,7 @@ dependencies = [ [[package]] name = "cosmic-files" -version = "1.2.0" +version = "1.3.0" dependencies = [ "anyhow", "atomic_float", @@ -9350,6 +9350,10 @@ dependencies = [ "winnow", ] +[[patch.unused]] +name = "winit-x11" +version = "0.31.0-beta.2" + [[patch.unused]] name = "dnd" version = "0.1.0" @@ -9364,7 +9368,3 @@ source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x 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" From 30e562c8c2323c0b1cfd424d2bbb60e12ab2462f Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Sat, 25 Jul 2026 22:53:11 +0200 Subject: [PATCH 109/110] fix: nav_context_menu must produce one submenu per nav item The segmented_button widget asserts that context_menu children count matches model length. The yoda fork was building a single flat menu for the clicked item instead of iterating over all nav_model items like upstream, causing an assertion panic on right-click in the sidebar (trash, folders, etc.). Align with upstream: iterate self.nav_model.iter() and use menu::nav_context() instead of menu::items(). --- src/app.rs | 169 +++++++++++++++++++++++++++-------------------------- 1 file changed, 87 insertions(+), 82 deletions(-) diff --git a/src/app.rs b/src/app.rs index 0e572a0..ebd32d9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2833,94 +2833,99 @@ impl Application for App { fn nav_context_menu( &self, ) -> Option>>> { - let entity = self.nav_bar_context_id; - let favorite_index_opt = self.nav_model.data::(entity); - let location_opt = self.nav_model.data::(entity); + let items = self.nav_model.iter().map(|entity| { + let favorite_index_opt = self.nav_model.data::(entity); + let location_opt = self.nav_model.data::(entity); - let mut items = Vec::with_capacity(7); + let mut items = Vec::with_capacity(7); - if location_opt - .and_then(Location::path_opt) - .is_some_and(|x| x.is_file()) - { - items.push(cosmic::widget::menu::Item::Button( - fl!("open"), - None, - NavMenuAction::Open(entity), - )); - items.push(cosmic::widget::menu::Item::Button( - fl!("menu-open-with"), - None, - NavMenuAction::OpenWith(entity), - )); - } else { - items.push(cosmic::widget::menu::Item::Button( - fl!("open-in-new-tab"), - None, - NavMenuAction::OpenInNewTab(entity), - )); - items.push(cosmic::widget::menu::Item::Button( - fl!("open-in-new-window"), - None, - NavMenuAction::OpenInNewWindow(entity), - )); - } - if let Some(path) = location_opt.and_then(Location::path_opt) { - let selected_dir = usize::from(path.is_dir()); - let action_items: Vec<_> = self - .config - .context_actions - .iter() - .enumerate() - .filter(|(_, action)| action.matches_selection(1, selected_dir)) - .map(|(i, action)| { - cosmic::widget::menu::Item::Button( - action.name.clone(), - None, - NavMenuAction::RunContextAction(entity, i), - ) - }) - .collect(); - - if !action_items.is_empty() { - items.push(cosmic::widget::menu::Item::Divider); - items.extend(action_items); + if location_opt + .and_then(Location::path_opt) + .is_some_and(|x| x.is_file()) + { + items.push(cosmic::widget::menu::Item::Button( + fl!("open"), + None, + NavMenuAction::Open(entity), + )); + items.push(cosmic::widget::menu::Item::Button( + fl!("menu-open-with"), + None, + NavMenuAction::OpenWith(entity), + )); + } else { + items.push(cosmic::widget::menu::Item::Button( + fl!("open-in-new-tab"), + None, + NavMenuAction::OpenInNewTab(entity), + )); + items.push(cosmic::widget::menu::Item::Button( + fl!("open-in-new-window"), + None, + NavMenuAction::OpenInNewWindow(entity), + )); } - } - items.push(cosmic::widget::menu::Item::Divider); - if matches!(location_opt, Some(Location::Path(..))) { - items.push(cosmic::widget::menu::Item::Button( - fl!("show-details"), - None, - NavMenuAction::Preview(entity), - )); - } - items.push(cosmic::widget::menu::Item::Divider); - if favorite_index_opt.is_some() { - items.push(cosmic::widget::menu::Item::Button( - fl!("remove-from-sidebar"), - None, - NavMenuAction::RemoveFromSidebar(entity), - )); - } + if let Some(path) = location_opt.and_then(Location::path_opt) { + let selected_dir = usize::from(path.is_dir()); + let action_items: Vec<_> = self + .config + .context_actions + .iter() + .enumerate() + .filter(|(_, action)| action.matches_selection(1, selected_dir)) + .map(|(i, action)| { + cosmic::widget::menu::Item::Button( + action.name.clone(), + None, + NavMenuAction::RunContextAction(entity, i), + ) + }) + .collect(); - if matches!(location_opt, Some(Location::Recents)) && tab::has_recents() { - items.push(cosmic::widget::menu::Item::Button( - fl!("clear-recents-history"), - None, - NavMenuAction::ClearRecents, - )); - } + if !action_items.is_empty() { + items.push(cosmic::widget::menu::Item::Divider); + items.extend(action_items); + } + } + items.push(cosmic::widget::menu::Item::Divider); + if matches!(location_opt, Some(Location::Path(..))) { + items.push(cosmic::widget::menu::Item::Button( + fl!("show-details"), + None, + NavMenuAction::Preview(entity), + )); + } + items.push(cosmic::widget::menu::Item::Divider); + if favorite_index_opt.is_some() { + items.push(cosmic::widget::menu::Item::Button( + fl!("remove-from-sidebar"), + None, + NavMenuAction::RemoveFromSidebar(entity), + )); + } - if matches!(location_opt, Some(Location::Trash)) && !Trash::is_empty() { - items.push(cosmic::widget::menu::Item::Button( - fl!("empty-trash"), - None, - NavMenuAction::EmptyTrash, - )); - } + if matches!(location_opt, Some(Location::Recents)) && tab::has_recents() { + items.push(cosmic::widget::menu::Item::Button( + fl!("clear-recents-history"), + None, + NavMenuAction::ClearRecents, + )); + } - Some(cosmic::widget::menu::items(&HashMap::new(), items)) + if matches!(location_opt, Some(Location::Trash)) && !Trash::is_empty() { + items.push(cosmic::widget::menu::Item::Button( + fl!("empty-trash"), + None, + NavMenuAction::EmptyTrash, + )); + } + items + }); + + Some(cosmic::widget::menu::nav_context( + &HashMap::new(), + items.collect(), + )) } fn nav_model(&self) -> Option<&segmented_button::SingleSelectModel> { From 9e0c2726efb37b4116e782b51d5e637f114271a2 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Sat, 25 Jul 2026 22:54:15 +0200 Subject: [PATCH 110/110] feat: add empty-trash action to trash view context menu Right-clicking inside the trash view now shows 'Empty trash' when the trash is not empty, in addition to the existing per-item restore/delete actions and sort options. --- src/menu.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/menu.rs b/src/menu.rs index 0937595..8439655 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -418,6 +418,12 @@ pub fn context_menu<'a>( if tab.mode.multiple() { children.push(menu_item(fl!("select-all"), Action::SelectAll).into()); } + if !Trash::is_empty() { + if !children.is_empty() { + children.push(divider::horizontal::light().into()); + } + children.push(menu_item(fl!("empty-trash"), Action::EmptyTrash).into()); + } if !children.is_empty() { children.push(divider::horizontal::light().into()); }