Mac用ウィンドウマネージャ Slate
はじめに
Mac用のウィンドウマネージャ(ウィンドウの整列やサイズ調整を行うソフトウェア) Slateを紹介します。
導入
homebrew の導入については割愛します。
$ brew install --cask slate
Slate 実行後 システム環境設定 -> プライバシー で Slate.app にチェックマークを入れる必要があります。
設定例
設定ファイルはホームディレクトリ直下 .slate.js です。
Javascriptで記述されるので Javascriptに慣れた方にとってはとっつきやすいかも知れません。
(ただしES5以前の仕様であることにはご注意下さい)
関数
var util = {
// アプリ起動・フォーカス
// http://d.hatena.ne.jp/sugyan/20130301/1362129310
launch_and_focus: function (target) {
return function (win) {
var apps = [];
S.eachApp(function (app) { apps.push(app.name()); });
if (! _.find(apps, function (name) { return name === target; })) {
win.doOperation(
S.operation('shell', {
command: "/usr/bin/open -a " + target,
waithFoeExit: true
})
);
}
win.doOperation(S.operation('focus', { app: target }));
};
},
// ラッパー
// http://www.infiniteloop.co.jp/blog/2013/08/osx_slate/
//
// util.key('x') -> x:alt
// util.key('x', 'shift') -> x:alt,shift
key: function(k, mod) {
return k + ':alt' + (mod ? ',' + mod : '');
}
};
アプリランチャー
slate.bind(util.key('r'), util.launch_and_focus('Reeder'));
slate.bind(util.key('b'), util.launch_and_focus('Safari'));
slate.bind(util.key('t'), util.launch_and_focus('iTerm'));
slate.bind(util.key('m'), util.launch_and_focus('Music'));
リサイズ・配置
細かくサイズ変更する機能は力技感ありますが
一つのキーバインドでサイクルできるのは便利です。
// m+shift .. 最大化
slate.bind(util.key('m', 'shift'), function(win) {
if (!win) return;
var bounds = win.screen().visibleRect();
win.doOperation('move', bounds);
});
// n+shift .. タテ分割1/2サイズにする
slate.bind(util.key('n', 'shift'), slate.operation('chain', {
operations: _.map(['left', 'right'], function(d) {
return slate.operation('push', {
direction: d,
style: 'bar-resize:screenSizeX/2'
});
})
}));
// o+shift .. 1/4サイズにする
slate.bind(util.key('o', 'shift'), slate.operation('chain', {
operations: _.map(['top-left', 'top-right', 'bottom-right', 'bottom-left'], function(d) {
return slate.operation('corner', {
direction: d,
width: 'screenSizeX/2',
height: 'screenSizeY/2'
});
})
}));
// b+shift .. 細かくサイズ変更
slate.bind(util.key('b', 'shift'), slate.operation('chain', {
operations: _.map([
{direction: 'left', style: 'bar-resize:screenSizeX/3'},
{direction: 'left', style: 'bar-resize:screenSizeX/2'},
{direction: 'left', style: 'bar-resize:screenSizeX*2/3'},
{direction: 'left', style: 'bar-resize:screenSizeX'},
{direction: 'right', style: 'bar-resize:screenSizeX*2/3'},
{direction: 'right', style: 'bar-resize:screenSizeX/2'},
{direction: 'right', style: 'bar-resize:screenSizeX/3'},
{direction: 'right', style: 'bar-resize:screenSizeX/2'},
{direction: 'right', style: 'bar-resize:screenSizeX*2/3'},
{direction: 'left', style: 'bar-resize:screenSizeX'},
{direction: 'left', style: 'bar-resize:screenSizeX*2/3'},
{direction: 'left', style: 'bar-resize:screenSizeX/2'}
], function(d) {
return slate.operation('push', d);
})
}));
フォーカス
// スクリーン内のウィンドウをフォーカス
slate.bind(util.key('h'), slate.operation('focus', { direction: 'left' }));
slate.bind(util.key('j'), slate.operation('focus', { direction: 'down' }));
slate.bind(util.key('k'), slate.operation('focus', { direction: 'up' }));
slate.bind(util.key('l'), slate.operation('focus', { direction: 'right' }));
ウィンドウ移動
// a+shift .. ウィンドウを左に移動
slate.bind(util.key('a', 'shift'), function(win) {
if (!win) return;
var rect = win.rect();
var bounds = win.screen().visibleRect();
rect.x -= bounds.width * 0.05;
win.doOperation('move', rect);
});
// d+shift .. ウィンドウを右に移動
slate.bind(util.key('d', 'shift'), function(win) {
if (!win) return;
var rect = win.rect();
var bounds = win.screen().visibleRect();
rect.x += bounds.width * 0.05;
win.doOperation('move', rect);
});
// w+shift .. ウィンドウを上に移動
slate.bind(util.key('w', 'shift'), function(win) {
if (!win) return;
var rect = win.rect();
var bounds = win.screen().visibleRect();
rect.y -= bounds.height * 0.05;
win.doOperation('move', rect);
});
// s+shift .. ウィンドウを下に移動
slate.bind(util.key('s', 'shift'), function(win) {
if (!win) return;
var rect = win.rect();
var bounds = win.screen().visibleRect();
rect.y += bounds.height * 0.05;
win.doOperation('move', rect);
});
// f+shift .. 次のスクリーンへ飛ばす
//slate.bind(util.key('f', 'shift'), function(win) {
// if (!win) return;
// var next = util.nextScreen(win.screen());
// win.move(next.visibleRect());
//});
ウィンドウ拡大・縮小
// h+shift .. ウィンドウが左にあるなら縮小, 右にあるなら拡大
slate.bind(util.key('h', 'shift'), function(win) {
if (!win) return;
var rect = win.rect();
var bounds = win.screen().visibleRect();
if (bounds.x + bounds.width - 30 < rect.x + rect.width) {
rect.x -= bounds.width * 0.05;
rect.width = bounds.x + bounds.width - rect.x;
} else {
rect.width -= bounds.width * 0.05;
}
win.doOperation('move', rect);
});
// l+shift .. ウィンドウが右にあるなら縮小, 左にあるなら拡大
slate.bind(util.key('l', 'shift'), function(win) {
if (!win) return;
var rect = win.rect();
var bounds = win.screen().visibleRect();
if (rect.x < bounds.x + 30) {
rect.x = bounds.x;
rect.width += bounds.width * 0.05;
} else {
rect.x += bounds.width * 0.05;
rect.width -= bounds.width * 0.05;
}
win.doOperation('move', rect);
});
// k+shift .. ウィンドウが上にあるなら縮小, 下にあるなら拡大
slate.bind(util.key('k', 'shift'), function(win) {
if (!win) return;
var rect = win.rect();
var bounds = win.screen().visibleRect();
if (bounds.y + bounds.height - 30 < rect.y + rect.height) {
rect.y -= bounds.height * 0.05;
rect.height += bounds.height * 0.05;
} else {
rect.height -= bounds.height * 0.05;
}
win.doOperation('move', rect);
});
// j+shift .. ウィンドウが下にあるなら縮小, 上にあるなら拡大
slate.bind(util.key('j', 'shift'), function(win) {
if (!win) return;
var rect = win.rect();
var bounds = win.screen().visibleRect();
if (rect.y < bounds.y + 30) {
rect.y = bounds.y;
rect.height += bounds.height * 0.05;
} else {
rect.y += bounds.height * 0.05;
rect.height -= bounds.height * 0.05;
}
win.doOperation('move', rect);
});
おわりに
最終更新が2013年とメンテナンスされてないことが気になりますが
設定が柔軟に書けるため Mac をお使いの方にはおすすめです。
(自動で賢くレイアウトしてくれる ヤバいウィンドウマネージャ もおすすめです)