mirror of
https://github.com/morgan9e/dash-to-panel
synced 2026-04-15 00:34:05 +09:00
Pull in workspace isolation and hide dash from d2d
This commit is contained in:
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 = convenience.js panel.js taskbar.js secondaryMenu.js windowPreview.js prefs.js Settings.ui
|
EXTRA_MODULES = convenience.js panel.js overview.js taskbar.js secondaryMenu.js windowPreview.js prefs.js Settings.ui
|
||||||
#EXTRA_MEDIA = logo.svg
|
#EXTRA_MEDIA = logo.svg
|
||||||
TOLOCALIZE = prefs.js
|
TOLOCALIZE = prefs.js
|
||||||
MSGSRC = $(wildcard po/*.po)
|
MSGSRC = $(wildcard po/*.po)
|
||||||
|
|||||||
16
README.md
16
README.md
@@ -1,8 +1,8 @@
|
|||||||
# Dash to Panel
|
# Dash to Panel
|
||||||

|

|
||||||
|
|
||||||
## An icon-only taskbar for the GNOME Shell
|
## An icon taskbar for the GNOME Shell
|
||||||
An icon-only taskbar for the Gnome Shell. This extension moves the dash into the gnome main panel (top bar) to behave as an icon-only task manager similar to that found in KDE Plasma and Windows 7+.
|
An icon taskbar for the Gnome Shell. This extension moves the dash into the gnome main panel (top bar) to behave as an icon-only task manager similar to that found in KDE Plasma and Windows 7+.
|
||||||
|
|
||||||
## Installation from source
|
## Installation from source
|
||||||
|
|
||||||
@@ -16,18 +16,6 @@ make install
|
|||||||
to install the extension in your home directory. A Shell reload is required <code>Alt+F2 r Enter</code> and the extension has to be enabled with *gnome-tweak-tool* or with *dconf*.
|
to install the extension in your home directory. A Shell reload is required <code>Alt+F2 r Enter</code> and the extension has to be enabled with *gnome-tweak-tool* or with *dconf*.
|
||||||
|
|
||||||
|
|
||||||
## TODO
|
|
||||||
- configure tray item spacing
|
|
||||||
- isolate workspaces
|
|
||||||
- add "show desktop" button
|
|
||||||
- replace activities (overview) button text with an icon
|
|
||||||
- reorder "activities" and open apps view" buttons when both visible
|
|
||||||
- allow moving overview hotspot to bottom left
|
|
||||||
- allow moving notifications popup
|
|
||||||
- disable built-in dash
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Bug Reporting
|
## Bug Reporting
|
||||||
|
|
||||||
Bugs should be reported to the Github bug tracker [https://github.com/jderose9/dash-to-panel/issues](https://github.com/jderose9/dash-to-panel/issues).
|
Bugs should be reported to the Github bug tracker [https://github.com/jderose9/dash-to-panel/issues](https://github.com/jderose9/dash-to-panel/issues).
|
||||||
|
|||||||
44
Settings.ui
44
Settings.ui
@@ -722,6 +722,50 @@
|
|||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkListBoxRow" id="isolate_workspaces_row">
|
||||||
|
<property name="width_request">100</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkGrid" id="isolate_workspaces_grid">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_left">12</property>
|
||||||
|
<property name="margin_right">12</property>
|
||||||
|
<property name="margin_top">12</property>
|
||||||
|
<property name="margin_bottom">12</property>
|
||||||
|
<property name="column_spacing">32</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSwitch" id="isolate_workspaces_switch">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="isolate_workspaces_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="label" translatable="yes">Isolate Workspaces</property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child type="label_item">
|
<child type="label_item">
|
||||||
|
|||||||
@@ -166,3 +166,29 @@ const GlobalSignalsHandler = new Lang.Class({
|
|||||||
item[0].disconnect(item[1]);
|
item[0].disconnect(item[1]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage function injection: both instances and prototype can be overridden
|
||||||
|
* and restored
|
||||||
|
*/
|
||||||
|
const InjectionsHandler = new Lang.Class({
|
||||||
|
Name: 'Taskbar.InjectionsHandler',
|
||||||
|
Extends: BasicHandler,
|
||||||
|
|
||||||
|
_create: function(item) {
|
||||||
|
let object = item[0];
|
||||||
|
let name = item[1];
|
||||||
|
let injectedFunction = item[2];
|
||||||
|
let original = object[name];
|
||||||
|
|
||||||
|
object[name] = injectedFunction;
|
||||||
|
return [object, name, injectedFunction, original];
|
||||||
|
},
|
||||||
|
|
||||||
|
_remove: function(item) {
|
||||||
|
let object = item[0];
|
||||||
|
let name = item[1];
|
||||||
|
let original = item[3];
|
||||||
|
object[name] = original;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -21,8 +21,10 @@
|
|||||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||||
const Convenience = Me.imports.convenience;
|
const Convenience = Me.imports.convenience;
|
||||||
const Panel = Me.imports.panel;
|
const Panel = Me.imports.panel;
|
||||||
|
const Overview = Me.imports.overview;
|
||||||
|
|
||||||
let panel;
|
let panel;
|
||||||
|
let overview;
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
@@ -32,12 +34,16 @@ function enable() {
|
|||||||
settings = Convenience.getSettings('org.gnome.shell.extensions.dash-to-panel');
|
settings = Convenience.getSettings('org.gnome.shell.extensions.dash-to-panel');
|
||||||
panel = new Panel.taskbarPanel(settings);
|
panel = new Panel.taskbarPanel(settings);
|
||||||
panel.enable();
|
panel.enable();
|
||||||
|
overview = new Overview.taskbarOverview(settings);
|
||||||
|
overview.enable(panel.taskbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
function disable() {
|
function disable() {
|
||||||
|
overview.disable();
|
||||||
panel.disable();
|
panel.disable();
|
||||||
settings.run_dispose();
|
settings.run_dispose();
|
||||||
settings = null;
|
settings = null;
|
||||||
|
overview = null;
|
||||||
panel = null;
|
panel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"extension-id": "dash-to-panel",
|
"extension-id": "dash-to-panel",
|
||||||
"uuid": "dash-to-panel@jderose9.github.com",
|
"uuid": "dash-to-panel@jderose9.github.com",
|
||||||
"name": "Dash to Panel",
|
"name": "Dash to Panel",
|
||||||
"description": "An icon-only taskbar for the Gnome Shell. This extension moves the dash into the gnome main panel (top bar) to behave as an icon-only task manager similar to that found in KDE Plasma and Windows 7+.",
|
"description": "An icon taskbar for the Gnome Shell. This extension moves the dash into the gnome main panel (top bar) to behave as an icon-only task manager similar to that found in KDE Plasma and Windows 7+.",
|
||||||
"shell-version": [ "3.20", "3.22" ],
|
"shell-version": [ "3.20", "3.22" ],
|
||||||
"url": "https://github.com/jderose9/dash-to-panel",
|
"url": "https://github.com/jderose9/dash-to-panel",
|
||||||
"gettext-domain": "dash-to-panel"
|
"gettext-domain": "dash-to-panel"
|
||||||
|
|||||||
133
overview.js
Normal file
133
overview.js
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Some code was also adapted from the upstream Gnome Shell source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
||||||
|
const Convenience = Me.imports.convenience;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
const Shell = imports.gi.Shell;
|
||||||
|
|
||||||
|
const taskbarOverview = new Lang.Class({
|
||||||
|
Name: 'TaskBar.Overview',
|
||||||
|
|
||||||
|
_init: function(settings) {
|
||||||
|
this._dtpSettings = settings;
|
||||||
|
},
|
||||||
|
|
||||||
|
enable : function(taskbar) {
|
||||||
|
this.taskbar = taskbar;
|
||||||
|
|
||||||
|
this._injectionsHandler = new Convenience.InjectionsHandler();
|
||||||
|
this._signalsHandler = new Convenience.GlobalSignalsHandler();
|
||||||
|
|
||||||
|
// Hide usual Dash
|
||||||
|
Main.overview._controls.dash.actor.hide();
|
||||||
|
|
||||||
|
// Also set dash width to 1, so it's almost not taken into account by code
|
||||||
|
// calculaing the reserved space in the overview. The reason to keep it at 1 is
|
||||||
|
// to allow its visibility change to trigger an allocaion of the appGrid which
|
||||||
|
// in turn is triggergin the appsIcon spring animation, required when no other
|
||||||
|
// actors has this effect, i.e in horizontal mode and without the workspaceThumnails
|
||||||
|
// 1 static workspace only)
|
||||||
|
Main.overview._controls.dash.actor.set_width(1);
|
||||||
|
|
||||||
|
this._optionalWorkspaceIsolation();
|
||||||
|
this._bindSettingsChanges();
|
||||||
|
},
|
||||||
|
|
||||||
|
disable: function () {
|
||||||
|
Main.overview._controls.dash.actor.show();
|
||||||
|
Main.overview._controls.dash.actor.set_width(-1); //reset default dash size
|
||||||
|
// This force the recalculation of the icon size
|
||||||
|
Main.overview._controls.dash._maxHeight = -1;
|
||||||
|
|
||||||
|
// reset stored icon size to the default dash
|
||||||
|
Main.overview.dashIconSize = Main.overview._controls.dash.iconSize;
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindSettingsChanges: function() {
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Isolate overview to open new windows for inactive apps
|
||||||
|
*/
|
||||||
|
_optionalWorkspaceIsolation: function() {
|
||||||
|
|
||||||
|
let label = 'optionalWorkspaceIsolation';
|
||||||
|
|
||||||
|
this._dtpSettings.connect('changed::isolate-workspaces', Lang.bind(this, function() {
|
||||||
|
this.taskbar.resetAppIcons();
|
||||||
|
if (this._dtpSettings.get_boolean('isolate-workspaces'))
|
||||||
|
Lang.bind(this, enable)();
|
||||||
|
else
|
||||||
|
Lang.bind(this, disable)();
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (this._dtpSettings.get_boolean('isolate-workspaces'))
|
||||||
|
Lang.bind(this, enable)();
|
||||||
|
|
||||||
|
function enable() {
|
||||||
|
this._injectionsHandler.removeWithLabel(label);
|
||||||
|
|
||||||
|
this._injectionsHandler.addWithLabel(label, [
|
||||||
|
Shell.App.prototype,
|
||||||
|
'activate',
|
||||||
|
IsolatedOverview
|
||||||
|
]);
|
||||||
|
|
||||||
|
this._signalsHandler.removeWithLabel(label);
|
||||||
|
|
||||||
|
this._signalsHandler.addWithLabel(label, [
|
||||||
|
global.screen,
|
||||||
|
'restacked',
|
||||||
|
Lang.bind(this.taskbar, this.taskbar._queueRedisplay)
|
||||||
|
]);
|
||||||
|
this._signalsHandler.addWithLabel(label, [
|
||||||
|
global.window_manager,
|
||||||
|
'switch-workspace',
|
||||||
|
Lang.bind(this.taskbar, this.taskbar._queueRedisplay)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function disable() {
|
||||||
|
this._signalsHandler.removeWithLabel(label);
|
||||||
|
this._injectionsHandler.removeWithLabel(label);
|
||||||
|
|
||||||
|
this._signalsHandler.destroy();
|
||||||
|
this._injectionsHandler.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
function IsolatedOverview() {
|
||||||
|
// These lines take care of Nautilus for icons on Desktop
|
||||||
|
let windows = this.get_windows().filter(function(w) {
|
||||||
|
return w.get_workspace().index() == global.screen.get_active_workspace_index();
|
||||||
|
});
|
||||||
|
if (windows.length == 1)
|
||||||
|
if (windows[0].skip_taskbar)
|
||||||
|
return this.open_new_window(-1);
|
||||||
|
|
||||||
|
if (this.is_on_workspace(global.screen.get_active_workspace()))
|
||||||
|
return Main.activateWindow(windows[0]);
|
||||||
|
return this.open_new_window(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
4
prefs.js
4
prefs.js
@@ -139,6 +139,10 @@ const Settings = new Lang.Class({
|
|||||||
this._builder.get_object('application_button_animation_button'),
|
this._builder.get_object('application_button_animation_button'),
|
||||||
'sensitive',
|
'sensitive',
|
||||||
Gio.SettingsBindFlags.DEFAULT);
|
Gio.SettingsBindFlags.DEFAULT);
|
||||||
|
this._settings.bind('isolate-workspaces',
|
||||||
|
this._builder.get_object('isolate_workspaces_switch'),
|
||||||
|
'active',
|
||||||
|
Gio.SettingsBindFlags.DEFAULT);
|
||||||
|
|
||||||
this._builder.get_object('click_action_combo').set_active_id(this._settings.get_string('click-action'));
|
this._builder.get_object('click_action_combo').set_active_id(this._settings.get_string('click-action'));
|
||||||
this._builder.get_object('click_action_combo').connect('changed', Lang.bind (this, function(widget) {
|
this._builder.get_object('click_action_combo').connect('changed', Lang.bind (this, function(widget) {
|
||||||
|
|||||||
@@ -54,6 +54,11 @@
|
|||||||
<summary>Animate Show Applications from the desktop</summary>
|
<summary>Animate Show Applications from the desktop</summary>
|
||||||
<description>Animate Show Applications from the desktop</description>
|
<description>Animate Show Applications from the desktop</description>
|
||||||
</key>
|
</key>
|
||||||
|
<key type="b" name="isolate-workspaces">
|
||||||
|
<default>false</default>
|
||||||
|
<summary>Provide workspace isolation</summary>
|
||||||
|
<description>Dash shows only windows from the currentworkspace</description>
|
||||||
|
</key>
|
||||||
<key type="b" name="customize-click">
|
<key type="b" name="customize-click">
|
||||||
<default>true</default>
|
<default>true</default>
|
||||||
<summary>Customize click behaviour</summary>
|
<summary>Customize click behaviour</summary>
|
||||||
@@ -91,16 +96,16 @@
|
|||||||
<default>0</default>
|
<default>0</default>
|
||||||
<summary>Tray content size</summary>
|
<summary>Tray content size</summary>
|
||||||
<description>Set the size of the tray items. (0 for default)</description>
|
<description>Set the size of the tray items. (0 for default)</description>
|
||||||
</key>
|
</key>
|
||||||
<key type="i" name="leftbox-size">
|
<key type="i" name="leftbox-size">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<summary>Left content size</summary>
|
<summary>Left content size</summary>
|
||||||
<description>Set the size of the leftBox items. (0 for default)</description>
|
<description>Set the size of the leftBox items. (0 for default)</description>
|
||||||
</key>
|
</key>
|
||||||
<key type="i" name="appicon-margin">
|
<key type="i" name="appicon-margin">
|
||||||
<default>8</default>
|
<default>8</default>
|
||||||
<summary>App icon margin</summary>
|
<summary>App icon margin</summary>
|
||||||
<description>Set the margin for application icons in the embedded dash.</description>
|
<description>Set the margin for application icons in the embedded dash.</description>
|
||||||
</key>
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
</schemalist>
|
</schemalist>
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ const taskbarSecondaryMenu = new Lang.Class({
|
|||||||
Name: 'taskbarSecondaryMenu',
|
Name: 'taskbarSecondaryMenu',
|
||||||
Extends: AppDisplay.AppIconMenu,
|
Extends: AppDisplay.AppIconMenu,
|
||||||
|
|
||||||
_init: function(source) {
|
_init: function(source, settings) {
|
||||||
|
|
||||||
|
this._dtpSettings = settings;
|
||||||
|
|
||||||
let side = Taskbar.getPosition();
|
let side = Taskbar.getPosition();
|
||||||
|
|
||||||
@@ -65,7 +67,7 @@ const taskbarSecondaryMenu = new Lang.Class({
|
|||||||
|
|
||||||
// quit menu
|
// quit menu
|
||||||
let app = this._source.app;
|
let app = this._source.app;
|
||||||
let count = Taskbar.getAppInterestingWindows(app).length;
|
let count = Taskbar.getInterestingWindows(app, this._dtpSettings).length;
|
||||||
if ( count > 0) {
|
if ( count > 0) {
|
||||||
this._appendSeparator();
|
this._appendSeparator();
|
||||||
let quitFromTaskbarMenuText = "";
|
let quitFromTaskbarMenuText = "";
|
||||||
|
|||||||
93
taskbar.js
93
taskbar.js
@@ -709,6 +709,14 @@ const taskbar = new Lang.Class({
|
|||||||
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
let favorites = AppFavorites.getAppFavorites().getFavoriteMap();
|
||||||
|
|
||||||
let running = this._appSystem.get_running().sort(this.sortAppsCompareFunction);
|
let running = this._appSystem.get_running().sort(this.sortAppsCompareFunction);
|
||||||
|
if (this._dtpSettings.get_boolean('isolate-workspaces')) {
|
||||||
|
// When using isolation, we filter out apps that have no windows in
|
||||||
|
// the current workspace
|
||||||
|
let settings = this._dtpSettings;
|
||||||
|
running = running.filter(function(_app) {
|
||||||
|
return getInterestingWindows(_app, settings).length != 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let children = this._box.get_children().filter(function(actor) {
|
let children = this._box.get_children().filter(function(actor) {
|
||||||
return actor.child &&
|
return actor.child &&
|
||||||
@@ -1192,7 +1200,7 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
// function) caused the extension to crash.
|
// function) caused the extension to crash.
|
||||||
this._menuManagerWindowPreview = new PopupMenu.PopupMenuManager(this);
|
this._menuManagerWindowPreview = new PopupMenu.PopupMenuManager(this);
|
||||||
|
|
||||||
this._windowPreview = new WindowPreview.thumbnailPreviewMenu(this);
|
this._windowPreview = new WindowPreview.thumbnailPreviewMenu(this, this._dtpSettings);
|
||||||
this._windowPreview.connect('open-state-changed', Lang.bind(this, function (menu, isPoppedUp) {
|
this._windowPreview.connect('open-state-changed', Lang.bind(this, function (menu, isPoppedUp) {
|
||||||
if (!isPoppedUp)
|
if (!isPoppedUp)
|
||||||
this._onMenuPoppedDown();
|
this._onMenuPoppedDown();
|
||||||
@@ -1203,7 +1211,7 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
shouldShowTooltip: function() {
|
shouldShowTooltip: function() {
|
||||||
let windows = getAppInterestingWindows(this.app);
|
let windows = getInterestingWindows(this.app, this._dtpSettings);
|
||||||
if (windows.length > 0) {
|
if (windows.length > 0) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@@ -1272,6 +1280,16 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_updateRunningStyle: function() {
|
_updateRunningStyle: function() {
|
||||||
|
// When using workspace isolation, we need to hide the dots of apps with
|
||||||
|
// no windows in the current workspace
|
||||||
|
if (this._dtpSettings.get_boolean('isolate-workspaces')) {
|
||||||
|
if (this.app.state != Shell.AppState.STOPPED
|
||||||
|
&& getInterestingWindows(this.app, this._dtpSettings).length != 0)
|
||||||
|
this._dot.show();
|
||||||
|
else
|
||||||
|
this._dot.hide();
|
||||||
|
}
|
||||||
|
|
||||||
this._updateCounterClass();
|
this._updateCounterClass();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1281,9 +1299,9 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
this._draggable.fakeRelease();
|
this._draggable.fakeRelease();
|
||||||
|
|
||||||
if (!this._menu) {
|
if (!this._menu) {
|
||||||
this._menu = new SecondaryMenu.taskbarSecondaryMenu(this);
|
this._menu = new SecondaryMenu.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.activateWindow(window, this._dtpSettings);
|
||||||
}));
|
}));
|
||||||
this._menu.connect('open-state-changed', Lang.bind(this, function (menu, isPoppedUp) {
|
this._menu.connect('open-state-changed', Lang.bind(this, function (menu, isPoppedUp) {
|
||||||
if (!isPoppedUp)
|
if (!isPoppedUp)
|
||||||
@@ -1379,11 +1397,16 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
buttonAction = this._dtpSettings.get_string('click-action');
|
buttonAction = this._dtpSettings.get_string('click-action');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We check if the app is running, and that the # of windows is > 0 in
|
||||||
|
// case we use workspace isolation,
|
||||||
|
let appIsRunning = this.app.state == Shell.AppState.RUNNING
|
||||||
|
&& getInterestingWindows(this.app, this._dtpSettings).length > 0
|
||||||
|
|
||||||
// We customize the action only when the application is already running
|
// We customize the action only when the application is already running
|
||||||
if (this.app.state == Shell.AppState.RUNNING) {
|
if (appIsRunning) {
|
||||||
switch (buttonAction) {
|
switch (buttonAction) {
|
||||||
case "RAISE":
|
case "RAISE":
|
||||||
activateAllWindows(this.app);
|
activateAllWindows(this.app, this._dtpSettings);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "LAUNCH":
|
case "LAUNCH":
|
||||||
@@ -1404,10 +1427,10 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
if (Clutter.EventType.CLUTTER_BUTTON_PRESS)
|
if (Clutter.EventType.CLUTTER_BUTTON_PRESS)
|
||||||
click_count = event.get_click_count();
|
click_count = event.get_click_count();
|
||||||
let all_windows = (button == 1 && ! modifiers) || click_count > 1;
|
let all_windows = (button == 1 && ! modifiers) || click_count > 1;
|
||||||
minimizeWindow(this.app, all_windows);
|
minimizeWindow(this.app, all_windows, this._dtpSettings);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
activateAllWindows(this.app);
|
activateAllWindows(this.app, this._dtpSettings);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
this.app.activate();
|
this.app.activate();
|
||||||
@@ -1416,9 +1439,9 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
case "CYCLE":
|
case "CYCLE":
|
||||||
if (!Main.overview._shown){
|
if (!Main.overview._shown){
|
||||||
if (this.app == focusedApp)
|
if (this.app == focusedApp)
|
||||||
activateNextWindow(this.app, false);
|
activateNextWindow(this.app, false, this._dtpSettings);
|
||||||
else {
|
else {
|
||||||
activateFirstWindow(this.app);
|
activateFirstWindow(this.app, this._dtpSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1427,9 +1450,9 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
case "CYCLE-MIN":
|
case "CYCLE-MIN":
|
||||||
if (!Main.overview._shown){
|
if (!Main.overview._shown){
|
||||||
if (this.app == focusedApp)
|
if (this.app == focusedApp)
|
||||||
activateNextWindow(this.app, true);
|
activateNextWindow(this.app, true, this._dtpSettings);
|
||||||
else {
|
else {
|
||||||
activateFirstWindow(this.app);
|
activateFirstWindow(this.app, this._dtpSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1437,7 +1460,7 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case "QUIT":
|
case "QUIT":
|
||||||
closeAllWindows(this.app);
|
closeAllWindows(this.app, this._dtpSettings);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1457,7 +1480,7 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
this._dot.set_y_align(Clutter.ActorAlign.END);
|
this._dot.set_y_align(Clutter.ActorAlign.END);
|
||||||
|
|
||||||
let maxN = 4;
|
let maxN = 4;
|
||||||
this._nWindows = Math.min(getAppInterestingWindows(this.app).length, maxN);
|
this._nWindows = Math.min(getInterestingWindows(this.app, this._dtpSettings).length, maxN);
|
||||||
|
|
||||||
for (let i = 1; i <= maxN; i++){
|
for (let i = 1; i <= maxN; i++){
|
||||||
let className = 'running'+i;
|
let className = 'running'+i;
|
||||||
@@ -1500,9 +1523,9 @@ const taskbarAppIcon = new Lang.Class({
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function minimizeWindow(app, param){
|
function minimizeWindow(app, param, settings){
|
||||||
// Param true make all app windows minimize
|
// Param true make all app windows minimize
|
||||||
let windows = getAppInterestingWindows(app);
|
let windows = getInterestingWindows(app, settings);
|
||||||
let current_workspace = global.screen.get_active_workspace();
|
let current_workspace = global.screen.get_active_workspace();
|
||||||
for (let i = 0; i < windows.length; i++) {
|
for (let i = 0; i < windows.length; i++) {
|
||||||
let w = windows[i];
|
let w = windows[i];
|
||||||
@@ -1520,11 +1543,11 @@ function minimizeWindow(app, param){
|
|||||||
* By default only non minimized windows are activated.
|
* By default only non minimized windows are activated.
|
||||||
* This activates all windows in the current workspace.
|
* This activates all windows in the current workspace.
|
||||||
*/
|
*/
|
||||||
function activateAllWindows(app){
|
function activateAllWindows(app, settings){
|
||||||
|
|
||||||
// First activate first window so workspace is switched if needed,
|
// First activate first window so workspace is switched if needed,
|
||||||
// then activate all other app windows in the current workspace.
|
// then activate all other app windows in the current workspace.
|
||||||
let windows = getAppInterestingWindows(app);
|
let windows = getInterestingWindows(app, settings);
|
||||||
let w = windows[0];
|
let w = windows[0];
|
||||||
Main.activateWindow(w);
|
Main.activateWindow(w);
|
||||||
let activeWorkspace = global.screen.get_active_workspace_index();
|
let activeWorkspace = global.screen.get_active_workspace_index();
|
||||||
@@ -1542,9 +1565,9 @@ function activateAllWindows(app){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function activateFirstWindow(app){
|
function activateFirstWindow(app, settings){
|
||||||
|
|
||||||
let windows = getAppInterestingWindows(app).sort(function(windowA, windowB) {
|
let windows = getInterestingWindows(app, settings).sort(function(windowA, windowB) {
|
||||||
return windowA.get_stable_sequence() > windowB.get_stable_sequence();
|
return windowA.get_stable_sequence() > windowB.get_stable_sequence();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1554,9 +1577,9 @@ function activateFirstWindow(app){
|
|||||||
/*
|
/*
|
||||||
* Activate the next running window for the current application
|
* Activate the next running window for the current application
|
||||||
*/
|
*/
|
||||||
function activateNextWindow(app, shouldMinimize){
|
function activateNextWindow(app, shouldMinimize, settings){
|
||||||
|
|
||||||
let windows = getAppInterestingWindows(app).sort(function(windowA, windowB) {
|
let windows = getInterestingWindows(app, settings).sort(function(windowA, windowB) {
|
||||||
return windowA.get_stable_sequence() > windowB.get_stable_sequence();
|
return windowA.get_stable_sequence() > windowB.get_stable_sequence();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1567,22 +1590,20 @@ function activateNextWindow(app, shouldMinimize){
|
|||||||
if(i < windows.length - 1)
|
if(i < windows.length - 1)
|
||||||
Main.activateWindow(windows[i + 1]);
|
Main.activateWindow(windows[i + 1]);
|
||||||
else
|
else
|
||||||
shouldMinimize ? minimizeWindow(app, true) : Main.activateWindow(windows[0]);
|
shouldMinimize ? minimizeWindow(app, true, settings) : Main.activateWindow(windows[0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeAllWindows(app) {
|
function closeAllWindows(app, settings) {
|
||||||
let windows = getAppInterestingWindows(app);
|
let windows = getInterestingWindows(app, settings);
|
||||||
for (let i = 0; i < windows.length; i++)
|
for (let i = 0; i < windows.length; i++)
|
||||||
windows[i].delete(global.get_current_time());
|
windows[i].delete(global.get_current_time());
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAppInterestingWindows(app) {
|
function getAppInterestingWindows(app, settings) {
|
||||||
// Filter out unnecessary windows, for instance
|
|
||||||
// nautilus desktop window.
|
|
||||||
let windows = app.get_windows().filter(function(w) {
|
let windows = app.get_windows().filter(function(w) {
|
||||||
return !w.skip_taskbar;
|
return !w.skip_taskbar;
|
||||||
});
|
});
|
||||||
@@ -1590,6 +1611,22 @@ function getAppInterestingWindows(app) {
|
|||||||
return windows;
|
return windows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Filter out unnecessary windows, for instance
|
||||||
|
// nautilus desktop window.
|
||||||
|
function getInterestingWindows(app, settings) {
|
||||||
|
let windows = app.get_windows().filter(function(w) {
|
||||||
|
return !w.skip_taskbar;
|
||||||
|
});
|
||||||
|
|
||||||
|
// When using workspace isolation, we filter out windows
|
||||||
|
// that are not in the current workspace
|
||||||
|
if (settings.get_boolean('isolate-workspaces'))
|
||||||
|
windows = windows.filter(function(w) {
|
||||||
|
return w.get_workspace().index() == global.screen.get_active_workspace_index();
|
||||||
|
});
|
||||||
|
|
||||||
|
return windows;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a copy of the same function in utils.js, but also adjust horizontal scrolling
|
* This is a copy of the same function in utils.js, but also adjust horizontal scrolling
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ const thumbnailPreviewMenu = new Lang.Class({
|
|||||||
Name: 'thumbnailPreviewMenu',
|
Name: 'thumbnailPreviewMenu',
|
||||||
Extends: PopupMenu.PopupMenu,
|
Extends: PopupMenu.PopupMenu,
|
||||||
|
|
||||||
_init: function(source) {
|
_init: function(source, settings) {
|
||||||
|
|
||||||
|
this._dtpSettings = settings;
|
||||||
|
|
||||||
let side = Taskbar.getPosition();
|
let side = Taskbar.getPosition();
|
||||||
|
|
||||||
@@ -82,7 +84,7 @@ const thumbnailPreviewMenu = new Lang.Class({
|
|||||||
this._boxPointer._arrowSide = side;
|
this._boxPointer._arrowSide = side;
|
||||||
this._boxPointer._userArrowSide = side;
|
this._boxPointer._userArrowSide = side;
|
||||||
|
|
||||||
this._previewBox = new thumbnailPreviewList(this._app, THUMBNAIL_HEIGHT);
|
this._previewBox = new thumbnailPreviewList(this._app, this._dtpSettings);
|
||||||
this.addMenuItem(this._previewBox);
|
this.addMenuItem(this._previewBox);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@ const thumbnailPreviewMenu = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
popup: function() {
|
popup: function() {
|
||||||
let windows = Taskbar.getAppInterestingWindows(this._app);
|
let windows = Taskbar.getInterestingWindows(this._app, this._dtpSettings);
|
||||||
if (windows.length > 0) {
|
if (windows.length > 0) {
|
||||||
this._redisplay();
|
this._redisplay();
|
||||||
this.open();
|
this.open();
|
||||||
@@ -408,7 +410,9 @@ const thumbnailPreviewList = new Lang.Class({
|
|||||||
Name: 'thumbnailPreviewList',
|
Name: 'thumbnailPreviewList',
|
||||||
Extends: PopupMenu.PopupMenuSection,
|
Extends: PopupMenu.PopupMenuSection,
|
||||||
|
|
||||||
_init: function(app) {
|
_init: function(app, settings) {
|
||||||
|
this._dtpSettings = settings;
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
|
|
||||||
this._ensurePreviewVisibilityTimeoutId = 0;
|
this._ensurePreviewVisibilityTimeoutId = 0;
|
||||||
@@ -561,7 +565,7 @@ const thumbnailPreviewList = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_redisplay: function () {
|
_redisplay: function () {
|
||||||
let windows = Taskbar.getAppInterestingWindows(this.app).sort(this.sortWindowsCompareFunction);
|
let windows = Taskbar.getInterestingWindows(this.app, this._dtpSettings).sort(this.sortWindowsCompareFunction);
|
||||||
let children = this.box.get_children().filter(function(actor) {
|
let children = this.box.get_children().filter(function(actor) {
|
||||||
return actor._delegate.window && actor._delegate.preview;
|
return actor._delegate.window && actor._delegate.preview;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user