[gnome-shell] add ability move window in SingleView



commit 7183aac362cf820340e67afa10ca4e30904b4243
Author: Maxim Ermilov <zaspire rambler ru>
Date:   Tue Mar 16 18:51:24 2010 +0300

    add ability move window in SingleView
    
    https://bugzilla.gnome.org/show_bug.cgi?id=607821

 data/Makefile.am                  |    1 +
 data/theme/gnome-shell.css        |   32 ++++
 data/theme/move-window-on-new.svg |   89 +++++++++++
 js/ui/workspace.js                |   52 ++++++-
 js/ui/workspacesView.js           |  301 ++++++++++++++++++++++++++++++++----
 5 files changed, 433 insertions(+), 42 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 8afd703..43ec39d 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -27,6 +27,7 @@ dist_theme_DATA =				\
 	theme/gnome-shell.css			\
 	theme/mosaic-view-active.svg          \
 	theme/mosaic-view.svg          \
+	theme/move-window-on-new.svg          \
 	theme/remove-workspace.svg          \
 	theme/scroll-button-down-hover.png	\
 	theme/scroll-button-down.png		\
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index a559234..888f76c 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -168,6 +168,38 @@ StTooltip {
     border: 1px solid #666666;
 }
 
+.new-workspace-area {
+    border: 2px solid rgba(255, 255, 255, 0.8);
+    border-radius: 10px;
+    background-color: #111;
+}
+
+.new-workspace-area-internal {
+    background-gradient-direction: horizontal;
+    background-gradient-start: rgba(16, 16, 16, 0);
+    background-gradient-end: rgba(16, 16, 16, 1.0);
+    background-image: url("move-window-on-new.svg");
+}
+
+.new-workspace-area:hover {
+    border: 2px solid rgba(255, 255, 255, 1.0);
+    background-gradient-direction: horizontal;
+    background-gradient-start: rgba(130, 130, 130, 0.9);
+    background-gradient-end: rgba(16, 16, 16, 0.9);
+}
+
+.left-workspaces-shadow {
+    background-gradient-direction: horizontal;
+    background-gradient-start: rgba(16, 16, 16, 1.0);
+    background-gradient-end: rgba(16, 16, 16, 0.0);
+}
+
+.right-workspaces-shadow {
+    background-gradient-direction: horizontal;
+    background-gradient-end: rgba(16, 16, 16, 1.0);
+    background-gradient-start: rgba(16, 16, 16, 0);
+}
+
 .workspaces {
     color: white;
 }
diff --git a/data/theme/move-window-on-new.svg b/data/theme/move-window-on-new.svg
new file mode 100644
index 0000000..5087c40
--- /dev/null
+++ b/data/theme/move-window-on-new.svg
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="98"
+   height="98"
+   id="svg6375"
+   version="1.1"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="add-workspace.svg">
+  <defs
+     id="defs6377">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 16 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="32 : 16 : 1"
+       inkscape:persp3d-origin="16 : 10.666667 : 1"
+       id="perspective6383" />
+    <inkscape:perspective
+       id="perspective6366"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="3.9590209"
+     inkscape:cx="56.650687"
+     inkscape:cy="20.635343"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:window-width="1680"
+     inkscape:window-height="997"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata6380">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     transform="translate(0,66)">
+    <g
+       id="g2824"
+       transform="matrix(11.568551,0,0,11.698271,-78.828159,-304.81518)">
+      <path
+         style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="m 11.07363,21.36834 0,6.43903"
+         id="path5322" />
+      <path
+         style="fill:none;stroke:#666666;stroke-width:1.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
+         d="m 14.29314,24.58786 -6.43902,0"
+         id="path5324" />
+    </g>
+    <path
+       style="fill:#000000;fill-opacity:0.98823529"
+       d="m 48.239516,97.908047 c -0.41677,-0.05102 -1.269253,-0.222408 -1.894408,-0.380859 -4.088493,-1.036262 -7.520781,-4.753234 -8.330163,-9.021094 -0.154947,-0.817026 -0.257819,-6.68112 -0.257819,-14.696556 l 0,-13.337088 -13.829177,-0.08909 C 10.802042,60.298796 10.026884,60.268266 8.6851548,59.783022 3.6288503,57.954375 0.62673331,53.828648 0.62673331,48.708554 c 0,-5.625522 4.25936019,-10.425065 9.97721469,-11.242548 0.987903,-0.141242 7.368912,-0.254994 14.460646,-0.257791 l 12.692532,-0.005 0,-13.586668 c 0,-14.6441583 0.03287,-15.0698926 1.364686,-17.6753047 2.185477,-4.2754229 6.938193,-6.75739913 11.687647,-6.10355607 3.382776,0.46569661 6.737962,2.72496967 8.414081,5.66577137 1.480816,2.5981315 1.519067,3.0522448 1.519067,18.0333334 l 0,13.666424 12.692533,0.005 c 7.091733,0.0028 13.472742,0.116549 14.460646,0.257791 6.395303,0.914337 10.804785,6.623716 9.941157,12.871766 -0.698243,5.051565 -4.792685,9.104635 -9.941157,9.840713 -0.987904,0.141242 -7.368913,0.25
 4995 -14.460646,0.257791 l -12.692533,0.005 0,13.801945 c 0,13.031417 -0.02798,13.895893 -0.501177,15.484801 -1.526902,5.127058 -6.919246,8.802262 -12.001914,8.18002 z"
