Created
July 24, 2017 09:36
-
-
Save yeled/81269ee2825418c09dbe59409da77ea2 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
-- === sizeup === | |
-- | |
-- SizeUp emulation for hammerspoon | |
-- | |
-- To use, you can tweak the key bindings and the margins | |
local sizeup = { } | |
-------------- | |
-- Bindings -- | |
-------------- | |
--- Split Screen Actions --- | |
-- Send Window Left | |
hs.hotkey.bind({"ctrl","alt","cmd"}, "Left", function() | |
sizeup.send_window_left() | |
end) | |
-- Send Window Right | |
hs.hotkey.bind({"ctrl","alt","cmd"}, "Right", function() | |
sizeup.send_window_right() | |
end) | |
-- Send Window Up | |
hs.hotkey.bind({"ctrl","alt","cmd"}, "Up", function() | |
sizeup.send_window_up() | |
end) | |
-- Send Window Down | |
hs.hotkey.bind({"ctrl","alt","cmd"}, "Down", function() | |
sizeup.send_window_down() | |
end) | |
--- Quarter Screen Actions --- | |
-- Send Window Upper Left | |
hs.hotkey.bind({"ctrl","alt","cmd"}, "Home", function() | |
sizeup.send_window_upper_left() | |
end) | |
-- Send Window Upper Right | |
hs.hotkey.bind({"ctrl","alt","cmd"}, "PageUp", function() | |
sizeup.send_window_upper_right() | |
end) | |
-- Send Window Lower Left | |
hs.hotkey.bind({"ctrl","alt","cmd"}, "End", function() | |
sizeup.send_window_lower_left() | |
end) | |
-- Send Window Lower Right | |
hs.hotkey.bind({"ctrl","alt","cmd"}, "PageDown", function() | |
sizeup.send_window_lower_right() | |
end) | |
--- Multiple Monitor Actions --- | |
-- Send Window Prev Monitor | |
hs.hotkey.bind({ "ctrl", "alt" }, "Left", function() | |
sizeup.send_window_prev_monitor() | |
end) | |
-- Send Window Next Monitor | |
hs.hotkey.bind({ "ctrl", "alt" }, "Right", function() | |
sizeup.send_window_next_monitor() | |
end) | |
--- Spaces Actions --- | |
-- Apple no longer provides any reliable API access to spaces. | |
-- As such, this feature no longer works in SizeUp on Yosemite and | |
-- Hammerspoon currently has no solution that isn't a complete hack. | |
-- If you have any ideas, please visit the ticket | |
--- Snapback Action --- | |
hs.hotkey.bind({"ctrl","alt","cmd"}, "Z", function() | |
sizeup.snapback() | |
end) | |
--- Other Actions --- | |
-- Make Window Full Screen | |
hs.hotkey.bind({"cmd","alt","ctrl"}, "M", function() | |
sizeup.maximize() | |
end) | |
-- Send Window Center | |
hs.hotkey.bind({"cmd","alt","ctrl"}, "C", function() | |
-- sizeup.move_to_center_absolute({w=800, h=600}) | |
sizeup.move_to_center_relative({w=0.75, h=1}) | |
end) | |
------------------- | |
-- Configuration -- | |
------------------- | |
-- Margins -- | |
sizeup.screen_edge_margins = { | |
top = 0, -- px | |
left = 0, | |
right = 0, | |
bottom = 0 | |
} | |
sizeup.partition_margins = { | |
x = 0, -- px | |
y = 0 | |
} | |
-- Partitions -- | |
sizeup.split_screen_partitions = { | |
x = 0.5, -- % | |
y = 0.5 | |
} | |
sizeup.quarter_screen_partitions = { | |
x = 0.5, -- % | |
y = 0.5 | |
} | |
---------------- | |
-- Public API -- | |
---------------- | |
function sizeup.send_window_left() | |
local s = sizeup.screen() | |
local ssp = sizeup.split_screen_partitions | |
local g = sizeup.gutter() | |
sizeup.set_frame("Left", { | |
x = s.x, | |
y = s.y, | |
w = (s.w * ssp.x) - sizeup.gutter().x, | |
h = s.h | |
}) | |
end | |
function sizeup.send_window_right() | |
local s = sizeup.screen() | |
local ssp = sizeup.split_screen_partitions | |
local g = sizeup.gutter() | |
sizeup.set_frame("Right", { | |
x = s.x + (s.w * ssp.x) + g.x, | |
y = s.y, | |
w = (s.w * (1 - ssp.x)) - g.x, | |
h = s.h | |
}) | |
end | |
function sizeup.send_window_up() | |
local s = sizeup.screen() | |
local ssp = sizeup.split_screen_partitions | |
local g = sizeup.gutter() | |
sizeup.set_frame("Up", { | |
x = s.x, | |
y = s.y, | |
w = s.w, | |
h = (s.h * ssp.y) - g.y | |
}) | |
end | |
function sizeup.send_window_down() | |
local s = sizeup.screen() | |
local ssp = sizeup.split_screen_partitions | |
local g = sizeup.gutter() | |
sizeup.set_frame("Down", { | |
x = s.x, | |
y = s.y + (s.h * ssp.y) + g.y, | |
w = s.w, | |
h = (s.h * (1 - ssp.y)) - g.y | |
}) | |
end | |
function sizeup.send_window_upper_left() | |
local s = sizeup.screen() | |
local qsp = sizeup.quarter_screen_partitions | |
local g = sizeup.gutter() | |
sizeup.set_frame("Upper Left", { | |
x = s.x, | |
y = s.y, | |
w = (s.w * qsp.x) - g.x, | |
h = (s.h * qsp.y) - g.y | |
}) | |
end | |
function sizeup.send_window_upper_right() | |
local s = sizeup.screen() | |
local qsp = sizeup.quarter_screen_partitions | |
local g = sizeup.gutter() | |
sizeup.set_frame("Upper Right", { | |
x = s.x + (s.w * qsp.x) + g.x, | |
y = s.y, | |
w = (s.w * (1 - qsp.x)) - g.x, | |
h = (s.h * (qsp.y)) - g.y | |
}) | |
end | |
function sizeup.send_window_lower_left() | |
local s = sizeup.screen() | |
local qsp = sizeup.quarter_screen_partitions | |
local g = sizeup.gutter() | |
sizeup.set_frame("Lower Left", { | |
x = s.x, | |
y = s.y + (s.h * qsp.y) + g.y, | |
w = (s.w * qsp.x) - g.x, | |
h = (s.h * (1 - qsp.y)) - g.y | |
}) | |
end | |
function sizeup.send_window_lower_right() | |
local s = sizeup.screen() | |
local qsp = sizeup.quarter_screen_partitions | |
local g = sizeup.gutter() | |
sizeup.set_frame("Lower Right", { | |
x = s.x + (s.w * qsp.x) + g.x, | |
y = s.y + (s.h * qsp.y) + g.y, | |
w = (s.w * (1 - qsp.x)) - g.x, | |
h = (s.h * (1 - qsp.y)) - g.y | |
}) | |
end | |
function sizeup.send_window_prev_monitor() | |
hs.alert.show("Prev Monitor") | |
local win = hs.window.focusedWindow() | |
local nextScreen = win:screen():previous() | |
win:moveToScreen(nextScreen) | |
end | |
function sizeup.send_window_next_monitor() | |
hs.alert.show("Next Monitor") | |
local win = hs.window.focusedWindow() | |
local nextScreen = win:screen():next() | |
win:moveToScreen(nextScreen) | |
end | |
-- snapback return the window to its last position. calling snapback twice returns the window to its original position. | |
-- snapback holds state for each window, and will remember previous state even when focus is changed to another window. | |
function sizeup.snapback() | |
local win = sizeup.win() | |
local id = win:id() | |
local state = win:frame() | |
local prev_state = sizeup.snapback_window_state[id] | |
if prev_state then | |
win:setFrame(prev_state) | |
end | |
sizeup.snapback_window_state[id] = state | |
end | |
function sizeup.maximize() | |
sizeup.set_frame("Full Screen", sizeup.screen()) | |
end | |
--- move_to_center_relative(size) | |
--- Method | |
--- Centers and resizes the window to the the fit on the given portion of the screen. | |
--- The argument is a size with each key being between 0.0 and 1.0. | |
--- Example: win:move_to_center_relative(w=0.5, h=0.5) -- window is now centered and is half the width and half the height of screen | |
function sizeup.move_to_center_relative(unit) | |
local s = sizeup.screen() | |
sizeup.set_frame("Center", { | |
x = s.x + (s.w * ((1 - unit.w) / 2)), | |
y = s.y + (s.h * ((1 - unit.h) / 2)), | |
w = s.w * unit.w, | |
h = s.h * unit.h | |
}) | |
end | |
--- move_to_center_absolute(size) | |
--- Method | |
--- Centers and resizes the window to the the fit on the given portion of the screen given in pixels. | |
--- Example: win:move_to_center_relative(w=800, h=600) -- window is now centered and is 800px wide and 600px high | |
function sizeup.move_to_center_absolute(unit) | |
local s = sizeup.screen() | |
sizeup.set_frame("Center", { | |
x = (s.w - unit.w) / 2, | |
y = (s.h - unit.h) / 2, | |
w = unit.w, | |
h = unit.h | |
}) | |
end | |
------------------ | |
-- Internal API -- | |
------------------ | |
-- SizeUp uses no animations | |
hs.window.animation_duration = 0.0 | |
-- Initialize Snapback state | |
sizeup.snapback_window_state = { } | |
-- return currently focused window | |
function sizeup.win() | |
return hs.window.focusedWindow() | |
end | |
-- display title, save state and move win to unit | |
function sizeup.set_frame(title, unit) | |
hs.alert.show(title) | |
local win = sizeup.win() | |
sizeup.snapback_window_state[win:id()] = win:frame() | |
return win:setFrame(unit) | |
end | |
-- screen is the available rect inside the screen edge margins | |
function sizeup.screen() | |
local screen = sizeup.win():screen():frame() | |
local sem = sizeup.screen_edge_margins | |
return { | |
x = screen.x + sem.left, | |
y = screen.y + sem.top, | |
w = screen.w - (sem.left + sem.right), | |
h = screen.h - (sem.top + sem.bottom) | |
} | |
end | |
-- gutter is the adjustment required to accomidate partition | |
-- margins between windows | |
function sizeup.gutter() | |
local pm = sizeup.partition_margins | |
return { | |
x = pm.x / 2, | |
y = pm.y / 2 | |
} | |
end | |
--- hs.window:moveToScreen(screen) | |
--- Method | |
--- move window to the the given screen, keeping the relative proportion and position window to the original screen. | |
--- Example: win:moveToScreen(win:screen():next()) -- move window to next screen | |
function hs.window:moveToScreen(nextScreen) | |
local currentFrame = self:frame() | |
local screenFrame = self:screen():frame() | |
local nextScreenFrame = nextScreen:frame() | |
self:setFrame({ | |
x = ((((currentFrame.x - screenFrame.x) / screenFrame.w) * nextScreenFrame.w) + nextScreenFrame.x), | |
y = ((((currentFrame.y - screenFrame.y) / screenFrame.h) * nextScreenFrame.h) + nextScreenFrame.y), | |
h = ((currentFrame.h / screenFrame.h) * nextScreenFrame.h), | |
w = ((currentFrame.w / screenFrame.w) * nextScreenFrame.w) | |
}) | |
end | |
--- end sizeup | |
local alert_sound = hs.sound.getByName("Pop") | |
-- Set up hotkey combinations | |
local mash = {"cmd", "alt", "ctrl"} | |
local mashshift = {"cmd", "alt", "shift"} | |
local funkymash = {"cmd", "ctrl", "shift"} | |
hs.window.animationDuration = 0 | |
-- Set volume increments | |
local volumeIncrement = 5 | |
hs.hotkey.bind(mashshift, 'space', hs.spotify.displayCurrentTrack) | |
hs.hotkey.bind(mashshift, 'P', hs.spotify.play) | |
hs.hotkey.bind(mashshift, 'O', hs.spotify.pause) | |
hs.hotkey.bind(mashshift, 'N', hs.spotify.next) | |
hs.hotkey.bind(mashshift, 'I', hs.spotify.previous) | |
hs.hotkey.bind(funkymash, 'space', hs.itunes.displayCurrentTrack) | |
hs.hotkey.bind(funkymash, 'P', hs.itunes.play) | |
hs.hotkey.bind(funkymash, 'O', hs.itunes.pause) | |
hs.hotkey.bind(funkymash, 'N', hs.itunes.next) | |
hs.hotkey.bind(funkymash, 'I', hs.itunes.previous) | |
hs.hotkey.bind({}, 'F13', function() hs.eventtap.keyStrokes("ಠ_ಠ") end) | |
--- hs.hotkey.bind(mashshift, ']', function() hs.audiodevice.defaultOutputDevice():setVolume(hs.audiodevice.current().volume + 5) end) | |
--- hs.hotkey.bind(mashshift, '[', function() hs.audiodevice.defaultOutputDevice():setVolume(hs.audiodevice.current().volume - 5) end) | |
hs.hotkey.bind({}, 'F14', function() hs.audiodevice.defaultOutputDevice():setVolume(hs.audiodevice.current().volume - 5) alert_sound:play() end) | |
hs.hotkey.bind({}, 'F15', function() hs.audiodevice.defaultOutputDevice():setVolume(hs.audiodevice.current().volume + 5) alert_sound:play() end) | |
-- habbie | |
function blurothers() dark={{red=0.5, green=0.5, blue=0.5}, {alpha=1.0, red=0.0, green=0.0, blue=0.0}} light ={{red=1.0, green=1.0, blue=1.0}, {alpha=1.0, red=0.0, green=0.0, blue=0.0}} main = hs.screen.mainScreen() for i,v in ipairs(hs.screen.allScreens()) do if v == main then v:setGamma(light[1], light[2]) else v:setGamma(dark[1], dark[2]) end end end | |
blurtimer = hs.timer.new(0.1, blurothers) | |
blurtimer:start() | |
-- /habbie | |
alert_sound:play() | |
hs.alert.show("Hammerspoon, at your service.", 3) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment