Merge pull request #792 from ellieplayswow/feature/open-with-subclasses
Adding in new functionality to open / open-with MIME subclasses
This commit is contained in:
commit
7be1be885d
4 changed files with 73 additions and 5 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
|
@ -7546,8 +7546,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "xdg-mime"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58d325d0ca93fb1984a56eb926f019acfc67bd2ec559b0dbf09cafcc92e81ec9"
|
||||
source = "git+https://github.com/ellieplayswow/xdg-mime-rs?branch=feature/get-same-as#4f8d07ceedabbe58368a8e7f5547232490860790"
|
||||
dependencies = [
|
||||
"dirs-next",
|
||||
"glob",
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ url = "2.5"
|
|||
walkdir = "2.5.0"
|
||||
wayland-client = { version = "0.31.8", optional = true }
|
||||
xdg = { version = "2.5.2", optional = true }
|
||||
xdg-mime = "0.4"
|
||||
xdg-mime = "0.4.0"
|
||||
# Compression
|
||||
bzip2 = { version = "0.5", optional = true } #TODO: replace with pure Rust crate
|
||||
flate2 = "1.0"
|
||||
|
|
@ -96,6 +96,8 @@ tokio = { version = "1", features = ["rt", "macros"] }
|
|||
[patch.crates-io]
|
||||
# https://github.com/alexcrichton/filetime/pull/104
|
||||
filetime = { git = "https://github.com/jackpot51/filetime" }
|
||||
# https://github.com/ebassi/xdg-mime-rs/pull/31
|
||||
xdg-mime = { git = "https://github.com/ellieplayswow/xdg-mime-rs", branch = "feature/get-same-as" }
|
||||
|
||||
# [patch.'https://github.com/pop-os/cosmic-text']
|
||||
# cosmic-text = { path = "../cosmic-text" }
|
||||
|
|
|
|||
65
src/app.rs
65
src/app.rs
|
|
@ -15,6 +15,7 @@ use cosmic::iced::{
|
|||
};
|
||||
#[cfg(feature = "wayland")]
|
||||
use cosmic::iced_winit::commands::overlap_notify::overlap_notify;
|
||||
use cosmic::widget::{Button, ListColumn};
|
||||
use cosmic::{
|
||||
app::{self, context_drawer, message, Core, Task},
|
||||
cosmic_config, cosmic_theme, executor,
|
||||
|
|
@ -41,6 +42,7 @@ use cosmic::{
|
|||
},
|
||||
Application, ApplicationExt, Element,
|
||||
};
|
||||
use mime_guess::Mime;
|
||||
use notify_debouncer_full::{
|
||||
new_debouncer,
|
||||
notify::{self, RecommendedWatcher, Watcher},
|
||||
|
|
@ -62,6 +64,7 @@ use trash::TrashItem;
|
|||
#[cfg(feature = "wayland")]
|
||||
use wayland_client::{protocol::wl_output::WlOutput, Proxy};
|
||||
|
||||
use crate::mime_app::MimeApp;
|
||||
use crate::operation::{OperationError, OperationErrorType};
|
||||
use crate::{
|
||||
clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste},
|
||||
|
|
@ -560,6 +563,7 @@ pub struct App {
|
|||
impl App {
|
||||
fn open_file(&mut self, path: &PathBuf) {
|
||||
let mime = mime_icon::mime_for_path(path);
|
||||
|
||||
if mime == "application/x-desktop" {
|
||||
// Try opening desktop application
|
||||
match freedesktop_entry_parser::parse_entry(path) {
|
||||
|
|
@ -627,6 +631,31 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
// loop through subclasses if available
|
||||
if let Some(mime_sub_classes) = mime_icon::parent_mime_types(&mime) {
|
||||
for sub_class in mime_sub_classes {
|
||||
for app in self.mime_app_cache.get(&sub_class) {
|
||||
let Some(mut command) = app.command(Some(path.clone().into())) else {
|
||||
continue;
|
||||
};
|
||||
match spawn_detached(&mut command) {
|
||||
Ok(()) => {
|
||||
let _ = recently_used_xbel::update_recently_used(
|
||||
path,
|
||||
App::APP_ID.to_string(),
|
||||
"cosmic-files".to_string(),
|
||||
None,
|
||||
);
|
||||
return;
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("failed to open {:?} with {:?}: {}", path, app.id, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to using open crate
|
||||
match open::that_detached(path) {
|
||||
Ok(()) => {
|
||||
|
|
@ -1567,6 +1596,36 @@ impl App {
|
|||
.into()
|
||||
}
|
||||
|
||||
fn get_programs_for_mime(&self, mime_type: &Mime) -> Vec<&MimeApp> {
|
||||
let mut results = Vec::new();
|
||||
|
||||
let mut dedupe = HashSet::new();
|
||||
|
||||
// start with exact matches
|
||||
for mime_app in self.mime_app_cache.get(mime_type) {
|
||||
let app_id = &mime_app.id;
|
||||
if !dedupe.contains(app_id) {
|
||||
results.push(mime_app);
|
||||
dedupe.insert(app_id);
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
for mime_app in self.mime_app_cache.get(&parent_type) {
|
||||
let app_id = &mime_app.id;
|
||||
if !dedupe.contains(app_id) {
|
||||
results.push(mime_app);
|
||||
dedupe.insert(app_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results
|
||||
}
|
||||
|
||||
// Update favorites based on renaming or moving dirs.
|
||||
fn update_favorites(&mut self, path_changes: &[(PathBuf, PathBuf)]) -> bool {
|
||||
let mut favorites_changed = false;
|
||||
|
|
@ -2187,7 +2246,9 @@ impl Application for App {
|
|||
selected,
|
||||
..
|
||||
} => {
|
||||
if let Some(app) = self.mime_app_cache.get(&mime).get(selected) {
|
||||
let all_apps = self.get_programs_for_mime(&mime);
|
||||
|
||||
if let Some(app) = all_apps.get(selected) {
|
||||
if let Some(mut command) = app.command(Some(path.clone().into())) {
|
||||
match spawn_detached(&mut command) {
|
||||
Ok(()) => {
|
||||
|
|
@ -4229,7 +4290,7 @@ impl Application for App {
|
|||
};
|
||||
|
||||
let mut column = widget::list_column();
|
||||
for (i, app) in self.mime_app_cache.get(mime).iter().enumerate() {
|
||||
for (i, app) in self.get_programs_for_mime(&mime).iter().enumerate() {
|
||||
column = column.add(
|
||||
widget::button::custom(
|
||||
widget::row::with_children(vec![
|
||||
|
|
|
|||
|
|
@ -73,3 +73,9 @@ pub fn mime_icon(mime: Mime, size: u16) -> icon::Handle {
|
|||
None => icon::from_name(FALLBACK_MIME_ICON).size(size).handle(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parent_mime_types(mime: &Mime) -> Option<Vec<Mime>> {
|
||||
let mut mime_icon_cache = MIME_ICON_CACHE.lock().unwrap();
|
||||
|
||||
mime_icon_cache.shared_mime_info.get_parents_aliased(mime)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue