'Phoenix: Excellent Mac / OS X Window Manager'

As far as default window management and Mac’s OS X goes, my opinion is that it’s a sad, sad state of affairs. For all the design sense that Apple has, it strikes me that managing windows on OS X is a painful, frustrating experience. And that’s using the awesome mouse and/or trackpad that Apple came up with. If you’re trying to use the keyboard to handle your windows, you’re basically tough out of luck. Period.

I’m a keyboard person, even when I’m on a full desktop using an external (read: real) mouse that lives on my table. Even then I still prefer to control as much of my user experience through the keyboard as possible. On a laptop, not having keyboard control is just.. ridiculous.

On Windows, I use AutoHotKey to solve my problem. I needed something similar for the Mac.

After reading recommendations and asking around for trusted opinions, it seems that Slate was a good choice. In fact, I used it for a while and pretty much tried to sell it to anybody who had the same desires as me, and was using a Mac. Well, yea, Slate’s written for OS X.

However, after a while, as powerful and scriptable as Slate was, I began to notice quirks that irritated me. Particularly, after using Slate for a while, it tends to become slow. Worst case, it completely doesn’t respond and you wonder just what happened. Then you fumble around trying to find that.. what’s that called? Ah, the mouse.

Okay, so the point of this post. Basically, I found Phoenix. It lives on GitHub. Here:

phoenix The lightweight OS X window manager for hackers.

So, Phoenix. Really, it’s a window manager that’s designed for hackers. In that you write (as simple or complex) code as you want to control it. So what Phoenix gives you is a framework which takes care of handling windows for you, and presents them to you as objects. It also gives you an API to do stuff with those objects, like, say, use them to move windows around.

Furthermore, it also gives you APIs to launch applications and bind hotkeys to those launch actions. Pretty nifty.

Most of all, it’s very, very light, and very fast. Awesome. Really, you should try it.

Installing Phoenix

Phoenix is for Macs. Only. Just saying, in case.

Installing it is real easy using brew cask. If you’re not using Cask, you really should.

brew cask install phoenix

That’s it.

Configuring Phoenix

Phoenix has a single configuration file, called .phoenix.js, which lives in your home directory. In other words, it’s here:

~/.phoenix.js

The Wiki page has a bunch of configurations that you can use as a starting point.

The one I started off from was jakemcc’s config, found here.

I made precious few modifications, actually. I just preferred the ability to organize windows in a 2x2 grid pattern, with Vim-like key bindings. So i rebound my keys as follows:

// Key combinations
var hyper = ['ctrl','alt','cmd','shift'];
var mash  = ['ctrl','alt','cmd'];

// Screen placement movement
api.bind('h', mash, function() { to_left(1, 2); });          // left
api.bind('l', mash, function() { to_right(1, 2); });         // right
api.bind('k', mash, function() { to_top(1, 2); });           // up
api.bind('j', mash, function() { to_bottom(1, 2); });        // down
api.bind('.', mash, function() { to_bottom_right(1, 2); });  // bottom-right
api.bind('n', mash, function() { to_bottom_left(1, 2); });   // bottom-left
api.bind('p', mash, function() { to_top_right(1, 2); });     // top-right
api.bind('y', mash, function() { to_top_left(1, 2); });      // top-left

// Monitor movement
api.bind('left', mash, left_one_monitor);
api.bind('right', mash, right_one_monitor);

// Full screen
api.bind('space', hyper, full_screen);
api.bind('space', mash, full_screen);
api.bind('i', mash, full_screen);

I also like to shift the focus from window to window:

// Focus
api.bind('h', hyper, function() {focus(LEFT);});
api.bind('l', hyper, function() {focus(RIGHT);});
api.bind('k', hyper, function() {focus(UP);});
api.bind('j', hyper, function() {focus(DOWN);});

Finally, I also have my own hotkeys for application launching:

// Launcher
api.bind('e',   ['cmd'], function() {App.focusOrStart('path finder');});
api.bind('f9',  ['cmd'], function() {App.focusOrStart('emacs');});
api.bind('f10', ['cmd'], function() {App.focusOrStart('iterm');});
api.bind('f11', ['shift', 'cmd'], function() {App.focusOrStart('google chrome canary');});
api.bind('f11', ['cmd'], function() {App.focusOrStart('google chrome');});
api.bind('f12', ['cmd'], function() {App.focusOrStart('notes');});
api.bind('f', ['ctrl', 'shift', 'cmd'], function() {App.focusOrStart('evernote');});

Feel free to use and or adopt. And oh really, do give Phoenix a try if you’re looking for a better way to handle windows on a Mac.