Calculate open with apps, when xdg feature is enabled

This commit is contained in:
Jeremy Soller 2024-03-01 13:20:47 -07:00
parent 88eb934564
commit 18e847abb8
No known key found for this signature in database
GPG key ID: D02FD439211AF56F
6 changed files with 208 additions and 33 deletions

130
Cargo.lock generated
View file

@ -1127,10 +1127,11 @@ dependencies = [
[[package]]
name = "cosmic-config"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"atomicwrites",
"cosmic-config-derive",
"dirs",
"dirs 5.0.1",
"iced_futures",
"known-folders",
"notify",
@ -1143,6 +1144,7 @@ dependencies = [
[[package]]
name = "cosmic-config-derive"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"quote",
"syn 1.0.109",
@ -1153,7 +1155,7 @@ name = "cosmic-files"
version = "0.1.0"
dependencies = [
"chrono",
"dirs",
"dirs 5.0.1",
"env_logger",
"fastrand 2.0.1",
"fork",
@ -1182,7 +1184,7 @@ dependencies = [
[[package]]
name = "cosmic-text"
version = "0.11.2"
source = "git+https://github.com/pop-os/cosmic-text.git#2766961af621b9235616e186046f6d14a2f5fbc0"
source = "git+https://github.com/pop-os/cosmic-text.git#22e61965aa38ab0bd64bbdddf3848ae891edceba"
dependencies = [
"bitflags 2.4.2",
"fontdb",
@ -1204,6 +1206,7 @@ dependencies = [
[[package]]
name = "cosmic-theme"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"almost",
"cosmic-config",
@ -1348,7 +1351,7 @@ version = "0.19.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=20fda69#20fda698341efbdc870b8027d6d49f5bf3f36109"
dependencies = [
"bitflags 2.4.2",
"libloading 0.8.1",
"libloading 0.8.2",
"winapi",
]
@ -1493,13 +1496,22 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "dirs"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309"
dependencies = [
"dirs-sys 0.3.7",
]
[[package]]
name = "dirs"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
dependencies = [
"dirs-sys",
"dirs-sys 0.4.1",
]
[[package]]
@ -1512,6 +1524,17 @@ dependencies = [
"dirs-sys-next",
]
[[package]]
name = "dirs-sys"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"
@ -1567,7 +1590,7 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
dependencies = [
"libloading 0.8.1",
"libloading 0.8.2",
]
[[package]]
@ -2021,13 +2044,26 @@ dependencies = [
"num",
]
[[package]]
name = "freedesktop-desktop-entry"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45157175a725e81f3f594382430b6b78af5f8f72db9bd51b94f0785f80fc6d29"
dependencies = [
"dirs 3.0.2",
"gettext-rs",
"memchr",
"thiserror",
"xdg",
]
[[package]]
name = "freedesktop-icons"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8ef34245e0540c9a3ce7a28340b98d2c12b75da0d446da4e8224923fcaa0c16"
dependencies = [
"dirs",
"dirs 5.0.1",
"once_cell",
"rust-ini",
"thiserror",
@ -2222,6 +2258,26 @@ dependencies = [
"wasi",
]
[[package]]
name = "gettext-rs"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e49ea8a8fad198aaa1f9655a2524b64b70eb06b2f3ff37da407566c93054f364"
dependencies = [
"gettext-sys",
"locale_config",
]
[[package]]
name = "gettext-sys"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c63ce2e00f56a206778276704bbe38564c8695249fdc8f354b4ef71c57c3839d"
dependencies = [
"cc",
"temp-dir",
]
[[package]]
name = "gif"
version = "0.11.4"
@ -2462,7 +2518,7 @@ dependencies = [
"bitflags 2.4.2",
"com",
"libc",
"libloading 0.8.1",
"libloading 0.8.2",
"thiserror",
"widestring",
"winapi",
@ -2594,6 +2650,7 @@ dependencies = [
[[package]]
name = "iced"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"iced_accessibility",
"iced_core",
@ -2608,6 +2665,7 @@ dependencies = [
[[package]]
name = "iced_accessibility"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"accesskit",
"accesskit_winit",
@ -2616,6 +2674,7 @@ dependencies = [
[[package]]
name = "iced_core"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"bitflags 1.3.2",
"log",
@ -2632,6 +2691,7 @@ dependencies = [
[[package]]
name = "iced_futures"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"futures",
"iced_core",
@ -2644,6 +2704,7 @@ dependencies = [
[[package]]
name = "iced_graphics"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"bitflags 1.3.2",
"bytemuck",
@ -2667,6 +2728,7 @@ dependencies = [
[[package]]
name = "iced_renderer"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"iced_graphics",
"iced_tiny_skia",
@ -2678,6 +2740,7 @@ dependencies = [
[[package]]
name = "iced_runtime"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"iced_core",
"iced_futures",
@ -2687,6 +2750,7 @@ dependencies = [
[[package]]
name = "iced_style"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"iced_core",
"once_cell",
@ -2696,6 +2760,7 @@ dependencies = [
[[package]]
name = "iced_tiny_skia"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"bytemuck",
"cosmic-text",
@ -2712,6 +2777,7 @@ dependencies = [
[[package]]
name = "iced_wgpu"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"bitflags 1.3.2",
"bytemuck",
@ -2730,6 +2796,7 @@ dependencies = [
[[package]]
name = "iced_widget"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"iced_renderer",
"iced_runtime",
@ -2743,6 +2810,7 @@ dependencies = [
[[package]]
name = "iced_winit"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"iced_graphics",
"iced_runtime",
@ -2995,7 +3063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76"
dependencies = [
"libc",
"libloading 0.8.1",
"libloading 0.8.2",
"pkg-config",
]
@ -3086,6 +3154,7 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libcosmic"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic.git#268b47d0002a5daa4cc50b124223737afe9a1dc5"
dependencies = [
"apply",
"ashpd",
@ -3094,6 +3163,7 @@ dependencies = [
"css-color",
"derive_setters",
"fraction",
"freedesktop-desktop-entry",
"freedesktop-icons",
"iced",
"iced_core",
@ -3106,8 +3176,11 @@ dependencies = [
"iced_widget",
"iced_winit",
"lazy_static",
"mime",
"nix 0.27.1",
"palette",
"rfd",
"shlex",
"slotmap",
"taffy",
"thiserror",
@ -3140,12 +3213,12 @@ dependencies = [
[[package]]
name = "libloading"
version = "0.8.1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
checksum = "2caa5afb8bf9f3a2652760ce7d4f62d21c4d5a423e68466fca30df82f2330164"
dependencies = [
"cfg-if 1.0.0",
"windows-sys 0.48.0",
"windows-targets 0.52.4",
]
[[package]]
@ -3578,6 +3651,17 @@ dependencies = [
"memoffset 0.7.1",
]
[[package]]
name = "nix"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
dependencies = [
"bitflags 2.4.2",
"cfg-if 1.0.0",
"libc",
]
[[package]]
name = "nom"
version = "5.1.3"
@ -4797,6 +4881,12 @@ dependencies = [
"digest",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook-registry"
version = "1.4.1"
@ -5113,6 +5203,12 @@ version = "0.12.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
[[package]]
name = "temp-dir"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd16aa9ffe15fe021c6ee3766772132c6e98dfa395a167e16864f61a9cfb71d6"
[[package]]
name = "tempfile"
version = "3.10.1"
@ -5273,7 +5369,7 @@ checksum = "d4098d49269baa034a8d1eae9bd63e9fa532148d772121dace3bcd6a6c98eb6d"
dependencies = [
"as-raw-xcb-connection",
"ctor",
"libloading 0.8.1",
"libloading 0.8.2",
"tracing",
]
@ -5683,9 +5779,9 @@ checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690"
[[package]]
name = "walkdir"
version = "2.4.0"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
@ -6058,7 +6154,7 @@ dependencies = [
"js-sys",
"khronos-egl",
"libc",
"libloading 0.8.1",
"libloading 0.8.2",
"log",
"metal",
"naga",
@ -6515,7 +6611,7 @@ dependencies = [
"as-raw-xcb-connection",
"gethostname",
"libc",
"libloading 0.8.1",
"libloading 0.8.2",
"once_cell",
"rustix 0.38.31",
"x11rb-protocol",

View file

@ -46,7 +46,8 @@ features = ["serde"]
git = "https://github.com/jackpot51/systemicons"
[features]
default = ["wgpu"]
default = ["xdg", "wgpu"]
xdg = ["libcosmic/desktop"]
wgpu = ["libcosmic/wgpu"]
[profile.release-with-debug]

View file

@ -20,6 +20,8 @@ mod mime_icon;
mod mouse_area;
mod operation;
mod tab;
#[cfg(feature = "xdg")]
mod xdg;
pub fn home_dir() -> PathBuf {
match dirs::home_dir() {

View file

@ -32,6 +32,8 @@ use std::{
time::{Duration, Instant},
};
#[cfg(feature = "xdg")]
use crate::xdg::{mime_apps, DesktopEntryData};
use crate::{
app::Action,
config::{IconSizes, TabConfig},
@ -261,6 +263,11 @@ pub fn scan_path(tab_path: &PathBuf, sizes: IconSizes) -> Vec<Item> {
icon_handle_grid,
icon_handle_list,
icon_handle_list_condensed,
#[cfg(feature = "xdg")]
open_with: mime_guess
.first()
.map(|mime| mime_apps(&mime))
.unwrap_or_default(),
thumbnail_res_opt: match mime_guess.first() {
Some(mime) if mime.type_() == "image" => None,
_ => Some(Err(())),
@ -295,7 +302,7 @@ pub fn scan_path(tab_path: &PathBuf, sizes: IconSizes) -> Vec<Item> {
not(target_os = "android")
)
)))]
pub fn scan_trash() -> Vec<Item> {
pub fn scan_trash(_sizes: IconSizes) -> Vec<Item> {
log::warn!("viewing trash not supported on this platform");
Vec::new()
}
@ -351,6 +358,8 @@ pub fn scan_trash(sizes: IconSizes) -> Vec<Item> {
icon_handle_grid,
icon_handle_list,
icon_handle_list_condensed,
#[cfg(feature = "xdg")]
open_with: Vec::new(),
thumbnail_res_opt: Some(Err(())),
button_id: widget::Id::unique(),
pos_opt: Cell::new(None),
@ -458,6 +467,8 @@ pub struct Item {
pub icon_handle_grid: widget::icon::Handle,
pub icon_handle_list: widget::icon::Handle,
pub icon_handle_list_condensed: widget::icon::Handle,
#[cfg(feature = "xdg")]
pub open_with: Vec<DesktopEntryData>,
pub thumbnail_res_opt: Option<Result<image::RgbaImage, ()>>,
pub button_id: widget::Id,
pub pos_opt: Cell<Option<(usize, usize)>>,
@ -544,20 +555,22 @@ impl Item {
impl fmt::Debug for Item {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Item")
.field("name", &self.name)
.field("metadata", &self.metadata)
.field("hidden", &self.hidden)
.field("path", &self.path)
.field("mime_guess", &self.mime_guess)
// icon_handles
// thumbnail_res_opt
.field("button_id", &self.button_id)
.field("pos_opt", &self.pos_opt)
.field("rect_opt", &self.rect_opt)
.field("selected", &self.selected)
.field("click_time", &self.click_time)
.finish()
let mut d = f.debug_struct("Item");
d.field("name", &self.name);
d.field("metadata", &self.metadata);
d.field("hidden", &self.hidden);
d.field("path", &self.path);
d.field("mime_guess", &self.mime_guess);
// icon_handles
#[cfg(feature = "xdg")]
d.field("open_with", &self.open_with);
// thumbnail_res_opt
d.field("button_id", &self.button_id);
d.field("pos_opt", &self.pos_opt);
d.field("rect_opt", &self.rect_opt);
d.field("selected", &self.selected);
d.field("click_time", &self.click_time);
d.finish()
}
}

58
src/xdg/mime_app.rs Normal file
View file

@ -0,0 +1,58 @@
// Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only
pub use cosmic::desktop::DesktopEntryData;
use cosmic::desktop::{load_applications, Mime};
use once_cell::sync::Lazy;
use std::{collections::HashMap, sync::Mutex, time::Instant};
pub struct MimeAppCache {
cache: HashMap<Mime, Vec<DesktopEntryData>>,
empty: Vec<DesktopEntryData>,
}
impl MimeAppCache {
pub fn new() -> Self {
let mut mime_app_cache = Self {
cache: HashMap::new(),
empty: Vec::new(),
};
mime_app_cache.reload();
mime_app_cache
}
pub fn reload(&mut self) {
let start = Instant::now();
self.cache.clear();
//TODO: get proper locale?
let locale = None;
for app in load_applications(locale, false) {
for mime_type in app.mime_types.iter() {
self.cache
.entry(mime_type.clone())
.or_insert_with(|| Vec::with_capacity(1))
.push(app.clone());
}
}
for apps in self.cache.values_mut() {
apps.sort_by(|a, b| lexical_sort::natural_lexical_cmp(&a.name, &b.name));
}
let elapsed = start.elapsed();
log::info!("loaded mime app cache in {:?}", elapsed);
}
pub fn get(&self, key: &Mime) -> &Vec<DesktopEntryData> {
self.cache.get(&key).unwrap_or_else(|| &self.empty)
}
}
static MIME_APP_CACHE: Lazy<Mutex<MimeAppCache>> = Lazy::new(|| Mutex::new(MimeAppCache::new()));
pub fn mime_apps(mime: &Mime) -> Vec<DesktopEntryData> {
let mime_app_cache = MIME_APP_CACHE.lock().unwrap();
mime_app_cache.get(mime).clone()
}

5
src/xdg/mod.rs Normal file
View file

@ -0,0 +1,5 @@
// Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only
pub mod mime_app;
pub use mime_app::*;