workspaces: Rework workspace controls for the view selector
As workspaces will appear as a particular view in the view selector, merge WorkspacesControls and WorkspacesManager to control workspaces and related controls, so that a single actor can be added to the selector instead of positioning the elements from the overview. https://bugzilla.gnome.org/show_bug.cgi?id=634948
This commit is contained in:
parent
6c5c3bedbe
commit
7811632e6f
@ -262,21 +262,46 @@ StTooltip StLabel {
|
|||||||
spacing: 25px;
|
spacing: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workspaces-bar {
|
.workspace-indicator-panel {
|
||||||
spacing: 5px;
|
spacing: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workspace-indicator {
|
.workspace-indicator {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
background: rgba(155,155,155,0.8);
|
background: rgba(255,255,255,0.2);
|
||||||
border-spacing: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.workspace-indicator.active {
|
.workspace-indicator.active {
|
||||||
background: rgba(255,255,255,0.8);
|
background: rgba(255,255,255,0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.workspace-controls {
|
||||||
|
width: 48px;
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ffffff;
|
||||||
|
border: 2px solid rgba(128, 128, 128, 0.4);
|
||||||
|
border-right: 0px;
|
||||||
|
border-radius: 9px 0px 0px 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-workspace {
|
||||||
|
background-color: rgba(128, 128, 128, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-workspace:hover {
|
||||||
|
background-color: rgba(128, 128, 128, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-workspace {
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-workspace:hover {
|
||||||
|
background-color: rgba(128, 128, 128, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
.window-caption {
|
.window-caption {
|
||||||
background: rgba(0,0,0,0.8);
|
background: rgba(0,0,0,0.8);
|
||||||
border: 1px solid rgba(128,128,128,0.40);
|
border: 1px solid rgba(128,128,128,0.40);
|
||||||
@ -294,39 +319,6 @@ StTooltip StLabel {
|
|||||||
-shell-close-overlap: 16px;
|
-shell-close-overlap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.single-view-controls {
|
|
||||||
padding: 0px 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-controls {
|
|
||||||
width: 24px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-controls.add {
|
|
||||||
background-image: url("add-workspace.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-controls.remove {
|
|
||||||
background-image: url("remove-workspace.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-controls.switch-single {
|
|
||||||
background-image: url("single-view.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-controls.switch-mosaic {
|
|
||||||
background-image: url("mosaic-view.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-controls.switch-single:checked {
|
|
||||||
background-image: url("single-view-active.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-controls.switch-mosaic:checked {
|
|
||||||
background-image: url("mosaic-view-active.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dash */
|
/* Dash */
|
||||||
|
|
||||||
#dash {
|
#dash {
|
||||||
|
@ -184,18 +184,10 @@ Overview.prototype = {
|
|||||||
|
|
||||||
this._group = new St.Group({ name: 'overview' });
|
this._group = new St.Group({ name: 'overview' });
|
||||||
this._group._delegate = this;
|
this._group._delegate = this;
|
||||||
this._group.connect('destroy', Lang.bind(this,
|
|
||||||
function() {
|
|
||||||
if (this._lightbox) {
|
|
||||||
this._lightbox.destroy();
|
|
||||||
this._lightbox = null;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
this.shellInfo = new ShellInfo();
|
this.shellInfo = new ShellInfo();
|
||||||
|
|
||||||
this._workspacesManager = null;
|
this._workspacesDisplay = null;
|
||||||
this._lightbox = null;
|
|
||||||
|
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
this.animationInProgress = false;
|
this.animationInProgress = false;
|
||||||
@ -258,18 +250,6 @@ Overview.prototype = {
|
|||||||
return clone;
|
return clone;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onViewChanged: function() {
|
|
||||||
if (!this.visible)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.workspaces = this._workspacesManager.workspacesView;
|
|
||||||
|
|
||||||
// Show new workspacesView
|
|
||||||
this._group.add_actor(this.workspaces.actor);
|
|
||||||
this._workspacesBar.raise(this.workspaces.actor);
|
|
||||||
this._dash.actor.raise(this.workspaces.actor);
|
|
||||||
},
|
|
||||||
|
|
||||||
_recalculateGridSizes: function () {
|
_recalculateGridSizes: function () {
|
||||||
let primary = global.get_primary_monitor();
|
let primary = global.get_primary_monitor();
|
||||||
wideScreen = (primary.width/primary.height > WIDE_SCREEN_CUT_OFF_RATIO) &&
|
wideScreen = (primary.width/primary.height > WIDE_SCREEN_CUT_OFF_RATIO) &&
|
||||||
@ -326,10 +306,6 @@ Overview.prototype = {
|
|||||||
}
|
}
|
||||||
this._dash.actor.height = this._workspacesHeight;
|
this._dash.actor.height = this._workspacesHeight;
|
||||||
|
|
||||||
// place the 'Add Workspace' button in the bottom row of the grid
|
|
||||||
this._workspacesBarX = this._workspacesX;
|
|
||||||
this._workspacesBarWidth = this._workspacesWidth;
|
|
||||||
this._workspacesBarY = primary.height - displayGridRowHeight;
|
|
||||||
|
|
||||||
this._paneContainer.set_position(this._dash.actor.x + this._dash.actor.width + DEFAULT_PADDING,
|
this._paneContainer.set_position(this._dash.actor.x + this._dash.actor.width + DEFAULT_PADDING,
|
||||||
this._workspacesY);
|
this._workspacesY);
|
||||||
@ -375,11 +351,6 @@ Overview.prototype = {
|
|||||||
this._activeDisplayPane.close();
|
this._activeDisplayPane.close();
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
if (!this._lightbox)
|
|
||||||
this._lightbox = new Lightbox.Lightbox(this._group,
|
|
||||||
{ fadeTime: PANE_FADE_TIME });
|
|
||||||
this._lightbox.show();
|
|
||||||
this._lightbox.highlight(this._paneContainer);
|
|
||||||
} else if (pane == this._activeDisplayPane) {
|
} else if (pane == this._activeDisplayPane) {
|
||||||
this._activeDisplayPane = null;
|
this._activeDisplayPane = null;
|
||||||
if (backgroundEventId != null) {
|
if (backgroundEventId != null) {
|
||||||
@ -388,7 +359,6 @@ Overview.prototype = {
|
|||||||
}
|
}
|
||||||
this._transparentBackground.lower_bottom();
|
this._transparentBackground.lower_bottom();
|
||||||
this._paneContainer.hide();
|
this._paneContainer.hide();
|
||||||
this._lightbox.hide();
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
@ -443,29 +413,23 @@ Overview.prototype = {
|
|||||||
this.animationInProgress = true;
|
this.animationInProgress = true;
|
||||||
|
|
||||||
/* TODO: make this stuff dynamic */
|
/* TODO: make this stuff dynamic */
|
||||||
this._workspacesManager =
|
this._workspacesDisplay =
|
||||||
new WorkspacesView.WorkspacesManager(this._workspacesWidth,
|
new WorkspacesView.WorkspacesDisplay(this._workspacesWidth,
|
||||||
this._workspacesHeight,
|
this._workspacesHeight,
|
||||||
this._workspacesX,
|
this._workspacesX,
|
||||||
this._workspacesY);
|
this._workspacesY);
|
||||||
this._workspacesManager.connect('view-changed',
|
this._workspacesDisplay.actor.set_size(this._workspacesWidth,
|
||||||
Lang.bind(this, this._onViewChanged));
|
this._workspacesHeight);
|
||||||
this.workspaces = this._workspacesManager.workspacesView;
|
this._workspacesDisplay.actor.set_position(this._workspacesX,
|
||||||
|
this._workspacesY);
|
||||||
|
this._group.add_actor(this._workspacesDisplay.actor);
|
||||||
|
|
||||||
|
this._workspacesDisplay.show();
|
||||||
|
this.workspaces = this._workspacesDisplay.workspacesView;
|
||||||
|
|
||||||
|
// Show new workspacesView
|
||||||
this._group.add_actor(this.workspaces.actor);
|
this._group.add_actor(this.workspaces.actor);
|
||||||
|
|
||||||
// The workspaces actor is as big as the screen, so we have to raise the dash above it
|
|
||||||
// for drag and drop to work. In the future we should fix the workspaces to not
|
|
||||||
// be as big as the screen.
|
|
||||||
this._dash.actor.raise(this.workspaces.actor);
|
|
||||||
|
|
||||||
this._workspacesBar = this._workspacesManager.controlsBar.actor;
|
|
||||||
this._workspacesBar.set_position(this._workspacesBarX,
|
|
||||||
this._workspacesBarY);
|
|
||||||
this._workspacesBar.width = this._workspacesBarWidth;
|
|
||||||
|
|
||||||
this._group.add_actor(this._workspacesBar);
|
|
||||||
this._workspacesBar.raise(this.workspaces.actor);
|
|
||||||
|
|
||||||
if (!this._desktopFade.child)
|
if (!this._desktopFade.child)
|
||||||
this._desktopFade.child = this._getDesktopClone();
|
this._desktopFade.child = this._getDesktopClone();
|
||||||
|
|
||||||
@ -605,10 +569,8 @@ Overview.prototype = {
|
|||||||
this.workspaces.destroy();
|
this.workspaces.destroy();
|
||||||
this.workspaces = null;
|
this.workspaces = null;
|
||||||
|
|
||||||
this._workspacesBar.destroy();
|
this._workspacesDisplay.actor.destroy();
|
||||||
this._workspacesBar = null;
|
this._workspacesDisplay = null;
|
||||||
|
|
||||||
this._workspacesManager = null;
|
|
||||||
|
|
||||||
this._desktopFade.hide();
|
this._desktopFade.hide();
|
||||||
this._background.hide();
|
this._background.hide();
|
||||||
|
@ -22,135 +22,9 @@ const MAX_WORKSPACES = 16;
|
|||||||
const WORKSPACE_DRAGGING_SCALE = 0.85;
|
const WORKSPACE_DRAGGING_SCALE = 0.85;
|
||||||
|
|
||||||
|
|
||||||
|
const CONTROLS_POP_IN_FRACTION = 0.8;
|
||||||
|
const CONTROLS_POP_IN_TIME = 0.1;
|
||||||
|
|
||||||
function WorkspaceIndicator(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb) {
|
|
||||||
this._init(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb);
|
|
||||||
}
|
|
||||||
|
|
||||||
WorkspaceIndicator.prototype = {
|
|
||||||
_init: function(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb) {
|
|
||||||
this._activateWorkspace = activateWorkspace;
|
|
||||||
this._workspaceAcceptDrop = workspaceAcceptDrop;
|
|
||||||
this._workspaceHandleDragOver = workspaceHandleDragOver;
|
|
||||||
this._scrollEventCb = scrollEventCb;
|
|
||||||
let actor = new St.Bin({ style_class: 'panel-button' });
|
|
||||||
|
|
||||||
this._indicatorsPanel = new Shell.GenericContainer();
|
|
||||||
this._indicatorsPanel.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
|
||||||
this._indicatorsPanel.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
|
||||||
this._indicatorsPanel.connect('allocate', Lang.bind(this, this._allocate));
|
|
||||||
this._indicatorsPanel.clip_to_allocation = true;
|
|
||||||
|
|
||||||
actor.set_child(this._indicatorsPanel);
|
|
||||||
actor.set_alignment(St.Align.MIDDLE, St.Align.MIDDLE);
|
|
||||||
this._indicatorsPanel.hide();
|
|
||||||
actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
|
||||||
|
|
||||||
let workId = Main.initializeDeferredWork(actor, Lang.bind(this, this._workspacesChanged));
|
|
||||||
this._nWorkspacesNotifyId =
|
|
||||||
global.screen.connect('notify::n-workspaces', function() {
|
|
||||||
Main.queueDeferredWork(workId);
|
|
||||||
});
|
|
||||||
this._switchWorkspaceNotifyId =
|
|
||||||
global.window_manager.connect('switch-workspace', function() {
|
|
||||||
Main.queueDeferredWork(workId);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.actor = actor;
|
|
||||||
},
|
|
||||||
|
|
||||||
_workspacesChanged: function() {
|
|
||||||
let active = global.screen.get_active_workspace_index();
|
|
||||||
let n = global.screen.n_workspaces;
|
|
||||||
if (n > 1)
|
|
||||||
this._indicatorsPanel.show();
|
|
||||||
else
|
|
||||||
this._indicatorsPanel.hide();
|
|
||||||
this._fillPositionalIndicator();
|
|
||||||
},
|
|
||||||
|
|
||||||
_onDestroy: function() {
|
|
||||||
if (this._nWorkspacesNotifyId > 0)
|
|
||||||
global.screen.disconnect(this._nWorkspacesNotifyId);
|
|
||||||
this._nWorkspacesNotifyId = 0;
|
|
||||||
if (this._switchWorkspaceNotifyId > 0)
|
|
||||||
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
|
||||||
this._switchWorkspaceNotifyId = 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
_allocate: function(actor, box, flags) {
|
|
||||||
let children = actor.get_children();
|
|
||||||
let childBox = new Clutter.ActorBox();
|
|
||||||
for (let i = 0; i < children.length; i++) {
|
|
||||||
childBox.x1 = children[i].x;
|
|
||||||
childBox.y1 = 0;
|
|
||||||
childBox.x2 = children[i].x + children[i].width;
|
|
||||||
childBox.y2 = children[i].height;
|
|
||||||
children[i].allocate(childBox, flags);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getPreferredWidth: function(actor, fh, alloc) {
|
|
||||||
let children = actor.get_children();
|
|
||||||
let width = 0;
|
|
||||||
for (let i = 0; i < children.length; i++) {
|
|
||||||
if (children[i].x + children[i].width <= width)
|
|
||||||
continue;
|
|
||||||
width = children[i].x + children[i].width;
|
|
||||||
}
|
|
||||||
alloc.min_size = 0;
|
|
||||||
alloc.natural_size = width;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getPreferredHeight: function(actor, fw, alloc) {
|
|
||||||
let children = actor.get_children();
|
|
||||||
let height = 0;
|
|
||||||
if (children.length)
|
|
||||||
height = children[0].height;
|
|
||||||
alloc.min_size = height;
|
|
||||||
alloc.natural_size = height;
|
|
||||||
},
|
|
||||||
|
|
||||||
_addIndicatorClone: function(i, active) {
|
|
||||||
let actor = new St.Button({ style_class: 'workspace-indicator' });
|
|
||||||
if (active) {
|
|
||||||
actor.style_class = 'workspace-indicator active';
|
|
||||||
}
|
|
||||||
actor.connect('clicked', Lang.bind(this, function() {
|
|
||||||
this._activateWorkspace(i);
|
|
||||||
}));
|
|
||||||
|
|
||||||
actor._delegate = {};
|
|
||||||
actor._delegate.acceptDrop = Lang.bind(this, function(source, actor, x, y, time) {
|
|
||||||
if (this._workspaceAcceptDrop(i, source, actor, x, y, time)) {
|
|
||||||
this._activateWorkspace(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
actor._delegate.handleDragOver = Lang.bind(this, function(source, actor, x, y, time) {
|
|
||||||
return this._workspaceHandleDragOver(i, source, actor, x, y, time);
|
|
||||||
});
|
|
||||||
|
|
||||||
actor.connect('scroll-event', this._scrollEventCb);
|
|
||||||
|
|
||||||
this._indicatorsPanel.add_actor(actor);
|
|
||||||
|
|
||||||
let spacing = actor.get_theme_node().get_length('border-spacing');
|
|
||||||
actor.x = spacing * i + actor.width * i;
|
|
||||||
},
|
|
||||||
|
|
||||||
_fillPositionalIndicator: function() {
|
|
||||||
this._indicatorsPanel.remove_all();
|
|
||||||
|
|
||||||
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
|
||||||
let n = global.screen.n_workspaces;
|
|
||||||
for (let i = 0; i < n; i++) {
|
|
||||||
this._addIndicatorClone(i, i == activeWorkspaceIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function WorkspacesView(width, height, x, y, workspaces) {
|
function WorkspacesView(width, height, x, y, workspaces) {
|
||||||
this._init(width, height, x, y, workspaces);
|
this._init(width, height, x, y, workspaces);
|
||||||
@ -775,6 +649,8 @@ WorkspacesView.prototype = {
|
|||||||
dragMotion: Lang.bind(this, this._onDragMotion)
|
dragMotion: Lang.bind(this, this._onDragMotion)
|
||||||
};
|
};
|
||||||
DND.addDragMonitor(this._dragMonitor);
|
DND.addDragMonitor(this._dragMonitor);
|
||||||
|
|
||||||
|
this.emit('window-drag-begin');
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDragMotion: function(dragEvent) {
|
_onDragMotion: function(dragEvent) {
|
||||||
@ -865,6 +741,8 @@ WorkspacesView.prototype = {
|
|||||||
|
|
||||||
for (let i = 0; i < this._workspaces.length; i++)
|
for (let i = 0; i < this._workspaces.length; i++)
|
||||||
this._workspaces[i].setReservedSlot(null);
|
this._workspaces[i].setReservedSlot(null);
|
||||||
|
|
||||||
|
this.emit('window-drag-end');
|
||||||
},
|
},
|
||||||
|
|
||||||
// sync the workspaces' positions to the value of the scroll adjustment
|
// sync the workspaces' positions to the value of the scroll adjustment
|
||||||
@ -901,6 +779,128 @@ WorkspacesView.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getWorkspaceIndexToRemove: function() {
|
||||||
|
return global.screen.get_active_workspace_index();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Signals.addSignalMethods(WorkspacesView.prototype);
|
||||||
|
|
||||||
|
|
||||||
|
function WorkspaceIndicatorPanel() {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkspaceIndicatorPanel.prototype = {
|
||||||
|
_init: function() {
|
||||||
|
this.actor = new Shell.GenericContainer({ clip_to_allocation: true });
|
||||||
|
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
|
||||||
|
this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
|
||||||
|
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
|
|
||||||
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
||||||
|
|
||||||
|
this._box = new St.BoxLayout({ style_class: 'workspace-indicator-panel' });
|
||||||
|
this.actor.add_actor(this._box);
|
||||||
|
|
||||||
|
this._switchWorkspaceNotifyId =
|
||||||
|
global.window_manager.connect('switch-workspace',
|
||||||
|
Lang.bind(this, this._updateActive));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDestroy: function() {
|
||||||
|
if (this._switchWorkspaceNotifyId > 0)
|
||||||
|
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
||||||
|
this._switchWorkspaceNotifyId = 0;
|
||||||
|
this._workspaces = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Allocate the box centered to the available area like StBin would do,
|
||||||
|
// except that the full height is used even if the box is not actually
|
||||||
|
// shown. This is a workaround, as the size of the workspace area is
|
||||||
|
// determined once when entering the overview, so if it would take up
|
||||||
|
// the indicator space in that case, it would overlap it later when
|
||||||
|
// additional workspaces were added.
|
||||||
|
_allocate: function(actor, box, flags) {
|
||||||
|
let children = this._box.get_children();
|
||||||
|
|
||||||
|
let availWidth = box.x2 - box.x1;
|
||||||
|
let availHeight = box.y2 - box.y1;
|
||||||
|
let [minWidth, natWidth] = this._box.get_preferred_width(-1);
|
||||||
|
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
childBox.x1 = Math.floor((availWidth - natWidth) / 2);
|
||||||
|
childBox.x2 = childBox.x1 + natWidth;
|
||||||
|
childBox.y1 = 0;
|
||||||
|
childBox.y2 = availHeight;
|
||||||
|
|
||||||
|
this._box.allocate(childBox, flags);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||||
|
let [minWidth, natWidth] = this._box.get_preferred_width(-1);
|
||||||
|
alloc.min_size = 0;
|
||||||
|
alloc.natural_size = natWidth;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||||
|
let [minHeight, natHeight] = this._box.get_preferred_height(-1);
|
||||||
|
alloc.min_size = minHeight;
|
||||||
|
alloc.natural_size = natHeight;
|
||||||
|
},
|
||||||
|
|
||||||
|
updateWorkspaces: function(workspaces) {
|
||||||
|
this._workspaces = workspaces;
|
||||||
|
|
||||||
|
// Do not display a single indicator
|
||||||
|
if (this._workspaces.length == 1)
|
||||||
|
this.actor.set_skip_paint(this._box, true);
|
||||||
|
else
|
||||||
|
this.actor.set_skip_paint(this._box, false);
|
||||||
|
|
||||||
|
this._box.remove_all();
|
||||||
|
for (let i = 0; i < this._workspaces.length; i++) {
|
||||||
|
let actor = new St.Button({ style_class: 'workspace-indicator' });
|
||||||
|
let workspace = this._workspaces[i];
|
||||||
|
let metaWorkspace = this._workspaces[i].metaWorkspace;
|
||||||
|
|
||||||
|
actor.connect('clicked', Lang.bind(this, function() {
|
||||||
|
metaWorkspace.activate(global.get_current_time());
|
||||||
|
}));
|
||||||
|
|
||||||
|
actor._delegate = {
|
||||||
|
acceptDrop: Lang.bind(this,
|
||||||
|
function(source, actor, x, y, time) {
|
||||||
|
if (workspace.acceptDrop(source, actor, x, y, time)) {
|
||||||
|
metaWorkspace.activate(time);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}),
|
||||||
|
handleDragOver: Lang.bind(this,
|
||||||
|
function(source, actor, x, y, time) {
|
||||||
|
return workspace.handleDragOver(source, actor, x, y, time);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
actor.connect('scroll-event', Lang.bind(this, this._onScrollEvent));
|
||||||
|
|
||||||
|
this._box.add(actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateActive();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateActive: function() {
|
||||||
|
let children = this._box.get_children();
|
||||||
|
let activeIndex = global.screen.get_active_workspace_index();
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
if (i == activeIndex)
|
||||||
|
children[i].add_style_class_name('active');
|
||||||
|
else
|
||||||
|
children[i].remove_style_class_name('active');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// handle scroll wheel events:
|
// handle scroll wheel events:
|
||||||
// activate the next or previous workspace and let the signal handler
|
// activate the next or previous workspace and let the signal handler
|
||||||
// manage the animation
|
// manage the animation
|
||||||
@ -921,140 +921,118 @@ WorkspacesView.prototype = {
|
|||||||
let metaWorkspace = this._workspaces[activate].metaWorkspace;
|
let metaWorkspace = this._workspaces[activate].metaWorkspace;
|
||||||
metaWorkspace.activate(global.get_current_time());
|
metaWorkspace.activate(global.get_current_time());
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
createControllerBar: function() {
|
|
||||||
let actor = new St.BoxLayout({ style_class: 'single-view-controls',
|
|
||||||
pack_start: true,
|
|
||||||
vertical: true });
|
|
||||||
|
|
||||||
let indicator = new WorkspaceIndicator(Lang.bind(this, function(i) {
|
|
||||||
if (this._workspaces[i] != undefined)
|
|
||||||
this._workspaces[i].metaWorkspace.activate(global.get_current_time());
|
|
||||||
}), Lang.bind(this, function(i, source, actor, x, y, time) {
|
|
||||||
if (this._workspaces[i] != undefined)
|
|
||||||
return this._workspaces[i].acceptDrop(source, actor, x, y, time);
|
|
||||||
return false;
|
|
||||||
}), Lang.bind(this, function(i, source, actor, x, y, time) {
|
|
||||||
if (this._workspaces[i] != undefined)
|
|
||||||
return this._workspaces[i].handleDragOver(source, actor, x, y, time);
|
|
||||||
return DND.DragMotionResult.CONTINUE;
|
|
||||||
}), Lang.bind(this, this._onScrollEvent));
|
|
||||||
|
|
||||||
actor.add(indicator.actor, { expand: true, x_fill: true, y_fill: true });
|
|
||||||
return actor;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getWorkspaceIndexToRemove: function() {
|
|
||||||
return global.screen.get_active_workspace_index();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function WorkspacesControls() {
|
|
||||||
this._init();
|
function WorkspaceControlsContainer(controls) {
|
||||||
|
this._init(controls);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkspacesControls.prototype = {
|
WorkspaceControlsContainer.prototype = {
|
||||||
_init: function() {
|
_init: function(controls) {
|
||||||
this.actor = new St.BoxLayout({ style_class: 'workspaces-bar' });
|
this.actor = new Shell.GenericContainer({ clip_to_allocation: true });
|
||||||
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
this.actor.connect('get-preferred-width',
|
||||||
|
Lang.bind(this, this._getPreferredWidth));
|
||||||
|
this.actor.connect('get-preferred-height',
|
||||||
|
Lang.bind(this, this._getPreferredHeight));
|
||||||
|
this.actor.connect('allocate', Lang.bind(this, this._allocate));
|
||||||
|
|
||||||
this._currentView = null;
|
this.actor.add_actor(controls);
|
||||||
|
|
||||||
// View specific controls
|
this._controls = controls;
|
||||||
this._viewControls = new St.Bin({ x_fill: true, y_fill: true });
|
this._controls.reactive = true;
|
||||||
this.actor.add(this._viewControls, { expand: true, x_fill: true });
|
this._controls.track_hover = true;
|
||||||
|
this._controls.connect('notify::hover',
|
||||||
|
Lang.bind(this, this._onHoverChanged));
|
||||||
|
|
||||||
// Add/remove workspace buttons
|
this._itemDragBeginId = 0;
|
||||||
this._removeButton = new St.Button({ style_class: 'workspace-controls remove' });
|
this._itemDragEndId = 0;
|
||||||
this._removeButton.connect('clicked', Lang.bind(this, function() {
|
|
||||||
this._currentView.removeWorkspace();
|
|
||||||
}));
|
|
||||||
this.actor.add(this._removeButton, { y_fill: false,
|
|
||||||
y_align: St.Align.START });
|
|
||||||
|
|
||||||
this._addButton = new St.Button({ style_class: 'workspace-controls add' });
|
|
||||||
this._addButton.connect('clicked', Lang.bind(this, function() {
|
|
||||||
this._currentView.addWorkspace();
|
|
||||||
}));
|
|
||||||
this._addButton._delegate = this._addButton;
|
|
||||||
this._addButton._delegate.acceptDrop = Lang.bind(this,
|
|
||||||
function(source, actor, x, y, time) {
|
|
||||||
return this._currentView._acceptNewWorkspaceDrop(source, actor, x, y, time);
|
|
||||||
});
|
|
||||||
this._addButton._delegate.handleDragOver = Lang.bind(this,
|
|
||||||
function(source, actor, x, y, time) {
|
|
||||||
return this._currentView._handleDragOverNewWorkspace(source, actor, x, y, time);
|
|
||||||
});
|
|
||||||
this.actor.add(this._addButton, { y_fill: false,
|
|
||||||
y_align: St.Align.START });
|
|
||||||
|
|
||||||
this._nWorkspacesNotifyId =
|
|
||||||
global.screen.connect('notify::n-workspaces',
|
|
||||||
Lang.bind(this, this.updateControlsSensitivity));
|
|
||||||
this._switchWorkspaceNotifyId =
|
|
||||||
global.window_manager.connect('switch-workspace',
|
|
||||||
Lang.bind(this, this.updateControlsSensitivity));
|
|
||||||
|
|
||||||
this.updateControlsSensitivity();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updateControls: function(view) {
|
show: function() {
|
||||||
this._currentView = view;
|
if (this._itemDragBeginId == 0)
|
||||||
|
this._itemDragBeginId = Main.overview.connect('item-drag-begin',
|
||||||
|
Lang.bind(this, this.popOut));
|
||||||
|
if (this._itemDragEndId == 0)
|
||||||
|
this._itemDragEndId = Main.overview.connect('item-drag-end',
|
||||||
|
Lang.bind(this, this.popIn));
|
||||||
|
this._controls.x = this._poppedInX();
|
||||||
|
},
|
||||||
|
|
||||||
this.updateControlsSensitivity();
|
hide: function() {
|
||||||
|
if (this._itemDragBeginId > 0) {
|
||||||
let newControls = this._currentView.createControllerBar();
|
Main.overview.disconnect(this._itemDragBeginId);
|
||||||
if (newControls) {
|
this._itemDragBeginId = 0;
|
||||||
this._viewControls.child = newControls;
|
}
|
||||||
this._viewControls.child.opacity = 0;
|
if (this._itemEndBeginId > 0) {
|
||||||
Tweener.addTween(this._viewControls.child,
|
Main.overview.disconnect(this._itemDragEndId);
|
||||||
{ opacity: 255,
|
this._itemDragEndId = 0;
|
||||||
time: Overview.ANIMATION_TIME,
|
|
||||||
transition: 'easeOutQuad' });
|
|
||||||
} else {
|
|
||||||
if (this._viewControls.child)
|
|
||||||
Tweener.addTween(this._viewControls.child,
|
|
||||||
{ opacity: 0,
|
|
||||||
time: Overview.ANIMATION_TIME,
|
|
||||||
transition: 'easeOutQuad',
|
|
||||||
onComplete: Lang.bind(this, function() {
|
|
||||||
this._viewControls.child.destroy();
|
|
||||||
})});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDestroy: function() {
|
_getPreferredWidth: function(actor, forHeight, alloc) {
|
||||||
if (this._nWorkspacesNotifyId > 0) {
|
let [minWidth, natWidth] = this._controls.get_preferred_width(-1);
|
||||||
global.screen.disconnect(this._nWorkspacesNotifyId);
|
alloc.min_size = minWidth;
|
||||||
this._nWorkspacesNotifyId = 0;
|
alloc.natural_size = natWidth;
|
||||||
}
|
|
||||||
if (this._switchWorkspaceNotifyId > 0) {
|
|
||||||
global.window_manager.disconnect(this._switchWorkspaceNotifyId);
|
|
||||||
this._switchWorkspaceNotifyId = 0;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_setButtonSensitivity: function(button, sensitive) {
|
// Always request the full width ...
|
||||||
if (button == null)
|
_getPreferredHeight: function(actor, forWidth, alloc) {
|
||||||
return;
|
let [minHeight, natHeight] = this._controls.get_preferred_height(-1);
|
||||||
button.opacity = sensitive ? 255 : 85;
|
alloc.min_size = minHeight;
|
||||||
|
alloc.natural_size = natHeight;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateControlsSensitivity: function() {
|
// ... even when the controls are popped in, to keep the width constant.
|
||||||
if (this._currentView) {
|
// This is necessary as the workspace size is determined once before
|
||||||
this._setButtonSensitivity(this._removeButton, this._currentView.canRemoveWorkspace());
|
// entering the overview, when the controls are popped in - if the width
|
||||||
this._setButtonSensitivity(this._addButton, this._currentView.canAddWorkspace());
|
// varied, the workspaces would be given too much width, and the controls
|
||||||
}
|
// would be overlapped by the workspaces when popped out, rendering them
|
||||||
|
// useless.
|
||||||
|
_allocate: function(actor, box, flags) {
|
||||||
|
let childBox = new Clutter.ActorBox();
|
||||||
|
childBox.x1 = this._controls.x;
|
||||||
|
childBox.x2 = this._controls.x + this._controls.width;
|
||||||
|
childBox.y1 = 0;
|
||||||
|
childBox.y2 = box.y2 - box.y1;
|
||||||
|
this._controls.allocate(childBox, flags);
|
||||||
|
},
|
||||||
|
|
||||||
|
_onHoverChanged: function() {
|
||||||
|
if (this._controls.hover)
|
||||||
|
this.popOut();
|
||||||
|
else
|
||||||
|
this.popIn();
|
||||||
|
},
|
||||||
|
|
||||||
|
_poppedInX: function() {
|
||||||
|
let x = CONTROLS_POP_IN_FRACTION * this._controls.width;
|
||||||
|
if (St.Widget.get_default_direction() == St.TextDirection.RTL)
|
||||||
|
return -x;
|
||||||
|
return x;
|
||||||
|
},
|
||||||
|
|
||||||
|
popOut: function() {
|
||||||
|
Tweener.addTween(this._controls,
|
||||||
|
{ x: 0,
|
||||||
|
time: CONTROLS_POP_IN_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
|
},
|
||||||
|
|
||||||
|
popIn: function() {
|
||||||
|
Tweener.addTween(this._controls,
|
||||||
|
{ x: this._poppedInX(),
|
||||||
|
time: CONTROLS_POP_IN_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(WorkspacesControls.prototype);
|
|
||||||
|
|
||||||
function WorkspacesManager(width, height, x, y) {
|
function WorkspacesDisplay(width, height, x, y) {
|
||||||
this._init(width, height, x, y);
|
this._init(width, height, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkspacesManager.prototype = {
|
WorkspacesDisplay.prototype = {
|
||||||
_init: function(width, height, x, y) {
|
_init: function(width, height, x, y) {
|
||||||
this._workspacesWidth = width;
|
this._workspacesWidth = width;
|
||||||
this._workspacesHeight = height;
|
this._workspacesHeight = height;
|
||||||
@ -1067,18 +1045,52 @@ WorkspacesManager.prototype = {
|
|||||||
this._workspaces[w] = new Workspace.Workspace(metaWorkspace);
|
this._workspaces[w] = new Workspace.Workspace(metaWorkspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.workspacesView = null;
|
this.actor = new St.BoxLayout();
|
||||||
this.controlsBar = new WorkspacesControls();
|
|
||||||
this._updateView();
|
|
||||||
|
|
||||||
this.controlsBar.actor.connect('destroy',
|
let workspacesBox = new St.BoxLayout({ vertical: true });
|
||||||
Lang.bind(this, this._onDestroy));
|
this.actor.add(workspacesBox, { expand: true });
|
||||||
this._nWorkspacesNotifyId =
|
|
||||||
global.screen.connect('notify::n-workspaces',
|
// placeholder for window previews
|
||||||
Lang.bind(this, this._workspacesChanged));
|
workspacesBox.add(new St.Bin(), { expand: true });
|
||||||
|
|
||||||
|
this._workspaceIndicatorPanel = new WorkspaceIndicatorPanel();
|
||||||
|
workspacesBox.add(this._workspaceIndicatorPanel.actor);
|
||||||
|
|
||||||
|
let controls = new St.BoxLayout({ vertical: true,
|
||||||
|
style_class: 'workspace-controls' });
|
||||||
|
this._controlsContainer = new WorkspaceControlsContainer(controls);
|
||||||
|
this.actor.add(this._controlsContainer.actor);
|
||||||
|
|
||||||
|
// Add/remove workspace buttons
|
||||||
|
this._removeButton = new St.Button({ label: '–', // n-dash
|
||||||
|
style_class: 'remove-workspace' });
|
||||||
|
this._removeButton.connect('clicked', Lang.bind(this, function() {
|
||||||
|
this.workspacesView.removeWorkspace();
|
||||||
|
}));
|
||||||
|
controls.add(this._removeButton);
|
||||||
|
|
||||||
|
this._addButton = new St.Button({ label: '+',
|
||||||
|
style_class: 'add-workspace' });
|
||||||
|
this._addButton.connect('clicked', Lang.bind(this, function() {
|
||||||
|
this.workspacesView.addWorkspace();
|
||||||
|
}));
|
||||||
|
this._addButton._delegate = this._addButton;
|
||||||
|
this._addButton._delegate.acceptDrop = Lang.bind(this,
|
||||||
|
function(source, actor, x, y, time) {
|
||||||
|
return this.workspacesView._acceptNewWorkspaceDrop(source, actor, x, y, time);
|
||||||
|
});
|
||||||
|
this._addButton._delegate.handleDragOver = Lang.bind(this,
|
||||||
|
function(source, actor, x, y, time) {
|
||||||
|
return this.workspacesView._handleDragOverNewWorkspace(source, actor, x, y, time);
|
||||||
|
});
|
||||||
|
controls.add(this._addButton, { expand: true });
|
||||||
|
|
||||||
|
this.workspacesView = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateView: function() {
|
show: function() {
|
||||||
|
this._controlsContainer.show();
|
||||||
|
|
||||||
let newView = new WorkspacesView(this._workspacesWidth,
|
let newView = new WorkspacesView(this._workspacesWidth,
|
||||||
this._workspacesHeight,
|
this._workspacesHeight,
|
||||||
this._workspacesX,
|
this._workspacesX,
|
||||||
@ -1089,9 +1101,33 @@ WorkspacesManager.prototype = {
|
|||||||
this.workspacesView.destroy();
|
this.workspacesView.destroy();
|
||||||
this.workspacesView = newView;
|
this.workspacesView = newView;
|
||||||
|
|
||||||
this.controlsBar.updateControls(this.workspacesView);
|
this.workspacesView.connect('window-drag-begin', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._controlsContainer.popOut();
|
||||||
|
}));
|
||||||
|
this.workspacesView.connect('window-drag-end', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._controlsContainer.popIn();
|
||||||
|
}));
|
||||||
|
|
||||||
this.emit('view-changed');
|
this._workspaceIndicatorPanel.updateWorkspaces(this._workspaces);
|
||||||
|
|
||||||
|
this._nWorkspacesNotifyId =
|
||||||
|
global.screen.connect('notify::n-workspaces',
|
||||||
|
Lang.bind(this, this._workspacesChanged));
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function() {
|
||||||
|
this._controlsContainer.hide();
|
||||||
|
|
||||||
|
if (this._nWorkspacesNotifyId > 0)
|
||||||
|
global.screen.disconnect(this._nWorkspacesNotifyId);
|
||||||
|
this.workspacesView.destroy();
|
||||||
|
this.workspacesView = null;
|
||||||
|
for (let w = 0; w < this._workspaces.length; w++) {
|
||||||
|
this._workspaces[w].disconnectAll();
|
||||||
|
this._workspaces[w].destroy();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_workspacesChanged: function() {
|
_workspacesChanged: function() {
|
||||||
@ -1134,17 +1170,7 @@ WorkspacesManager.prototype = {
|
|||||||
this.workspacesView.updateWorkspaces(oldNumWorkspaces,
|
this.workspacesView.updateWorkspaces(oldNumWorkspaces,
|
||||||
newNumWorkspaces,
|
newNumWorkspaces,
|
||||||
lostWorkspaces);
|
lostWorkspaces);
|
||||||
},
|
this._workspaceIndicatorPanel.updateWorkspaces(this._workspaces);
|
||||||
|
|
||||||
_onDestroy: function() {
|
|
||||||
if (this._nWorkspacesNotifyId > 0)
|
|
||||||
global.screen.disconnect(this._nWorkspacesNotifyId);
|
|
||||||
if (this._viewChangedId > 0)
|
|
||||||
global.settings.disconnect(this._viewChangedId);
|
|
||||||
for (let w = 0; w < this._workspaces.length; w++) {
|
|
||||||
this._workspaces[w].disconnectAll();
|
|
||||||
this._workspaces[w].destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Signals.addSignalMethods(WorkspacesManager.prototype);
|
Signals.addSignalMethods(WorkspacesDisplay.prototype);
|
||||||
|
Loading…
Reference in New Issue
Block a user