+       id="path2828"
+       transform="translate(0,-66)" />
+  </g>
+</svg>
diff --git a/js/ui/workspace.js b/js/ui/workspace.js
index 672994f..20d5fd2 100644
--- a/js/ui/workspace.js
+++ b/js/ui/workspace.js
@@ -641,6 +641,8 @@ function Workspace(workspaceNum, parentActor) {
 
 Workspace.prototype = {
     _init : function(workspaceNum, parentActor) {
+        // When dragging a window, we use this slot for reserve space.
+        this._reservedSlot = null;
         this.workspaceNum = workspaceNum;
         this._windowOverlaysGroup = new Clutter.Group();
         // Without this the drop area will be overlapped.
@@ -1039,11 +1041,16 @@ Workspace.prototype = {
 
         let rect = new Meta.Rectangle();
         metaWindow.get_outer_rect(rect);
-
-        let [buttonOuterHeight, captionHeight] = this._windowOverlays[1].chromeHeights();
+        let buttonOuterHeight, captionHeight;
+        let buttonOuterWidth = 0;
+
+        if (this._windowOverlays[1]) {
+            [buttonOuterHeight, captionHeight] = this._windowOverlays[1].chromeHeights();
+            buttonOuterWidth = this._windowOverlays[1].chromeWidth() / this.scale;
+        } else
+            [buttonOuterHeight, captionHeight] = [0, 0];
         buttonOuterHeight /= this.scale;
         captionHeight /= this.scale;
-        let buttonOuterWidth = this._windowOverlays[1].chromeWidth() / this.scale;
 
         let desiredWidth = global.screen_width * fraction;
         let desiredHeight = global.screen_height * fraction;
@@ -1057,6 +1064,19 @@ Workspace.prototype = {
         return [x, y, scale];
     },
 
+    setReservedSlot: function(clone) {
+        if (clone && this.containsMetaWindow(clone.metaWindow)) {
+            this._reservedSlot = null;
+            this.positionWindows(WindowPositionFlags.ANIMATE);
+            return;
+        }
+        if (clone)
+            this._reservedSlot = clone;
+        else
+            this._reservedSlot = null;
+        this.positionWindows(WindowPositionFlags.ANIMATE);
+    },
+
     /**
      * positionWindows:
      * @flags:
@@ -1072,6 +1092,8 @@ Workspace.prototype = {
         let totalVisible = 0;
 
         let visibleClones = this._getVisibleClones();
+        if (this._reservedSlot)
+            visibleClones.push(this._reservedSlot);
 
         let workspaceZooming = flags & WindowPositionFlags.ZOOM;
         let animate = flags & WindowPositionFlags.ANIMATE;
@@ -1089,7 +1111,8 @@ Workspace.prototype = {
 
             let [x, y, scale] = this._computeWindowRelativeLayout(metaWindow, slot);
 
-            overlay.hide();
+            if (overlay)
+                overlay.hide();
             if (animate) {
                 if (!metaWindow.showing_on_its_workspace()) {
                     /* Hidden windows should fade in and grow
@@ -1163,8 +1186,10 @@ Workspace.prototype = {
         cloneWidth = this.scale * clone.actor.scale_x * cloneWidth;
         cloneHeight = this.scale * clone.actor.scale_y * cloneHeight;
 
-        overlay.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight);
-        overlay.fadeIn();
+        if (overlay) {
+            overlay.updatePositions(cloneX, cloneY, cloneWidth, cloneHeight);
+            overlay.fadeIn();
+        }
     },
 
     _fadeInAllOverlays: function() {
@@ -1205,6 +1230,15 @@ Workspace.prototype = {
         return false;
     },
 
+    showWindowsOverlays: function() {
+        this._windowOverlaysGroup.show();
+        this._fadeInAllOverlays();
+    },
+
+    hideWindowsOverlays: function() {
+        this._windowOverlaysGroup.hide();
+    },
+
     _windowRemoved : function(metaWorkspace, metaWin) {
         let win = metaWin.get_compositor_private();
 
@@ -1482,11 +1516,13 @@ Workspace.prototype = {
         clone.connect('selected',
                       Lang.bind(this, this._onCloneSelected));
         clone.connect('drag-begin',
-                      Lang.bind(this, function() {
+                      Lang.bind(this, function(clone) {
+                          this.emit('window-drag-begin', clone.actor);
                           overlay.hide();
                       }));
         clone.connect('drag-end',
-                      Lang.bind(this, function() {
+                      Lang.bind(this, function(clone) {
+                          this.emit('window-drag-end', clone.actor);
                           overlay.show();
                       }));
 
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index 64d444d..7876cf1 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -33,6 +33,9 @@ const WorkspacesViewType = {
 };
 const WORKSPACES_VIEW_KEY = 'overview/workspaces_view';
 
+const WORKSPACE_DRAGGING_SCALE = 0.85;
+const WORKSPACE_SHADOW_SCALE = (1 - WORKSPACE_DRAGGING_SCALE) / 2;
+
 function GenericWorkspacesView(width, height, x, y, animate) {
     this._init(width, height, x, y, animate);
 }
@@ -466,6 +469,33 @@ MosaicView.prototype = {
     }
 };
 
+function NewWorkspaceArea() {
+    this._init();
+}
+
+NewWorkspaceArea.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_style_pseudo_class(isHover ? 'hover' : null);
+    }
+};
+
 function SingleView(width, height, x, y, animate) {
     this._init(width, height, x, y, animate);
 }
@@ -474,8 +504,22 @@ SingleView.prototype = {
     __proto__: GenericWorkspacesView.prototype,
 
     _init: function(width, height, x, y, animate) {
+        this._newWorkspaceArea = new NewWorkspaceArea();
+        this._leftShadow = new St.Bin({ style_class: 'left-workspaces-shadow',
+                                        width: Math.ceil(global.screen_width * WORKSPACE_SHADOW_SCALE),
+                                        height: global.screen_height,
+                                        x: global.screen_width })
+        this._rightShadow = new St.Bin({ style_class: 'right-workspaces-shadow',
+                                         width: Math.ceil(global.screen_width * WORKSPACE_SHADOW_SCALE),
+                                         height: global.screen_height,
+                                         x: global.screen_width })
+
         GenericWorkspacesView.prototype._init.call(this, width, height, x, y, animate);
 
+        this._actor.add_actor(this._newWorkspaceArea.actor);
+        this._actor.add_actor(this._leftShadow);
+        this._actor.add_actor(this._rightShadow);
+
         this.actor.style_class = "workspaces single";
         this._actor.set_clip(x, y, width, height);
         this._addButton = null;
@@ -486,76 +530,156 @@ SingleView.prototype = {
         this._lostWorkspaces = [];
         this._scrolling = false;
         this._animatingScroll = false;
+
+        let primary = global.get_primary_monitor();
+        this._dropGroup = new Clutter.Group({ x: 0, y: 0,
+                                              width: primary.width,
+                                              height: primary.height });
+        this._dropGroup._delegate = this;
+        global.stage.add_actor(this._dropGroup);
+        this._dropGroup.lower_bottom();
+        this._timeoutId = 0;
     },
 
     _positionWorkspaces: function() {
-        let scale = this._width / global.screen_width;
+        let scale;
+
+        if (this._inDrag)
+            scale = this._width * WORKSPACE_DRAGGING_SCALE / global.screen_width;
+        else
+            scale = this._width / global.screen_width;
         let active = global.screen.get_active_workspace_index();
+        let _width = this._workspaces[0].actor.width * scale;
 
         for (let w = 0; w < this._workspaces.length; w++) {
             let workspace = this._workspaces[w];
 
+            if (this._inDrag)
+                workspace.opacity = 200;
+            else
+                workspace.opacity = 255;
+            if (active == w)
+                workspace.opacity = 255;
+
             workspace.gridRow = 0;
             workspace.gridCol = 0;
 
             workspace.scale = scale;
-            let _width = workspace.actor.width * scale;
-            workspace.gridX = this._x + (w - active) * (_width + this._spacing);
-            workspace.gridY = this._y;
+            workspace.gridX = this._x + (this._width - _width) / 2 + (w - active) * (_width + this._spacing);
+            workspace.gridY = this._y + (this._height - workspace.actor.height * scale) / 2;
 
             workspace.setSelected(false);
         }
-    },
 
-    _updateWorkspaceActors: function() {
-        for (let w = 0; w < this._workspaces.length; w++) {
-            let workspace = this._workspaces[w];
+        this._newWorkspaceArea.scale = scale;
+        this._newWorkspaceArea.gridX = this._x + (this._width - _width) / 2 + (this._workspaces.length - active) * (_width + this._spacing);
+        this._newWorkspaceArea.gridY = this._y + (this._height - this._newWorkspaceArea.actor.height * scale) / 2;
 
-            workspace.actor.set_scale(workspace.scale, workspace.scale);
-            workspace.actor.set_position(workspace.gridX, workspace.gridY);
-            workspace.positionWindows(0);
-        }
+        this._leftShadow.scale = scale;
+        this._leftShadow.gridX = this._x + (this._width - _width) / 2 - (this._leftShadow.width * scale + this._spacing);
+        this._leftShadow.gridY = this._y + (this._height - this._leftShadow.height * scale) / 2;
+
+        this._rightShadow.scale = scale;
+        this._rightShadow.gridX = this._x + (this._width - _width) / 2 + (_width + this._spacing);
+        this._rightShadow.gridY = this._y + (this._height - this._rightShadow.height * scale) / 2;
     },
 
     _scrollToActive: function(showAnimation) {
         let active = global.screen.get_active_workspace_index();
 
-        this._scrollWorkspacesToIndex(active, showAnimation);
+        this._updateWorkspaceActors(showAnimation);
         this._scrollScrollBarToIndex(active, showAnimation);
     },
 
-    _scrollWorkspacesToIndex: function(index, showAnimation) {
+    _updateWorkspaceActors: function(showAnimation) {
         let active = global.screen.get_active_workspace_index();
-        let targetWorkspaceNewX = this._x;
-        let targetWorkspaceCurrentX = this._workspaces[index].gridX;
-        let dx = targetWorkspaceNewX - targetWorkspaceCurrentX;
+
+        this._positionWorkspaces();
+
+        let dx = this._workspaces[0].gridX - this._workspaces[0].actor.x;
 
         for (let w = 0; w < this._workspaces.length; w++) {
             let workspace = this._workspaces[w];
 
-            workspace.gridX += dx;
             workspace.actor.show();
-            workspace._hideAllOverlays();
+            workspace.hideWindowsOverlays();
 
-            let visible = (w == active);
+            let i = w;
             if (showAnimation) {
                 Tweener.addTween(workspace.actor,
                     { x: workspace.gridX,
+                      y: workspace.gridY,
+                      scale_x: workspace.scale,
+                      scale_y: workspace.scale,
                       time: WORKSPACE_SWITCH_TIME,
+                      opacity: workspace.opacity,
                       transition: 'easeOutQuad',
+                      onCompleteScope: this,
                       onComplete: function() {
-                          if (visible)
-                              workspace._fadeInAllOverlays();
-                          else
-                              workspace.actor.hide();
+                          if (i == active) {
+                              if (!this._inDrag)
+                                  workspace.showWindowsOverlays();
+                          } else
+                              workspace.actor.visible = Math.abs(i - active) <= 1;
                     }});
             } else {
-                workspace.actor.x = workspace.gridX;
-                if (visible)
-                    workspace._fadeInAllOverlays();
-                else
-                    workspace.actor.hide();
+                workspace.actor.set_scale(workspace.scale, workspace.scale);
+                workspace.actor.set_position(workspace.gridX, workspace.gridY);
+                workspace.actor.opacity = workspace.opacity;
+                if (i == active) {
+                    if (!this._inDrag)
+                        workspace.showWindowsOverlays();
+                } else
+                    workspace.actor.visible = Math.abs(i - active) <= 1;
             }
+            workspace.positionWindows(0);
+        }
+        if (active)
+            this._leftShadow.show();
+        else
+            this._leftShadow.hide();
+
+        if (active == this._workspaces.length - 1)
+            this._rightShadow.hide();
+        else
+            this._rightShadow.show();
+
+        this._leftShadow.raise_top();
+        this._rightShadow.raise_top();
+
+        if (showAnimation) {
+            Tweener.addTween(this._newWorkspaceArea.actor,
+                { x: this._newWorkspaceArea.gridX,
+                  y: this._newWorkspaceArea.gridY,
+                  scale_x: this._newWorkspaceArea.scale,
+                  scale_y: this._newWorkspaceArea.scale,
+                  time: WORKSPACE_SWITCH_TIME,
+                  transition: 'easeOutQuad'
+                });
+            this._leftShadow.x = this._leftShadow.gridX;
+            Tweener.addTween(this._leftShadow,
+                { y: this._leftShadow.gridY,
+                  scale_x: this._leftShadow.scale,
+                  scale_y: this._leftShadow.scale,
+                  time: WORKSPACE_SWITCH_TIME,
+                  transition: 'easeOutQuad'
+                });
+            this._rightShadow.x = this._rightShadow.gridX;
+            Tweener.addTween(this._rightShadow,
+                { y: this._rightShadow.gridY,
+                  scale_x: this._rightShadow.scale,
+                  scale_y: this._rightShadow.scale,
+                  time: WORKSPACE_SWITCH_TIME,
+                  transition: 'easeOutQuad'
+                });
+        } else {
+            this._newWorkspaceArea.actor.set_scale(this._newWorkspaceArea.scale, this._newWorkspaceArea.scale);
+            this._newWorkspaceArea.actor.set_position(this._newWorkspaceArea.gridX, this._newWorkspaceArea.gridY);
+
+            this._leftShadow.set_scale(this._leftShadow.scale, this._leftShadow.scale);
+            this._leftShadow.set_position(this._leftShadow.gridX, this._leftShadow.gridY);
+            this._rightShadow.set_scale(this._rightShadow.scale, this._rightShadow.scale);
+            this._rightShadow.set_position(this._rightShadow.gridX, this._rightShadow.gridY);
         }
 
         for (let l = 0; l < this._lostWorkspaces.length; l++) {
@@ -667,9 +791,121 @@ SingleView.prototype = {
         this._scrollToActive(true);
     },
 
+    _onDestroy: function() {
+        GenericWorkspacesView.prototype._onDestroy.call(this);
+        this._dropGroup.destroy();
+        if (this._timeoutId) {
+            Mainloop.source_remove(this._timeoutId);
+            this._timeoutId = 0;
+        }
+    },
+
+    acceptDrop: function(source, dropActor, x, y, time) {
+        for (let i = 0; i < this._workspaces.length; i++) {
+            let [dx, dy] = this._workspaces[i].actor.get_transformed_position();
+            let [dw, dh] = this._workspaces[i].actor.get_transformed_size();
+
+            if (x > dx && x < dx + dw && y > dy && y < dy + dh)
+                return this._workspaces[i].acceptDrop(source, dropActor, x, y, time);
+        }
+
+        let [dx, dy] = this._newWorkspaceArea.actor.get_transformed_position();
+        let [dw, dh] = this._newWorkspaceArea.actor.get_transformed_size();
+        if (x > dx && x < dx + dw && y > dy && y < dy + dh)
+            return this._acceptNewWorkspaceDrop(source, dropActor, x, y, time);
+
+        return false;
+    },
+
+    _onWindowDragBegin: function(w, actor) {
+        if (!this._scroll || this._scroll.adjustment.value - Math.round(this._scroll.adjustment.value) != 0)
+            return;
+
+        this._inDrag = true;
+        this._updateWorkspaceActors(true);
+
+        this._dropGroup.raise_top();
+    },
+
+    handleDragOver: function(self, actor, x, y) {
+        let onPanel = false;
+
+        let activeWorkspaceIndex = global.screen.get_active_workspace_index();
+        if (x == 0 && activeWorkspaceIndex > 0 && this._dragOverLastX !== 0) {
+            this._workspaces[activeWorkspaceIndex - 1]._metaWorkspace.activate(global.get_current_time());
+            this._workspaces[activeWorkspaceIndex - 1].setReservedSlot(actor._delegate);
+            this._dragOverLastX = 0;
+            return;
+        }
+        if (x == global.screen_width - 1 && this._workspaces[activeWorkspaceIndex + 1] &&
+            this._dragOverLastX != global.screen_width - 1) {
+            this._workspaces[activeWorkspaceIndex + 1]._metaWorkspace.activate(global.get_current_time());
+            this._workspaces[activeWorkspaceIndex + 1].setReservedSlot(actor._delegate);
+            this._dragOverLastX = global.screen_width - 1;
+            return;
+        }
+
+        this._dragOverLastX = x;
+
+        let [dx, dy] = this._newWorkspaceArea.actor.get_transformed_position();
+        let [dw, dh] = this._newWorkspaceArea.actor.get_transformed_size();
+        this._newWorkspaceArea.setStyle(x > dx && x < dx + dw && y > dy && y < dy + dh);
+
+        [dx, dy] = this._leftShadow.get_transformed_position();
+        [dw, dh] = this._leftShadow.get_transformed_size();
+        if (this._workspaces[activeWorkspaceIndex - 1]) {
+            if (x > dx && x < dx + dw && y > dy && y < dy + dh) {
+                onPanel = -1;
+                this._workspaces[activeWorkspaceIndex - 1].actor.opacity = 255;
+            } else
+                this._workspaces[activeWorkspaceIndex - 1].actor.opacity = 200;
+        }
+
+        [dx, dy] = this._rightShadow.get_transformed_position();
+        [dw, dh] = this._rightShadow.get_transformed_size();
+        if (this._workspaces[activeWorkspaceIndex + 1]) {
+            if (x > dx && x < dx + dw && y > dy && y < dy + dh) {
+                onPanel = 1;
+                this._workspaces[activeWorkspaceIndex + 1].actor.opacity = 255;
+            } else
+                this._workspaces[activeWorkspaceIndex + 1].actor.opacity = 200;
+        }
+        if (onPanel) {
+            if (!this._timeoutId)
+                this._timeoutId = Mainloop.timeout_add_seconds (1, Lang.bind(this, function() {
+                   let i = global.screen.get_active_workspace_index();
+                   if (this._workspaces[i + onPanel]) {
+                       this._workspaces[i + onPanel]._metaWorkspace.activate(global.get_current_time());
+                       this._workspaces[i + onPanel].setReservedSlot(actor._delegate);
+                   }
+                   return true;
+                }));
+        } else {
+            if (this._timeoutId) {
+                Mainloop.source_remove(this._timeoutId);
+                this._timeoutId = 0;
+            }
+        }
+    },
+
+    _onWindowDragEnd: function(w, actor) {
+        if (this._timeoutId) {
+            Mainloop.source_remove(this._timeoutId);
+            this._timeoutId = 0;
+        }
+        this._dropGroup.lower_bottom();
+        actor.opacity = 255;
+        this._inDrag = false;
+        this._updateWorkspaceActors(true);
+
+        for (let i = 0; i < this._workspaces.length; i++)
+            this._workspaces[i].setReservedSlot(null);
+    },
+
     _addWorkspaceActor: function(workspaceNum) {
         let workspace  = new Workspace.Workspace(workspaceNum, this._actor);
-
+        workspace.connect('window-drag-begin', Lang.bind(this, this._onWindowDragBegin));
+        workspace.connect('window-drag-end', Lang.bind(this, this._onWindowDragEnd));
         this._actor.add_actor(workspace.actor);
         this._workspaces[workspaceNum] = workspace;
     },
@@ -719,10 +955,7 @@ SingleView.prototype = {
 
         for (let i = 0; i < this._workspaces.length; i++) {
             this._workspaces[i]._hideAllOverlays();
-            if (Math.abs(i - adj.value) <= 1)
-                this._workspaces[i].actor.show();
-            else
-                this._workspaces[i].actor.hide();
+            this._workspaces[i].actor.visible = Math.abs(i - adj.value) <= 1;
             this._workspaces[i].actor.x += dx;
         }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]