diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index c0c6aa935..4467e69bd 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -624,10 +624,6 @@ StScrollBar StButton#vhandle:active {
     spacing: 25px;
 }
 
-.workspace-controls {
-    visible-width: 32px; /* Amount visible before hovering */
-}
-
 .workspace-thumbnails-background {
     border: 1px solid rgba(128, 128, 128, 0.4);
     border-right: 0px;
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 8cfe025ae..915c3dbee 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -183,6 +183,8 @@ const Overview = new Lang.Class({
         Main.xdndHandler.connect('drag-begin', Lang.bind(this, this._onDragBegin));
         Main.xdndHandler.connect('drag-end', Lang.bind(this, this._onDragEnd));
 
+        global.screen.connect('restacked', Lang.bind(this, this._onRestacked));
+
         this._windowSwitchTimeoutId = 0;
         this._windowSwitchTimestamp = 0;
         this._lastActiveWorkspaceIndex = -1;
@@ -246,6 +248,9 @@ const Overview = new Lang.Class({
                                                            this._dash.showAppsButton);
         this._group.add_actor(this._viewSelector.actor);
 
+        this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
+        this._group.add_actor(this._thumbnailsBox.actor);
+
         // Add our same-line elements after the search entry
         this._overview.add_actor(this._group);
 
@@ -390,6 +395,18 @@ const Overview = new Lang.Class({
         this._coverPane.set_size(primary.width, contentHeight);
     },
 
+    _onRestacked: function() {
+        let stack = global.get_window_actors();
+        let stackIndices = {};
+
+        for (let i = 0; i < stack.length; i++) {
+            // Use the stable sequence for an integer to use as a hash key
+            stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
+        }
+
+        this.emit('sync-window-stacking', stackIndices);
+    },
+
     //// Public methods ////
 
     beginItemDrag: function(source) {
diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js
index 381c12c4f..428b1b5dc 100644
--- a/js/ui/workspaceThumbnail.js
+++ b/js/ui/workspaceThumbnail.js
@@ -746,6 +746,9 @@ const ThumbnailsBox = new Lang.Class({
         this._nWorkspacesNotifyId =
             global.screen.connect('notify::n-workspaces',
                                   Lang.bind(this, this._workspacesChanged));
+        this._syncStackingId =
+            Main.overview.connect('sync-window-stacking',
+                                  Lang.bind(this, this._syncStacking));
 
         this._targetScale = 0;
         this._scale = 0;
@@ -785,6 +788,10 @@ const ThumbnailsBox = new Lang.Class({
             global.screen.disconnect(this._nWorkspacesNotifyId);
             this._nWorkspacesNotifyId = 0;
         }
+        if (this._syncStackingId > 0) {
+            Main.overview.disconnect(this._syncStackingId);
+            this._syncStackingId = 0;
+        }
 
         for (let w = 0; w < this._thumbnails.length; w++)
             this._thumbnails[w].destroy();
@@ -906,7 +913,7 @@ const ThumbnailsBox = new Lang.Class({
         this._queueUpdateStates();
     },
 
-    syncStacking: function(stackIndices) {
+    _syncStacking: function(actor, stackIndices) {
         for (let i = 0; i < this._thumbnails.length; i++)
             this._thumbnails[i].syncStacking(stackIndices);
     },
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index 8ea5d0165..b635596ab 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -23,8 +23,6 @@ const MAX_WORKSPACES = 16;
 
 const OVERRIDE_SCHEMA = 'org.gnome.shell.overrides';
 
-const CONTROLS_POP_IN_TIME = 0.1;
-
 
 const WorkspacesView = new Lang.Class({
     Name: 'WorkspacesView',
@@ -439,9 +437,7 @@ const WorkspacesDisplay = new Lang.Class({
 
     _init: function() {
         this.actor = new Shell.GenericContainer();
-        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('allocate', Lang.bind(this, this._updateWorkspacesGeometry));
         this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
         this.actor.set_clip_to_allocation(true);
 
@@ -472,23 +468,8 @@ const WorkspacesDisplay = new Lang.Class({
         Main.overview.addAction(panAction);
         this.actor.bind_property('mapped', panAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
 
-        let controls = new St.Bin({ style_class: 'workspace-controls',
-                                    request_mode: Clutter.RequestMode.WIDTH_FOR_HEIGHT,
-                                    y_align: St.Align.START,
-                                    y_fill: true });
-        this._controls = controls;
-        this.actor.add_actor(controls);
-
-        controls.reactive = true;
-        controls.track_hover = true;
-        controls.connect('notify::hover',
-                         Lang.bind(this, this._onControlsHoverChanged));
-
         this._primaryIndex = Main.layoutManager.primaryIndex;
 
-        this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
-        controls.add_actor(this._thumbnailsBox.actor);
-
         this._workspacesViews = null;
         this._primaryScrollAdjustment = null;
 
@@ -501,26 +482,6 @@ const WorkspacesDisplay = new Lang.Class({
         this._inDrag = false;
         this._cancelledDrag = false;
 
-        this._controlsInitiallyHovered = false;
-        this._alwaysZoomOut = false;
-        this._zoomOut = false;
-        this._zoomFraction = 0;
-
-        this._updateAlwaysZoom();
-
-        // If we stop hiding the overview on layout changes, we will need to
-        // update the _workspacesViews here
-        Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateAlwaysZoom));
-
-        Main.xdndHandler.connect('drag-begin', Lang.bind(this, function(){
-            this._alwaysZoomOut = true;
-        }));
-
-        Main.xdndHandler.connect('drag-end', Lang.bind(this, function(){
-            this._alwaysZoomOut = false;
-            this._updateAlwaysZoom();
-        }));
-
         global.screen.connect('notify::n-workspaces',
                               Lang.bind(this, this._workspacesChanged));
 
@@ -545,30 +506,10 @@ const WorkspacesDisplay = new Lang.Class({
     },
 
     show: function() {
-        if(!this._alwaysZoomOut) {
-            let [mouseX, mouseY] = global.get_pointer();
-            let [x, y] = this._controls.get_transformed_position();
-            let [width, height] = this._controls.get_transformed_size();
-            let visibleWidth = this._controls.get_theme_node().get_length('visible-width');
-            let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
-            if(rtl)
-                x = x + width - visibleWidth;
-            if(mouseX > x - 0.5 && mouseX < x + visibleWidth + 0.5 &&
-               mouseY > y - 0.5 && mouseY < y + height + 0.5)
-                this._controlsInitiallyHovered = true;
-        }
-
-        this._zoomOut = this._alwaysZoomOut;
-        this._zoomFraction = this._alwaysZoomOut ? 1 : 0;
-        this._updateZoom();
-
-        this._controls.show();
-        this._thumbnailsBox.show();
-
         this._updateWorkspacesViews();
 
         this._restackedNotifyId =
-            global.screen.connect('restacked',
+            Main.overview.connect('sync-window-stacking',
                                   Lang.bind(this, this._onRestacked));
 
         if (this._itemDragBeginId == 0)
@@ -589,8 +530,6 @@ const WorkspacesDisplay = new Lang.Class({
         if (this._windowDragEndId == 0)
             this._windowDragEndId = Main.overview.connect('window-drag-end',
                                                           Lang.bind(this, this._dragEnd));
-
-        this._onRestacked();
     },
 
     zoomFromOverview: function() {
@@ -600,14 +539,8 @@ const WorkspacesDisplay = new Lang.Class({
     },
 
     hide: function() {
-        this._controls.hide();
-        this._thumbnailsBox.hide();
-
-        if (!this._alwaysZoomOut)
-            this.zoomFraction = 0;
-
         if (this._restackedNotifyId > 0){
-            global.screen.disconnect(this._restackedNotifyId);
+            Main.overview.disconnect(this._restackedNotifyId);
             this._restackedNotifyId = 0;
         }
         if (this._itemDragBeginId > 0) {
@@ -723,76 +656,6 @@ const WorkspacesDisplay = new Lang.Class({
         return this._getPrimaryView().getActiveWorkspace().hasMaximizedWindows();
     },
 
-    // zoomFraction property allows us to tween the controls sliding in and out
-    set zoomFraction(fraction) {
-        this._zoomFraction = fraction;
-        this.actor.queue_relayout();
-    },
-
-    get zoomFraction() {
-        return this._zoomFraction;
-    },
-
-    _updateAlwaysZoom: function()  {
-        // Always show the pager if workspaces are actually used,
-        // e.g. there are windows on more than one
-        this._alwaysZoomOut = global.screen.n_workspaces > 2;
-
-        if (this._alwaysZoomOut)
-            return;
-
-        let monitors = Main.layoutManager.monitors;
-        let primary = Main.layoutManager.primaryMonitor;
-
-        /* Look for any monitor to the right of the primary, if there is
-         * one, we always keep zoom out, otherwise its hard to reach
-         * the thumbnail area without passing into the next monitor. */
-        for (let i = 0; i < monitors.length; i++) {
-            if (monitors[i].x >= primary.x + primary.width) {
-                this._alwaysZoomOut = true;
-                break;
-            }
-        }
-    },
-
-    _getPreferredWidth: function (actor, forHeight, alloc) {
-        // pass through the call in case the child needs it, but report 0x0
-        this._controls.get_preferred_width(forHeight);
-    },
-
-    _getPreferredHeight: function (actor, forWidth, alloc) {
-        // pass through the call in case the child needs it, but report 0x0
-        this._controls.get_preferred_height(forWidth);
-    },
-
-    _allocate: function (actor, box, flags) {
-        let childBox = new Clutter.ActorBox();
-
-        let totalWidth = box.x2 - box.x1;
-
-        // width of the controls
-        let [controlsMin, controlsNatural] = this._controls.get_preferred_width(box.y2 - box.y1);
-
-        // Amount of space on the screen we reserve for the visible control
-        let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
-        let controlsReserved = controlsVisible * (1 - this._zoomFraction) + controlsNatural * this._zoomFraction;
-
-        let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
-        if (rtl) {
-            childBox.x2 = controlsReserved;
-            childBox.x1 = childBox.x2 - controlsNatural;
-        } else {
-            childBox.x1 = totalWidth - controlsReserved;
-            childBox.x2 = childBox.x1 + controlsNatural;
-        }
-
-        childBox.y1 = 0;
-        childBox.y2 = box.y2- box.y1;
-        this._controls.allocate(childBox, flags);
-
-        this._updateWorkspacesGeometry();
-    },
-
     _parentSet: function(actor, oldParent) {
         if (oldParent && this._notifyOpacityId)
             oldParent.disconnect(this._notifyOpacityId);
@@ -829,24 +692,19 @@ const WorkspacesDisplay = new Lang.Class({
         let width = fullWidth;
         let height = fullHeight;
 
-        let [controlsMin, controlsNatural] = this._controls.get_preferred_width(height);
-        let controlsVisible = this._controls.get_theme_node().get_length('visible-width');
-
         let [x, y] = this.actor.get_transformed_position();
 
         let rtl = (Clutter.get_default_text_direction () == Clutter.TextDirection.RTL);
 
-        let clipWidth = width - controlsVisible;
+        let clipWidth = width;
         let clipHeight = fullHeight;
-        let clipX = rtl ? x + controlsVisible : x;
+        let clipX = x;
         let clipY = y + (fullHeight - clipHeight) / 2;
 
         let overviewSpacing = Main.overview._spacing;
-        let widthAdjust = this._zoomOut ? controlsNatural : controlsVisible;
-        widthAdjust += overviewSpacing;
-        width -= widthAdjust;
+        width -= overviewSpacing;
         if (rtl)
-            x += widthAdjust;
+            x += overviewSpacing;
 
         let monitors = Main.layoutManager.monitors;
         let m = 0;
@@ -870,25 +728,12 @@ const WorkspacesDisplay = new Lang.Class({
         }
     },
 
-    _onRestacked: function() {
-        let stack = global.get_window_actors();
-        let stackIndices = {};
-
-        for (let i = 0; i < stack.length; i++) {
-            // Use the stable sequence for an integer to use as a hash key
-            stackIndices[stack[i].get_meta_window().get_stable_sequence()] = i;
-        }
-
+    _onRestacked: function(actor, stackIndices) {
         for (let i = 0; i < this._workspacesViews.length; i++)
             this._workspacesViews[i].syncStacking(stackIndices);
-
-        this._thumbnailsBox.syncStacking(stackIndices);
     },
 
     _workspacesChanged: function() {
-        this._updateAlwaysZoom();
-        this._updateZoom();
-
         if (this._workspacesViews == null)
             return;
 
@@ -942,35 +787,6 @@ const WorkspacesDisplay = new Lang.Class({
                                                       newNumWorkspaces);
     },
 
-    _updateZoom : function() {
-        if (Main.overview.animationInProgress)
-            return;
-
-        let shouldZoom = this._alwaysZoomOut || this._controls.hover;
-        if (shouldZoom != this._zoomOut) {
-            this._zoomOut = shouldZoom;
-            this._updateWorkspacesGeometry();
-
-            if (!this._workspacesViews)
-                return;
-
-            Tweener.addTween(this,
-                             { zoomFraction: this._zoomOut ? 1 : 0,
-                               time: WORKSPACE_SWITCH_TIME,
-                               transition: 'easeOutQuad' });
-
-            for (let i = 0; i < this._workspacesViews.length; i++)
-                this._workspacesViews[i].updateWindowPositions();
-        }
-    },
-
-    _onControlsHoverChanged: function() {
-        if(!this._controls.hover)
-            this._controlsInitiallyHovered = false;
-        if(!this._controlsInitiallyHovered)
-            this._updateZoom();
-    },
-
     _dragBegin: function() {
         this._inDrag = true;
         this._cancelledDrag = false;
@@ -986,22 +802,11 @@ const WorkspacesDisplay = new Lang.Class({
     },
 
     _onDragMotion: function(dragEvent) {
-        let controlsHovered = this._controls.contains(dragEvent.targetActor);
-        this._controls.set_hover(controlsHovered);
-
         return DND.DragMotionResult.CONTINUE;
     },
 
     _dragEnd: function() {
         this._inDrag = false;
-
-        // We do this deferred because drag-end is emitted before dnd.js emits
-        // event/leave events that were suppressed during the drag. If we didn't
-        // defer this, we'd zoom out then immediately zoom in because of the
-        // enter event we received. That would normally be invisible but we
-        // might as well avoid it.
-        Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
-                       Lang.bind(this, this._updateZoom));
     }
 });
 Signals.addSignalMethods(WorkspacesDisplay.prototype);