Last active
August 29, 2015 14:17
-
-
Save ProLoser/a55406df872c83dd71ea to your computer and use it in GitHub Desktop.
Slate Config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ = (function() { | |
$ = function() { | |
var args = _.toArray(arguments); | |
var sequence = false; | |
var func; | |
if (args.length == 1 && _.isArray(args[0])) { | |
sequence = true; | |
} else { | |
func = args.shift(); | |
} | |
function call(win, func, args) { | |
try { | |
ret = win[func].apply(win, args); | |
} finally { | |
if (win.isOffscreen()) | |
win.rescue(); | |
} | |
} | |
function dispatch(win) { | |
if (sequence) { | |
_.each(args, function(sub) { | |
var func = sub.shift(); | |
call(win, func, sub); | |
}); | |
} else { | |
call(win, func, args); | |
} | |
} | |
return dispatch; | |
}; | |
function Proxy(parent, keys, base) { | |
var proxy = {}; | |
var _super = {}; | |
_.each(keys, function(key) { | |
var value = parent[key]; | |
if (_.isFunction(value)) { | |
_super[key] = proxy[key] = (function() { | |
var func = value; | |
return function() { | |
return func.apply(parent, arguments); | |
}; | |
})(); | |
} else { | |
_super[key] = proxy[key] = parent[key]; | |
} | |
}); | |
$.addNames(base, function(member, key) { | |
var parent = base.name; | |
if (proxy.title) { | |
var title = '"' + proxy.title() + '"'; | |
if (proxy.app) { | |
var name = proxy.app().name(); | |
title = '[' + name + ']: ' + title; | |
} | |
parent += '(' + title + ')'; | |
} | |
return parent + '.' + key; | |
}); | |
_.extend(proxy, base); | |
proxy._super = _super; | |
if (proxy.update) | |
proxy.update(); | |
return proxy; | |
} | |
function ProxyMember() { | |
function wrapper() { | |
return wrapper._init.apply(wrapper, arguments); | |
} | |
return wrapper; | |
} | |
_.extend($, { | |
debug: false, | |
log: function() { | |
if (this.debug) { | |
S.log.apply(S, arguments); | |
} | |
}, | |
addNames: function(obj, extra) { | |
_.each(obj, function(member, key) { | |
if (_.isFunction(member)) { | |
if (_.isFunction(extra)) { | |
member._name = extra(member, key); | |
} else { | |
member._name = key + '()'; | |
} | |
} | |
}); | |
}, | |
backtrace: function(error) { | |
if (error) { | |
if (error instanceof Error) { | |
$.log('Error (line ' + error.line + ') : ' + error); | |
} else { | |
$.log('Error: ' + error); | |
} | |
} | |
var stack = []; | |
var current = arguments.callee.caller; | |
var iterations = 0; | |
while (current) { | |
iterations++; | |
if (iterations > 10) { | |
break; // nope nope nope | |
} | |
var fn = current; | |
var name = fn._name; | |
// determine the function name | |
if (! name) | |
name = (fn.name || fn); | |
var args = JSON.stringify(_.toArray(current.arguments)); | |
args = args.replace(/^\[/, '(').replace(/]$/, ')'); | |
var pretty = name + args; | |
stack.push(pretty); | |
// add a hotkey line to the stacktrace when we get to that point | |
if (fn._hotkey) { | |
var key = fn._hotkey; | |
if (_.contains(key, ':')) { | |
var parts = key.split(':'); | |
key = parts[0]; | |
mods = parts[1].replace(/;/g, '+'); | |
if (mods) { | |
key = mods + '-' + key; | |
} | |
} | |
key = key.replace(/\b\S/g, function(a) { return a.toUpperCase(); }); | |
stack.push('Hotkey Pressed: "' + key + '"'); | |
} | |
current = current.caller; | |
} | |
$.log('Backtrace:'); | |
for (var i = 0; i < stack.length; i++) { | |
$.log(' - ' + i + ': ' + stack[i]); | |
} | |
}, | |
focus: function(name) { | |
name = name.replace('"', '\"'); | |
return 'focus "' + name + '"'; | |
}, | |
chain: function() { | |
var ops = []; | |
_.each(arguments, function(op) { | |
if (_.isString(op)) { | |
op = slate.operationFromString(op); | |
} | |
if (_.isFunction(op)) { | |
var call = op; | |
op = function(win) { | |
return call($.window(win)); | |
}; | |
} | |
ops.push(op); | |
}); | |
return slate.operation('chain', {operations: ops}); | |
}, | |
rect: ProxyMember(), | |
window: ProxyMember(), | |
screen: ProxyMember() | |
}); | |
$.addNames($); | |
_.extend($.rect, { | |
_keys: ['x', 'y', 'width', 'height'], | |
_init: function(rect) { | |
if (rect === undefined) { | |
$.log('slate.js - warning: offscreen window?'); | |
rect = {x: 0, y: 0, width: 1, height: 1}; | |
} | |
return Proxy(rect, this._keys, $.rect); | |
} | |
}); | |
_.extend($.screen, { | |
_keys: ['id', 'rect', 'visibleRect', 'isMain'], | |
_init: function(screen) { | |
if (screen == undefined) { | |
screen = S.screen(); | |
} | |
return Proxy(screen, this._keys, $.screen); | |
}, | |
rect: function() { | |
return $.rect(this._super.visibleRect()); | |
}, | |
update: function() { | |
var _super = this._super; | |
_.extend(this, this.rect()); | |
this._super = _super; | |
} | |
}); | |
_.extend($.window, { | |
_keys: [ | |
'title', 'topLeft', 'size', 'rect', 'pid', | |
'focus', 'isMinimizedOrHidden', 'isMain', | |
'move', 'isMovable', 'resize', 'isResizable', | |
'doOperation', 'screen', 'app' | |
], | |
_init: function(win) { | |
if (win == undefined) { | |
win = S.window(); | |
} | |
var keys = | |
win = Proxy(win, this._keys, $.window); | |
if (win.isOffscreen()) | |
win.rescue(); | |
return win; | |
}, | |
// internals | |
rect: function() { | |
return $.rect(this._super.rect()); | |
}, | |
screen: function() { | |
return $.screen(this._super.screen()); | |
}, | |
update: function() { | |
// make sure to update if you use any internal move/resize ops | |
var _super = this._super; | |
_.extend(this, this.rect()); | |
this._super = _super; | |
}, | |
isOffscreen: function() { | |
return this.screen().visibleRect() === undefined; | |
}, | |
rescue: function() { | |
this.op('throw 0 resize'); | |
this.op('throw 0 resize'); | |
}, | |
op: function(cmd, args) { | |
var op; | |
if (args === undefined) { | |
op = slate.operationFromString(cmd); | |
} else { | |
op = slate.operation(cmd, args); | |
} | |
return this.doOperation(op); | |
} | |
}); | |
return $; | |
})(); | |
/* Slate monkeypatching | |
* | |
* Here, we replace slate commands and add some new ones. | |
* | |
* slate.alias(alias, modifier): | |
* Binds 'alias' to 'modifier'. | |
* | |
* Example: | |
* slate.alias('hyper', 'cmd;alt;shift'); | |
* slate.bind('u:hyper', 'throw 0'); | |
* | |
* slate.removeAlias(alias): | |
* Removes a previously created alias. | |
* | |
* slate.bind(key, operation): | |
* Bind a key to operation(s). | |
* | |
* Enhanced as follows: | |
* | |
* * Enables 'chain' functionality via array: | |
* slate.bind('a': ['throw 0', 'throw 1']); | |
* | |
* * Allows usage of string ops without calling operationFromString() | |
* * Overloads window objects passed to function callbacks. | |
* * Adds backtrace metadata. | |
* | |
* slate.bindAll(object): | |
* Bind key(s) to operation(s). | |
* | |
* Enhanced as follows: | |
* * Allows deeply nested bindings with inherited modifiers: | |
* slate.bind({ | |
* hyper: { | |
* u: 'throw 0', // hyper+u | |
* shift: { // hyper+shift | |
* u: 'throw 1' // hyper+shift+u | |
* } | |
* } | |
* }); | |
* | |
*/ | |
(function() { | |
var windows = {}; | |
var aliases = {}; | |
var preHooks = []; | |
var postHooks = []; | |
function appendModifier(key, modifier) { | |
modifier = modifier.replace(':', ';'); | |
if (key.indexOf(':') !== -1) { | |
return key + ';' + modifier; | |
} else { | |
return key + ':' + modifier; | |
} | |
} | |
function makeCallback(key, op) { | |
var func; | |
if (_.isArray(op)) { | |
var ops = []; | |
_.each(op, function(o) { | |
o = makeCallback(key, o); | |
ops.push(o); | |
}); | |
return $.chain.apply(null, ops); | |
} else if (_.isString(op)) { | |
var strOp = op; | |
func = function(win) { | |
win.op(strOp); | |
}; | |
} else if (_.isFunction(op)) { | |
func = op; | |
} else { | |
S.log('unknown op:', op, typeof op); | |
return null; | |
} | |
return function(win) { | |
try { | |
_.each(preHooks, function(callback) { | |
callback(key, win); | |
}); | |
} catch (e) { | |
$.backtrace(e); | |
S.log('supressing exception in pre-hook.'); | |
} | |
try { | |
return func(win); | |
} catch (e) { | |
$.backtrace(e); | |
throw e; | |
} finally { | |
try { | |
_.each(postHooks, function(callback) { | |
callback(key, win); | |
}); | |
} catch (e) { | |
throw e; | |
} | |
} | |
}; | |
} | |
var _bind = slate.bind; | |
_.extend(slate, { | |
alias: function(alias, mod) { | |
aliases[alias] = mod; | |
}, | |
removeAlias: function(alias) { | |
delete aliases[alias]; | |
}, | |
pre: function(func) { | |
preHooks.push(func); | |
}, | |
post: function(func) { | |
postHooks.push(func); | |
}, | |
bind: function(key, op) { | |
_.each(aliases, function(mod, alias) { | |
key = key.replace(alias, mod); | |
}); | |
if (_.isObject(op) && !(_.isArray(op) || _.isFunction(op))) { | |
// nested modifiers | |
slate.bindAll(op, key); | |
return; | |
} | |
op = makeCallback(key, op); | |
if (_.isFunction(op)) { | |
function callback(win) { | |
if (win === undefined) { | |
// this won't go well | |
return false; | |
} | |
// reuse proxy objects in callbacks | |
// this means you can store persistent data on a $.window() | |
var pid = win.pid(); | |
if (_.has(windows, pid)) { | |
win = _.extend(windows[pid], $.window(win)); | |
} else { | |
win = windows[pid] = $.window(win); | |
} | |
return op(win); | |
} | |
callback._hotkey = key; | |
_bind(key, callback); | |
} else if (op) { | |
_bind(key, op); | |
} | |
}, | |
bindAll: function(obj, modifier) { | |
_.each(obj, function(op, key) { | |
if (modifier !== undefined) { | |
key = appendModifier(key, modifier); | |
} | |
slate.bind(key, op); | |
}); | |
} | |
}); | |
})(); | |
// prototype+extensions | |
/* Rect methods. | |
* Keep in mind 'Window objects' and 'Screen objects' | |
* inherit all properties from their rect. | |
* | |
* rect.bordered(borderSize): | |
* Shrink the rect by a border and return it. | |
* | |
* rect.left(): | |
* rect.right(): | |
* rect.top(): | |
* rect.bottom(): | |
* Read the code below. It's simple wrapping/math. | |
* | |
* rect.midY(): | |
* Returns the rect's vertical center. | |
* | |
* rect.midX(): | |
* Returns the rect's horizontal center. | |
* | |
*/ | |
_.extend($.rect, { | |
bordered: function(border) { | |
this.x += border / 2; | |
this.y += border / 2; | |
this.width -= border; | |
this.height -= border; | |
return this; | |
}, | |
left: function() { | |
return this.x; | |
}, | |
right: function() { | |
return this.x + this.width; | |
}, | |
top: function() { | |
return this.y; | |
}, | |
bottom: function() { | |
return this.y + this.height; | |
}, | |
midY: function() { | |
return this.y + (this.height / 2); | |
}, | |
midX: function() { | |
return this.x + (this.width / 2); | |
} | |
}); | |
/* Window methods | |
* | |
* A few standard methods are replaced, and some operations | |
* are completely replaced with very similar object methods. | |
* | |
* window.barResize(dir, div, pos): | |
* Turns a window into a full-height or width bar across the screen, | |
* and pushes it to an edge. | |
* | |
* @dir = (left, right, top, bottom) | |
* @div (default=2) resizes the perpindicular side, | |
* with size based on the corresponding screen dimension | |
* @pos (default=0) can be used to place the resulting bar | |
* somewhere in the middle of the screen. | |
* | |
* window.center(dir, horiz, vert): | |
* Centers a window in direction, optionally changing the dimensions | |
* by a screen division horizontally/vertically. | |
* | |
* @dir: Pick one of the following: | |
* 1. any combination of (top, left, right, bottom). | |
* 2. one of "horiz", "vert", 'center" | |
* Valid choices include (but aren't limited to): | |
* "left", "top-left", "right", "bottom-right", "center", "horiz" | |
* | |
* @horiz, @vert (optional): see window.divResize() for details | |
* (You must provide both @horiz and @vert for the resize to take place). | |
* | |
* window.corner(dir, horiz, vert): | |
* Places a window in a corner, resizing by horiz and vert. | |
* | |
* @corner: Pick from: | |
* "top-left", "top-right", "bottom-left", "bottom-right" | |
* | |
* @horiz, @vert (optional): see window.divResize() for details | |
* | |
* window.divResize(horiz, vert): | |
* Resizes a window by dividing the current screen. | |
* | |
* @horiz (default=1): width = screen.width / @horiz | |
* @vert (default=1): height = screen.height / @vert | |
* | |
* window.move(args): | |
* Moves a window to args.x, args.y. | |
* | |
* Better than default .move() in the following ways: | |
* * Logs calls. | |
* * Refuses bogus coordinates, which can: | |
* * Crash Slate. | |
* * Lose your window into the ether. | |
* * Updates rect properties on the window (x, y, width, height). | |
* | |
* window.push(dir): | |
* Alias for window.snap(dir). | |
* | |
* window.resize(args): | |
* Resizes a window to args.width, args.height. | |
* | |
* Better than the default .resize() in the following ways: | |
* * Logs calls. | |
* * Refuses bogus width/height. | |
* * Guaranteed to end up <= your specified size, even in Terminal.app. | |
* * Won't get confused if the Window is in a weird position. | |
* * Updates rect properties on the window. | |
* | |
* window.snap(dir): | |
* Snaps a window to a direction, with slight bias | |
* to the top left of the screen for consistency. | |
* | |
* @dir: any combination of "left", "top", "right", "bottom" | |
* Examples: "left", "top-left", "left-top", "bottom", "bottom-right" | |
* | |
* window.throw(screen, resize): | |
* Aliased to 'toss'. Throw is a reserved keyword in JS. | |
* | |
* window.toss(screen, resize): | |
* Throws a window to a screen, resizing if desired. | |
* | |
* Advantages over default 'throw': | |
* * Resize consistently works the first time. | |
* * Better resize heuristics. | |
*/ | |
_.extend($.window, { | |
barResize: function(dir, div, pos) { | |
div = (div || 2); | |
var s = this.screen(); | |
if (dir == 'left' || dir == 'right') { | |
this.divResize(div, 1, pos, 0); | |
} else if (dir == 'top' || dir == 'bottom') { | |
this.divResize(1, div, 0, pos); | |
} | |
}, | |
center: function(dir, horiz, vert) { | |
$.log('center', dir, horiz, vert); | |
if (horiz && vert) | |
this.divResize(horiz, vert); | |
var s = this.screen(); | |
var width, height; | |
var x = this.x; | |
var y = this.y; | |
if (dir == 'left' || dir == 'right') { | |
this.center('vert'); | |
this.snap(dir); | |
} else if (dir == 'top' || dir == 'bottom') { | |
this.center('horiz'); | |
this.snap(dir); | |
} else if (dir == 'center') { | |
this.center('horiz'); | |
this.center('vert'); | |
} else if (dir == 'horiz') { | |
width = this.width; | |
x = s.midX() - (width / 2); | |
this.move({x: x, y: y}); | |
} else if (dir == 'vert') { | |
height = this.height; | |
y = s.midY() - (height / 2); | |
this.move({x: x, y: y}); | |
} else { | |
return; | |
} | |
}, | |
corner: function(corner, horiz, vert) { | |
$.log('corner', JSON.stringify([corner, horiz, vert])); | |
this.divResize(horiz || 2, vert || 2); | |
this.snap(corner); | |
}, | |
divResize: function(horiz, vert, horizPos, vertPos) { | |
var s = this.screen(); | |
var width = s.width / (horiz || 1); | |
var height = s.height / (vert || 1); | |
this.resize({width: width, height: height}); | |
if ( horizPos && ( ( horiz > 1 && horiz < 2) || horizPos == horiz - 1 ) ) | |
width = s.width - width; | |
else | |
width = width * (horizPos || 0); | |
if ( vertPos && ( (vert > 1 && vert < 2) || vertPos && vertPos == vert - 1 ) ) | |
height = s.height - height; | |
else | |
height = height * (vertPos || 0); | |
this.move({x: width, y: height}); | |
}, | |
move: function(args) { | |
// TODO: also allow calling with (x, y) | |
$.log('move', JSON.stringify(args)); | |
var x = args.x; | |
var y = args.y; | |
if ((x !== 0 && !x) || (y !== 0 && !y)) { | |
$.backtrace('Invalid move destination.'); | |
return; | |
} | |
this._super.move(args); | |
this.update(); | |
}, | |
push: function(dir) { | |
this.snap(dir); | |
}, | |
resize: function(args) { | |
// TODO: allow calling with (width, height) | |
$.log('resize', JSON.stringify(args)); | |
var width = args.width; | |
var height = args.height; | |
if ((width !== 0 && !width || width < 0) || | |
(height !== 0 && !height || height < 0)) { | |
$.backtrace('Invalid resize.'); | |
return; | |
} | |
var s = this.screen(); | |
// give ourselves enough room to resize | |
var x = Math.min(this.x, s.right() - width); | |
var y = Math.min(this.y, s.bottom() - height); | |
this.move({x: x, y: y}); | |
this._super.resize(args); | |
while (this.rect().height > height + 1) { | |
args.height -= 1; | |
if (args.height < 0) | |
break; | |
this._super.resize(args); | |
} | |
while (this.rect().width > width + 1) { | |
args.width -= 1; | |
if (args.width < 0) | |
break; | |
this._super.resize(args); | |
} | |
this.update(); | |
}, | |
snap: function(dir) { | |
// like slate's push, but rounds left/top to screen border/center | |
$.log('snap', dir); | |
var s = this.screen(); | |
var x = this.x; | |
var y = this.y; | |
// corners | |
var match = dir.match(/^([^-]+)-([^-]+)$/); | |
if (match) { | |
this.snap(match[1]); | |
this.snap(match[2]); | |
return; | |
} | |
// cardinal directions | |
var mid; | |
if (dir == 'left') { | |
x = s.left(); | |
} else if (dir == 'top') { | |
y = s.top(); | |
} else if (dir == 'right') { | |
x = s.right() - this.width; | |
mid = Math.abs(x - s.midX()); | |
if (this.width / mid < 0.05) { | |
x = s.midX(); | |
} | |
} else if (dir == 'bottom') { | |
y = s.bottom() - this.height; | |
mid = Math.abs(y - s.midY()); | |
if (this.height / mid < 0.05) { | |
x = s.midY(); | |
} | |
} | |
this.move({x: x, y: y}); | |
}, | |
'throw': function() { | |
return this.toss.apply(this, arguments); | |
}, | |
toss: function(num, resize) { | |
var count, current; | |
if (num === '+' || num === '-') { | |
count = slate.screenCount(); | |
$.log('count', count); | |
current = this.screen().id(); | |
$.log('current', current); | |
num = (num === '+') ? ++current : --current; | |
count--; | |
if (num > count) num = 0; | |
if (num < 0) num = count; | |
$.log('selected', num); | |
} | |
var screen = slate.screenForRef(num.toString()); | |
var s = $.screen(screen); | |
if (resize) | |
this.resize(s.rect()); | |
this.move(s.rect()); | |
if (resize) | |
this.resize(s.rect()); | |
} | |
}); | |
/* File: slate.example.js | |
* Author: lunixbochs (Ryan Hileman) and ProLoser (Dean Sofer) | |
* Project: http://github.com/lunixbochs/reslate https://github.com/ProLoser/reslate | |
*/ | |
// enable to see debug messages in Console.app | |
// $.debug = true; | |
slate.alias('hyper', 'ctrl;alt;cmd'); | |
// begin config | |
slate.configAll({ | |
defaultToCurrentScreen: true, | |
nudgePercentOf: 'screenSize', | |
resizePercentOf: 'screenSize', | |
undoOps: [ | |
'active-snapshot', | |
'chain', | |
'grid', | |
'layout', | |
'move', | |
'resize', | |
'sequence', | |
'shell', | |
'push' | |
] | |
}); | |
function position(win) { | |
$.log('position', 'cols:', win.splitx, 'rows:', win.splity, 'x:', win.offx, 'y:', win.offy); | |
var snapRight = (win.offx > 1 && win.offx < 2) && win.offx > 0, | |
snapBottom = (win.offy > 1 && win.offy < 2) && win.offy > 0; | |
win.divResize(win.splitx, win.splity, win.offx, win.offy, snapRight, snapBottom); | |
} | |
function reset(win, hard) { | |
if (!win.splitx || hard) { | |
win.splitx = 1; | |
win.splity = 1; | |
win.offx = 0; | |
win.offy = 0; | |
} | |
} | |
var screenCount = slate.screenCount(); | |
steps = [1.5, 2, 3]; | |
var lastStep = steps[steps.length-1]; | |
function nextStep(step) { | |
var index = steps.indexOf(step); | |
return (index >= steps.length-1) ? steps[0] : steps[++index]; | |
} | |
// bindings | |
slate.bindAll({ | |
hyper: { | |
shift: { | |
left: function(win) { | |
reset(win); | |
if (win.offx === 0) { | |
if (screenCount > 1) | |
win.toss('-'); | |
win.offx = Math.ceil(win.splitx) - 1; | |
} else { | |
win.offx--; | |
} | |
position(win); | |
}, | |
right: function(win) { | |
reset(win); | |
win.offx++; | |
if (win.offx >= Math.ceil(win.splitx)) { | |
if (screenCount > 1) | |
win.toss('+'); | |
win.offx = 0; | |
} | |
position(win); | |
}, | |
up: function(win) { | |
reset(win); | |
if (win.offy === 0) { | |
win.offy = Math.ceil(win.splity) - 1; | |
} else { | |
win.offy--; | |
} | |
position(win); | |
}, | |
down: function(win) { | |
reset(win); | |
win.offy++; | |
if (win.offy >= Math.ceil(win.splity)) | |
win.offy = 0; | |
position(win); | |
} | |
}, | |
left: function(win) { | |
reset(win); | |
if (win.offx === 0) { | |
if (screenCount > 1 && win.splitx === lastStep) { | |
reset(win, true); | |
win.toss('-', 'resize'); | |
} else { | |
win.splitx = nextStep(win.splitx); | |
position(win); | |
} | |
} else { | |
win.offx--; | |
position(win); | |
} | |
}, | |
j: function(win){this.left(win);}, | |
right: function(win) { | |
reset(win); | |
if (win.offx === win.splitx - 1 || win.offx && win.splitx > 1 && win.splitx < 2) { | |
if (screenCount > 1 && win.splitx === lastStep) { | |
reset(win, true); | |
win.toss('+', 'resize'); | |
} else { | |
var nextSplit = nextStep(win.splitx); | |
if (nextSplit > 2 || !win.offx) | |
win.offx++; | |
if (nextSplit < win.splitx) | |
win.offx = Math.ceil(nextSplit) - 1; | |
win.splitx = nextSplit; | |
position(win); | |
} | |
} else { | |
win.offx++; | |
position(win); | |
} | |
}, | |
l: function(win){this.right(win);}, | |
up: function(win) { | |
reset(win); | |
if (win.offy === 0) { | |
win.splity = nextStep(win.splity); | |
} else { | |
win.offy--; | |
} | |
position(win); | |
}, | |
i: function(win){this.up(win);}, | |
down: function(win) { | |
reset(win); | |
if (win.offy === win.splity - 1 || win.offy && win.splity > 1 && win.splity < 2) { | |
var nextSplit = nextStep(win.splity); | |
if (nextSplit > 2 || !win.offy) | |
win.offy++; | |
if (nextSplit < win.splity) | |
win.offy = Math.ceil(nextSplit) - 1; | |
win.splity = nextSplit; | |
} else { | |
win.offy++; | |
} | |
position(win); | |
}, | |
k: function(win){this.down(win);}, | |
space: function(win) { | |
reset(win, true); | |
position(win); | |
}, | |
'return': [ | |
$('barResize', 'left', 1), | |
$('center', 'center', 1.5, 1.25) | |
], | |
// throw to monitor | |
'`': ['throw 0 resize', | |
'throw 1 resize'], | |
// direct focus | |
// utility functions | |
f1: 'relaunch', | |
z: 'undo' | |
} | |
}); | |
// Auto Snapshotting | |
// Returns name generated from screen resolutions | |
function getName() { | |
var name = []; | |
slate.eachScreen(function(screen){ | |
var rect = screen.rect(); | |
name.push(rect.width+'x'+rect.height); | |
}); | |
return name; | |
} | |
// Save snapshot | |
function save(event, win){ | |
$.log('saved', getName()); | |
slate.operation("snapshot", { | |
name: getName().join('y'), | |
save: true | |
}).run(); | |
// slate.default(getName(), getName().join('y')); | |
} | |
// Load snapshot | |
function load(event, win){ | |
$.log('loaded', getName()); | |
slate.operation("activate-snapshot", { | |
name: getName().join('y') | |
}).run(); | |
} | |
// slate.on('windowMoved', save); | |
// slate.on('windowResized', save); | |
// slate.on('appOpened', load); | |
// TODO: Requires 'screenConfigurationChanged' for some reason | |
slate.on('screenConfigurationChanged', function(){ | |
screenCount = slate.screenCount(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment