Last active
August 28, 2021 18:10
-
-
Save feifanzhou/05dc353d291f63e103f1c9442fce238e to your computer and use it in GitHub Desktop.
Hammerspoon config (window moving and resizing)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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