Index: gnome-shell-extensions-3.20.0/extensions/apps-menu/extension.js =================================================================== --- gnome-shell-extensions-3.20.0.orig/extensions/apps-menu/extension.js +++ gnome-shell-extensions-3.20.0/extensions/apps-menu/extension.js @@ -6,10 +6,13 @@ const Lang = imports.lang; const Shell = imports.gi.Shell; const St = imports.gi.St; const Clutter = imports.gi.Clutter; +const BoxPointer = imports.ui.boxpointer; +const AppFavorites = imports.ui.appFavorites; const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; const Gtk = imports.gi.Gtk; +const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const Signals = imports.signals; const Pango = imports.gi.Pango; @@ -65,13 +68,118 @@ const ApplicationMenuItem = new Lang.Cla let textureCache = St.TextureCache.get_default(); let iconThemeChangedId = textureCache.connect('icon-theme-changed', Lang.bind(this, this._updateIcon)); + + this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress)); + this.actor.connect('popup-menu', Lang.bind(this, this._onKeyboardPopupMenu)); + this._menu = null; + this._menuManager = new PopupMenu.PopupMenuManager(this); + this.actor.connect('destroy', Lang.bind(this, function() { textureCache.disconnect(iconThemeChangedId); + if (this._menu) { + this._menu.destroy(); + this._menu = null; + this._menuManager = null; + } })); this._updateIcon(); }, + _onKeyboardPopupMenu: function() { + this.popupMenu(); + this._menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false); + }, + + _onButtonPress: function(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: function() { + 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', Lang.bind(this, function() { + 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', Lang.bind(this, function() { + 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', Lang.bind(this, function() { + 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)) { + destFile.set_attribute_uint32( + Gio.FILE_ATTRIBUTE_UNIX_MODE, 0755, + 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: function(event) { this._app.open_new_window(-1); this._button.selectCategory(null, null);