[gnome-shell] 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] workspaces: Rework workspace controls for the view selector
- Date: Mon, 29 Nov 2010 15:39:24 +0000 (UTC)
commit 7811632e6fddd0dd13a180d589866398ae8f42f9
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.
https://bugzilla.gnome.org/show_bug.cgi?id=634948
data/theme/gnome-shell.css | 66 +++---
js/ui/overview.js | 66 ++-----
js/ui/workspacesView.js | 548 +++++++++++++++++++++++---------------------
3 files changed, 330 insertions(+), 350 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 9ce3626..ed04a46 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -262,21 +262,46 @@ StTooltip StLabel {
spacing: 25px;
}
-.workspaces-bar {
- spacing: 5px;
+.workspace-indicator-panel {
+ spacing: 8px;
}
.workspace-indicator {
width: 24px;
height: 16px;
- background: rgba(155,155,155,0.8);
- border-spacing: 16px;
+ background: rgba(255,255,255,0.2);
}
.workspace-indicator.active {
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 {
background: rgba(0,0,0,0.8);
border: 1px solid rgba(128,128,128,0.40);
@@ -294,39 +319,6 @@ StTooltip StLabel {
-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 {
diff --git a/js/ui/overview.js b/js/ui/overview.js
index a27b25b..6c351fd 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -184,18 +184,10 @@ Overview.prototype = {
this._group = new St.Group({ name: '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;
@@ -258,18 +250,6 @@ Overview.prototype = {
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 () {
let primary = global.get_primary_monitor();
wideScreen = (primary.width/primary.height > WIDE_SCREEN_CUT_OFF_RATIO) &&
@@ -326,10 +306,6 @@ Overview.prototype = {
}
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._workspacesY);
@@ -375,11 +351,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) {
@@ -388,7 +359,6 @@ Overview.prototype = {
}
this._transparentBackground.lower_bottom();
this._paneContainer.hide();
- this._lightbox.hide();
}
}));
},
@@ -443,28 +413,22 @@ 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._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._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._workspacesBar = this._workspacesManager.controlsBar.actor;
- this._workspacesBar.set_position(this._workspacesBarX,
- this._workspacesBarY);
- this._workspacesBar.width = this._workspacesBarWidth;
+ this._workspacesDisplay.show();
+ this.workspaces = this._workspacesDisplay.workspacesView;
- this._group.add_actor(this._workspacesBar);
- this._workspacesBar.raise(this.workspaces.actor);
+ // Show new workspacesView
+ this._group.add_actor(this.workspaces.actor);
if (!this._desktopFade.child)
this._desktopFade.child = this._getDesktopClone();
@@ -605,10 +569,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._desktopFade.hide();
this._background.hide();
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index a1e5d1d..f05b7be 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -22,135 +22,9 @@ const MAX_WORKSPACES = 16;
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) {
this._init(width, height, x, y, workspaces);
@@ -775,6 +649,8 @@ WorkspacesView.prototype = {
dragMotion: Lang.bind(this, this._onDragMotion)
};
DND.addDragMonitor(this._dragMonitor);
+
+ this.emit('window-drag-begin');
},
_onDragMotion: function(dragEvent) {
@@ -865,6 +741,8 @@ WorkspacesView.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
@@ -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:
// activate the next or previous workspace and let the signal handler
// manage the animation
@@ -921,140 +921,118 @@ WorkspacesView.prototype = {
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;
- },
-
- _getWorkspaceIndexToRemove: function() {
- return global.screen.get_active_workspace_index();
}
};
-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));
- this._currentView = null;
-
- // View specific controls
- this._viewControls = new St.Bin({ x_fill: true, y_fill: true });
- this.actor.add(this._viewControls, { expand: true, x_fill: true });
+function WorkspaceControlsContainer(controls) {
+ this._init(controls);
+}
- // 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 });
+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));
+
+ this._itemDragBeginId = 0;
+ this._itemDragEndId = 0;
+ },
- 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 });
+ show: function() {
+ 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._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));
+ hide: function() {
+ if (this._itemDragBeginId > 0) {
+ Main.overview.disconnect(this._itemDragBeginId);
+ this._itemDragBeginId = 0;
+ }
+ if (this._itemEndBeginId > 0) {
+ Main.overview.disconnect(this._itemDragEndId);
+ this._itemDragEndId = 0;
+ }
+ },
- this.updateControlsSensitivity();
+ _getPreferredWidth: function(actor, forHeight, alloc) {
+ let [minWidth, natWidth] = this._controls.get_preferred_width(-1);
+ alloc.min_size = minWidth;
+ alloc.natural_size = natWidth;
},
- updateControls: function(view) {
- this._currentView = view;
+ // Always request the full width ...
+ _getPreferredHeight: function(actor, forWidth, alloc) {
+ let [minHeight, natHeight] = this._controls.get_preferred_height(-1);
+ alloc.min_size = minHeight;
+ alloc.natural_size = natHeight;
+ },
- this.updateControlsSensitivity();
+ // ... even when the controls are popped in, to keep the width constant.
+ // This is necessary as the workspace size is determined once before
+ // entering the overview, when the controls are popped in - if the width
+ // 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);
+ },
- 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();
- })});
- }
+ _onHoverChanged: function() {
+ if (this._controls.hover)
+ this.popOut();
+ else
+ this.popIn();
},
- _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;
- }
+ _poppedInX: function() {
+ let x = CONTROLS_POP_IN_FRACTION * this._controls.width;
+ if (St.Widget.get_default_direction() == St.TextDirection.RTL)
+ return -x;
+ return x;
},
- _setButtonSensitivity: function(button, sensitive) {
- if (button == null)
- return;
- button.opacity = sensitive ? 255 : 85;
+ popOut: function() {
+ Tweener.addTween(this._controls,
+ { x: 0,
+ time: CONTROLS_POP_IN_TIME,
+ transition: 'easeOutQuad' });
},
- updateControlsSensitivity: function() {
- if (this._currentView) {
- this._setButtonSensitivity(this._removeButton, this._currentView.canRemoveWorkspace());
- this._setButtonSensitivity(this._addButton, this._currentView.canAddWorkspace());
- }
+ 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);
}
-WorkspacesManager.prototype = {
+WorkspacesDisplay.prototype = {
_init: function(width, height, x, y) {
this._workspacesWidth = width;
this._workspacesHeight = height;
@@ -1067,18 +1045,52 @@ WorkspacesManager.prototype = {
this._workspaces[w] = new Workspace.Workspace(metaWorkspace);
}
- this.workspacesView = null;
- this.controlsBar = new WorkspacesControls();
- this._updateView();
+ this.actor = new St.BoxLayout();
- this.controlsBar.actor.connect('destroy',
- Lang.bind(this, this._onDestroy));
- this._nWorkspacesNotifyId =
- global.screen.connect('notify::n-workspaces',
- Lang.bind(this, this._workspacesChanged));
+ 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;
},
- _updateView: function() {
+ show: function() {
+ this._controlsContainer.show();
+
let newView = new WorkspacesView(this._workspacesWidth,
this._workspacesHeight,
this._workspacesX,
@@ -1089,9 +1101,33 @@ WorkspacesManager.prototype = {
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.emit('view-changed');
+ 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() {
@@ -1134,17 +1170,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]