Compare commits
10 Commits
citadel
...
wip/gestur
Author | SHA1 | Date | |
---|---|---|---|
|
38509081e7 | ||
|
f659b66a9d | ||
|
247a42ccc4 | ||
|
a50a463eb3 | ||
|
dc7cca7e6d | ||
|
38032bf820 | ||
|
624314ee3e | ||
|
ed6dc326d1 | ||
|
13b4290e55 | ||
|
f4e0f6385c |
@ -32,6 +32,7 @@
|
||||
<file>ui/animation.js</file>
|
||||
<file>ui/appDisplay.js</file>
|
||||
<file>ui/appFavorites.js</file>
|
||||
<file>ui/appSwitchAction.js</file>
|
||||
<file>ui/backgroundMenu.js</file>
|
||||
<file>ui/background.js</file>
|
||||
<file>ui/boxpointer.js</file>
|
||||
@ -41,6 +42,7 @@
|
||||
<file>ui/dash.js</file>
|
||||
<file>ui/dateMenu.js</file>
|
||||
<file>ui/dnd.js</file>
|
||||
<file>ui/edgeDragAction.js</file>
|
||||
<file>ui/endSessionDialog.js</file>
|
||||
<file>ui/environment.js</file>
|
||||
<file>ui/extensionDownloader.js</file>
|
||||
@ -79,6 +81,7 @@
|
||||
<file>ui/shellDBus.js</file>
|
||||
<file>ui/shellEntry.js</file>
|
||||
<file>ui/shellMountOperation.js</file>
|
||||
<file>ui/showOverviewAction.js</file>
|
||||
<file>ui/slider.js</file>
|
||||
<file>ui/switcherPopup.js</file>
|
||||
<file>ui/tweener.js</file>
|
||||
@ -89,6 +92,7 @@
|
||||
<file>ui/windowMenu.js</file>
|
||||
<file>ui/windowManager.js</file>
|
||||
<file>ui/workspace.js</file>
|
||||
<file>ui/workspaceSwitchAction.js</file>
|
||||
<file>ui/workspaceSwitcherPopup.js</file>
|
||||
<file>ui/workspaceThumbnail.js</file>
|
||||
<file>ui/workspacesView.js</file>
|
||||
|
64
js/ui/appSwitchAction.js
Normal file
64
js/ui/appSwitchAction.js
Normal file
@ -0,0 +1,64 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
|
||||
//in milliseconds
|
||||
let LONG_PRESS_TIMEOUT = 250;
|
||||
|
||||
let MOTION_THRESHOLD = 30;
|
||||
|
||||
const AppSwitchAction = new Lang.Class({
|
||||
Name: 'AppSwitchAction',
|
||||
Extends: Clutter.GestureAction,
|
||||
|
||||
_init : function() {
|
||||
this.parent();
|
||||
this.set_n_touch_points (3);
|
||||
global.display.connect('grab-op-begin', Lang.bind(this, this.cancel));
|
||||
global.display.connect('grab-op-end', Lang.bind(this, this.cancel));
|
||||
},
|
||||
|
||||
vfunc_gesture_prepare : function(action, actor) {
|
||||
return this.get_n_current_points() <= 4;
|
||||
},
|
||||
|
||||
vfunc_gesture_begin : function(action, actor) {
|
||||
let nPoints = this.get_n_current_points();
|
||||
let event = this.get_last_event (nPoints - 1);
|
||||
|
||||
if (nPoints == 3)
|
||||
this._longPressStartTime = event.get_time();
|
||||
else if (nPoints == 4) {
|
||||
// Check whether the 4th finger press happens after a 3-finger long press,
|
||||
// this only needs to be checked on the first 4th finger press
|
||||
if (this._longPressStartTime != null &&
|
||||
event.get_time() < this._longPressStartTime + LONG_PRESS_TIMEOUT)
|
||||
this.cancel();
|
||||
else {
|
||||
this._longPressStartTime = null;
|
||||
this.emit('activated');
|
||||
}
|
||||
}
|
||||
|
||||
return this.get_n_current_points() <= 4;
|
||||
},
|
||||
|
||||
vfunc_gesture_progress : function(action, actor) {
|
||||
if (this.get_n_current_points() == 3) {
|
||||
for (let i = 0; i < this.get_n_current_points(); i++) {
|
||||
[startX, startY] = this.get_press_coords(i);
|
||||
[x, y] = this.get_motion_coords(i);
|
||||
|
||||
if (Math.abs(x - startX) > MOTION_THRESHOLD ||
|
||||
Math.abs(y - startY) > MOTION_THRESHOLD)
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(AppSwitchAction.prototype);
|
@ -55,6 +55,10 @@ function addBackgroundMenu(actor, layoutManager) {
|
||||
});
|
||||
actor.add_action(clickAction);
|
||||
|
||||
global.display.connect('grab-op-begin', function () {
|
||||
clickAction.release();
|
||||
});
|
||||
|
||||
actor.connect('destroy', function() {
|
||||
actor._backgroundMenu.destroy();
|
||||
actor._backgroundMenu = null;
|
||||
|
76
js/ui/edgeDragAction.js
Normal file
76
js/ui/edgeDragAction.js
Normal file
@ -0,0 +1,76 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Lang = imports.lang;
|
||||
const Signals = imports.signals;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const St = imports.gi.St;
|
||||
|
||||
let EDGE_THRESHOLD = 20;
|
||||
let DRAG_DISTANCE = 80;
|
||||
|
||||
const EdgeDragAction = new Lang.Class({
|
||||
Name: 'EdgeDragAction',
|
||||
Extends: Clutter.GestureAction,
|
||||
|
||||
_init : function(side) {
|
||||
this.parent();
|
||||
this._side = side;
|
||||
this.set_n_touch_points (1);
|
||||
global.display.connect('grab-op-begin', Lang.bind(this, this.cancel));
|
||||
global.display.connect('grab-op-end', Lang.bind(this, this.cancel));
|
||||
},
|
||||
|
||||
_getMonitorRect : function (x, y) {
|
||||
let rect = new Meta.Rectangle({ x: x - 1, y: y - 1, width: 1, height: 1 });
|
||||
let monitorIndex = global.screen.get_monitor_index_for_rect(rect);
|
||||
|
||||
return global.screen.get_monitor_geometry(monitorIndex);
|
||||
},
|
||||
|
||||
vfunc_gesture_prepare : function(action, actor) {
|
||||
if (this.get_n_current_points() == 0)
|
||||
return false;
|
||||
|
||||
let [x, y] = this.get_press_coords(0);
|
||||
let monitorRect = this._getMonitorRect(x, y);
|
||||
|
||||
return ((this._side == St.Side.LEFT && x < monitorRect.x + EDGE_THRESHOLD) ||
|
||||
(this._side == St.Side.RIGHT && x > monitorRect.x + monitorRect.width - EDGE_THRESHOLD) ||
|
||||
(this._side == St.Side.TOP && y < monitorRect.y + EDGE_THRESHOLD) ||
|
||||
(this._side == St.Side.BOTTOM && y > monitorRect.y + monitorRect.height - EDGE_THRESHOLD));
|
||||
},
|
||||
|
||||
vfunc_gesture_progress : function (action, actor) {
|
||||
let [startX, startY] = this.get_press_coords(0);
|
||||
let [x, y] = this.get_motion_coords(0);
|
||||
let offsetX = Math.abs (x - startX);
|
||||
let offsetY = Math.abs (y - startY);
|
||||
|
||||
if (offsetX < EDGE_THRESHOLD && offsetY < EDGE_THRESHOLD)
|
||||
return true;
|
||||
|
||||
if ((offsetX > offsetY &&
|
||||
(this._side == St.Side.TOP || this._side == St.Side.BOTTOM)) ||
|
||||
(offsetY > offsetX &&
|
||||
(this._side == St.Side.LEFT || this._side == St.Side.RIGHT))) {
|
||||
this.cancel();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
vfunc_gesture_end : function (action, actor) {
|
||||
let [startX, startY] = this.get_press_coords(0);
|
||||
let [x, y] = this.get_motion_coords(0);
|
||||
let monitorRect = this._getMonitorRect(startX, startY);
|
||||
|
||||
if ((this._side == St.Side.TOP && y > monitorRect.y + DRAG_DISTANCE) ||
|
||||
(this._side == St.Side.BOTTOM && y < monitorRect.y + monitorRect.height - DRAG_DISTANCE) ||
|
||||
(this._side == St.Side.LEFT && x > monitorRect.x + DRAG_DISTANCE) ||
|
||||
(this._side == St.Side.RIGHT && x < monitorRect.x + monitorRect.width - DRAG_DISTANCE))
|
||||
this.emit('activated');
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(EdgeDragAction.prototype);
|
@ -15,6 +15,7 @@ const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Tp = imports.gi.TelepathyGLib;
|
||||
|
||||
const EdgeDragAction = imports.ui.edgeDragAction;
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
@ -1933,6 +1934,10 @@ const MessageTray = new Lang.Class({
|
||||
|
||||
this._messageTrayMenuButton = new MessageTrayMenuButton(this);
|
||||
this.actor.add_actor(this._messageTrayMenuButton.actor);
|
||||
|
||||
let gesture = new EdgeDragAction.EdgeDragAction(St.Side.BOTTOM);
|
||||
gesture.connect('activated', Lang.bind(this, this.toggle));
|
||||
global.stage.add_action(gesture);
|
||||
},
|
||||
|
||||
close: function() {
|
||||
|
66
js/ui/showOverviewAction.js
Normal file
66
js/ui/showOverviewAction.js
Normal file
@ -0,0 +1,66 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Signals = imports.signals;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
|
||||
const ShowOverviewAction = new Lang.Class({
|
||||
Name: 'ShowOverviewAction',
|
||||
Extends: Clutter.GestureAction,
|
||||
|
||||
_init : function() {
|
||||
this.parent();
|
||||
this.set_n_touch_points (3);
|
||||
global.display.connect('grab-op-begin', Lang.bind(this, this.cancel));
|
||||
global.display.connect('grab-op-end', Lang.bind(this, this.cancel));
|
||||
},
|
||||
|
||||
vfunc_gesture_prepare : function(action, actor) {
|
||||
return this.get_n_current_points() == this.get_n_touch_points();
|
||||
},
|
||||
|
||||
_getBoundingRect : function(motion) {
|
||||
let minX, minY, maxX, maxY;
|
||||
|
||||
for (let i = 0; i < this.get_n_current_points(); i++) {
|
||||
let x, y;
|
||||
|
||||
if (motion == true) {
|
||||
[x, y] = this.get_motion_coords(i);
|
||||
} else {
|
||||
[x, y] = this.get_press_coords(i);
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
minX = maxX = x;
|
||||
minY = maxY = y;
|
||||
} else {
|
||||
minX = Math.min(minX, x);
|
||||
minY = Math.min(minY, y);
|
||||
maxX = Math.max(maxX, x);
|
||||
maxY = Math.max(maxY, y);
|
||||
}
|
||||
}
|
||||
|
||||
return new Meta.Rectangle({ x: minX,
|
||||
y: minY,
|
||||
width: maxX - minX,
|
||||
height: maxY - minY });
|
||||
},
|
||||
|
||||
vfunc_gesture_begin : function(action, actor) {
|
||||
this._initialRect = this._getBoundingRect(false);
|
||||
return true;
|
||||
},
|
||||
|
||||
vfunc_gesture_end : function(action, actor) {
|
||||
let rect = this._getBoundingRect(true);
|
||||
let oldArea = this._initialRect.width * this._initialRect.height;
|
||||
let newArea = rect.width * rect.height;
|
||||
let areaDiff = newArea / oldArea;
|
||||
|
||||
this.emit('activated', areaDiff);
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(ShowOverviewAction.prototype);
|
@ -11,6 +11,8 @@ const Lang = imports.lang;
|
||||
const Shell = imports.gi.Shell;
|
||||
const St = imports.gi.St;
|
||||
|
||||
const EdgeDragAction = imports.ui.edgeDragAction;
|
||||
const ShowOverviewAction = imports.ui.showOverviewAction;
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const Main = imports.ui.main;
|
||||
const OverviewControls = imports.ui.overviewControls;
|
||||
@ -145,6 +147,21 @@ const ViewSelector = new Lang.Class({
|
||||
Shell.KeyBindingMode.OVERVIEW,
|
||||
Lang.bind(Main.overview, Main.overview.toggle));
|
||||
|
||||
let gesture = new EdgeDragAction.EdgeDragAction(St.Side.RIGHT);
|
||||
gesture.connect('activated', Lang.bind(this, function() {
|
||||
if (Main.overview.visible)
|
||||
Main.overview.hide();
|
||||
else
|
||||
this.showApps();
|
||||
}));
|
||||
global.stage.add_action(gesture);
|
||||
|
||||
gesture = new ShowOverviewAction.ShowOverviewAction();
|
||||
gesture.connect('activated', Lang.bind(this, function(action, areaDiff) {
|
||||
if (areaDiff < 0.7)
|
||||
Main.overview.show();
|
||||
}));
|
||||
global.stage.add_action(gesture);
|
||||
},
|
||||
|
||||
_toggleAppsPage: function() {
|
||||
|
@ -11,6 +11,8 @@ const St = imports.gi.St;
|
||||
const Shell = imports.gi.Shell;
|
||||
|
||||
const AltTab = imports.ui.altTab;
|
||||
const WorkspaceSwitchAction = imports.ui.workspaceSwitchAction;
|
||||
const AppSwitchAction = imports.ui.appSwitchAction;
|
||||
const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup;
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
@ -683,6 +685,53 @@ const WindowManager = new Lang.Class({
|
||||
|
||||
global.screen.override_workspace_layout(Meta.ScreenCorner.TOPLEFT,
|
||||
false, -1, 1);
|
||||
|
||||
let gesture = new WorkspaceSwitchAction.WorkspaceSwitchAction();
|
||||
gesture.connect('activated', Lang.bind(this, function(action, direction) {
|
||||
let newWs = global.screen.get_active_workspace().get_neighbor(direction);
|
||||
this.actionMoveWorkspace(newWs);
|
||||
}));
|
||||
global.stage.add_action(gesture);
|
||||
|
||||
gesture = new AppSwitchAction.AppSwitchAction();
|
||||
gesture.connect('activated', Lang.bind(this, this._switchApp));
|
||||
global.stage.add_action(gesture);
|
||||
},
|
||||
|
||||
_lookupIndex: function (windows, metaWindow) {
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
if (windows[i].metaWindow == metaWindow) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
_switchApp : function () {
|
||||
let windows = global.get_window_actors().filter(Lang.bind(this, function(actor) {
|
||||
let win = actor.metaWindow;
|
||||
return (!win.is_override_redirect() &&
|
||||
win.located_on_workspace(global.screen.get_active_workspace()));
|
||||
}));
|
||||
|
||||
if (windows.length == 0)
|
||||
return;
|
||||
|
||||
let focusWindow = global.display.focus_window;
|
||||
let nextWindow;
|
||||
|
||||
if (focusWindow == null)
|
||||
nextWindow = windows[0].metaWindow;
|
||||
else {
|
||||
let index = this._lookupIndex (windows, focusWindow) + 1;
|
||||
|
||||
if (index >= windows.length)
|
||||
index = 0;
|
||||
|
||||
nextWindow = windows[index].metaWindow;
|
||||
}
|
||||
|
||||
Main.activateWindow(nextWindow);
|
||||
},
|
||||
|
||||
keepWorkspaceAlive: function(workspace, duration) {
|
||||
|
52
js/ui/workspaceSwitchAction.js
Normal file
52
js/ui/workspaceSwitchAction.js
Normal file
@ -0,0 +1,52 @@
|
||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
const Signals = imports.signals;
|
||||
const Lang = imports.lang;
|
||||
const Meta = imports.gi.Meta;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
|
||||
let MOTION_THRESHOLD = 50;
|
||||
|
||||
const WorkspaceSwitchAction = new Lang.Class({
|
||||
Name: 'WorkspaceSwitchAction',
|
||||
Extends: Clutter.GestureAction,
|
||||
|
||||
_init : function() {
|
||||
this.parent();
|
||||
this.set_n_touch_points (4);
|
||||
global.display.connect('grab-op-begin', Lang.bind(this, this.cancel));
|
||||
global.display.connect('grab-op-end', Lang.bind(this, this.cancel));
|
||||
},
|
||||
|
||||
vfunc_gesture_prepare : function(action, actor) {
|
||||
return this.get_n_current_points() == this.get_n_touch_points();
|
||||
},
|
||||
|
||||
vfunc_gesture_end : function(action, actor) {
|
||||
// Just check one touchpoint here
|
||||
let [startX, startY] = this.get_press_coords(0);
|
||||
let [x, y] = this.get_motion_coords(0);
|
||||
let offsetX = x - startX;
|
||||
let offsetY = y - startY;
|
||||
let direction;
|
||||
|
||||
if (Math.abs(offsetX) < MOTION_THRESHOLD &&
|
||||
Math.abs(offsetY) < MOTION_THRESHOLD)
|
||||
return;
|
||||
|
||||
if (Math.abs(offsetY) > Math.abs(offsetX)) {
|
||||
if (offsetY > 0)
|
||||
direction = Meta.MotionDirection.UP;
|
||||
else
|
||||
direction = Meta.MotionDirection.DOWN;
|
||||
} else {
|
||||
if (offsetX > 0)
|
||||
direction = Meta.MotionDirection.LEFT;
|
||||
else
|
||||
direction = Meta.MotionDirection.RIGHT;
|
||||
}
|
||||
|
||||
this.emit('activated', direction);
|
||||
}
|
||||
});
|
||||
Signals.addSignalMethods(WorkspaceSwitchAction.prototype);
|
Loading…
Reference in New Issue
Block a user