Skip to content

Instantly share code, notes, and snippets.

@feifanzhou
Last active August 28, 2021 18:10
Show Gist options
  • Save feifanzhou/05dc353d291f63e103f1c9442fce238e to your computer and use it in GitHub Desktop.
Save feifanzhou/05dc353d291f63e103f1c9442fce238e to your computer and use it in GitHub Desktop.
Hammerspoon config (window moving and resizing)
-- Inspired by Linux alt-drag or Better Touch Tools move/resize functionality
-- from https://gist.github.com/kizzx2/e542fa74b80b7563045a#gistcomment-2023593
-- Command-Ctrl-move: move window under mouse
-- Command-Control-Shift-move: resize window under mouse
function get_window_under_mouse()
local my_pos = hs.geometry.new(hs.mouse.getAbsolutePosition())
local my_screen = hs.mouse.getCurrentScreen()
return hs.fnutils.find(hs.window.orderedWindows(), function(w)
return my_screen == w:screen() and
w:isStandard() and
(not w:isFullScreen()) and
my_pos:inside(w:frame())
end)
end
dragging = {} -- global variable to hold the dragging/resizing state
drag_event = hs.eventtap.new({ hs.eventtap.event.types.mouseMoved }, function(e)
if not dragging then return nil end
if dragging.mode==3 then -- just move
local dx = e:getProperty(hs.eventtap.event.properties.mouseEventDeltaX)
local dy = e:getProperty(hs.eventtap.event.properties.mouseEventDeltaY)
dragging.win:move({dx, dy}, nil, false, 0)
else -- resize
local pos=hs.mouse.getAbsolutePosition()
local w1 = dragging.size.w + (pos.x-dragging.off.x)
local h1 = dragging.size.h + (pos.y-dragging.off.y)
dragging.win:setSize(w1, h1)
end
end)
flags_event = hs.eventtap.new({ hs.eventtap.event.types.flagsChanged }, function(e)
local flags = e:getFlags()
local mode=(flags.shift and 1 or 0) + (flags.ctrl and 2 or 0) + (flags.alt and 4 or 0)
if mode==3 or mode==5 then -- valid modes
if dragging then
if dragging.mode == mode then return nil end -- already working
else
-- only update window if we hadn't started dragging/resizing already
dragging={win = get_window_under_mouse()}
if not dragging.win then -- no good window
dragging=nil
return nil
end
end
dragging.mode = mode -- 3=drag, 5=resize
if mode==5 then
dragging.off=hs.mouse.getAbsolutePosition()
dragging.size=dragging.win:size()
end
drag_event:start()
else -- not a valid mode
if dragging then
drag_event:stop()
dragging = nil
end
end
return nil
end)
flags_event:start()
hs.loadSpoon('ControlEscape'):start()
mxMasterSideButtons = hs.eventtap.new({ hs.eventtap.event.types.otherMouseDown }, function(e)
local button = e:getProperty(
hs.eventtap.event.properties['mouseEventButtonNumber']
)
local flags = e:getFlags()
-- print(string.format("Clicked Mouse Button: %i", button))
if button == 2 then -- MAX Master wheel
if flags.cmd then
hs.eventtap.event.newKeyEvent({'cmd'}, 'l', true):post()
hs.eventtap.event.newKeyEvent({'cmd'}, 'c', true):post()
return true
end
return nil
elseif button == 3 then -- MX Master lower side button
if flags.alt then
hs.eventtap.event.newKeyEvent({'cmd'}, 'w', true):post()
elseif flags.cmd then
hs.eventtap.event.newKeyEvent({'ctrl', 'shift'}, 'tab', true):post()
else
hs.eventtap.event.newKeyEvent({'cmd'}, '[', true):post()
end
return true
elseif button == 4 then -- MAX Master upper side button
if flags.cmd then
hs.eventtap.event.newKeyEvent({'ctrl'}, 'tab', true):post()
else
hs.eventtap.event.newKeyEvent({'cmd'}, ']', true):post()
end
return true
else
return nil
end
end)
mxMasterSideButtons:start()
keyboardHyperFunctions = hs.eventtap.new({ hs.eventtap.event.types.keyDown }, function(e)
local keycode = e:getProperty(hs.eventtap.event.properties['keyboardEventKeycode'])
-- local flags = hs.eventtap.checkKeyboardModifiers(true)
local flags = e:getFlags()
if keycode == 125 then -- down arrow
if flags.cmd and flags.alt and flags.ctrl and flags.shift then
local out, _, _, _ = hs.execute('/Users/feifan/bin/ddcctl -d 1 -b 10-')
print(out)
return true
end
elseif keycode == 126 then -- up arrow
if flags.cmd and flags.alt and flags.ctrl and flags.shift then
local out, _, _, _ = hs.execute('/Users/feifan/bin/ddcctl -d 1 -b 10+')
print(out)
return true
end
end
return nil
end)
keyboardHyperFunctions:start()
wakeWatcher = hs.caffeinate.watcher.new(function(eventType)
if (eventType == hs.caffeinate.watcher.systemDidWake) then
hs.reload()
end
end)
wakeWatcher:start()
-- App launchers
hs.hotkey.bind({'ctrl', 'alt', 'cmd', 'shift'}, 'M', function() hs.application.launchOrFocus('Messages') end)
hs.hotkey.bind({'ctrl', 'alt', 'cmd', 'shift'}, 'S', function() hs.application.launchOrFocus('Safari') end)
hs.hotkey.bind({'ctrl', 'alt', 'cmd', 'shift'}, 'V', function() hs.application.launchOrFocus('Visual Studio Code') end)
hs.hotkey.bind({'ctrl', 'alt', 'cmd', 'shift'}, 'X', function() hs.application.launchOrFocus('Xcode') end)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment