今までウィンドウの移動と拡大縮小については、ショートカット化されてきませんでした。
(いちいちウィンドウの頭や右下にカーソルをあわせなくてはいけない例 ✕)
本記事では
- それらにショートカットを設定する方法と
- それを実現するのに必要な素晴らしいツール(Hammerspoon)
を紹介します。これによりカーソル移動を最小化できます。
(ショートカット化によりカーソルをあわせなくてよくなった例 ◯)
前提
- hammerspoon
hammerspoon について
hammerspoonは、OS Xの自動化ツールです。他のウィンドウ管理アプリShiftItの代替ツールとして挙げられています1
インストールはbrewでできます。
brew install hammerspoon --cask
Qiitaにもいくつか記事があります。
hammerspoon を触ってみる
hammerspoonは、とても 手軽に プログラマブルに OS Xの設定が記述できます。
その一例を紹介します。
インストール後、menu barのハンマーのアイコンから「Open Config」を押して以下をコピペしてみてください。
DURATION = 0.05
DELTA = 10
function moveUp()
local win = hs.window.focusedWindow()
local f = win:frame()
f.y = f.y + DELTA
win:setFrame(f, DURATION)
end
function moveDown()
local win = hs.window.focusedWindow()
local f = win:frame()
f.y = f.y - DELTA
win:setFrame(f, DURATION)
end
function moveLeft(bound)
local win = hs.window.focusedWindow()
local f = win:frame()
f.x = f.x - DELTA
win:setFrame(f, DURATION)
end
function moveRight()
local win = hs.window.focusedWindow()
local f = win:frame()
f.x = f.x + DELTA
win:setFrame(f, DURATION)
end
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "J", moveUp,nil,moveUp)
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "K", moveDown,nil,moveDown)
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "H", moveLeft,nil,moveLeft)
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "L", moveRight,nil,moveRight)
ハンマーアイコンから「Reload Config」を押すと設定がロードされ、cmd+alt+ctrl+j,k,h,l
でフォーカスしているウィンドウをショートカットから移動することがわかると思います。
設定方法
それでは冒頭の操作をショートカット化する方法を紹介します。
前述と同様に「Open Config」から以下の設定をコピペし「Reload Config」します。
DURATION = 0.05
INTERVAL_SEC = 0.05
SCALE = 2.0
repeatMove = nil
function startMoveWindow()
prevPoint = hs.mouse.absolutePosition()
prevFrame = hs.window.focusedWindow():frame()
repeatMove = hs.timer.doEvery(INTERVAL_SEC, function()
local nextPoint = hs.mouse.absolutePosition()
local win = hs.window.focusedWindow()
local f = win:frame()
f.x = prevFrame.x - (prevPoint.x - nextPoint.x) * SCALE
f.y = prevFrame.y - (prevPoint.y - nextPoint.y) * SCALE
win:setFrameInScreenBounds(f, DURATION)
prevPoint = nextPoint
prevFrame = hs.window.focusedWindow():frame()
end)
repeatMove:start()
end
function stopMoveWindow() repeatMove:stop() end
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "A", startMoveWindow, stopMoveWindow, nil)
repeatResize = nil
function startResizeWindow()
prevPoint = hs.mouse.absolutePosition()
prevFrame = hs.window.focusedWindow():frame()
repeatResize = hs.timer.doEvery(INTERVAL_SEC, function()
local nextPoint = hs.mouse.absolutePosition()
local win = hs.window.focusedWindow()
local f = win:frame()
f.w = prevFrame.w - (prevPoint.x - nextPoint.x) * SCALE
f.h = prevFrame.h - (prevPoint.y - nextPoint.y) * SCALE
-- bound sizeA
local sf = hs.screen.find(f):frame()
if (sf.x + sf.w < f.x + f.w) then f.w = sf.x + sf.w - f.x end
if (sf.y + sf.h < f.y + f.h) then f.h = sf.y + sf.h - f.y end
win:setFrame(f, DURATION)
prevPoint = nextPoint
prevFrame = hs.window.focusedWindow():frame()
end)
repeatResize:start()
end
function stopResizeWindow() repeatResize:stop() end
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "S", startResizeWindow, stopResizeWindow, nil)
操作例
-
cmd+alt+ctrl+a
+マウス操作でウィンドウ移動 - 画面を超えないように止まってくれます (
setFrame
に変えると無効にできます)
![move.gif]](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F676735%2Feee53f04-c6e4-f22a-c3e4-0af59d83a077.gif?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=eb86cf6358980a121c0d6de9ac383727)
-
cmd+alt+ctrl+s
+マウス操作で拡大/縮小 - 同様に画面を超えないように拡大が止まります
![resize.gif]](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F676735%2F5c7be8c4-3660-2d37-5b9f-73886a8d4ff9.gif?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=c80d0721a62eff411da2181812d06148)
ショートカットやSCALEはお好みで変えてください。
終わりに
少なくともウィンドウの頭にカーソルを合わせる時間は削れたかと思います。
hammerspoonは便利なツールなので、興味のある方は、公式のチュートリアルやAPIドキュメントを読むといろいろ膨らむと思います。
-
https://www.hammerspoon.org/go
- 設定をリロードするショートカットも紹介されています
- https://www.hammerspoon.org/docs/index.html
-
A highly recommended alternative to ShiftIt that can be implemented using Hammerspoon. https://github.com/fikovnik/ShiftIt ↩