[Overview] Switch workspace when dragging the desktop
Depending on screen size and pointer position, the scroll bar used to switch the active workspace in linear view may not be a convenient target, so allow dragging the desktop as an alternative. https://bugzilla.gnome.org/show_bug.cgi?id=610892
This commit is contained in:
parent
b7c6ec4b46
commit
47644cad6a
@ -36,6 +36,8 @@ const WORKSPACES_VIEW_KEY = 'overview/workspaces_view';
|
|||||||
const WORKSPACE_DRAGGING_SCALE = 0.85;
|
const WORKSPACE_DRAGGING_SCALE = 0.85;
|
||||||
const WORKSPACE_SHADOW_SCALE = (1 - WORKSPACE_DRAGGING_SCALE) / 2;
|
const WORKSPACE_SHADOW_SCALE = (1 - WORKSPACE_DRAGGING_SCALE) / 2;
|
||||||
|
|
||||||
|
const WORKSPACE_DRAG_THRESHOLD = 0.2;
|
||||||
|
|
||||||
function GenericWorkspacesView(width, height, x, y, animate) {
|
function GenericWorkspacesView(width, height, x, y, animate) {
|
||||||
this._init(width, height, x, y, animate);
|
this._init(width, height, x, y, animate);
|
||||||
}
|
}
|
||||||
@ -511,6 +513,10 @@ SingleView.prototype = {
|
|||||||
this._dropGroup._delegate = this;
|
this._dropGroup._delegate = this;
|
||||||
global.stage.add_actor(this._dropGroup);
|
global.stage.add_actor(this._dropGroup);
|
||||||
this._dropGroup.lower_bottom();
|
this._dropGroup.lower_bottom();
|
||||||
|
this._dragIndex = -1;
|
||||||
|
|
||||||
|
this._buttonPressId = 0;
|
||||||
|
this._capturedEventId = 0;
|
||||||
this._timeoutId = 0;
|
this._timeoutId = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -524,6 +530,8 @@ SingleView.prototype = {
|
|||||||
let active = global.screen.get_active_workspace_index();
|
let active = global.screen.get_active_workspace_index();
|
||||||
let _width = this._workspaces[0].actor.width * scale;
|
let _width = this._workspaces[0].actor.width * scale;
|
||||||
|
|
||||||
|
this._setWorkspaceDraggable(active, true);
|
||||||
|
|
||||||
for (let w = 0; w < this._workspaces.length; w++) {
|
for (let w = 0; w < this._workspaces.length; w++) {
|
||||||
let workspace = this._workspaces[w];
|
let workspace = this._workspaces[w];
|
||||||
|
|
||||||
@ -564,6 +572,108 @@ SingleView.prototype = {
|
|||||||
this._scrollScrollBarToIndex(active, showAnimation);
|
this._scrollScrollBarToIndex(active, showAnimation);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// _setWorkspaceDraggable:
|
||||||
|
// @index: workspace index
|
||||||
|
// @draggable: whether workspace @index should be draggable
|
||||||
|
//
|
||||||
|
// If @draggable is %true, set up workspace @index to allow switching
|
||||||
|
// workspaces by dragging the desktop - if a draggable workspace has
|
||||||
|
// been set up before, it will be reset before the new one is made
|
||||||
|
// draggable.
|
||||||
|
// If @draggable is %false, workspace @index is reset to no longer allow
|
||||||
|
// dragging.
|
||||||
|
_setWorkspaceDraggable: function(index, draggable) {
|
||||||
|
if (index < 0 || index >= global.n_workspaces)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let dragActor = this._workspaces[index]._desktop.actor;
|
||||||
|
|
||||||
|
if (draggable) {
|
||||||
|
this._workspaces[index].actor.reactive = true;
|
||||||
|
|
||||||
|
// reset old draggable workspace
|
||||||
|
if (this._dragIndex > -1)
|
||||||
|
this._setWorkspaceDraggable(this._dragIndex, false);
|
||||||
|
|
||||||
|
this._dragIndex = index;
|
||||||
|
this._buttonPressId = dragActor.connect('button-press-event',
|
||||||
|
Lang.bind(this, this._onButtonPress));
|
||||||
|
} else {
|
||||||
|
this._dragIndex = -1;
|
||||||
|
|
||||||
|
if (this._buttonPressId > 0) {
|
||||||
|
if (dragActor.get_stage())
|
||||||
|
dragActor.disconnect(this._buttonPressId);
|
||||||
|
this._buttonPressId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._capturedEventId > 0) {
|
||||||
|
global.stage.disconnect(this._capturedEventId);
|
||||||
|
this._capturedEventId = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// start dragging the active workspace
|
||||||
|
_onButtonPress: function(actor, event) {
|
||||||
|
if (this._dragIndex == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let [stageX, stageY] = event.get_coords();
|
||||||
|
this._dragStartX = this._dragX = stageX;
|
||||||
|
this._scrolling = true;
|
||||||
|
this._capturedEventId = global.stage.connect('captured-event',
|
||||||
|
Lang.bind(this, this._onCapturedEvent));
|
||||||
|
},
|
||||||
|
|
||||||
|
// handle captured events while dragging a workspace
|
||||||
|
_onCapturedEvent: function(actor, event) {
|
||||||
|
let active = global.screen.get_active_workspace_index();
|
||||||
|
let stageX, stageY;
|
||||||
|
|
||||||
|
switch (event.type()) {
|
||||||
|
case Clutter.EventType.BUTTON_RELEASE:
|
||||||
|
this._scrolling = false;
|
||||||
|
|
||||||
|
[stageX, stageY] = event.get_coords();
|
||||||
|
|
||||||
|
// default to snapping back to the original workspace
|
||||||
|
let activate = this._dragIndex;
|
||||||
|
let last = global.screen.n_workspaces - 1;
|
||||||
|
|
||||||
|
// switch workspaces according to the drag direction
|
||||||
|
if (stageX > this._dragStartX && activate > 0)
|
||||||
|
activate--;
|
||||||
|
else if (stageX < this._dragStartX && activate < last)
|
||||||
|
activate++;
|
||||||
|
|
||||||
|
if (activate != active) {
|
||||||
|
let workspace = this._workspaces[activate]._metaWorkspace;
|
||||||
|
workspace.activate(global.get_current_time());
|
||||||
|
} else {
|
||||||
|
this._scrollToActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stageX == this._dragStartX)
|
||||||
|
// no motion? It's a click!
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Clutter.EventType.MOTION:
|
||||||
|
[stageX, stageY] = event.get_coords();
|
||||||
|
let dx = this._dragX - stageX;
|
||||||
|
let primary = global.get_primary_monitor();
|
||||||
|
|
||||||
|
this._scroll.adjustment.value += (dx / primary.width);
|
||||||
|
this._dragX = stageX;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
_updateWorkspaceActors: function(showAnimation) {
|
_updateWorkspaceActors: function(showAnimation) {
|
||||||
let active = global.screen.get_active_workspace_index();
|
let active = global.screen.get_active_workspace_index();
|
||||||
|
|
||||||
@ -571,6 +681,7 @@ SingleView.prototype = {
|
|||||||
|
|
||||||
let dx = this._workspaces[0].gridX - this._workspaces[0].actor.x;
|
let dx = this._workspaces[0].gridX - this._workspaces[0].actor.x;
|
||||||
|
|
||||||
|
this._setWorkspaceDraggable(active, true);
|
||||||
for (let w = 0; w < this._workspaces.length; w++) {
|
for (let w = 0; w < this._workspaces.length; w++) {
|
||||||
let workspace = this._workspaces[w];
|
let workspace = this._workspaces[w];
|
||||||
|
|
||||||
@ -766,6 +877,7 @@ SingleView.prototype = {
|
|||||||
|
|
||||||
_onDestroy: function() {
|
_onDestroy: function() {
|
||||||
GenericWorkspacesView.prototype._onDestroy.call(this);
|
GenericWorkspacesView.prototype._onDestroy.call(this);
|
||||||
|
this._setWorkspaceDraggable(this._dragIndex, false);
|
||||||
this._dropGroup.destroy();
|
this._dropGroup.destroy();
|
||||||
if (this._timeoutId) {
|
if (this._timeoutId) {
|
||||||
Mainloop.source_remove(this._timeoutId);
|
Mainloop.source_remove(this._timeoutId);
|
||||||
|
Loading…
Reference in New Issue
Block a user