From 6921cb045d63c0541775f95b74b0c46978ed2843 Mon Sep 17 00:00:00 2001 From: carsten Date: Tue, 20 Jan 2026 23:26:21 +0100 Subject: [PATCH] FIX: Restore "Open with" context menu for recent/favorite files The "Open with" functionality was lost when commit d1ea12a27 ("menu: Simplify path buttons") refactored RecentButton/FavoriteButton into the generic PathButton class. This fix adds context menu support to PathButton: - Enable withMenu for type='recent' and type='favorite' - Add populateMenu() method with "Open with" functionality - Add hasLocalPath() helper for URI validation The menu provides: - Default application option - List of compatible applications - "Other application..." (launches nemo-open-with) Fixes: linuxmint/cinnamon#13440 --- .../applets/menu@cinnamon.org/applet.js | 61 ++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js b/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js index e2d290d0d9..967df1c6b6 100644 --- a/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js +++ b/files/usr/share/cinnamon/applets/menu@cinnamon.org/applet.js @@ -795,7 +795,7 @@ class PathButton extends SimpleMenuItem { description: shorten_path(uri, name), type: type, styleClass: 'appmenu-application-button', - withMenu: false, + withMenu: (type === 'recent' || type === 'favorite'), uri: uri, }); @@ -827,6 +827,65 @@ class PathButton extends SimpleMenuItem { source.notify(notification); } } + + hasLocalPath(file) { + return file.is_native() || file.get_path() != null; + } + + populateMenu(menu) { + if (this.type !== 'recent' && this.type !== 'favorite') + return; + + let menuItem; + menuItem = new PopupMenu.PopupMenuItem(_("Open with"), { reactive: false }); + menuItem.actor.style = "font-weight: bold"; + menu.addMenuItem(menuItem); + + let file = Gio.File.new_for_uri(this.uri); + let mimeType = Gio.content_type_guess(this.uri, null)[0]; + + let default_info = Gio.AppInfo.get_default_for_type(mimeType, !this.hasLocalPath(file)); + + if (default_info) { + menuItem = new PopupMenu.PopupMenuItem(default_info.get_display_name()); + menuItem.connect('activate', () => { + default_info.launch([file], null); + this.applet.toggleContextMenu(this); + this.applet.menu.close(); + }); + menu.addMenuItem(menuItem); + } + + let infos = Gio.AppInfo.get_all_for_type(mimeType); + + for (let i = 0; i < infos.length; i++) { + let info = infos[i]; + + if (!this.hasLocalPath(file) && !info.supports_uris()) + continue; + + if (info.equal(default_info)) + continue; + + menuItem = new PopupMenu.PopupMenuItem(info.get_display_name()); + menuItem.connect('activate', () => { + info.launch([file], null); + this.applet.toggleContextMenu(this); + this.applet.menu.close(); + }); + menu.addMenuItem(menuItem); + } + + if (GLib.find_program_in_path("nemo-open-with") != null) { + menuItem = new PopupMenu.PopupMenuItem(_("Other application...")); + menuItem.connect('activate', () => { + Util.spawnCommandLine("nemo-open-with " + this.uri); + this.applet.toggleContextMenu(this); + this.applet.menu.close(); + }); + menu.addMenuItem(menuItem); + } + } } class CategoryButton extends SimpleMenuItem {