Skip to content

Instantly share code, notes, and snippets.

@curioussavage
Created July 23, 2016 21:18
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 curioussavage/e58e7034c302f42faf47bcc7c810d15d to your computer and use it in GitHub Desktop.
Save curioussavage/e58e7034c302f42faf47bcc7c810d15d to your computer and use it in GitHub Desktop.
-- **** 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