feat: add "edit desktop entry" to the desktop file context menu

Opening a .desktop file launches the application it describes, so the
file manager offered no way to look at or change the file itself: the
only way out was a terminal. Reported upstream on 2025-05-11 and still
open.

Add an "Edit desktop entry" action to the context menu, next to the
entry own desktop actions. It opens the file with the default
text/plain handler instead of its application/x-desktop one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Lionel DARNIS 2026-08-19 20:42:34 +02:00
parent 9e0c2726ef
commit d78a22d87c
4 changed files with 37 additions and 0 deletions

View file

@ -342,6 +342,7 @@ extract-here = Extract
new-file = New file...
new-folder = New folder...
open-in-terminal = Open in terminal
edit-desktop-entry = Edit desktop entry
move-to = Move to...
move-to-trash = Move to trash
restore-from-trash = Restore from trash

View file

@ -349,6 +349,7 @@ extract-here = Extraire
new-file = Nouveau fichier...
new-folder = Nouveau dossier...
open-in-terminal = Ouvrir dans le terminal
edit-desktop-entry = Modifier le fichier .desktop
move-to-trash = Déplacer vers la corbeille
restore-from-trash = Restaurer depuis la corbeille
remove-from-sidebar = Supprimer de la barre latérale

View file

@ -247,6 +247,7 @@ pub enum Action {
CosmicSettingsWallpaper,
DesktopViewOptions,
Delete,
EditDesktopEntry,
EditHistory,
EditLocation,
Eject,
@ -320,6 +321,7 @@ impl Action {
Self::CosmicSettingsWallpaper => Message::CosmicSettings("wallpaper"),
Self::Delete => Message::Delete(entity_opt),
Self::DesktopViewOptions => Message::DesktopViewOptions,
Self::EditDesktopEntry => Message::EditDesktopEntry(entity_opt),
Self::EditHistory => Message::ToggleContextPage(ContextPage::EditHistory),
Self::EditLocation => Message::TabMessage(entity_opt, tab::Message::EditLocationEnable),
Self::Eject => Message::Eject,
@ -455,6 +457,7 @@ pub enum Message {
DesktopDialogs(bool),
DialogCancel,
DialogComplete,
EditDesktopEntry(Option<Entity>),
Eject,
FileDialogMessage(DialogMessage),
DialogPush(DialogPage, Option<widget::Id>),
@ -1060,6 +1063,21 @@ impl App {
}
}
/// Open paths with the default text editor, ignoring their own MIME type.
///
/// Desktop entries launch the application they describe when opened, so
/// `open_file` never shows the file itself. This gives the file manager a
/// way to edit one without falling back to a terminal.
fn edit_file(&self, paths: &[PathBuf]) -> Task<Message> {
let Ok(text_plain) = "text/plain".parse::<Mime>() else {
return Task::none();
};
if !self.launch_from_mime_cache(&text_plain, paths) {
log::warn!("no application registered for text/plain, cannot edit {paths:?}");
}
Task::none()
}
fn launch_from_mime_cache<P>(&self, mime: &Mime, paths: &[P]) -> bool
where
P: std::fmt::Debug + AsRef<Path> + AsRef<std::ffi::OsStr>,
@ -4114,6 +4132,21 @@ impl Application for App {
}
None => {}
},
Message::EditDesktopEntry(entity_opt) => {
let entity = entity_opt.unwrap_or_else(|| self.tab_model.active());
if let Some(tab) = self.tab_model.data::<Tab>(entity)
&& let Some(items) = tab.items_opt()
{
let paths: Vec<PathBuf> = items
.iter()
.filter(|item| item.selected)
.filter_map(|item| item.path_opt().cloned())
.collect();
if !paths.is_empty() {
return self.edit_file(&paths);
}
}
}
Message::OpenWithDialog(entity_opt) => {
let entity = entity_opt.unwrap_or_else(|| self.tab_model.active());
if let Some(tab) = self.tab_model.data::<Tab>(entity)

View file

@ -214,6 +214,8 @@ pub fn context_menu<'a>(
|(i, action)| menu_item(action.name, Action::ExecEntryAction(i)).into(),
));
}
children
.push(menu_item(fl!("edit-desktop-entry"), Action::EditDesktopEntry).into());
children.push(divider::horizontal::light().into());
children.push(menu_item(fl!("rename"), Action::Rename).into());
children.push(menu_item(fl!("cut"), Action::Cut).into());