Skip to content

Commit 4bc1285

Browse files
Improved desktop entry menu
Currently, desktop entries display a generic menu with items that aren't relevant to apps. This patch improves the menu by removing the unneeded items and listing desktop specific entries such as icons. Should compose well with pop-os/cosmic-applibrary#179
1 parent 1297d59 commit 4bc1285

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

src/app.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ pub enum Action {
9797
EditHistory,
9898
EditLocation,
9999
EmptyTrash,
100+
ExecEntryAction(usize),
100101
ExtractHere,
101102
Gallery,
102103
HistoryNext,
@@ -158,6 +159,9 @@ impl Action {
158159
}
159160
Action::EmptyTrash => Message::TabMessage(None, tab::Message::EmptyTrash),
160161
Action::ExtractHere => Message::ExtractHere(entity_opt),
162+
Action::ExecEntryAction(action) => {
163+
Message::TabMessage(entity_opt, tab::Message::ExecEntryAction(None, *action))
164+
}
161165
Action::Gallery => Message::TabMessage(entity_opt, tab::Message::GalleryToggle),
162166
Action::HistoryNext => Message::TabMessage(entity_opt, tab::Message::GoNext),
163167
Action::HistoryPrevious => Message::TabMessage(entity_opt, tab::Message::GoPrevious),
@@ -2639,6 +2643,9 @@ impl Application for App {
26392643
tab::Command::EmptyTrash => {
26402644
self.dialog_pages.push_back(DialogPage::EmptyTrash);
26412645
}
2646+
tab::Command::ExecEntryAction(entry, action) => {
2647+
self.exec_entry_action(entry, action);
2648+
}
26422649
tab::Command::Iced(iced_command) => {
26432650
commands.push(iced_command.0.map(move |tab_message| {
26442651
message::app(Message::TabMessage(Some(entity), tab_message))

src/menu.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use cosmic::{
1010
},
1111
Element,
1212
};
13+
use i18n_embed::LanguageLoader;
1314
use mime_guess::Mime;
1415
use std::collections::HashMap;
1516

@@ -86,6 +87,7 @@ pub fn context_menu<'a>(
8687
let mut selected_dir = 0;
8788
let mut selected = 0;
8889
let mut selected_trash_only = false;
90+
let mut selected_desktop_entry = None;
8991
let mut selected_types: Vec<Mime> = vec![];
9092
tab.items_opt().map(|items| {
9193
for item in items.iter() {
@@ -94,8 +96,16 @@ pub fn context_menu<'a>(
9496
if item.metadata.is_dir() {
9597
selected_dir += 1;
9698
}
97-
if item.location_opt == Some(Location::Trash) {
98-
selected_trash_only = true;
99+
match &item.location_opt {
100+
Some(Location::Trash) => selected_trash_only = true,
101+
Some(Location::Path(path)) => {
102+
if selected == 1
103+
&& path.extension().and_then(|s| s.to_str()) == Some("desktop")
104+
{
105+
selected_desktop_entry = Some(&**path);
106+
}
107+
}
108+
_ => (),
99109
}
100110
selected_types.push(item.mime.clone());
101111
}
@@ -104,6 +114,17 @@ pub fn context_menu<'a>(
104114
selected_types.sort_unstable();
105115
selected_types.dedup();
106116
selected_trash_only = selected_trash_only && selected == 1;
117+
// Parse the desktop entry if it is the only selection
118+
let selected_desktop_entry = selected_desktop_entry.and_then(|path| {
119+
if selected == 1 {
120+
let lang_id = crate::localize::LANGUAGE_LOADER.current_language();
121+
let language = lang_id.language.as_str();
122+
// Cache?
123+
cosmic::desktop::load_desktop_file(Some(language), path)
124+
} else {
125+
None
126+
}
127+
});
107128

108129
let mut children: Vec<Element<_>> = Vec::new();
109130
match (&tab.mode, &tab.location) {
@@ -116,6 +137,15 @@ pub fn context_menu<'a>(
116137
if tab::trash_entries() > 0 {
117138
children.push(menu_item(fl!("empty-trash"), Action::EmptyTrash).into());
118139
}
140+
} else if let Some(entry) = selected_desktop_entry {
141+
children.push(menu_item(fl!("open"), Action::Open).into());
142+
for (i, action) in entry.desktop_actions.into_iter().enumerate() {
143+
children.push(menu_item(action.name, Action::ExecEntryAction(i)).into())
144+
}
145+
children.push(divider::horizontal::light().into());
146+
children.push(menu_item(fl!("rename"), Action::Rename).into());
147+
// Should this simply bypass trash and remove the shortcut?
148+
children.push(menu_item(fl!("move-to-trash"), Action::MoveToTrash).into());
119149
} else if selected > 0 {
120150
if selected_dir == 1 && selected == 1 || selected_dir == 0 {
121151
children.push(menu_item(fl!("open"), Action::Open).into());

src/tab.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use cosmic::{
3838
};
3939

4040
use chrono::{DateTime, Utc};
41+
use i18n_embed::LanguageLoader;
4142
use mime_guess::{mime, Mime};
4243
use once_cell::sync::Lazy;
4344
use serde::{Deserialize, Serialize};
@@ -1005,6 +1006,7 @@ pub enum Command {
10051006
ChangeLocation(String, Location, Option<PathBuf>),
10061007
DropFiles(PathBuf, ClipboardPaste),
10071008
EmptyTrash,
1009+
ExecEntryAction(cosmic::desktop::DesktopEntryData, usize),
10081010
Iced(TaskWrapper),
10091011
MoveToTrash(Vec<PathBuf>),
10101012
OpenFile(PathBuf),
@@ -1034,6 +1036,7 @@ pub enum Message {
10341036
EditLocationEnable,
10351037
OpenInNewTab(PathBuf),
10361038
EmptyTrash,
1039+
ExecEntryAction(Option<PathBuf>, usize),
10371040
Gallery(bool),
10381041
GalleryPrevious,
10391042
GalleryNext,
@@ -2312,6 +2315,24 @@ impl Tab {
23122315
Message::EmptyTrash => {
23132316
commands.push(Command::EmptyTrash);
23142317
}
2318+
Message::ExecEntryAction(path, action) => {
2319+
let lang_id = crate::localize::LANGUAGE_LOADER.current_language();
2320+
let language = lang_id.language.as_str();
2321+
match path.map_or_else(
2322+
|| {
2323+
let items = self.items_opt.as_deref()?;
2324+
items.iter().find(|item| item.selected).and_then(|item| {
2325+
let location = item.location_opt.as_ref()?;
2326+
let path = location.path_opt()?;
2327+
cosmic::desktop::load_desktop_file(Some(language), path)
2328+
})
2329+
},
2330+
|path| cosmic::desktop::load_desktop_file(Some(language), path),
2331+
) {
2332+
Some(entry) => commands.push(Command::ExecEntryAction(entry, action)),
2333+
None => log::warn!("Invalid desktop entry path passed to ExecEntryAction"),
2334+
}
2335+
}
23152336
Message::Gallery(gallery) => {
23162337
self.gallery = gallery;
23172338
}

0 commit comments

Comments
 (0)