Created
July 23, 2016 21:18
-
-
Save curioussavage/e58e7034c302f42faf47bcc7c810d15d to your computer and use it in GitHub Desktop.
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
-- **** copied from https://gist.github.com/spartanatreyu/850788a0441e1c5565668a35ed9a1dfc **** -- | |
--required to be non zero for dragging windows to work some weird timing issue with hammerspoon fighting against osx events | |
hs.window.animationDuration = 0.00000001 | |
--flag for dragging, 0 means no drag, 1 means dragging a window, -1 means dragging but not dragging the window | |
dragging = 0 | |
--the window being dragged | |
dragging_window = nil | |
--the height of the window's title area in pixels, can change if you have different sized windows (might happen one day) or need a different window grabbing sensitivity | |
window_titlebar_height = 21 | |
-- Exists because lua doesn't have a round function. WAT?! | |
function round(num) | |
return math.floor(num + 0.5) | |
end | |
--based on kizzx2's hammerspoon-move-resize.lua | |
function get_window_under_mouse() | |
-- Invoke `hs.application` because `hs.window.orderedWindows()` doesn't do it | |
-- and breaks itself | |
local _ = hs.application | |
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 my_pos:inside(w:frame()) | |
end) | |
end | |
------------------------------------------------------------------- | |
--Window snapping with mouse, Windows style (Cinch Alternative) | |
------------------------------------------------------------------- | |
--Setup drag start and dragging | |
click_event = hs.eventtap.new({hs.eventtap.event.types.leftMouseDragged}, function(e) | |
--if drag is just starting... | |
if dragging == 0 then | |
dragging_window = get_window_under_mouse() | |
--if mouse over a window... | |
if dragging_window ~= nil then | |
local m = hs.mouse.getAbsolutePosition() | |
local mx = round(m.x) | |
local my = round(m.y) | |
--print('mx: ' .. mx .. ', my: ' .. my) | |
local f = dragging_window:frame() | |
local screen = dragging_window:screen() | |
local max = screen:frame() | |
--print('fx: ' .. f.x .. ', fy: ' .. f.y .. ', fw: ' .. f.w .. ', fh: ' .. f.h) | |
dragging_window_pos = { x = max.x, y = max.y } | |
--if mouse inside titlebar horizontally | |
if mx > f.x and mx < (f.x + f.w) then | |
--print('mouse is inside titlebar horizontally') | |
--if mouse inside titlebar vertically | |
if my > f.y and my < (f.y + window_titlebar_height) then | |
--print('mouse is inside titlebar') | |
dragging = 1 | |
--print(' - start dragging - window: ' .. dragging_window:id()) | |
else | |
--print('mouse is not inside titlebar') | |
dragging = -1 | |
dragging_window = nil | |
end | |
else | |
--print('mouse is not inside titlebar horizontally') | |
dragging = -1 | |
dragging_window = nil | |
end | |
end | |
--else if drag is already going | |
--[[ | |
else | |
if dragging_window ~= nil then | |
local dx = e:getProperty(hs.eventtap.event.properties.mouseEventDeltaX) | |
local dy = e:getProperty(hs.eventtap.event.properties.mouseEventDeltaY) | |
local m = hs.mouse.getAbsolutePosition() | |
local mx = round(m.x) | |
local my = round(m.y) | |
print(' - dragging: ' .. mx .. "," .. my .. ". window id: " .. dragging_window:id()) | |
end | |
]]-- | |
end | |
end) | |
function setframe(frame, windowFrame, x, y, w, h) | |
frame.x = windowFrame.x + (windowFrame.w * x) | |
frame.y = windowFrame.y + (windowFrame.h * y) | |
frame.w = windowFrame.w * w | |
frame.h = windowFrame.h * h | |
return frame | |
end | |
--Setup drag end | |
unclick_event = hs.eventtap.new({hs.eventtap.event.types.leftMouseUp}, function(e) | |
local buffer_zone = 20 | |
--print('unclick, dragging: ' .. dragging) | |
--if dragging the mouse | |
if dragging == 1 then | |
--if the mouse is dragging a window | |
if dragging_window ~= nil then | |
--print('letting go of window: ' .. dragging_window:id()) | |
local m = hs.mouse.getRelativePosition() | |
local mx = round(m.x) | |
local my = round(m.y) | |
local win = dragging_window | |
local f = win:frame() | |
local screen = win:screen() | |
local frame = screen:frame() | |
print('mouse - x: ' .. m.x .. ', y: ' .. m.y) | |
if m.y < buffer_zone then -- touching top | |
if m.x < frame.w * .3 then | |
win:setFrame(setframe(f, frame, 0, 0, .5, .5)) | |
elseif m.x > frame.w * .7 then | |
win:setFrame(setframe(f, frame, .5, 0, .5, .5)) | |
else | |
win:setFrame(setframe(f, frame, 0, 0, 1, 1)) | |
end | |
elseif m.x < buffer_zone then -- touching left | |
if m.y < frame.h * .3 then | |
win:setFrame(setframe(f, frame, 0, 0, .5, .5)) | |
elseif m.y > frame.h * .7 then | |
win:setFrame(setframe(f, frame, 0, .5, .5, .5)) | |
else | |
win:setFrame(setframe(f, frame, 0, 0, .5, 1)) | |
end | |
elseif m.x > frame.w - buffer_zone then -- touching right | |
if m.y < frame.h * .3 then | |
win:setFrame(setframe(f, frame, .5, 0, .5, .5)) | |
elseif m.y > frame.h * .7 then | |
win:setFrame(setframe(f, frame, .5, .5, .5, .5)) | |
else | |
win:setFrame(setframe(f, frame, .5, 0, .5, 1)) | |
end | |
elseif m.y > frame.h - buffer_zone then -- bottom | |
if m.x < frame.w * .3 then | |
win:setFrame(setframe(f, frame, 0, .5, .5, .5)) | |
elseif m.x > frame.w * .7 then | |
win:setFrame(setframe(f, frame, .5, .5, .5, .5)) | |
else | |
win:setFrame(setframe(f, frame, 0, 0, 1, 1)) | |
end | |
end | |
end | |
--print("end dragging") | |
end | |
dragging = 0 | |
dragging_window = nil | |
end) | |
--Start watching for dragging (AKA: turn dragging on) | |
click_event:start() | |
unclick_event:start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment