add ability move window in SingleView

https://bugzilla.gnome.org/show_bug.cgi?id=607821
This commit is contained in:
Maxim Ermilov 2010-03-16 18:51:24 +03:00
parent 011db9f34d
commit 7183aac362
5 changed files with 432 additions and 41 deletions

View File

@ -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 \

View File

@ -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;
}

View File

@ -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.254995 -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>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -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;
let buttonOuterWidth = 0;
let [buttonOuterHeight, captionHeight] = this._windowOverlays[1].chromeHeights();
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();
}));

View File

@ -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;
}