[gnome-shell/overview-relayout: 12/15] workspaces: Rework workspace controls for the view selector
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/overview-relayout: 12/15] workspaces: Rework workspace controls for the view selector
- Date: Thu, 11 Nov 2010 15:41:35 +0000 (UTC)
commit ca4eb9148c9f98282c749cd369f50fa76a058971
Author: Florian Müllner <fmuellner gnome org>
Date: Mon Oct 4 16:42:11 2010 +0200
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.
Also enforce linear view, the grid will have its comeback with the
new DND behavior.
data/theme/gnome-shell.css | 39 ++--
js/ui/overview.js | 65 ++----
js/ui/workspace.js | 63 -----
js/ui/workspacesView.js | 567 ++++++++++++++++++--------------------------
4 files changed, 269 insertions(+), 465 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 15982cb..5303503 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -293,8 +293,8 @@ StTooltip {
.workspace-indicator {
width: 24px;
height: 16px;
- background: rgba(155,155,155,0.8);
- border-spacing: 16px;
+ background: rgba(255,255,255,0.2);
+ border-spacing: 8px;
}
.workspace-indicator.active {
@@ -319,36 +319,33 @@ StTooltip {
}
.single-view-controls {
- padding: 0px 15px;
+ padding: 8px 0px;
}
.workspace-controls {
- width: 24px;
- height: 16px;
-}
-
-.workspace-controls.add {
- background-image: url("add-workspace.svg");
-}
-
-.workspace-controls.remove {
- background-image: url("remove-workspace.svg");
+ 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;
}
-.workspace-controls.switch-single {
- background-image: url("single-view.svg");
+.add-workspace {
+ background-color: rgba(128, 128, 128, 0.4);
}
-.workspace-controls.switch-mosaic {
- background-image: url("mosaic-view.svg");
+.add-workspace:hover {
+ background-color: rgba(128, 128, 128, 0.6);
}
-.workspace-controls.switch-single:checked {
- background-image: url("single-view-active.svg");
+.remove-workspace {
+ height: 48px;
}
-.workspace-controls.switch-mosaic:checked {
- background-image: url("mosaic-view-active.svg");
+.remove-workspace:hover {
+ background-color: rgba(128, 128, 128, 0.2);
}
/* Dash */
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 184f685..ae89d8b 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -177,18 +177,10 @@ Overview.prototype = {
this._group = new St.Group({ style_class: 'overview' });
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._workspacesManager = null;
- this._lightbox = null;
+ this._workspacesDisplay = null;
this.visible = false;
this.animationInProgress = false;
@@ -250,18 +242,6 @@ Overview.prototype = {
return new Clutter.Clone({ source: windows[0].get_texture() });
},
- _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._appWell.actor.raise(this.workspaces.actor);
- },
-
_recalculateGridSizes: function () {
let primary = global.get_primary_monitor();
wideScreen = (primary.width/primary.height > WIDE_SCREEN_CUT_OFF_RATIO) &&
@@ -317,11 +297,6 @@ Overview.prototype = {
this._appWell.actor.set_position(0, this._workspacesY);
}
- // 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;
-
// The parent (this._group) is positioned at the top left of the primary monitor
// while this._backOver occupies the entire screen.
this._backOver.set_position(- primary.x, - primary.y);
@@ -371,11 +346,6 @@ Overview.prototype = {
this._activeDisplayPane.close();
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) {
this._activeDisplayPane = null;
if (backgroundEventId != null) {
@@ -384,7 +354,6 @@ Overview.prototype = {
}
this._transparentBackground.lower_bottom();
this._paneContainer.hide();
- this._lightbox.hide();
}
}));
},
@@ -439,29 +408,29 @@ Overview.prototype = {
this.animationInProgress = true;
/* TODO: make this stuff dynamic */
- this._workspacesManager =
- new WorkspacesView.WorkspacesManager(this._workspacesWidth,
+ this._workspacesDisplay =
+ new WorkspacesView.WorkspacesDisplay(this._workspacesWidth,
this._workspacesHeight,
this._workspacesX,
this._workspacesY);
- this._workspacesManager.connect('view-changed',
- Lang.bind(this, this._onViewChanged));
- this.workspaces = this._workspacesManager.workspacesView;
+ this._workspacesDisplay.actor.set_size(this._workspacesWidth,
+ this._workspacesHeight);
+ 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._appWell.actor.raise(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._appWell.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._desktop.child)
this._desktop.child = this._getDesktopClone();
@@ -601,10 +570,8 @@ Overview.prototype = {
this.workspaces.destroy();
this.workspaces = null;
- this._workspacesBar.destroy();
- this._workspacesBar = null;
-
- this._workspacesManager = null;
+ this._workspacesDisplay.actor.destroy();
+ this._workspacesDisplay = null;
this._desktop.hide();
this._group.hide();
diff --git a/js/ui/workspace.js b/js/ui/workspace.js
index 574f8e4..65c3718 100644
--- a/js/ui/workspace.js
+++ b/js/ui/workspace.js
@@ -1329,69 +1329,6 @@ Workspace.prototype = {
this._visible = false;
},
- // Animates grid shrinking/expanding when a row or column
- // of workspaces is added or removed
- resizeToGrid : function (oldScale) {
- this._hideAllOverlays();
- Tweener.addTween(this.actor,
- { x: this.gridX,
- y: this.gridY,
- scale_x: this.scale,
- scale_y: this.scale,
- time: Overview.ANIMATION_TIME,
- transition: 'easeOutQuad',
- onComplete: Lang.bind(this, this._fadeInAllOverlays)
- });
- },
-
- // Animates the addition of a new (empty) workspace
- slideIn : function(oldScale) {
- if (this.gridCol > this.gridRow) {
- this.actor.set_position(global.screen_width, this.gridY);
- this.actor.set_scale(oldScale, oldScale);
- } else {
- this.actor.set_position(this.gridX, global.screen_height);
- this.actor.set_scale(this.scale, this.scale);
- }
- Tweener.addTween(this.actor,
- { x: this.gridX,
- y: this.gridY,
- scale_x: this.scale,
- scale_y: this.scale,
- time: Overview.ANIMATION_TIME,
- transition: 'easeOutQuad'
- });
-
- this._visible = true;
- },
-
- // Animates the removal of a workspace
- slideOut : function(onComplete) {
- let destX = this.actor.x, destY = this.actor.y;
-
- this._hideAllOverlays();
-
- if (this.gridCol > this.gridRow)
- destX = global.screen_width;
- else
- destY = global.screen_height;
- Tweener.addTween(this.actor,
- { x: destX,
- y: destY,
- scale_x: this.scale,
- scale_y: this.scale,
- time: Overview.ANIMATION_TIME,
- transition: 'easeOutQuad',
- onComplete: onComplete
- });
-
- this._visible = false;
-
- // Don't let the user try to select this workspace as it's
- // making its exit.
- this._desktop.reactive = false;
- },
-
destroy : function() {
this.actor.destroy();
},
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index da5db2b..f0afb4f 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -30,6 +30,9 @@ const WORKSPACES_VIEW_KEY = 'workspaces-view';
const WORKSPACE_DRAGGING_SCALE = 0.85;
const WORKSPACE_SHADOW_SCALE = (1 - WORKSPACE_DRAGGING_SCALE) / 2;
+const CONTROLS_POP_IN_FRACTION = 0.8;
+const CONTROLS_POP_IN_TIME = 0.1;
+
function GenericWorkspacesView(width, height, x, y, workspaces) {
this._init(width, height, x, y, workspaces);
}
@@ -221,10 +224,6 @@ GenericWorkspacesView.prototype = {
return [activeWorkspace.gridX, activeWorkspace.gridY];
},
- createControllerBar: function() {
- throw new Error('Not implemented');
- },
-
canAddWorkspace: function() {
return global.screen.n_workspaces < MAX_WORKSPACES;
},
@@ -463,110 +462,65 @@ MosaicView.prototype = {
this._workspaces[to].setSelected(true);
},
- createControllerBar: function() {
- return null;
- },
-
_getWorkspaceIndexToRemove: function() {
return this._workspaces.length - 1;
}
};
-function NewWorkspaceArea() {
+function WorkspaceIndicatorPanel() {
this._init();
}
-NewWorkspaceArea.prototype = {
+WorkspaceIndicatorPanel.prototype = {
_init: function() {
- let width = Math.ceil(global.screen_width * WORKSPACE_SHADOW_SCALE);
- this.actor = new Clutter.Group({ width: width,
- height: global.screen_height,
- x: global.screen_width });
-
- this._child1 = new St.Bin({ style_class: 'new-workspace-area',
- width: width,
- height: global.screen_height });
- this._child2 = new St.Bin({ style_class: 'new-workspace-area-internal',
- width: width,
- height: global.screen_height,
- reactive: true });
- this.actor.add_actor(this._child1);
- this.actor.add_actor(this._child2);
- },
-
- setStyle: function(isHover) {
- this._child1.set_hover(isHover);
- }
-};
+ this.actor = new St.Bin({ style_class: 'workspace-indicator-panel',
+ x_align: St.Align.MIDDLE,
+ y_align: St.Align.MIDDLE
+ });
-function WorkspaceIndicator(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb) {
- this._init(activateWorkspace, workspaceAcceptDrop, workspaceHandleDragOver, scrollEventCb);
-}
+ this._indicatorPanel = new Shell.GenericContainer({ clip_to_allocation: true });
+ this._indicatorPanel.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
+ this._indicatorPanel.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
+ this._indicatorPanel.connect('allocate', Lang.bind(this, this._allocate));
-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.actor.set_child(this._indicatorPanel);
+ this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
+
+ let workId = Main.initializeDeferredWork(this._indicatorPanel,
+ Lang.bind(this, this._updateActive));
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;
+ this._workspaces = null;
},
_allocate: function(actor, box, flags) {
let children = actor.get_children();
+
+ // Don't display a single indicator
+ if (children.length == 1)
+ return;
+
let childBox = new Clutter.ActorBox();
+ let height = box.y2 - box.y1;
+
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;
+ childBox.y2 = height;
children[i].allocate(childBox, flags);
}
},
- _getPreferredWidth: function(actor, fh, alloc) {
+ _getPreferredWidth: function(actor, forHeight, alloc) {
let children = actor.get_children();
let width = 0;
for (let i = 0; i < children.length; i++) {
@@ -578,52 +532,81 @@ WorkspaceIndicator.prototype = {
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;
+ _getPreferredHeight: function(actor, forWidth, 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);
- }));
+ updateWorkspaces: function(workspaces) {
+ this._workspaces = workspaces;
- 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);
- });
+ this._indicatorPanel.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('scroll-event', this._scrollEventCb);
+ actor.connect('clicked', Lang.bind(this, function() {
+ metaWorkspace.activate(global.get_current_time());
+ }));
- this._indicatorsPanel.add_actor(actor);
+ 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._indicatorPanel.add_actor(actor);
+
+ let spacing = actor.get_theme_node().get_length('border-spacing');
+ actor.x = (actor.width + spacing) * i;
+ }
- let spacing = actor.get_theme_node().get_length('border-spacing');
- actor.x = spacing * i + actor.width * i;
+ this._updateActive();
},
- _fillPositionalIndicator: function() {
- this._indicatorsPanel.remove_all();
+ _updateActive: function() {
+ let children = this._indicatorPanel.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');
+ }
+ },
- 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);
+ // handle scroll wheel events:
+ // activate the next or previous workspace and let the signal handler
+ // manage the animation
+ _onScrollEvent: function(actor, event) {
+ let direction = event.get_scroll_direction();
+ let current = global.screen.get_active_workspace_index();
+ let last = global.screen.n_workspaces - 1;
+ let activate = current;
+ if (direction == Clutter.ScrollDirection.DOWN && current < last)
+ activate++;
+ else if (direction == Clutter.ScrollDirection.UP && current > 0)
+ activate--;
+
+ if (activate != current) {
+ let metaWorkspace = this._workspaces[activate].metaWorkspace;
+ metaWorkspace.activate(global.get_current_time());
}
}
};
@@ -1072,6 +1055,8 @@ SingleView.prototype = {
dragMotion: Lang.bind(this, this._onDragMotion)
};
DND.addDragMonitor(this._dragMonitor);
+
+ this.emit('window-drag-begin');
},
_onDragMotion: function(dragEvent) {
@@ -1156,6 +1141,8 @@ SingleView.prototype = {
for (let i = 0; i < this._workspaces.length; i++)
this._workspaces[i].setReservedSlot(null);
+
+ this.emit('window-drag-end');
},
// sync the workspaces' positions to the value of the scroll adjustment
@@ -1192,47 +1179,6 @@ SingleView.prototype = {
}
},
- // handle scroll wheel events:
- // activate the next or previous workspace and let the signal handler
- // manage the animation
- _onScrollEvent: function(actor, event) {
- let direction = event.get_scroll_direction();
- let current = global.screen.get_active_workspace_index();
- let last = global.screen.n_workspaces - 1;
- let activate = current;
- if (direction == Clutter.ScrollDirection.DOWN && current < last)
- activate++;
- else if (direction == Clutter.ScrollDirection.UP && current > 0)
- activate--;
-
- if (activate != current) {
- let metaWorkspace = this._workspaces[activate].metaWorkspace;
- 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;
- },
-
addWorkspace: function() {
let ws = GenericWorkspacesView.prototype.addWorkspace.call(this);
if (ws != null)
@@ -1245,160 +1191,95 @@ SingleView.prototype = {
return global.screen.get_active_workspace_index();
}
};
+Signals.addSignalMethods(SingleView.prototype);
-function WorkspacesControls() {
- this._init();
-}
-
-WorkspacesControls.prototype = {
- _init: function() {
- this.actor = new St.BoxLayout({ style_class: 'workspaces-bar' });
- this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
-
- let view = global.settings.get_string(WORKSPACES_VIEW_KEY).toUpperCase();
- if (view in WorkspacesViewType)
- this._currentViewType = WorkspacesViewType[view];
- else
- this._currentViewType = WorkspacesViewType.SINGLE;
-
- this._currentView = null;
-
- // View switcher button
- this._toggleViewButton = new St.Button();
- this._updateToggleButtonStyle();
-
- this._toggleViewButton.connect('clicked', Lang.bind(this, function() {
- if (this._currentViewType == WorkspacesViewType.SINGLE)
- this._setView(WorkspacesViewType.GRID);
- else
- this._setView(WorkspacesViewType.SINGLE);
- }));
-
- this.actor.add(this._toggleViewButton, { y_fill: false, y_align: St.Align.START });
- // View specific controls
- this._viewControls = new St.Bin({ x_fill: true, y_fill: true });
- this.actor.add(this._viewControls, { expand: true, x_fill: true });
-
- // Add/remove workspace buttons
- this._removeButton = new St.Button({ style_class: 'workspace-controls remove' });
- 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._workspacesChanged));
- this._switchWorkspaceNotifyId =
- global.window_manager.connect('switch-workspace',
- Lang.bind(this, this.updateControlsSensitivity));
+function WorkspaceControlsContainer(controls) {
+ this._init(controls);
+}
- this._workspacesChanged();
+WorkspaceControlsContainer.prototype = {
+ _init: function(controls) {
+ 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.add_actor(controls);
+
+ this._controls = controls;
+ this._controls.reactive = true;
+ this._controls.track_hover = true;
+ this._controls.connect('notify::hover',
+ Lang.bind(this, this._onHoverChanged));
+
+ let workId = Main.initializeDeferredWork(this.actor,
+ Lang.bind(this, function() {
+ Main.overview.connect('item-drag-begin',
+ Lang.bind(this, this.popOut));
+ Main.overview.connect('item-drag-end',
+ Lang.bind(this, this.popIn));
+ this._controls.x = this._poppedInX();
+ }));
},
- updateControls: function(view) {
- this._currentView = view;
-
- this.updateControlsSensitivity();
-
- let newControls = this._currentView.createControllerBar();
- if (newControls) {
- this._viewControls.child = newControls;
- this._viewControls.child.opacity = 0;
- Tweener.addTween(this._viewControls.child,
- { opacity: 255,
- 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();
- })});
- }
+ _getPreferredWidth: function(actor, forHeight, alloc) {
+ let [minWidth, natWidth] = this._controls.get_preferred_width(-1);
+ alloc.min_size = minWidth;
+ alloc.natural_size = natWidth;
},
- _updateToggleButtonStyle: function() {
- if (this._currentViewType == WorkspacesViewType.SINGLE)
- this._toggleViewButton.set_style_class_name('workspace-controls switch-mosaic');
- else
- this._toggleViewButton.set_style_class_name('workspace-controls switch-single');
+ _getPreferredHeight: function(actor, forWidth, alloc) {
+ let [minHeight, natHeight] = this._controls.get_preferred_height(-1);
+ alloc.min_size = minHeight;
+ alloc.natural_size = natHeight;
},
- _setView: function(view) {
- if (this._currentViewType == view)
- return;
-
- if (WorkspacesViewType.SINGLE == view)
- this._toggleViewButton.set_style_class_name('workspace-controls switch-mosaic');
- else
- this._toggleViewButton.set_style_class_name('workspace-controls switch-single');
-
- this._currentViewType = view;
- global.settings.set_string(WORKSPACES_VIEW_KEY, view);
+ _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);
},
- _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;
- }
+ _onHoverChanged: function() {
+ if (this._controls.hover)
+ this.popOut();
+ else
+ this.popIn();
},
- _setButtonSensitivity: function(button, sensitive) {
- if (button == null)
- return;
- button.opacity = sensitive ? 255 : 85;
+ _poppedInX: function() {
+ let x = CONTROLS_POP_IN_FRACTION * this._controls.width;
+ if (St.Widget.get_default_direction() == St.TextDirection.RTL)
+ return -x;
+ return x;
},
- updateControlsSensitivity: function() {
- if (this._currentView) {
- this._setButtonSensitivity(this._removeButton, this._currentView.canRemoveWorkspace());
- this._setButtonSensitivity(this._addButton, this._currentView.canAddWorkspace());
- }
+ popOut: function() {
+ Tweener.addTween(this._controls,
+ { x: 0,
+ time: CONTROLS_POP_IN_TIME,
+ transition: 'easeOutQuad' });
},
- _workspacesChanged: function() {
- let showToggleButton = (global.screen.n_workspaces > 1);
- Tweener.addTween(this._toggleViewButton,
- { opacity: showToggleButton ? 255 : 0,
- time: WORKSPACE_SWITCH_TIME,
+ popIn: function() {
+ Tweener.addTween(this._controls,
+ { x: this._poppedInX(),
+ time: CONTROLS_POP_IN_TIME,
transition: 'easeOutQuad' });
- this.updateControlsSensitivity();
}
};
-Signals.addSignalMethods(WorkspacesControls.prototype);
-function WorkspacesManager(width, height, x, y) {
+function WorkspacesDisplay(width, height, x, y) {
this._init(width, height, x, y);
}
-WorkspacesManager.prototype = {
+WorkspacesDisplay.prototype = {
_init: function(width, height, x, y) {
this._workspacesWidth = width;
this._workspacesHeight = height;
@@ -1411,53 +1292,85 @@ WorkspacesManager.prototype = {
this._workspaces[w] = new Workspace.Workspace(metaWorkspace);
}
+ this.actor = new St.BoxLayout();
+
+ let workspacesBox = new St.BoxLayout({ vertical: true });
+ this.actor.add(workspacesBox, { expand: true });
+
+ // placeholder for window previews
+ 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;
- this.controlsBar = new WorkspacesControls();
- this._updateView();
-
- this.controlsBar.actor.connect('destroy',
- Lang.bind(this, this._onDestroy));
- this._viewChangedId =
- global.settings.connect('changed::' + WORKSPACES_VIEW_KEY,
- Lang.bind(this, this._updateView));
- this._nWorkspacesNotifyId =
- global.screen.connect('notify::n-workspaces',
- Lang.bind(this, this._workspacesChanged));
},
- _updateView: function() {
- let viewType, newView;
+ show: function() {
+ let newView = new SingleView(this._workspacesWidth,
+ this._workspacesHeight,
+ this._workspacesX,
+ this._workspacesY,
+ this._workspaces);
- let view = global.settings.get_string(WORKSPACES_VIEW_KEY).toUpperCase();
- if (view in WorkspacesViewType)
- viewType = WorkspacesViewType[view];
- else
- viewType = WorkspacesViewType.SINGLE;
-
- switch (viewType) {
- case WorkspacesViewType.SINGLE:
- newView = new SingleView(this._workspacesWidth,
- this._workspacesHeight,
- this._workspacesX,
- this._workspacesY,
- this._workspaces);
- break;
- case WorkspacesViewType.GRID:
- default:
- newView = new MosaicView(this._workspacesWidth,
- this._workspacesHeight,
- this._workspacesX,
- this._workspacesY,
- this._workspaces);
- break;
- }
if (this.workspacesView)
this.workspacesView.destroy();
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._workspaceIndicatorPanel.updateWorkspaces(this._workspaces);
+
+ this._nWorkspacesNotifyId =
+ global.screen.connect('notify::n-workspaces',
+ Lang.bind(this, this._workspacesChanged));
+ },
- this.emit('view-changed');
+ hide: function() {
+ 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() {
@@ -1500,17 +1413,7 @@ WorkspacesManager.prototype = {
this.workspacesView.updateWorkspaces(oldNumWorkspaces,
newNumWorkspaces,
lostWorkspaces);
- },
-
- _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();
- }
+ this._workspaceIndicatorPanel.updateWorkspaces(this._workspaces);
}
};
-Signals.addSignalMethods(WorkspacesManager.prototype);
+Signals.addSignalMethods(WorkspacesDisplay.prototype);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]