Index: gnome-shell-extensions-3.33.91/extensions/apps-menu/extension.js =================================================================== --- gnome-shell-extensions-3.33.91.orig/extensions/apps-menu/extension.js +++ gnome-shell-extensions-3.33.91/extensions/apps-menu/extension.js @@ -5,6 +5,8 @@ const { Atk, Clutter, Gio, GLib, GMenu, GObject, Gtk, Meta, Shell, St, } = imports.gi; const Signals = imports.signals; +const BoxPointer = imports.ui.boxpointer; +const AppFavorites = imports.ui.appFavorites; const DND = imports.ui.dnd; const ExtensionUtils = imports.misc.extensionUtils; @@ -46,8 +48,19 @@ class ApplicationMenuItem extends PopupM let textureCache = St.TextureCache.get_default(); let iconThemeChangedId = textureCache.connect('icon-theme-changed', this._updateIcon.bind(this)); + + this.actor.connect('button-press-event', this._onButtonPress.bind(this)); + this.actor.connect('popup-menu', this._onKeyboardPopupMenu.bind(this)); + this._menu = null; + this._menuManager = new PopupMenu.PopupMenuManager(this); + this.connect('destroy', () => { textureCache.disconnect(iconThemeChangedId); + if (this._menu) { + this._menu.destroy(); + this._menu = null; + this._menuManager = null; + } }); this._updateIcon(); @@ -62,6 +75,106 @@ class ApplicationMenuItem extends PopupM }; } + _onKeyboardPopupMenu() { + this.popupMenu(); + this._menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); + } + + _onButtonPress(actor, event) { + // close any opened menu to avoid input focus grab + if (this._menu && this._menu.isOpen) { + this._menu.close(); + return; + } + + let button = event.get_button(); + if (button == 3) { + this.popupMenu(); + return true; + } + return false; + } + + popupMenu() { + if (!this._menu) { + this._menu = new PopupMenu.PopupMenu(this.actor, 0.0, St.Side.TOP, 0); + let openItem = new PopupMenu.PopupMenuItem(_("Open")); + this._menu.addMenuItem(openItem); + openItem.connect('activate', () => { + this._app.open_new_window(-1); + this._button.selectCategory(null, null); + this._button.menu.toggle(); + }); + + let sepItem = new PopupMenu.PopupSeparatorMenuItem(); + this._menu.addMenuItem(sepItem); + + let isFavorite = AppFavorites.getAppFavorites().isFavorite(this._app.get_id()); + let favText = null; + if (isFavorite) + favText = _("Remove from Favorites"); + else + favText = _("Add to Favorites"); + + let favItem = new PopupMenu.PopupMenuItem(favText); + this._menu.addMenuItem(favItem); + favItem.connect('activate', () => { + let favs = AppFavorites.getAppFavorites(); + let isFavorite = favs.isFavorite(this._app.get_id()); + if (isFavorite) + favs.removeFavorite(this._app.get_id()); + else + favs.addFavorite(this._app.get_id()); + + /*As the item text changes, we need to re-generate the menu */ + this._menu.destroy(); + this._menu = null; + + this._button.selectCategory(null, null); + this._button.menu.toggle(); + }); + + let desktopItem = new PopupMenu.PopupMenuItem(_("Add to Desktop")); + this._menu.addMenuItem(desktopItem); + desktopItem.connect('activate', () => { + let desktopApp = this._app.get_app_info(); + let sourcePath = desktopApp.get_filename(); + let sourceFile = Gio.File.new_for_path(sourcePath); + let destDirPath = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP); + let destDir = Gio.File.new_for_path(destDirPath); + + if (!destDir.query_exists(null)) { + destDirPath = Glib.build_filenamev([GLib.get_home_dir(), "Desktop"]); + } + let destFile = Gio.File.new_for_path(destDirPath + '/' + sourceFile.get_basename()); + if (sourceFile.copy(destFile, Gio.FileCopyFlags.OVERWRITE, + null, null, null)) { + // In order to make the general monitor recognize the setting of metadata, + // this function call should before the setting of unix mode. + destFile.set_attribute_string("metadata::trusted", + "yes", + Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, + null); + destFile.set_attribute_uint32( + Gio.FILE_ATTRIBUTE_UNIX_MODE, parseInt("0755", 8), + Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, + null); + } + this._button.selectCategory(null, null); + this._button.menu.toggle(); + }); + + Main.uiGroup.add_actor(this._menu.actor); + + this._menuManager.addMenu(this._menu); + } + + this._menu.open(BoxPointer.PopupAnimation.NONE); + this._menuManager.ignoreRelease(); + + return false; + } + activate(event) { this._app.open_new_window(-1); this._button.selectCategory(null);