mirror of
https://github.com/morgan9e/dash-to-panel
synced 2026-04-14 00:04:17 +09:00
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
UUID = dash-to-panel@jderose9.github.com
|
UUID = dash-to-panel@jderose9.github.com
|
||||||
BASE_MODULES = extension.js stylesheet.css metadata.json COPYING README.md
|
BASE_MODULES = extension.js stylesheet.css metadata.json COPYING README.md
|
||||||
EXTRA_MODULES = appIcons.js convenience.js panel.js panelStyle.js overview.js taskbar.js secondaryMenu.js windowPreview.js prefs.js Settings.ui
|
EXTRA_MODULES = appIcons.js convenience.js panel.js panelStyle.js overview.js taskbar.js windowPreview.js prefs.js Settings.ui
|
||||||
EXTRA_IMAGES = highlight_bg.svg highlight_stacked_bg.svg
|
EXTRA_IMAGES = highlight_bg.svg highlight_stacked_bg.svg
|
||||||
TOLOCALIZE = prefs.js
|
TOLOCALIZE = prefs.js
|
||||||
MSGSRC = $(wildcard po/*.po)
|
MSGSRC = $(wildcard po/*.po)
|
||||||
|
|||||||
327
appIcons.js
327
appIcons.js
@@ -40,13 +40,13 @@ const DND = imports.ui.dnd;
|
|||||||
const IconGrid = imports.ui.iconGrid;
|
const IconGrid = imports.ui.iconGrid;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
const PopupMenu = imports.ui.popupMenu;
|
||||||
|
const RemoteMenu = imports.ui.remoteMenu;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
const Util = imports.misc.util;
|
const Util = imports.misc.util;
|
||||||
const Workspace = imports.ui.workspace;
|
const Workspace = imports.ui.workspace;
|
||||||
|
|
||||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||||
const Convenience = Me.imports.convenience;
|
const Convenience = Me.imports.convenience;
|
||||||
const SecondaryMenu = Me.imports.secondaryMenu;
|
|
||||||
const WindowPreview = Me.imports.windowPreview;
|
const WindowPreview = Me.imports.windowPreview;
|
||||||
const Taskbar = Me.imports.taskbar;
|
const Taskbar = Me.imports.taskbar;
|
||||||
|
|
||||||
@@ -302,7 +302,7 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
this._draggable.fakeRelease();
|
this._draggable.fakeRelease();
|
||||||
|
|
||||||
if (!this._menu) {
|
if (!this._menu) {
|
||||||
this._menu = new SecondaryMenu.taskbarSecondaryMenu(this, this._dtpSettings);
|
this._menu = new taskbarSecondaryMenu(this, this._dtpSettings);
|
||||||
this._menu.connect('activate-window', Lang.bind(this, function (menu, window) {
|
this._menu.connect('activate-window', Lang.bind(this, function (menu, window) {
|
||||||
this.activateWindow(window, this._dtpSettings);
|
this.activateWindow(window, this._dtpSettings);
|
||||||
}));
|
}));
|
||||||
@@ -842,8 +842,233 @@ function getInterestingWindows(app, settings) {
|
|||||||
return windows;
|
return windows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend AppIconMenu
|
||||||
|
*
|
||||||
|
* - set popup arrow side based on taskbar orientation
|
||||||
|
* - Add close windows option based on quitfromdash extension
|
||||||
|
* (https://github.com/deuill/shell-extension-quitfromdash)
|
||||||
|
*/
|
||||||
|
|
||||||
// define first this function to use it in extendDashItemContainer
|
const taskbarSecondaryMenu = new Lang.Class({
|
||||||
|
Name: 'DashToPanel.SecondaryMenu',
|
||||||
|
Extends: AppDisplay.AppIconMenu,
|
||||||
|
|
||||||
|
_init: function(source, settings) {
|
||||||
|
this._dtpSettings = settings;
|
||||||
|
|
||||||
|
let side = Taskbar.getPosition();
|
||||||
|
|
||||||
|
// Damm it, there has to be a proper way of doing this...
|
||||||
|
// As I can't call the parent parent constructor (?) passing the side
|
||||||
|
// parameter, I overwite what I need later
|
||||||
|
this.parent(source);
|
||||||
|
|
||||||
|
// Change the initialized side where required.
|
||||||
|
this._arrowSide = side;
|
||||||
|
this._boxPointer._arrowSide = side;
|
||||||
|
this._boxPointer._userArrowSide = side;
|
||||||
|
},
|
||||||
|
|
||||||
|
// helper function for the quit windows abilities
|
||||||
|
_closeWindowInstance: function(metaWindow) {
|
||||||
|
metaWindow.delete(global.get_current_time());
|
||||||
|
},
|
||||||
|
|
||||||
|
_redisplay: function() {
|
||||||
|
this.removeAll();
|
||||||
|
|
||||||
|
let appMenu = this._source.app.menu;
|
||||||
|
if(appMenu) {
|
||||||
|
let remoteMenu = new RemoteMenu.RemoteMenu(this._source.actor, this._source.app.menu, this._source.app.action_group);
|
||||||
|
let appMenuItems = remoteMenu._getMenuItems();
|
||||||
|
let isItemsAdded = false;
|
||||||
|
for(let appMenuIdx in appMenuItems){
|
||||||
|
let menuItem = appMenuItems[appMenuIdx];
|
||||||
|
let labelText = menuItem.actor.label_actor.text;
|
||||||
|
if(labelText == _("New Window") || labelText == _("Quit"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(menuItem instanceof PopupMenu.PopupSeparatorMenuItem)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
isItemsAdded = true;
|
||||||
|
|
||||||
|
// this ends up getting called multiple times, and bombing due to the signal id's being invalid
|
||||||
|
// on a 2nd pass. disconnect the base handler and attach our own that wraps the id's in if statements
|
||||||
|
menuItem.disconnect(menuItem._popupMenuDestroyId)
|
||||||
|
menuItem._popupMenuDestroyId = menuItem.connect('destroy', Lang.bind(this, function(menuItem) {
|
||||||
|
if(menuItem._popupMenuDestroyId) {
|
||||||
|
menuItem.disconnect(menuItem._popupMenuDestroyId);
|
||||||
|
menuItem._popupMenuDestroyId = 0;
|
||||||
|
}
|
||||||
|
if(menuItem._activateId) {
|
||||||
|
menuItem.disconnect(menuItem._activateId);
|
||||||
|
menuItem._activateId = 0;
|
||||||
|
}
|
||||||
|
if(menuItem._activeChangeId) {
|
||||||
|
menuItem.disconnect(menuItem._activeChangeId);
|
||||||
|
menuItem._activeChangeId = 0;
|
||||||
|
}
|
||||||
|
if(menuItem._sensitiveChangeId) {
|
||||||
|
menuItem.disconnect(menuItem._sensitiveChangeId);
|
||||||
|
menuItem._sensitiveChangeId = 0;
|
||||||
|
}
|
||||||
|
this.disconnect(menuItem._parentSensitiveChangeId);
|
||||||
|
if (menuItem == this._activeMenuItem)
|
||||||
|
this._activeMenuItem = null;
|
||||||
|
}));
|
||||||
|
|
||||||
|
menuItem.actor.get_parent().remove_child(menuItem.actor);
|
||||||
|
if(menuItem instanceof PopupMenu.PopupSubMenuMenuItem) {
|
||||||
|
let newSubMenuMenuItem = new PopupMenu.PopupSubMenuMenuItem(labelText);
|
||||||
|
let appSubMenuItems = menuItem.menu._getMenuItems();
|
||||||
|
for(let appSubMenuIdx in appSubMenuItems){
|
||||||
|
let subMenuItem = appSubMenuItems[appSubMenuIdx];
|
||||||
|
subMenuItem.actor.get_parent().remove_child(subMenuItem.actor);
|
||||||
|
newSubMenuMenuItem.menu.addMenuItem(subMenuItem);
|
||||||
|
}
|
||||||
|
this.addMenuItem(newSubMenuMenuItem);
|
||||||
|
} else
|
||||||
|
this.addMenuItem(menuItem);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isItemsAdded)
|
||||||
|
this._appendSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
let windows = this._source.app.get_windows().filter(function(w) {
|
||||||
|
return !w.skip_taskbar;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Display the app windows menu items and the separator between windows
|
||||||
|
// of the current desktop and other windows.
|
||||||
|
let activeWorkspace = global.screen.get_active_workspace();
|
||||||
|
let separatorShown = windows.length > 0 && windows[0].get_workspace() != activeWorkspace;
|
||||||
|
|
||||||
|
for (let i = 0; i < windows.length; i++) {
|
||||||
|
let window = windows[i];
|
||||||
|
if (!separatorShown && window.get_workspace() != activeWorkspace) {
|
||||||
|
this._appendSeparator();
|
||||||
|
separatorShown = true;
|
||||||
|
}
|
||||||
|
let item = this._appendMenuItem(window.title);
|
||||||
|
item.connect('activate', Lang.bind(this, function() {
|
||||||
|
this.emit('activate-window', window);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._source.app.is_window_backed()) {
|
||||||
|
this._appendSeparator();
|
||||||
|
|
||||||
|
let appInfo = this._source.app.get_app_info();
|
||||||
|
let actions = appInfo.list_actions();
|
||||||
|
if (this._source.app.can_open_new_window() &&
|
||||||
|
actions.indexOf('new-window') == -1) {
|
||||||
|
this._newWindowMenuItem = this._appendMenuItem(_("New Window"));
|
||||||
|
this._newWindowMenuItem.connect('activate', Lang.bind(this, function() {
|
||||||
|
if (this._source.app.state == Shell.AppState.STOPPED)
|
||||||
|
this._source.animateLaunch();
|
||||||
|
|
||||||
|
this._source.app.open_new_window(-1);
|
||||||
|
this.emit('activate-window', null);
|
||||||
|
}));
|
||||||
|
this._appendSeparator();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PopupMenu.discreteGpuAvailable &&
|
||||||
|
this._source.app.state == Shell.AppState.STOPPED &&
|
||||||
|
actions.indexOf('activate-discrete-gpu') == -1) {
|
||||||
|
this._onDiscreteGpuMenuItem = this._appendMenuItem(_("Launch using Dedicated Graphics Card"));
|
||||||
|
this._onDiscreteGpuMenuItem.connect('activate', Lang.bind(this, function() {
|
||||||
|
if (this._source.app.state == Shell.AppState.STOPPED)
|
||||||
|
this._source.animateLaunch();
|
||||||
|
|
||||||
|
this._source.app.launch(0, -1, true);
|
||||||
|
this.emit('activate-window', null);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < actions.length; i++) {
|
||||||
|
let action = actions[i];
|
||||||
|
let item = this._appendMenuItem(appInfo.get_action_name(action));
|
||||||
|
item.connect('activate', Lang.bind(this, function(emitter, event) {
|
||||||
|
this._source.app.launch_action(action, event.get_time(), -1);
|
||||||
|
this.emit('activate-window', null);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
let canFavorite = global.settings.is_writable('favorite-apps');
|
||||||
|
|
||||||
|
if (canFavorite) {
|
||||||
|
this._appendSeparator();
|
||||||
|
|
||||||
|
let isFavorite = AppFavorites.getAppFavorites().isFavorite(this._source.app.get_id());
|
||||||
|
|
||||||
|
if (isFavorite) {
|
||||||
|
let item = this._appendMenuItem(_("Remove from Favorites"));
|
||||||
|
item.connect('activate', Lang.bind(this, function() {
|
||||||
|
let favs = AppFavorites.getAppFavorites();
|
||||||
|
favs.removeFavorite(this._source.app.get_id());
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
let item = this._appendMenuItem(_("Add to Favorites"));
|
||||||
|
item.connect('activate', Lang.bind(this, function() {
|
||||||
|
let favs = AppFavorites.getAppFavorites();
|
||||||
|
favs.addFavorite(this._source.app.get_id());
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop')) {
|
||||||
|
// this._appendSeparator();
|
||||||
|
// let item = this._appendMenuItem(_("Show Details"));
|
||||||
|
// item.connect('activate', Lang.bind(this, function() {
|
||||||
|
// let id = this._source.app.get_id();
|
||||||
|
// let args = GLib.Variant.new('(ss)', [id, '']);
|
||||||
|
// Gio.DBus.get(Gio.BusType.SESSION, null,
|
||||||
|
// function(o, res) {
|
||||||
|
// let bus = Gio.DBus.get_finish(res);
|
||||||
|
// bus.call('org.gnome.Software',
|
||||||
|
// '/org/gnome/Software',
|
||||||
|
// 'org.gtk.Actions', 'Activate',
|
||||||
|
// GLib.Variant.new('(sava{sv})',
|
||||||
|
// ['details', [args], null]),
|
||||||
|
// null, 0, -1, null, null);
|
||||||
|
// Main.overview.hide();
|
||||||
|
// });
|
||||||
|
// }));
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// quit menu
|
||||||
|
let app = this._source.app;
|
||||||
|
let count = getInterestingWindows(app, this._dtpSettings).length;
|
||||||
|
if ( count > 0) {
|
||||||
|
this._appendSeparator();
|
||||||
|
let quitFromTaskbarMenuText = "";
|
||||||
|
if (count == 1)
|
||||||
|
quitFromTaskbarMenuText = _("Quit");
|
||||||
|
else
|
||||||
|
quitFromTaskbarMenuText = _("Quit") + ' ' + count + ' ' + _("Windows");
|
||||||
|
|
||||||
|
this._quitfromTaskbarMenuItem = this._appendMenuItem(quitFromTaskbarMenuText);
|
||||||
|
this._quitfromTaskbarMenuItem.connect('activate', Lang.bind(this, function() {
|
||||||
|
let app = this._source.app;
|
||||||
|
let windows = app.get_windows();
|
||||||
|
for (let i = 0; i < windows.length; i++) {
|
||||||
|
this._closeWindowInstance(windows[i])
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(taskbarSecondaryMenu.prototype);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used for both extendShowAppsIcon and extendDashItemContainer
|
||||||
|
*/
|
||||||
function ItemShowLabel() {
|
function ItemShowLabel() {
|
||||||
if (!this._labelText)
|
if (!this._labelText)
|
||||||
return;
|
return;
|
||||||
@@ -897,4 +1122,98 @@ function ItemShowLabel() {
|
|||||||
time: DASH_ITEM_LABEL_SHOW_TIME,
|
time: DASH_ITEM_LABEL_SHOW_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend ShowAppsIcon
|
||||||
|
*
|
||||||
|
* - Pass settings to the constructor
|
||||||
|
* - set label position based on dash orientation
|
||||||
|
* - implement a popupMenu based on the AppIcon code
|
||||||
|
*
|
||||||
|
* I can't subclass the original object because of this: https://bugzilla.gnome.org/show_bug.cgi?id=688973.
|
||||||
|
* thus use this ugly pattern.
|
||||||
|
*/
|
||||||
|
function extendShowAppsIcon(showAppsIcon, settings) {
|
||||||
|
showAppsIcon._dtpSettings = settings;
|
||||||
|
/* the variable equivalent to toggleButton has a different name in the appIcon class
|
||||||
|
(actor): duplicate reference to easily reuse appIcon methods */
|
||||||
|
showAppsIcon.actor = showAppsIcon.toggleButton;
|
||||||
|
|
||||||
|
// Re-use appIcon methods
|
||||||
|
showAppsIcon._removeMenuTimeout = AppDisplay.AppIcon.prototype._removeMenuTimeout;
|
||||||
|
showAppsIcon._setPopupTimeout = AppDisplay.AppIcon.prototype._setPopupTimeout;
|
||||||
|
showAppsIcon._onButtonPress = AppDisplay.AppIcon.prototype._onButtonPress;
|
||||||
|
showAppsIcon._onKeyboardPopupMenu = AppDisplay.AppIcon.prototype._onKeyboardPopupMenu;
|
||||||
|
showAppsIcon._onLeaveEvent = AppDisplay.AppIcon.prototype._onLeaveEvent;
|
||||||
|
showAppsIcon._onTouchEvent = AppDisplay.AppIcon.prototype._onTouchEvent;
|
||||||
|
showAppsIcon._onMenuPoppedDown = AppDisplay.AppIcon.prototype._onMenuPoppedDown;
|
||||||
|
|
||||||
|
|
||||||
|
// No action on clicked (showing of the appsview is controlled elsewhere)
|
||||||
|
showAppsIcon._onClicked = function(actor, button) {
|
||||||
|
showAppsIcon._removeMenuTimeout();
|
||||||
|
};
|
||||||
|
|
||||||
|
showAppsIcon.actor.connect('leave-event', Lang.bind(showAppsIcon, showAppsIcon._onLeaveEvent));
|
||||||
|
showAppsIcon.actor.connect('button-press-event', Lang.bind(showAppsIcon, showAppsIcon._onButtonPress));
|
||||||
|
showAppsIcon.actor.connect('touch-event', Lang.bind(showAppsIcon, showAppsIcon._onTouchEvent));
|
||||||
|
showAppsIcon.actor.connect('clicked', Lang.bind(showAppsIcon, showAppsIcon._onClicked));
|
||||||
|
showAppsIcon.actor.connect('popup-menu', Lang.bind(showAppsIcon, showAppsIcon._onKeyboardPopupMenu));
|
||||||
|
|
||||||
|
showAppsIcon._menu = null;
|
||||||
|
showAppsIcon._menuManager = new PopupMenu.PopupMenuManager(showAppsIcon);
|
||||||
|
showAppsIcon._menuTimeoutId = 0;
|
||||||
|
|
||||||
|
showAppsIcon.showLabel = ItemShowLabel;
|
||||||
|
|
||||||
|
showAppsIcon.popupMenu = function() {
|
||||||
|
showAppsIcon._removeMenuTimeout();
|
||||||
|
showAppsIcon.actor.fake_release();
|
||||||
|
|
||||||
|
if (!showAppsIcon._menu) {
|
||||||
|
showAppsIcon._menu = new MyShowAppsIconMenu(showAppsIcon, showAppsIcon._dtpSettings);
|
||||||
|
showAppsIcon._menu.connect('open-state-changed', Lang.bind(showAppsIcon, function(menu, isPoppedUp) {
|
||||||
|
if (!isPoppedUp)
|
||||||
|
showAppsIcon._onMenuPoppedDown();
|
||||||
|
}));
|
||||||
|
let id = Main.overview.connect('hiding', Lang.bind(showAppsIcon, function() {
|
||||||
|
showAppsIcon._menu.close();
|
||||||
|
}));
|
||||||
|
showAppsIcon._menu.actor.connect('destroy', function() {
|
||||||
|
Main.overview.disconnect(id);
|
||||||
|
});
|
||||||
|
showAppsIcon._menuManager.addMenu(showAppsIcon._menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
showAppsIcon.emit('menu-state-changed', true);
|
||||||
|
|
||||||
|
showAppsIcon.actor.set_hover(true);
|
||||||
|
showAppsIcon._menu.popup();
|
||||||
|
showAppsIcon._menuManager.ignoreRelease();
|
||||||
|
showAppsIcon.emit('sync-tooltip');
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Signals.addSignalMethods(showAppsIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A menu for the showAppsIcon
|
||||||
|
*/
|
||||||
|
const MyShowAppsIconMenu = new Lang.Class({
|
||||||
|
Name: 'DashToPanel.ShowAppsIconMenu',
|
||||||
|
Extends: taskbarSecondaryMenu,
|
||||||
|
|
||||||
|
_redisplay: function() {
|
||||||
|
this.removeAll();
|
||||||
|
|
||||||
|
let item = this._appendMenuItem('Dash to Panel ' + _('Settings'));
|
||||||
|
|
||||||
|
item.connect('activate', function () {
|
||||||
|
Util.spawn(["gnome-shell-extension-prefs", Me.metadata.uuid]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
259
secondaryMenu.js
259
secondaryMenu.js
@@ -1,259 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of the Dash-To-Panel extension for Gnome 3
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Credits:
|
|
||||||
* This file is based on code from the Dash to Dock extension by micheleg
|
|
||||||
* and code from the Taskbar extension by Zorin OS
|
|
||||||
* Some code was also adapted from the upstream Gnome Shell source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
const AppDisplay = imports.ui.appDisplay;
|
|
||||||
const Lang = imports.lang;
|
|
||||||
|
|
||||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
|
||||||
const Taskbar = Me.imports.taskbar;
|
|
||||||
const RemoteMenu = imports.ui.remoteMenu;
|
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
|
||||||
const Shell = imports.gi.Shell;
|
|
||||||
const AppFavorites = imports.ui.appFavorites;
|
|
||||||
const Convenience = Me.imports.convenience;
|
|
||||||
const AppIcons = Me.imports.appIcons;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extend AppIconMenu
|
|
||||||
*
|
|
||||||
* - set popup arrow side based on taskbar orientation
|
|
||||||
* - Add close windows option based on quitfromdash extension
|
|
||||||
* (https://github.com/deuill/shell-extension-quitfromdash)
|
|
||||||
*/
|
|
||||||
|
|
||||||
const taskbarSecondaryMenu = new Lang.Class({
|
|
||||||
Name: 'DashToPanel.SecondaryMenu',
|
|
||||||
Extends: AppDisplay.AppIconMenu,
|
|
||||||
|
|
||||||
_init: function(source, settings) {
|
|
||||||
|
|
||||||
this._dtpSettings = settings;
|
|
||||||
|
|
||||||
let side = Taskbar.getPosition();
|
|
||||||
|
|
||||||
// Damm it, there has to be a proper way of doing this...
|
|
||||||
// As I can't call the parent parent constructor (?) passing the side
|
|
||||||
// parameter, I overwite what I need later
|
|
||||||
this.parent(source);
|
|
||||||
|
|
||||||
// Change the initialized side where required.
|
|
||||||
this._arrowSide = side;
|
|
||||||
this._boxPointer._arrowSide = side;
|
|
||||||
this._boxPointer._userArrowSide = side;
|
|
||||||
},
|
|
||||||
|
|
||||||
// helper function for the quit windows abilities
|
|
||||||
_closeWindowInstance: function(metaWindow) {
|
|
||||||
metaWindow.delete(global.get_current_time());
|
|
||||||
},
|
|
||||||
|
|
||||||
_redisplay: function() {
|
|
||||||
this.removeAll();
|
|
||||||
|
|
||||||
let appMenu = this._source.app.menu;
|
|
||||||
if(appMenu) {
|
|
||||||
let remoteMenu = new RemoteMenu.RemoteMenu(this._source.actor, this._source.app.menu, this._source.app.action_group);
|
|
||||||
let appMenuItems = remoteMenu._getMenuItems();
|
|
||||||
let isItemsAdded = false;
|
|
||||||
for(let appMenuIdx in appMenuItems){
|
|
||||||
let menuItem = appMenuItems[appMenuIdx];
|
|
||||||
let labelText = menuItem.actor.label_actor.text;
|
|
||||||
if(labelText == _("New Window") || labelText == _("Quit"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(menuItem instanceof PopupMenu.PopupSeparatorMenuItem)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
isItemsAdded = true;
|
|
||||||
|
|
||||||
// this ends up getting called multiple times, and bombing due to the signal id's being invalid
|
|
||||||
// on a 2nd pass. disconnect the base handler and attach our own that wraps the id's in if statements
|
|
||||||
menuItem.disconnect(menuItem._popupMenuDestroyId)
|
|
||||||
menuItem._popupMenuDestroyId = menuItem.connect('destroy', Lang.bind(this, function(menuItem) {
|
|
||||||
if(menuItem._popupMenuDestroyId) {
|
|
||||||
menuItem.disconnect(menuItem._popupMenuDestroyId);
|
|
||||||
menuItem._popupMenuDestroyId = 0;
|
|
||||||
}
|
|
||||||
if(menuItem._activateId) {
|
|
||||||
menuItem.disconnect(menuItem._activateId);
|
|
||||||
menuItem._activateId = 0;
|
|
||||||
}
|
|
||||||
if(menuItem._activeChangeId) {
|
|
||||||
menuItem.disconnect(menuItem._activeChangeId);
|
|
||||||
menuItem._activeChangeId = 0;
|
|
||||||
}
|
|
||||||
if(menuItem._sensitiveChangeId) {
|
|
||||||
menuItem.disconnect(menuItem._sensitiveChangeId);
|
|
||||||
menuItem._sensitiveChangeId = 0;
|
|
||||||
}
|
|
||||||
this.disconnect(menuItem._parentSensitiveChangeId);
|
|
||||||
if (menuItem == this._activeMenuItem)
|
|
||||||
this._activeMenuItem = null;
|
|
||||||
}));
|
|
||||||
|
|
||||||
menuItem.actor.get_parent().remove_child(menuItem.actor);
|
|
||||||
if(menuItem instanceof PopupMenu.PopupSubMenuMenuItem) {
|
|
||||||
let newSubMenuMenuItem = new PopupMenu.PopupSubMenuMenuItem(labelText);
|
|
||||||
let appSubMenuItems = menuItem.menu._getMenuItems();
|
|
||||||
for(let appSubMenuIdx in appSubMenuItems){
|
|
||||||
let subMenuItem = appSubMenuItems[appSubMenuIdx];
|
|
||||||
subMenuItem.actor.get_parent().remove_child(subMenuItem.actor);
|
|
||||||
newSubMenuMenuItem.menu.addMenuItem(subMenuItem);
|
|
||||||
}
|
|
||||||
this.addMenuItem(newSubMenuMenuItem);
|
|
||||||
} else
|
|
||||||
this.addMenuItem(menuItem);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isItemsAdded)
|
|
||||||
this._appendSeparator();
|
|
||||||
}
|
|
||||||
|
|
||||||
let windows = this._source.app.get_windows().filter(function(w) {
|
|
||||||
return !w.skip_taskbar;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Display the app windows menu items and the separator between windows
|
|
||||||
// of the current desktop and other windows.
|
|
||||||
let activeWorkspace = global.screen.get_active_workspace();
|
|
||||||
let separatorShown = windows.length > 0 && windows[0].get_workspace() != activeWorkspace;
|
|
||||||
|
|
||||||
for (let i = 0; i < windows.length; i++) {
|
|
||||||
let window = windows[i];
|
|
||||||
if (!separatorShown && window.get_workspace() != activeWorkspace) {
|
|
||||||
this._appendSeparator();
|
|
||||||
separatorShown = true;
|
|
||||||
}
|
|
||||||
let item = this._appendMenuItem(window.title);
|
|
||||||
item.connect('activate', Lang.bind(this, function() {
|
|
||||||
this.emit('activate-window', window);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._source.app.is_window_backed()) {
|
|
||||||
this._appendSeparator();
|
|
||||||
|
|
||||||
let appInfo = this._source.app.get_app_info();
|
|
||||||
let actions = appInfo.list_actions();
|
|
||||||
if (this._source.app.can_open_new_window() &&
|
|
||||||
actions.indexOf('new-window') == -1) {
|
|
||||||
this._newWindowMenuItem = this._appendMenuItem(_("New Window"));
|
|
||||||
this._newWindowMenuItem.connect('activate', Lang.bind(this, function() {
|
|
||||||
if (this._source.app.state == Shell.AppState.STOPPED)
|
|
||||||
this._source.animateLaunch();
|
|
||||||
|
|
||||||
this._source.app.open_new_window(-1);
|
|
||||||
this.emit('activate-window', null);
|
|
||||||
}));
|
|
||||||
this._appendSeparator();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PopupMenu.discreteGpuAvailable &&
|
|
||||||
this._source.app.state == Shell.AppState.STOPPED &&
|
|
||||||
actions.indexOf('activate-discrete-gpu') == -1) {
|
|
||||||
this._onDiscreteGpuMenuItem = this._appendMenuItem(_("Launch using Dedicated Graphics Card"));
|
|
||||||
this._onDiscreteGpuMenuItem.connect('activate', Lang.bind(this, function() {
|
|
||||||
if (this._source.app.state == Shell.AppState.STOPPED)
|
|
||||||
this._source.animateLaunch();
|
|
||||||
|
|
||||||
this._source.app.launch(0, -1, true);
|
|
||||||
this.emit('activate-window', null);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < actions.length; i++) {
|
|
||||||
let action = actions[i];
|
|
||||||
let item = this._appendMenuItem(appInfo.get_action_name(action));
|
|
||||||
item.connect('activate', Lang.bind(this, function(emitter, event) {
|
|
||||||
this._source.app.launch_action(action, event.get_time(), -1);
|
|
||||||
this.emit('activate-window', null);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let canFavorite = global.settings.is_writable('favorite-apps');
|
|
||||||
|
|
||||||
if (canFavorite) {
|
|
||||||
this._appendSeparator();
|
|
||||||
|
|
||||||
let isFavorite = AppFavorites.getAppFavorites().isFavorite(this._source.app.get_id());
|
|
||||||
|
|
||||||
if (isFavorite) {
|
|
||||||
let item = this._appendMenuItem(_("Remove from Favorites"));
|
|
||||||
item.connect('activate', Lang.bind(this, function() {
|
|
||||||
let favs = AppFavorites.getAppFavorites();
|
|
||||||
favs.removeFavorite(this._source.app.get_id());
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
let item = this._appendMenuItem(_("Add to Favorites"));
|
|
||||||
item.connect('activate', Lang.bind(this, function() {
|
|
||||||
let favs = AppFavorites.getAppFavorites();
|
|
||||||
favs.addFavorite(this._source.app.get_id());
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop')) {
|
|
||||||
// this._appendSeparator();
|
|
||||||
// let item = this._appendMenuItem(_("Show Details"));
|
|
||||||
// item.connect('activate', Lang.bind(this, function() {
|
|
||||||
// let id = this._source.app.get_id();
|
|
||||||
// let args = GLib.Variant.new('(ss)', [id, '']);
|
|
||||||
// Gio.DBus.get(Gio.BusType.SESSION, null,
|
|
||||||
// function(o, res) {
|
|
||||||
// let bus = Gio.DBus.get_finish(res);
|
|
||||||
// bus.call('org.gnome.Software',
|
|
||||||
// '/org/gnome/Software',
|
|
||||||
// 'org.gtk.Actions', 'Activate',
|
|
||||||
// GLib.Variant.new('(sava{sv})',
|
|
||||||
// ['details', [args], null]),
|
|
||||||
// null, 0, -1, null, null);
|
|
||||||
// Main.overview.hide();
|
|
||||||
// });
|
|
||||||
// }));
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// quit menu
|
|
||||||
let app = this._source.app;
|
|
||||||
let count = AppIcons.getInterestingWindows(app, this._dtpSettings).length;
|
|
||||||
if ( count > 0) {
|
|
||||||
this._appendSeparator();
|
|
||||||
let quitFromTaskbarMenuText = "";
|
|
||||||
if (count == 1)
|
|
||||||
quitFromTaskbarMenuText = _("Quit");
|
|
||||||
else
|
|
||||||
quitFromTaskbarMenuText = _("Quit") + ' ' + count + ' ' + _("Windows");
|
|
||||||
|
|
||||||
this._quitfromTaskbarMenuItem = this._appendMenuItem(quitFromTaskbarMenuText);
|
|
||||||
this._quitfromTaskbarMenuItem.connect('activate', Lang.bind(this, function() {
|
|
||||||
let app = this._source.app;
|
|
||||||
let windows = app.get_windows();
|
|
||||||
for (let i = 0; i < windows.length; i++) {
|
|
||||||
this._closeWindowInstance(windows[i])
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
19
taskbar.js
19
taskbar.js
@@ -46,7 +46,6 @@ const Workspace = imports.ui.workspace;
|
|||||||
|
|
||||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||||
const Convenience = Me.imports.convenience;
|
const Convenience = Me.imports.convenience;
|
||||||
const SecondaryMenu = Me.imports.secondaryMenu;
|
|
||||||
const WindowPreview = Me.imports.windowPreview;
|
const WindowPreview = Me.imports.windowPreview;
|
||||||
const AppIcons = Me.imports.appIcons;
|
const AppIcons = Me.imports.appIcons;
|
||||||
|
|
||||||
@@ -218,9 +217,8 @@ const taskbar = new Lang.Class({
|
|||||||
this._scrollView.add_actor(this._box);
|
this._scrollView.add_actor(this._box);
|
||||||
|
|
||||||
this._showAppsIcon = new Dash.ShowAppsIcon();
|
this._showAppsIcon = new Dash.ShowAppsIcon();
|
||||||
this._showAppsIcon.showLabel = AppIcons.ItemShowLabel;
|
AppIcons.extendShowAppsIcon(this._showAppsIcon, this._dtpSettings);
|
||||||
this.showAppsButton = this._showAppsIcon.toggleButton;
|
this.showAppsButton = this._showAppsIcon.toggleButton;
|
||||||
this._showAppsIcon.actor = this.showAppsButton;
|
|
||||||
|
|
||||||
this.showAppsButton.connect('notify::checked', Lang.bind(this, this._onShowAppsButtonToggled));
|
this.showAppsButton.connect('notify::checked', Lang.bind(this, this._onShowAppsButtonToggled));
|
||||||
|
|
||||||
@@ -229,6 +227,11 @@ const taskbar = new Lang.Class({
|
|||||||
this._showAppsIcon.icon.setIconSize(this.iconSize);
|
this._showAppsIcon.icon.setIconSize(this.iconSize);
|
||||||
this._hookUpLabel(this._showAppsIcon);
|
this._hookUpLabel(this._showAppsIcon);
|
||||||
|
|
||||||
|
let appsIcon = this._showAppsIcon;
|
||||||
|
appsIcon.connect('menu-state-changed', Lang.bind(this, function(appsIcon, opened) {
|
||||||
|
this._itemMenuStateChanged(appsIcon, opened);
|
||||||
|
}));
|
||||||
|
|
||||||
this._container.add_actor(this._showAppsIcon);
|
this._container.add_actor(this._showAppsIcon);
|
||||||
|
|
||||||
if (!this._dtpSettings.get_boolean('show-show-apps-button'))
|
if (!this._dtpSettings.get_boolean('show-show-apps-button'))
|
||||||
@@ -399,6 +402,7 @@ const taskbar = new Lang.Class({
|
|||||||
_endDrag: function() {
|
_endDrag: function() {
|
||||||
this._clearDragPlaceholder();
|
this._clearDragPlaceholder();
|
||||||
this._clearEmptyDropTarget();
|
this._clearEmptyDropTarget();
|
||||||
|
this._showAppsIcon.setDragApp(null);
|
||||||
DND.removeDragMonitor(this._dragMonitor);
|
DND.removeDragMonitor(this._dragMonitor);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -407,9 +411,16 @@ const taskbar = new Lang.Class({
|
|||||||
if (app == null)
|
if (app == null)
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
|
|
||||||
if (!this._box.contains(dragEvent.targetActor))
|
let showAppsHovered = this._showAppsIcon.contains(dragEvent.targetActor);
|
||||||
|
|
||||||
|
if (!this._box.contains(dragEvent.targetActor) || showAppsHovered)
|
||||||
this._clearDragPlaceholder();
|
this._clearDragPlaceholder();
|
||||||
|
|
||||||
|
if (showAppsHovered)
|
||||||
|
this._showAppsIcon.setDragApp(app);
|
||||||
|
else
|
||||||
|
this._showAppsIcon.setDragApp(null);
|
||||||
|
|
||||||
return DND.DragMotionResult.CONTINUE;
|
return DND.DragMotionResult.CONTINUE;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user