2011-09-28 09:16:26 -04:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
2019-01-31 09:07:06 -05:00
|
|
|
/* exported Overview */
|
2008-10-31 19:09:46 -04:00
|
|
|
|
2019-08-30 21:51:02 -04:00
|
|
|
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
|
2009-02-02 18:02:16 -05:00
|
|
|
const Signals = imports.signals;
|
|
|
|
|
2012-12-24 09:20:39 -05:00
|
|
|
const Background = imports.ui.background;
|
2011-01-05 09:47:27 -05:00
|
|
|
const DND = imports.ui.dnd;
|
2013-03-01 18:00:59 -05:00
|
|
|
const LayoutManager = imports.ui.layout;
|
2014-03-06 10:17:36 -05:00
|
|
|
const Lightbox = imports.ui.lightbox;
|
2009-02-02 18:02:16 -05:00
|
|
|
const Main = imports.ui.main;
|
2010-07-22 11:49:43 -04:00
|
|
|
const MessageTray = imports.ui.messageTray;
|
2012-12-11 17:26:09 -05:00
|
|
|
const OverviewControls = imports.ui.overviewControls;
|
2011-08-28 10:24:48 -04:00
|
|
|
const Params = imports.misc.params;
|
2013-04-22 17:56:34 -04:00
|
|
|
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
|
2008-10-31 19:09:46 -04:00
|
|
|
|
2009-08-11 07:46:10 -04:00
|
|
|
// Time for initial animation going into Overview mode
|
2019-08-01 19:13:10 -04:00
|
|
|
var ANIMATION_TIME = 250;
|
2008-11-06 09:00:14 -05:00
|
|
|
|
2012-12-24 09:20:39 -05:00
|
|
|
// Must be less than ANIMATION_TIME, since we switch to
|
|
|
|
// or from the overview completely after ANIMATION_TIME,
|
|
|
|
// and don't want the shading animation to get cut off
|
2019-08-01 19:13:10 -04:00
|
|
|
var SHADE_ANIMATION_TIME = 200;
|
2011-01-05 09:47:27 -05:00
|
|
|
|
2017-07-18 13:47:27 -04:00
|
|
|
var DND_WINDOW_SWITCH_TIMEOUT = 750;
|
2012-08-29 20:22:39 -04:00
|
|
|
|
2017-07-18 13:47:27 -04:00
|
|
|
var OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
|
2013-03-01 16:00:37 -05:00
|
|
|
|
2017-10-30 21:19:44 -04:00
|
|
|
var ShellInfo = class {
|
|
|
|
constructor() {
|
2010-07-22 11:49:43 -04:00
|
|
|
this._source = null;
|
2010-02-08 17:50:50 -05:00
|
|
|
this._undoCallback = null;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-02-08 17:50:50 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onUndoClicked() {
|
2010-02-08 17:50:50 -05:00
|
|
|
if (this._undoCallback)
|
|
|
|
this._undoCallback();
|
|
|
|
this._undoCallback = null;
|
|
|
|
|
2010-07-22 11:49:43 -04:00
|
|
|
if (this._source)
|
|
|
|
this._source.destroy();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-02-08 17:50:50 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
setMessage(text, options) {
|
2019-02-12 09:02:09 -05:00
|
|
|
options = Params.parse(options, {
|
|
|
|
undoCallback: null,
|
|
|
|
forFeedback: false,
|
|
|
|
});
|
2012-11-02 13:06:40 -04:00
|
|
|
|
|
|
|
let undoCallback = options.undoCallback;
|
|
|
|
let forFeedback = options.forFeedback;
|
|
|
|
|
2010-07-22 11:49:43 -04:00
|
|
|
if (this._source == null) {
|
2010-11-30 10:47:28 -05:00
|
|
|
this._source = new MessageTray.SystemNotificationSource();
|
2017-10-30 20:38:18 -04:00
|
|
|
this._source.connect('destroy', () => {
|
|
|
|
this._source = null;
|
|
|
|
});
|
2010-07-22 11:49:43 -04:00
|
|
|
Main.messageTray.add(this._source);
|
|
|
|
}
|
2010-02-08 17:50:50 -05:00
|
|
|
|
2011-03-21 17:43:34 -04:00
|
|
|
let notification = null;
|
|
|
|
if (this._source.notifications.length == 0) {
|
2010-07-22 11:49:43 -04:00
|
|
|
notification = new MessageTray.Notification(this._source, text, null);
|
2012-08-20 10:14:22 -04:00
|
|
|
notification.setTransient(true);
|
2012-11-02 13:06:40 -04:00
|
|
|
notification.setForFeedback(forFeedback);
|
2011-03-21 17:43:34 -04:00
|
|
|
} else {
|
|
|
|
notification = this._source.notifications[0];
|
2010-07-22 11:49:43 -04:00
|
|
|
notification.update(text, null, { clear: true });
|
2011-03-21 17:43:34 -04:00
|
|
|
}
|
2010-03-10 09:14:56 -05:00
|
|
|
|
2010-02-08 17:50:50 -05:00
|
|
|
this._undoCallback = undoCallback;
|
2013-10-13 23:06:09 -04:00
|
|
|
if (undoCallback)
|
2017-12-01 19:27:35 -05:00
|
|
|
notification.addAction(_("Undo"), this._onUndoClicked.bind(this));
|
2010-07-22 11:49:43 -04:00
|
|
|
|
2019-05-13 17:32:31 -04:00
|
|
|
this._source.showNotification(notification);
|
2010-02-08 17:50:50 -05:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
};
|
2010-02-08 17:50:50 -05:00
|
|
|
|
2019-08-30 21:51:02 -04:00
|
|
|
var OverviewActor = GObject.registerClass(
|
|
|
|
class OverviewActor extends St.BoxLayout {
|
|
|
|
_init() {
|
|
|
|
super._init({
|
|
|
|
name: 'overview',
|
|
|
|
/* Translators: This is the main view to select
|
|
|
|
activities. See also note for "Activities" string. */
|
|
|
|
accessible_name: _("Overview"),
|
2019-08-20 17:43:54 -04:00
|
|
|
vertical: true,
|
2019-08-30 21:51:02 -04:00
|
|
|
});
|
|
|
|
|
|
|
|
this.add_constraint(new LayoutManager.MonitorConstraint({ primary: true }));
|
|
|
|
|
|
|
|
// Add a clone of the panel to the overview so spacing and such is
|
|
|
|
// automatic
|
|
|
|
let panelGhost = new St.Bin({
|
|
|
|
child: new Clutter.Clone({ source: Main.panel }),
|
|
|
|
reactive: false,
|
2019-08-20 17:43:54 -04:00
|
|
|
opacity: 0,
|
2019-08-30 21:51:02 -04:00
|
|
|
});
|
|
|
|
this.add_actor(panelGhost);
|
|
|
|
|
|
|
|
this._searchEntry = new St.Entry({
|
|
|
|
style_class: 'search-entry',
|
|
|
|
/* Translators: this is the text displayed
|
|
|
|
in the search entry when no search is
|
|
|
|
active; it should not exceed ~30
|
|
|
|
characters. */
|
2020-02-14 16:11:27 -05:00
|
|
|
hint_text: _('Type to search'),
|
2019-08-30 21:51:02 -04:00
|
|
|
track_hover: true,
|
2019-08-20 17:43:54 -04:00
|
|
|
can_focus: true,
|
2019-08-30 21:51:02 -04:00
|
|
|
});
|
2020-02-19 06:09:07 -05:00
|
|
|
this._searchEntry.set_offscreen_redirect(Clutter.OffscreenRedirect.ON_IDLE);
|
2019-08-30 21:51:02 -04:00
|
|
|
let searchEntryBin = new St.Bin({
|
|
|
|
child: this._searchEntry,
|
2019-10-17 17:40:24 -04:00
|
|
|
x_align: Clutter.ActorAlign.CENTER,
|
2019-08-30 21:51:02 -04:00
|
|
|
});
|
|
|
|
this.add_actor(searchEntryBin);
|
|
|
|
|
|
|
|
this._controls = new OverviewControls.ControlsManager(this._searchEntry);
|
|
|
|
|
|
|
|
// Add our same-line elements after the search entry
|
2019-10-21 14:44:00 -04:00
|
|
|
this.add_child(this._controls);
|
2019-08-30 21:51:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
get dash() {
|
|
|
|
return this._controls.dash;
|
|
|
|
}
|
|
|
|
|
|
|
|
get searchEntry() {
|
|
|
|
return this._searchEntry;
|
|
|
|
}
|
|
|
|
|
|
|
|
get viewSelector() {
|
|
|
|
return this._controls.viewSelector;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-10-30 21:19:44 -04:00
|
|
|
var Overview = class {
|
|
|
|
constructor() {
|
2012-11-29 11:58:31 -05:00
|
|
|
this._initCalled = false;
|
2020-01-29 11:48:57 -05:00
|
|
|
this._visible = false;
|
2012-09-01 08:42:53 -04:00
|
|
|
|
2017-12-01 19:27:35 -05:00
|
|
|
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
2012-09-01 08:42:53 -04:00
|
|
|
this._sessionUpdated();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-08-28 10:24:48 -04:00
|
|
|
|
2019-08-30 21:51:02 -04:00
|
|
|
get dash() {
|
|
|
|
return this._overview.dash;
|
|
|
|
}
|
|
|
|
|
|
|
|
get dashIconSize() {
|
|
|
|
logError(new Error('Usage of Overview.\'dashIconSize\' is deprecated, ' +
|
|
|
|
'use \'dash.iconSize\' property instead'));
|
|
|
|
return this.dash.iconSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
get viewSelector() {
|
|
|
|
return this._overview.viewSelector;
|
|
|
|
}
|
|
|
|
|
2019-08-30 22:04:34 -04:00
|
|
|
get animationInProgress() {
|
|
|
|
return this._animationInProgress;
|
|
|
|
}
|
|
|
|
|
|
|
|
get visible() {
|
|
|
|
return this._visible;
|
|
|
|
}
|
|
|
|
|
|
|
|
get visibleTarget() {
|
|
|
|
return this._visibleTarget;
|
|
|
|
}
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_createOverview() {
|
2019-08-30 21:51:02 -04:00
|
|
|
if (this._overview)
|
2011-08-28 10:24:48 -04:00
|
|
|
return;
|
2012-09-01 08:42:53 -04:00
|
|
|
|
|
|
|
if (this.isDummy)
|
|
|
|
return;
|
|
|
|
|
2015-07-16 09:14:50 -04:00
|
|
|
// The main Background actors are inside global.window_group which are
|
|
|
|
// hidden when displaying the overview, so we create a new
|
|
|
|
// one. Instances of this class share a single CoglTexture behind the
|
|
|
|
// scenes which allows us to show the background with different
|
|
|
|
// rendering options without duplicating the texture data.
|
2016-05-26 12:20:25 -04:00
|
|
|
this._backgroundGroup = new Meta.BackgroundGroup({ reactive: true });
|
2013-05-21 16:15:01 -04:00
|
|
|
Main.layoutManager.overviewGroup.add_child(this._backgroundGroup);
|
2012-12-24 09:20:39 -05:00
|
|
|
this._bgManagers = [];
|
|
|
|
|
2014-01-24 17:05:46 -05:00
|
|
|
this._desktopFade = new St.Widget();
|
2013-11-14 10:34:59 -05:00
|
|
|
Main.layoutManager.overviewGroup.add_child(this._desktopFade);
|
|
|
|
|
2013-03-01 16:00:37 -05:00
|
|
|
this._activationTime = 0;
|
|
|
|
|
2019-08-30 22:04:34 -04:00
|
|
|
this._visible = false; // animating to overview, in overview, animating out
|
2011-01-05 09:39:36 -05:00
|
|
|
this._shown = false; // show() and not hide()
|
|
|
|
this._modal = false; // have a modal grab
|
2019-08-30 22:04:34 -04:00
|
|
|
this._animationInProgress = false;
|
|
|
|
this._visibleTarget = false;
|
2009-06-24 18:24:48 -04:00
|
|
|
|
2009-09-13 14:54:56 -04:00
|
|
|
// During transitions, we raise this to the top to avoid having the overview
|
|
|
|
// area be reactive; it causes too many issues such as double clicks on
|
|
|
|
// Dash elements, or mouseover handlers in the workspaces.
|
2013-05-08 21:53:20 -04:00
|
|
|
this._coverPane = new Clutter.Actor({ opacity: 0,
|
|
|
|
reactive: true });
|
2013-09-29 17:20:27 -04:00
|
|
|
Main.layoutManager.overviewGroup.add_child(this._coverPane);
|
2017-10-30 20:38:18 -04:00
|
|
|
this._coverPane.connect('event', () => Clutter.EVENT_STOP);
|
2011-02-11 17:53:27 -05:00
|
|
|
this._coverPane.hide();
|
|
|
|
|
|
|
|
// XDND
|
|
|
|
this._dragMonitor = {
|
2019-08-20 17:43:54 -04:00
|
|
|
dragMotion: this._onDragMotion.bind(this),
|
2011-02-11 17:53:27 -05:00
|
|
|
};
|
|
|
|
|
2016-07-02 05:16:22 -04:00
|
|
|
|
|
|
|
Main.layoutManager.overviewGroup.connect('scroll-event',
|
2017-12-01 19:27:35 -05:00
|
|
|
this._onScrollEvent.bind(this));
|
|
|
|
Main.xdndHandler.connect('drag-begin', this._onDragBegin.bind(this));
|
|
|
|
Main.xdndHandler.connect('drag-end', this._onDragEnd.bind(this));
|
2011-02-11 17:53:27 -05:00
|
|
|
|
2018-01-03 02:55:38 -05:00
|
|
|
global.display.connect('restacked', this._onRestacked.bind(this));
|
2012-12-13 11:00:30 -05:00
|
|
|
|
2011-02-11 17:53:27 -05:00
|
|
|
this._windowSwitchTimeoutId = 0;
|
|
|
|
this._windowSwitchTimestamp = 0;
|
|
|
|
this._lastActiveWorkspaceIndex = -1;
|
|
|
|
this._lastHoveredWindow = null;
|
2012-11-29 11:58:31 -05:00
|
|
|
|
|
|
|
if (this._initCalled)
|
|
|
|
this.init();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-02-11 17:53:27 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_updateBackgrounds() {
|
2012-12-24 09:20:39 -05:00
|
|
|
for (let i = 0; i < this._bgManagers.length; i++)
|
|
|
|
this._bgManagers[i].destroy();
|
|
|
|
|
|
|
|
this._bgManagers = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < Main.layoutManager.monitors.length; i++) {
|
|
|
|
let bgManager = new Background.BackgroundManager({ container: this._backgroundGroup,
|
|
|
|
monitorIndex: i,
|
2014-08-11 12:15:45 -04:00
|
|
|
vignette: true });
|
2012-12-24 09:20:39 -05:00
|
|
|
this._bgManagers.push(bgManager);
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_unshadeBackgrounds() {
|
2012-12-24 09:20:39 -05:00
|
|
|
let backgrounds = this._backgroundGroup.get_children();
|
|
|
|
for (let i = 0; i < backgrounds.length; i++) {
|
2019-07-24 20:06:05 -04:00
|
|
|
backgrounds[i].ease_property('brightness', 1.0, {
|
|
|
|
duration: SHADE_ANIMATION_TIME,
|
2019-08-20 17:43:54 -04:00
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
2019-07-24 20:06:05 -04:00
|
|
|
});
|
|
|
|
backgrounds[i].ease_property('vignette-sharpness', 0.0, {
|
|
|
|
duration: SHADE_ANIMATION_TIME,
|
2019-08-20 17:43:54 -04:00
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
2019-07-24 20:06:05 -04:00
|
|
|
});
|
2012-12-24 09:20:39 -05:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_shadeBackgrounds() {
|
2012-12-24 09:20:39 -05:00
|
|
|
let backgrounds = this._backgroundGroup.get_children();
|
|
|
|
for (let i = 0; i < backgrounds.length; i++) {
|
2019-07-24 20:06:05 -04:00
|
|
|
backgrounds[i].ease_property('brightness', Lightbox.VIGNETTE_BRIGHTNESS, {
|
|
|
|
duration: SHADE_ANIMATION_TIME,
|
2019-08-20 17:43:54 -04:00
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
2019-07-24 20:06:05 -04:00
|
|
|
});
|
|
|
|
backgrounds[i].ease_property('vignette-sharpness', Lightbox.VIGNETTE_SHARPNESS, {
|
|
|
|
duration: SHADE_ANIMATION_TIME,
|
2019-08-20 17:43:54 -04:00
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
2019-07-24 20:06:05 -04:00
|
|
|
});
|
2012-12-24 09:20:39 -05:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-24 09:20:39 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_sessionUpdated() {
|
2012-09-01 08:42:53 -04:00
|
|
|
this.isDummy = !Main.sessionMode.hasOverview;
|
|
|
|
this._createOverview();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-09-01 08:42:53 -04:00
|
|
|
|
2011-02-11 17:53:27 -05:00
|
|
|
// The members we construct that are implemented in JS might
|
|
|
|
// want to access the overview as Main.overview to connect
|
|
|
|
// signal handlers and so forth. So we create them after
|
|
|
|
// construction in this init() method.
|
2017-10-30 20:03:21 -04:00
|
|
|
init() {
|
2012-11-29 11:58:31 -05:00
|
|
|
this._initCalled = true;
|
|
|
|
|
2011-08-28 10:24:48 -04:00
|
|
|
if (this.isDummy)
|
|
|
|
return;
|
|
|
|
|
2019-08-30 21:51:02 -04:00
|
|
|
this._overview = new OverviewActor();
|
|
|
|
this._overview._delegate = this;
|
|
|
|
Main.layoutManager.overviewGroup.add_child(this._overview);
|
2012-12-10 15:39:15 -05:00
|
|
|
|
2019-08-30 21:51:02 -04:00
|
|
|
this._shellInfo = new ShellInfo();
|
2013-01-24 16:34:06 -05:00
|
|
|
|
2017-12-01 19:27:35 -05:00
|
|
|
Main.layoutManager.connect('monitors-changed', this._relayout.bind(this));
|
2011-06-13 09:54:05 -04:00
|
|
|
this._relayout();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2009-06-24 18:24:48 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
addSearchProvider(provider) {
|
2011-07-09 09:30:42 -04:00
|
|
|
this.viewSelector.addSearchProvider(provider);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-08-28 07:20:37 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
removeSearchProvider(provider) {
|
2011-07-09 09:30:42 -04:00
|
|
|
this.viewSelector.removeSearchProvider(provider);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-09-03 06:01:33 -04:00
|
|
|
|
2012-11-02 13:06:40 -04:00
|
|
|
//
|
|
|
|
// options:
|
|
|
|
// - undoCallback (function): the callback to be called if undo support is needed
|
|
|
|
// - forFeedback (boolean): whether the message is for direct feedback of a user action
|
|
|
|
//
|
2017-10-30 20:03:21 -04:00
|
|
|
setMessage(text, options) {
|
2011-08-28 10:24:48 -04:00
|
|
|
if (this.isDummy)
|
|
|
|
return;
|
|
|
|
|
2012-11-02 13:06:40 -04:00
|
|
|
this._shellInfo.setMessage(text, options);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-08-28 10:07:44 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onDragBegin() {
|
2013-03-04 17:02:02 -05:00
|
|
|
this._inXdndDrag = true;
|
|
|
|
|
2011-01-05 09:47:27 -05:00
|
|
|
DND.addDragMonitor(this._dragMonitor);
|
|
|
|
// Remember the workspace we started from
|
2018-01-03 02:55:38 -05:00
|
|
|
let workspaceManager = global.workspace_manager;
|
|
|
|
this._lastActiveWorkspaceIndex = workspaceManager.get_active_workspace_index();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-01-05 09:47:27 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onDragEnd(time) {
|
2013-03-04 17:02:02 -05:00
|
|
|
this._inXdndDrag = false;
|
|
|
|
|
2011-01-05 09:47:27 -05:00
|
|
|
// In case the drag was canceled while in the overview
|
|
|
|
// we have to go back to where we started and hide
|
|
|
|
// the overview
|
2013-03-04 17:02:02 -05:00
|
|
|
if (this._shown) {
|
2018-01-03 02:55:38 -05:00
|
|
|
let workspaceManager = global.workspace_manager;
|
|
|
|
workspaceManager.get_workspace_by_index(this._lastActiveWorkspaceIndex).activate(time);
|
2013-03-04 17:02:02 -05:00
|
|
|
this.hide();
|
2011-01-05 09:47:27 -05:00
|
|
|
}
|
2011-02-24 05:30:46 -05:00
|
|
|
this._resetWindowSwitchTimeout();
|
2011-01-07 05:12:00 -05:00
|
|
|
this._lastHoveredWindow = null;
|
2011-06-27 12:59:56 -04:00
|
|
|
DND.removeDragMonitor(this._dragMonitor);
|
2011-03-13 14:34:47 -04:00
|
|
|
this.endItemDrag();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-01-05 09:47:27 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_resetWindowSwitchTimeout() {
|
2011-02-24 05:30:46 -05:00
|
|
|
if (this._windowSwitchTimeoutId != 0) {
|
2019-08-19 14:50:33 -04:00
|
|
|
GLib.source_remove(this._windowSwitchTimeoutId);
|
2011-02-24 05:30:46 -05:00
|
|
|
this._windowSwitchTimeoutId = 0;
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-02-24 05:30:46 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onDragMotion(dragEvent) {
|
2011-01-07 05:12:00 -05:00
|
|
|
let targetIsWindow = dragEvent.targetActor &&
|
|
|
|
dragEvent.targetActor._delegate &&
|
2011-03-21 18:20:36 -04:00
|
|
|
dragEvent.targetActor._delegate.metaWindow &&
|
|
|
|
!(dragEvent.targetActor._delegate instanceof WorkspaceThumbnail.WindowClone);
|
2011-01-07 05:12:00 -05:00
|
|
|
|
2011-02-24 05:25:29 -05:00
|
|
|
this._windowSwitchTimestamp = global.get_current_time();
|
|
|
|
|
2011-01-07 05:12:00 -05:00
|
|
|
if (targetIsWindow &&
|
|
|
|
dragEvent.targetActor._delegate.metaWindow == this._lastHoveredWindow)
|
2011-01-20 10:46:55 -05:00
|
|
|
return DND.DragMotionResult.CONTINUE;
|
|
|
|
|
|
|
|
this._lastHoveredWindow = null;
|
2011-01-07 05:12:00 -05:00
|
|
|
|
2011-02-24 05:30:46 -05:00
|
|
|
this._resetWindowSwitchTimeout();
|
2011-01-05 09:47:27 -05:00
|
|
|
|
2011-01-07 05:12:00 -05:00
|
|
|
if (targetIsWindow) {
|
|
|
|
this._lastHoveredWindow = dragEvent.targetActor._delegate.metaWindow;
|
2019-08-19 14:50:33 -04:00
|
|
|
this._windowSwitchTimeoutId = GLib.timeout_add(
|
|
|
|
GLib.PRIORITY_DEFAULT,
|
|
|
|
DND_WINDOW_SWITCH_TIMEOUT,
|
2017-10-30 20:38:18 -04:00
|
|
|
() => {
|
|
|
|
this._windowSwitchTimeoutId = 0;
|
|
|
|
Main.activateWindow(dragEvent.targetActor._delegate.metaWindow,
|
|
|
|
this._windowSwitchTimestamp);
|
|
|
|
this.hide();
|
|
|
|
this._lastHoveredWindow = null;
|
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
});
|
2014-04-10 13:26:52 -04:00
|
|
|
GLib.Source.set_name_by_id(this._windowSwitchTimeoutId, '[gnome-shell] Main.activateWindow');
|
2011-01-05 09:47:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return DND.DragMotionResult.CONTINUE;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-01-05 09:47:27 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onScrollEvent(actor, event) {
|
2012-10-22 11:39:19 -04:00
|
|
|
this.emit('scroll-event', event);
|
2013-11-29 13:17:34 -05:00
|
|
|
return Clutter.EVENT_PROPAGATE;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-10-22 11:39:19 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
addAction(action) {
|
2012-11-25 23:40:48 -05:00
|
|
|
if (this.isDummy)
|
|
|
|
return;
|
|
|
|
|
2016-05-26 12:20:25 -04:00
|
|
|
this._backgroundGroup.add_action(action);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-11-25 23:40:48 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_getDesktopClone() {
|
2017-10-30 20:38:18 -04:00
|
|
|
let windows = global.get_window_actors().filter(
|
|
|
|
w => w.meta_window.get_window_type() == Meta.WindowType.DESKTOP
|
|
|
|
);
|
2010-07-15 10:21:32 -04:00
|
|
|
if (windows.length == 0)
|
|
|
|
return null;
|
|
|
|
|
2012-10-04 14:01:03 -04:00
|
|
|
let window = windows[0];
|
2017-02-01 13:01:47 -05:00
|
|
|
let clone = new Clutter.Clone({ source: window,
|
2012-10-04 14:01:03 -04:00
|
|
|
x: window.x, y: window.y });
|
2017-10-30 20:38:18 -04:00
|
|
|
clone.source.connect('destroy', () => {
|
2010-07-15 10:21:32 -04:00
|
|
|
clone.destroy();
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2010-07-15 10:21:32 -04:00
|
|
|
return clone;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-07-15 10:21:32 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_relayout() {
|
2011-06-13 09:54:05 -04:00
|
|
|
// To avoid updating the position and size of the workspaces
|
|
|
|
// we just hide the overview. The positions will be updated
|
|
|
|
// when it is next shown.
|
|
|
|
this.hide();
|
|
|
|
|
2018-07-24 08:45:03 -04:00
|
|
|
this._coverPane.set_position(0, 0);
|
|
|
|
this._coverPane.set_size(global.screen_width, global.screen_height);
|
2012-12-24 09:20:39 -05:00
|
|
|
|
|
|
|
this._updateBackgrounds();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2008-12-01 14:51:43 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onRestacked() {
|
2012-12-13 11:00:30 -05:00
|
|
|
let stack = global.get_window_actors();
|
|
|
|
let stackIndices = {};
|
|
|
|
|
|
|
|
for (let i = 0; i < stack.length; i++) {
|
|
|
|
// Use the stable sequence for an integer to use as a hash key
|
|
|
|
stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.emit('windows-restacked', stackIndices);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-12-13 11:00:30 -05:00
|
|
|
|
2019-01-31 09:08:10 -05:00
|
|
|
beginItemDrag(_source) {
|
2010-05-08 10:06:28 -04:00
|
|
|
this.emit('item-drag-begin');
|
2017-11-16 11:27:12 -05:00
|
|
|
this._inItemDrag = true;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2009-03-11 15:21:45 -04:00
|
|
|
|
2019-01-31 09:08:10 -05:00
|
|
|
cancelledItemDrag(_source) {
|
2011-03-09 10:40:48 -05:00
|
|
|
this.emit('item-drag-cancelled');
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-03-09 10:40:48 -05:00
|
|
|
|
2019-01-31 09:08:10 -05:00
|
|
|
endItemDrag(_source) {
|
2017-11-16 11:27:12 -05:00
|
|
|
if (!this._inItemDrag)
|
|
|
|
return;
|
2010-05-08 10:06:28 -04:00
|
|
|
this.emit('item-drag-end');
|
2017-11-16 11:27:12 -05:00
|
|
|
this._inItemDrag = false;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2009-03-11 15:21:45 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
beginWindowDrag(window) {
|
2014-09-03 15:55:05 -04:00
|
|
|
this.emit('window-drag-begin', window);
|
2017-11-16 11:27:12 -05:00
|
|
|
this._inWindowDrag = true;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-11-15 15:58:27 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
cancelledWindowDrag(window) {
|
2014-09-03 15:55:05 -04:00
|
|
|
this.emit('window-drag-cancelled', window);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-03-08 08:44:47 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
endWindowDrag(window) {
|
2017-11-16 11:27:12 -05:00
|
|
|
if (!this._inWindowDrag)
|
|
|
|
return;
|
2014-09-03 15:55:05 -04:00
|
|
|
this.emit('window-drag-end', window);
|
2017-11-16 11:27:12 -05:00
|
|
|
this._inWindowDrag = false;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2010-11-15 15:58:27 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
focusSearch() {
|
2013-05-17 11:31:27 -04:00
|
|
|
this.show();
|
2019-08-30 21:51:02 -04:00
|
|
|
this._overview.searchEntry.grab_key_focus();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-05-17 11:31:27 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
fadeInDesktop() {
|
2019-01-29 14:36:54 -05:00
|
|
|
this._desktopFade.opacity = 0;
|
|
|
|
this._desktopFade.show();
|
2018-07-20 15:46:19 -04:00
|
|
|
this._desktopFade.ease({
|
|
|
|
opacity: 255,
|
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
2019-08-20 17:43:54 -04:00
|
|
|
duration: ANIMATION_TIME,
|
2018-07-20 15:46:19 -04:00
|
|
|
});
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-07-28 16:06:46 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
fadeOutDesktop() {
|
2014-02-03 05:26:19 -05:00
|
|
|
if (!this._desktopFade.get_n_children()) {
|
|
|
|
let clone = this._getDesktopClone();
|
|
|
|
if (!clone)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this._desktopFade.add_child(clone);
|
|
|
|
}
|
2012-07-28 16:06:46 -04:00
|
|
|
|
|
|
|
this._desktopFade.opacity = 255;
|
|
|
|
this._desktopFade.show();
|
2018-07-20 15:46:19 -04:00
|
|
|
this._desktopFade.ease({
|
|
|
|
opacity: 0,
|
2019-09-14 07:39:28 -04:00
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
2019-08-20 17:43:54 -04:00
|
|
|
duration: ANIMATION_TIME,
|
2018-07-20 15:46:19 -04:00
|
|
|
});
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-07-28 16:06:46 -04:00
|
|
|
|
2014-07-03 09:33:09 -04:00
|
|
|
// Checks if the Activities button is currently sensitive to
|
|
|
|
// clicks. The first call to this function within the
|
|
|
|
// OVERVIEW_ACTIVATION_TIMEOUT time of the hot corner being
|
|
|
|
// triggered will return false. This avoids opening and closing
|
|
|
|
// the overview if the user both triggered the hot corner and
|
|
|
|
// clicked the Activities button.
|
2017-10-30 20:03:21 -04:00
|
|
|
shouldToggleByCornerOrButton() {
|
2019-08-30 22:04:34 -04:00
|
|
|
if (this._animationInProgress)
|
2014-07-03 09:33:09 -04:00
|
|
|
return false;
|
2017-11-16 11:27:12 -05:00
|
|
|
if (this._inItemDrag || this._inWindowDrag)
|
2014-07-03 09:33:09 -04:00
|
|
|
return false;
|
2019-08-30 21:51:02 -04:00
|
|
|
if (!this._activationTime ||
|
2018-01-15 09:36:44 -05:00
|
|
|
GLib.get_monotonic_time() / GLib.USEC_PER_SEC - this._activationTime > OVERVIEW_ACTIVATION_TIMEOUT)
|
2014-07-03 09:33:09 -04:00
|
|
|
return true;
|
|
|
|
return false;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-07-03 09:33:09 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_syncGrab() {
|
2014-07-03 09:33:09 -04:00
|
|
|
// We delay grab changes during animation so that when removing the
|
|
|
|
// overview we don't have a problem with the release of a press/release
|
|
|
|
// going to an application.
|
2019-08-30 22:04:34 -04:00
|
|
|
if (this._animationInProgress)
|
2014-07-03 09:33:09 -04:00
|
|
|
return true;
|
|
|
|
|
|
|
|
if (this._shown) {
|
|
|
|
let shouldBeModal = !this._inXdndDrag;
|
2019-08-19 22:25:24 -04:00
|
|
|
if (shouldBeModal && !this._modal) {
|
|
|
|
let actionMode = Shell.ActionMode.OVERVIEW;
|
|
|
|
if (Main.pushModal(this._overview, { actionMode })) {
|
|
|
|
this._modal = true;
|
|
|
|
} else {
|
|
|
|
this.hide();
|
|
|
|
return false;
|
2014-07-03 09:33:09 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2019-08-19 22:24:37 -04:00
|
|
|
// eslint-disable-next-line no-lonely-if
|
2014-07-03 09:33:09 -04:00
|
|
|
if (this._modal) {
|
|
|
|
Main.popModal(this._overview);
|
|
|
|
this._modal = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-07-03 09:33:09 -04:00
|
|
|
|
|
|
|
// show:
|
|
|
|
//
|
|
|
|
// Animates the overview visible and grabs mouse and keyboard input
|
2017-10-30 20:03:21 -04:00
|
|
|
show() {
|
2014-07-03 09:33:09 -04:00
|
|
|
if (this.isDummy)
|
|
|
|
return;
|
|
|
|
if (this._shown)
|
|
|
|
return;
|
|
|
|
this._shown = true;
|
|
|
|
|
|
|
|
if (!this._syncGrab())
|
|
|
|
return;
|
|
|
|
|
|
|
|
Main.layoutManager.showOverview();
|
|
|
|
this._animateVisible();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-07-03 09:33:09 -04:00
|
|
|
|
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_animateVisible() {
|
2019-08-30 22:04:34 -04:00
|
|
|
if (this._visible || this._animationInProgress)
|
2011-01-05 09:39:36 -05:00
|
|
|
return;
|
2008-11-28 15:12:20 -05:00
|
|
|
|
2019-08-30 22:04:34 -04:00
|
|
|
this._visible = true;
|
|
|
|
this._animationInProgress = true;
|
|
|
|
this._visibleTarget = true;
|
2018-01-15 09:36:44 -05:00
|
|
|
this._activationTime = GLib.get_monotonic_time() / GLib.USEC_PER_SEC;
|
2008-11-28 15:12:20 -05:00
|
|
|
|
2018-01-03 02:55:38 -05:00
|
|
|
Meta.disable_unredirect_for_display(global.display);
|
2011-07-09 09:30:42 -04:00
|
|
|
this.viewSelector.show();
|
2010-07-15 10:21:32 -04:00
|
|
|
|
2016-06-24 09:45:03 -04:00
|
|
|
this._overview.opacity = 0;
|
2018-07-20 15:46:19 -04:00
|
|
|
this._overview.ease({
|
|
|
|
opacity: 255,
|
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
|
|
|
duration: ANIMATION_TIME,
|
2019-08-20 17:43:54 -04:00
|
|
|
onComplete: () => this._showDone(),
|
2018-07-20 15:46:19 -04:00
|
|
|
});
|
2012-12-24 09:20:39 -05:00
|
|
|
this._shadeBackgrounds();
|
2011-08-28 21:41:28 -04:00
|
|
|
|
2019-11-05 14:17:19 -05:00
|
|
|
Main.layoutManager.overviewGroup.set_child_above_sibling(
|
|
|
|
this._coverPane, null);
|
2011-01-21 08:08:42 -05:00
|
|
|
this._coverPane.show();
|
2009-05-07 09:47:48 -04:00
|
|
|
this.emit('showing');
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2008-12-01 14:51:43 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_showDone() {
|
2019-08-30 22:04:34 -04:00
|
|
|
this._animationInProgress = false;
|
2014-07-03 09:33:09 -04:00
|
|
|
this._desktopFade.hide();
|
|
|
|
this._coverPane.hide();
|
|
|
|
|
|
|
|
this.emit('shown');
|
|
|
|
// Handle any calls to hide* while we were showing
|
|
|
|
if (!this._shown)
|
|
|
|
this._animateNotVisible();
|
|
|
|
|
|
|
|
this._syncGrab();
|
|
|
|
global.sync_pointer();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-07-03 09:33:09 -04:00
|
|
|
|
2011-01-05 09:39:36 -05:00
|
|
|
// hide:
|
|
|
|
//
|
|
|
|
// Reverses the effect of show()
|
2017-10-30 20:03:21 -04:00
|
|
|
hide() {
|
2011-08-28 10:24:48 -04:00
|
|
|
if (this.isDummy)
|
|
|
|
return;
|
|
|
|
|
2011-01-05 09:39:36 -05:00
|
|
|
if (!this._shown)
|
|
|
|
return;
|
|
|
|
|
2013-03-04 17:54:02 -05:00
|
|
|
let event = Clutter.get_current_event();
|
2013-03-14 11:34:09 -04:00
|
|
|
if (event) {
|
|
|
|
let type = event.type();
|
2019-08-19 15:38:51 -04:00
|
|
|
let button = type == Clutter.EventType.BUTTON_PRESS ||
|
|
|
|
type == Clutter.EventType.BUTTON_RELEASE;
|
2013-03-14 11:34:09 -04:00
|
|
|
let ctrl = (event.get_state() & Clutter.ModifierType.CONTROL_MASK) != 0;
|
|
|
|
if (button && ctrl)
|
|
|
|
return;
|
|
|
|
}
|
2013-02-21 09:57:00 -05:00
|
|
|
|
2011-01-05 09:39:36 -05:00
|
|
|
this._shown = false;
|
2014-11-26 21:05:36 -05:00
|
|
|
|
|
|
|
this._animateNotVisible();
|
2013-05-22 12:05:24 -04:00
|
|
|
this._syncGrab();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2011-01-05 09:39:36 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_animateNotVisible() {
|
2019-08-30 22:04:34 -04:00
|
|
|
if (!this._visible || this._animationInProgress)
|
2008-12-01 14:51:43 -05:00
|
|
|
return;
|
|
|
|
|
2019-08-30 22:04:34 -04:00
|
|
|
this._animationInProgress = true;
|
|
|
|
this._visibleTarget = false;
|
2010-07-15 10:21:32 -04:00
|
|
|
|
2014-07-14 13:06:08 -04:00
|
|
|
this.viewSelector.animateFromOverview();
|
2008-12-04 10:16:16 -05:00
|
|
|
|
2010-11-11 12:50:19 -05:00
|
|
|
// Make other elements fade out.
|
2018-07-20 15:46:19 -04:00
|
|
|
this._overview.ease({
|
|
|
|
opacity: 0,
|
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
|
|
|
duration: ANIMATION_TIME,
|
2019-08-20 17:43:54 -04:00
|
|
|
onComplete: () => this._hideDone(),
|
2018-07-20 15:46:19 -04:00
|
|
|
});
|
2012-12-24 09:20:39 -05:00
|
|
|
this._unshadeBackgrounds();
|
2011-08-28 21:41:28 -04:00
|
|
|
|
2019-11-05 14:17:19 -05:00
|
|
|
Main.layoutManager.overviewGroup.set_child_above_sibling(
|
|
|
|
this._coverPane, null);
|
2011-01-21 08:08:42 -05:00
|
|
|
this._coverPane.show();
|
2009-05-07 09:47:48 -04:00
|
|
|
this.emit('hiding');
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2009-05-07 09:47:48 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_hideDone() {
|
2011-08-29 17:55:42 -04:00
|
|
|
// Re-enable unredirection
|
2018-01-03 02:55:38 -05:00
|
|
|
Meta.enable_unredirect_for_display(global.display);
|
2011-08-29 17:55:42 -04:00
|
|
|
|
2011-07-09 09:30:42 -04:00
|
|
|
this.viewSelector.hide();
|
2010-07-15 10:21:32 -04:00
|
|
|
this._desktopFade.hide();
|
2013-05-22 12:05:24 -04:00
|
|
|
this._coverPane.hide();
|
2009-03-20 12:06:34 -04:00
|
|
|
|
2019-08-30 22:04:34 -04:00
|
|
|
this._visible = false;
|
|
|
|
this._animationInProgress = false;
|
2008-12-01 14:51:43 -05:00
|
|
|
|
2009-05-07 09:47:48 -04:00
|
|
|
this.emit('hidden');
|
2011-01-05 09:39:36 -05:00
|
|
|
// Handle any calls to show* while we were hiding
|
2013-03-04 17:02:02 -05:00
|
|
|
if (this._shown)
|
2011-01-05 09:39:36 -05:00
|
|
|
this._animateVisible();
|
2013-05-22 12:05:24 -04:00
|
|
|
else
|
|
|
|
Main.layoutManager.hideOverview();
|
2011-01-05 09:39:36 -05:00
|
|
|
|
2013-05-22 12:05:24 -04:00
|
|
|
this._syncGrab();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-07-03 09:33:09 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
toggle() {
|
2014-07-03 09:33:09 -04:00
|
|
|
if (this.isDummy)
|
|
|
|
return;
|
|
|
|
|
2019-08-30 22:04:34 -04:00
|
|
|
if (this._visible)
|
2014-07-03 09:33:09 -04:00
|
|
|
this.hide();
|
|
|
|
else
|
|
|
|
this.show();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-06-17 13:10:54 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
getShowAppsButton() {
|
2019-08-30 21:51:02 -04:00
|
|
|
logError(new Error('Usage of Overview.\'getShowAppsButton\' is deprecated, ' +
|
|
|
|
'use \'dash.showAppsButton\' property instead'));
|
|
|
|
|
|
|
|
return this.dash.showAppsButton;
|
2008-12-01 14:51:43 -05:00
|
|
|
}
|
2020-01-09 15:44:22 -05:00
|
|
|
|
|
|
|
get searchEntry() {
|
|
|
|
return this._overview.searchEntry;
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
};
|
2009-08-11 07:46:10 -04:00
|
|
|
Signals.addSignalMethods(Overview.prototype);
|