Created
October 22, 2015 19:23
-
-
Save majman/d901f2049dc9b077821f to your computer and use it in GitHub Desktop.
config for phoenix window manager
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
| // Forked originally from @JasonM23’s config in literate coffee-script | |
| // https://github.com/jasonm23/Phoenix-config/blob/master/Phoenix-config.litcoffee | |
| // Released under MIT license - http://opensource.org/licenses/MIT | |
| var forApp, key_binding, layouts, mash, | |
| moveWindowLeftOneColumn, moveWindowRightOneColumn, moveWindowToNextScreen, | |
| switchLayout, | |
| windowDownOneRow, windowGrowOneGridColumn, windowGrowOneGridRow, windowShrinkOneGridColumn, | |
| windowShrinkOneGridRow, windowToFullHeight, windowUpOneRow; | |
| function debug(message) { | |
| return api.alert(message, 8); | |
| }; | |
| function testScreens(){ | |
| var screens = {}; | |
| var win; | |
| win = Window.focusedWindow(); | |
| // win.screen().nextScreen() | |
| var s = win.screen(); | |
| var rect1 = s.frameWithoutDockOrMenu(); | |
| var rect2 = s.frameIncludingDockAndMenu(); | |
| } | |
| // testScreens(); | |
| MARGIN_X = 5; | |
| MARGIN_Y = 5; | |
| GRID_WIDTH = 20; | |
| GRID_HEIGHT = 12; | |
| // App Layouts | |
| // app: Name of app | |
| // x: 0 - 1 * Number of Screens (1st screen starts at 0, 2nd at 1, etc); | |
| // y: 0 - 1 (0 top of screen) | |
| // width: 1 is full width of a single screen | |
| // height: 1 is full height of screen | |
| // cascade: if more than one window open for app, stack them | |
| var finderLayout = { | |
| app: "Finder", | |
| opts: { | |
| x: 1, | |
| y: 0.5, | |
| width: 0.375, | |
| height: 0.5 | |
| }, | |
| cascade: true | |
| } | |
| var slackLayout = { | |
| app: "Slack", | |
| opts: { | |
| x: 1.625, | |
| y: 0, | |
| width: 0.375, | |
| height: 0.5 | |
| } | |
| } | |
| var browserLayout = { | |
| app: "Google Chrome", | |
| opts: { | |
| x: 0.1, | |
| y: 0.05, | |
| width: 0.8, | |
| height: 0.9 | |
| }, | |
| cascade: true | |
| }; | |
| var terminalLayout = { | |
| app: "iTerm", | |
| opts: { | |
| x: 1, | |
| y: 0.5, | |
| width: 0.375, | |
| height: 0.5 | |
| }, | |
| cascade: true | |
| }; | |
| var editorLayout = { | |
| app: "Sublime Text", | |
| opts: { | |
| x: 1.125, | |
| y: 0, | |
| width: 0.75, | |
| height: 1 | |
| }, | |
| cascade: true | |
| }; | |
| layouts = { | |
| "maj": [ | |
| finderLayout, | |
| slackLayout, | |
| browserLayout, | |
| terminalLayout, | |
| editorLayout | |
| ], | |
| "maj2": [ | |
| browserLayout, | |
| editorLayout, | |
| terminalLayout | |
| ] | |
| }; | |
| function switchLayout(name) { | |
| var visibleWindows = Window.visibleWindows(); | |
| var layoutApps = _.pluck(layouts[name], 'app'); | |
| var visibleApps = _.unique(_.map(visibleWindows, function(vw){ | |
| return vw.app().title(); | |
| })); | |
| var diffApps = _.difference(visibleApps, layoutApps); | |
| _.each(diffApps, function(appTitle){ | |
| var app; | |
| app = App.byTitle(appTitle, true); | |
| app.hide(); | |
| }); | |
| return _.each(layouts[name], function(config) { | |
| var app; | |
| App.focusOrStart(config.app); | |
| app = App.byTitle(config.app); | |
| var opts = config.opts; | |
| if(config.cascade == true){ | |
| return _.each(app.visibleWindows(), function(win, i){ | |
| win.toGrid(Number(opts.x) + (i * 0.01), Number(opts.y) + (i * 0.02), opts.width, opts.height); | |
| }); | |
| }else { | |
| return app.firstWindow().toGrid(opts.x, opts.y, opts.width, opts.height); | |
| } | |
| }); | |
| }; | |
| Window.prototype.getGrid = function() { | |
| var halfScreenHeight, screenRect, thirdScreenWidth, winFrame; | |
| winFrame = this.frame(); | |
| screenRect = this.screen().frameWithoutDockOrMenu(); | |
| thirdScreenWidth = screenRect.width / GRID_WIDTH; | |
| halfScreenHeight = screenRect.height / GRID_HEIGHT; | |
| return { | |
| x: Math.round((winFrame.x - screenRect.x) / thirdScreenWidth), | |
| y: Math.round((winFrame.y - screenRect.y) / halfScreenHeight), | |
| width: Math.max(1, Math.round(winFrame.width / thirdScreenWidth)), | |
| height: Math.max(1, Math.round(winFrame.height / halfScreenHeight)) | |
| }; | |
| }; | |
| Window.prototype.setGrid = function(grid, screen) { | |
| var halfScreenHeight, newFrame, screenRect, thirdScreenWidth; | |
| screenRect = screen.frameWithoutDockOrMenu(); | |
| thirdScreenWidth = screenRect.width / GRID_WIDTH; | |
| halfScreenHeight = screenRect.height / GRID_HEIGHT; | |
| newFrame = { | |
| x: (grid.x * thirdScreenWidth) + screenRect.x, | |
| y: (grid.y * halfScreenHeight) + screenRect.y, | |
| width: grid.width * thirdScreenWidth, | |
| height: grid.height * halfScreenHeight | |
| }; | |
| newFrame.x += MARGIN_X; | |
| newFrame.y += MARGIN_Y; | |
| newFrame.width -= MARGIN_X * 2.0; | |
| newFrame.height -= MARGIN_Y * 2.0; | |
| this.setFrame(newFrame); | |
| return newFrame; | |
| }; | |
| Window.prototype.snapToGrid = function() { | |
| if (this.isNormalWindow()) { | |
| return this.setGrid(this.getGrid(), this.screen()); | |
| } | |
| }; | |
| Window.prototype.calculateGrid = function(x, y, width, height) { | |
| var screen; | |
| screen = this.screen().frameWithoutDockOrMenu(); | |
| if(x >= 1){ | |
| screen.x -= screen.width; | |
| } | |
| return { | |
| x: Math.round(x * screen.width) + MARGIN_X + screen.x, | |
| y: Math.round(y * screen.height) + MARGIN_Y + screen.y, | |
| width: Math.round(width * screen.width) - 2.0 * MARGIN_X, | |
| height: Math.round(height * screen.height) - 2.0 * MARGIN_Y | |
| }; | |
| }; | |
| Window.prototype.toGrid = function(x, y, width, height) { | |
| var rect; | |
| rect = this.calculateGrid(x, y, width, height); | |
| this.setFrame(rect); | |
| return this; | |
| }; | |
| Window.prototype.topRight = function() { | |
| var f; | |
| f = this.frame(); | |
| return { | |
| x: f.x + f.width, | |
| y: f.y | |
| }; | |
| }; | |
| Window.prototype.toLeft = function() { | |
| var p; | |
| p = this.topLeft(); | |
| return _.chain(this.windowsToWest()).filter(function(win) { | |
| return win.topLeft().x < p.x - 10; | |
| }).value(); | |
| }; | |
| Window.prototype.toRight = function() { | |
| var p; | |
| p = this.topRight(); | |
| return _.chain(this.windowsToEast()).filter(function(win) { | |
| return win.topRight().x > p.x + 10; | |
| }).value(); | |
| }; | |
| Window.prototype.info = function() { | |
| var f; | |
| f = this.frame(); | |
| return "[" + (this.app().pid) + "] " + (this.app().title()) + " : " + (this.title()) + "\n{x:" + f.x + ", y:" + f.y + ", width:" + f.width + ", height:" + f.height + "}\n"; | |
| }; | |
| Window.sortByMostRecent = function(windows) { | |
| var allVisible; | |
| allVisible = Window.visibleWindowsMostRecentFirst(); | |
| return _.chain(windows).sortBy(function(win) { | |
| return _.map(allVisible, function(w) { | |
| return w.info(); | |
| }).indexOf(win.info()); | |
| }).value(); | |
| }; | |
| Window.prototype.toTopHalf = function() { | |
| return this.toGrid(0, 0, 1, 0.5); | |
| }; | |
| Window.prototype.toBottomHalf = function() { | |
| return this.toGrid(0, 0.5, 1, 0.5); | |
| }; | |
| Window.prototype.toLeftHalf = function() { | |
| return this.toGrid(0, 0, 0.5, 1); | |
| }; | |
| Window.prototype.toRightHalf = function() { | |
| return this.toGrid(0.5, 0, 0.5, 1); | |
| }; | |
| Window.prototype.toTopRight = function() { | |
| return this.toGrid(0.5, 0, 0.5, 0.5); | |
| }; | |
| Window.prototype.toBottomRight = function() { | |
| return this.toGrid(0.5, 0.5, 0.5, 0.5); | |
| }; | |
| Window.prototype.toTopLeft = function() { | |
| return this.toGrid(0, 0, 0.5, 0.5); | |
| }; | |
| Window.prototype.toBottomLeft = function() { | |
| return this.toGrid(0, 0.5, 0.5, 0.5); | |
| }; | |
| moveWindowToNextScreen = function() { | |
| var win; | |
| win = Window.focusedWindow(); | |
| return win.setGrid(win.getGrid(), win.screen().nextScreen()); | |
| }; | |
| moveWindowLeftOneColumn = function() { | |
| var frame, win; | |
| win = Window.focusedWindow(); | |
| frame = win.getGrid(); | |
| if(frame.x == 0){ | |
| frame.width --; | |
| } | |
| frame.x = Math.max(frame.x - 1, 0); | |
| return win.setGrid(frame, win.screen()); | |
| }; | |
| moveWindowRightOneColumn = function() { | |
| var frame, win; | |
| win = Window.focusedWindow(); | |
| frame = win.getGrid(); | |
| if(frame.x + frame.width >= GRID_WIDTH){ | |
| frame.width --; | |
| } | |
| frame.x = Math.min(frame.x + 1, GRID_WIDTH - frame.width); | |
| return win.setGrid(frame, win.screen()); | |
| }; | |
| windowGrowOneGridColumn = function() { | |
| var frame, win; | |
| win = Window.focusedWindow(); | |
| frame = win.getGrid(); | |
| frame.width = Math.min(frame.width + 1, GRID_WIDTH - frame.x); | |
| return win.setGrid(frame, win.screen()); | |
| }; | |
| windowShrinkOneGridColumn = function() { | |
| var frame, win; | |
| win = Window.focusedWindow(); | |
| frame = win.getGrid(); | |
| frame.width = Math.max(frame.width - 1, 1); | |
| return win.setGrid(frame, win.screen()); | |
| }; | |
| windowGrowOneGridRow = function() { | |
| var frame, win; | |
| win = Window.focusedWindow(); | |
| frame = win.getGrid(); | |
| frame.height = Math.min(frame.height + 1, GRID_HEIGHT); | |
| return win.setGrid(frame, win.screen()); | |
| }; | |
| windowShrinkOneGridRow = function() { | |
| var frame, win; | |
| win = Window.focusedWindow(); | |
| frame = win.getGrid(); | |
| frame.height = Math.max(frame.height - 1, 1); | |
| return win.setGrid(frame, win.screen()); | |
| }; | |
| windowDownOneRow = function() { | |
| var frame, win; | |
| win = Window.focusedWindow(); | |
| frame = win.getGrid(); | |
| frame.y = Math.min(Math.floor(frame.y + 1), GRID_HEIGHT - 1); | |
| return win.setGrid(frame, win.screen()); | |
| }; | |
| windowUpOneRow = function() { | |
| var frame, win; | |
| win = Window.focusedWindow(); | |
| frame = win.getGrid(); | |
| frame.y = Math.max(Math.floor(frame.y - 1), 0); | |
| return win.setGrid(frame, win.screen()); | |
| }; | |
| windowToFullHeight = function() { | |
| var frame, win; | |
| win = Window.focusedWindow(); | |
| frame = win.getGrid(); | |
| frame.y = 0; | |
| frame.height = GRID_HEIGHT; | |
| return win.setGrid(frame, win.screen()); | |
| }; | |
| App.prototype.firstWindow = function() { | |
| return this.visibleWindows()[0]; | |
| }; | |
| App.byTitle = function(title, ignoreShow) { | |
| var app, apps, i; | |
| apps = this.runningApps(); | |
| i = 0; | |
| while (i < apps.length) { | |
| app = apps[i]; | |
| if (app.title() === title) { | |
| if(ignoreShow){ | |
| return app; | |
| } | |
| app.show(); | |
| return app; | |
| } | |
| i++; | |
| } | |
| }; | |
| App.allWithTitle = function(title) { | |
| return _(this.runningApps()).filter(function(app) { | |
| if (app.title() === title) { | |
| return true; | |
| } | |
| }); | |
| }; | |
| App.focusOrStart = function(title) { | |
| var activeWindows, apps, windows; | |
| apps = App.allWithTitle(title); | |
| if (_.isEmpty(apps)) { | |
| api.alert("Attempting to start " + title); | |
| api.launch(title); | |
| return; | |
| } | |
| windows = _.chain(apps).map(function(x) { | |
| return x.allWindows(); | |
| }).flatten().value(); | |
| activeWindows = _(windows).reject(function(win) { | |
| return win.isWindowMinimized(); | |
| }); | |
| if (_.isEmpty(activeWindows)) { | |
| api.launch(title); | |
| } | |
| activeWindows.forEach(function(win) { | |
| win.focusWindow(); | |
| }); | |
| }; | |
| forApp = function(title, fn) { | |
| var app; | |
| app = App.byTitle(title); | |
| if (app) { | |
| return _.each(app.visibleWindows(), fn); | |
| } | |
| }; | |
| /* KEY BINDINGS | |
| */ | |
| function key_binding(key, modifier, fn) { | |
| return api.bind(key, modifier, fn); | |
| }; | |
| mash = 'cmd+alt+ctrl'.split('+'); | |
| key_binding('0', mash, function() { | |
| return switchLayout('maj'); | |
| }); | |
| key_binding('9', mash, function() { | |
| return switchLayout('maj2'); | |
| }); | |
| // Convenience key bindings... | |
| key_binding('up', mash, function() { | |
| return windowUpOneRow(); | |
| }); | |
| key_binding('down', mash, function() { | |
| return windowDownOneRow(); | |
| }); | |
| key_binding('left', mash, function() { | |
| return moveWindowLeftOneColumn(); | |
| }); | |
| key_binding('right', mash, function() { | |
| return moveWindowRightOneColumn(); | |
| }); | |
| key_binding('\\', mash, function() { | |
| return moveWindowToNextScreen(); | |
| }); | |
| key_binding('-', mash, function() { | |
| return windowShrinkOneGridRow(); | |
| }); | |
| key_binding('=', mash, function() { | |
| return windowGrowOneGridRow(); | |
| }); | |
| key_binding('[', mash, function() { | |
| return windowShrinkOneGridColumn(); | |
| }); | |
| key_binding(']', mash, function() { | |
| return windowGrowOneGridColumn(); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment