Skip to content

Instantly share code, notes, and snippets.

@cigumo
Last active November 13, 2020 23:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cigumo/d0d6c488874fbe6c8ee4323cd4488d28 to your computer and use it in GitHub Desktop.
Save cigumo/d0d6c488874fbe6c8ee4323cd4488d28 to your computer and use it in GitHub Desktop.
hammerspoon ultra simple window manager with modal keywords
------------------------------------------------------------
-- ccc window manager
------------------------------------------------------------
cccwm = {}
-- config
cccwm.config = {
grid_base = {w=6,h=8},
grids = {
-- full width
['1'] = {x=0,y=0,w=6,h=6},
['2'] = {x=0,y=0,w=6,h=4},
['3'] = {x=0,y=4,w=6,h=2},
-- full height columns
['4'] = {x=0,y=0,w=2,h=8},
['5'] = {x=2,y=0,w=2,h=8},
['6'] = {x=4,y=0,w=2,h=8},
-- small top third
['e'] = {x=0,y=0,w=2,h=2},
['r'] = {x=2,y=0,w=2,h=2},
['t'] = {x=4,y=0,w=2,h=2},
-- big bottom halves/full
['d'] = {x=0,y=2,w=4,h=6},
['f'] = {x=0,y=2,w=6,h=6},
['g'] = {x=2,y=2,w=4,h=6},
-- bottom columns
['c'] = {x=0,y=2,w=2,h=6},
['v'] = {x=2,y=2,w=2,h=6},
['b'] = {x=4,y=2,w=2,h=6},
-- small bottom halves
['z'] = {x=0,y=6,w=3,h=2},
['x'] = {x=3,y=6,w=3,h=2},
},
auto_disable_time = 5,
menu_bar_h = 25,
}
cccwm.modal_timer = nil
cccwm.modal = nil
function cccwm:cancel_timer()
if self.modal_timer and self.modal_timer:running() then
self.modal_timer:stop()
self.modal_timer = nil
end
end
function cccwm:reset_timer()
print('resetting timer...')
self:cancel_timer()
self.modal_timer = hs.timer.doAfter(self.config.auto_disable_time, function() self.modal:exit() end)
end
function cccwm:do_grid(grid)
local win = hs.window.focusedWindow()
local f = win:frame()
local s = win:screen()
local menuh = s:fullFrame().h - s:frame().h
local m = s:frame()
local gw,gh = m.w/self.config.grid_base.w,m.h/self.config.grid_base.h
f.x = grid.x * gw
f.y = grid.y * gh + menuh
f.w = grid.w * gw
f.h = grid.h * gh
f = s:localToAbsolute(f)
win:setFrameInScreenBounds(f,0)
self:reset_timer()
end
function cccwm:print_window_info()
local win = hs.window.focusedWindow()
local f = win:frame()
local s = win:screen()
print('window', win)
print('frame', f)
print('screen', s)
end
function cccwm:move_monitor(dir)
local win = hs.window.focusedWindow()
local f = win:frame()
local s = win:screen()
local fn = s['to'..dir]
local ns = fn and fn(s)
print('monitor to the ' .. dir .. ' ', ns)
if ns then
local nf = s:absoluteToLocal(f)
f = ns:localToAbsolute(nf)
win:setFrameInScreenBounds(f,0)
end
self:reset_timer()
end
function cccwm:init()
-- modal hotkeys
self.modal = hs.hotkey.modal.new('ctrl', '`')
function self.modal:entered()
hs.alert'CCCWM in'
cccwm:reset_timer()
end
function self.modal:exited()
hs.alert'CCCWM out'
cccwm:cancel_timer()
end
self.modal:bind('', 'escape', function() self.modal:exit() end)
self.modal:bind('', 'Right', function() self:move_monitor('East') end)
self.modal:bind('', 'Left', function() self:move_monitor('West') end)
self.modal:bind('', 'Up', function() self:move_monitor('North') end)
self.modal:bind('', 'Down', function() self:move_monitor('South') end)
self.modal:bind('', '/', function() self:print_window_info() end)
for k,v in pairs(self.config.grids) do
self.modal:bind('', k, 'Pressed ' .. k, function() self:do_grid(v) end)
end
end
------------------------------------------------------------
------------------------------------------------------------
cccwm:init()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment