forked from codeforamerica/clientcomm-setup
-
Notifications
You must be signed in to change notification settings - Fork 1
/
init.lua
411 lines (341 loc) · 13.6 KB
/
init.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
--
-- CLIPBOARD MANIPULATION
--
-- contents of clipboard saved to ~/Downloads as a formatted json file
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "Z", function()
hs.execute("~/bin/sctj", true)
end)
--
-- WINDOW MANAGEMENT
--
-- disable accessibility settings used by 1Password which
-- messes up window movement for Firefox
-- source: https://github.com/Hammerspoon/hammerspoon/issues/3224#issuecomment-1294359070
local function specialSetFrame(win, window_frame)
local axApp = hs.axuielement.applicationElement(win:application())
local wasEnhanced = axApp.AXEnhancedUserInterface
if wasEnhanced then
axApp.AXEnhancedUserInterface = false
end
win:setFrame(window_frame) -- or win:moveToScreen(someScreen), etc.
if wasEnhanced then
axApp.AXEnhancedUserInterface = true
end
end
-- focused window takes the full screen
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "M", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local screen_frame = focused_window:screen():frame()
specialSetFrame(focused_window, screen_frame)
end)
-- all the frontmost application's windows centered on whatever screen they're on
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "A", function()
hs.window.animationDuration = 0
local app = hs.application.frontmostApplication()
local app_windows = app:allWindows()
local screen_frame, window_frame, wide, high
for _, win in pairs(app_windows) do
screen_frame = win:screen():frame()
window_frame = win:frame()
wide = window_frame.w
high = window_frame.h
window_frame.x = screen_frame.x + ((screen_frame.w / 2) - (wide / 2))
window_frame.y = screen_frame.y + ((screen_frame.h / 2) - (high / 2))
specialSetFrame(win, window_frame)
end
end)
-- focused window sized to set dimensions and centered
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "C", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local window_frame = focused_window:frame()
local screen_frame = focused_window:screen():frame()
local wide = window_frame.w
local high = window_frame.h
-- first, try centering the widnow at its current size
window_frame.x = screen_frame.x + ((screen_frame.w / 2) - (wide / 2))
window_frame.y = screen_frame.y + ((screen_frame.h / 2) - (high / 2))
-- some apps may not size to exactly wide x high, so check before and after
local before_frame = focused_window:frame()
specialSetFrame(focused_window, window_frame)
local after_frame = focused_window:frame()
-- if the window was already centered, resize to set dimensions
local resized_wide = 801
local resized_high = 605
if before_frame == after_frame and (wide ~= resized_wide or high ~= resized_high) then
window_frame.x = screen_frame.x + ((screen_frame.w / 2) - (resized_wide / 2))
window_frame.y = screen_frame.y + ((screen_frame.h / 2) - (resized_high / 2))
window_frame.w = resized_wide
window_frame.h = resized_high
specialSetFrame(focused_window, window_frame)
elseif before_frame == after_frame and wide == resized_wide and high == resized_high then
-- if the window was already sized and centered, grow it to full screen height
window_frame.y = screen_frame.y
window_frame.h = screen_frame.h
specialSetFrame(focused_window, window_frame)
end
end)
-- move the passed window to the passed screen
local function moveWindowToScreen(window, screen)
-- shrink the window if it's bigger than the target screen
local target_screen_frame = screen:frame()
local window_frame = window:frame()
local wide = window_frame.w
local high = window_frame.h
if wide > target_screen_frame.w then
wide = target_screen_frame.w
end
if high > target_screen_frame.h then
high = target_screen_frame.h
end
-- center the frame in the new screen
window_frame.x = target_screen_frame.x + ((target_screen_frame.w / 2) - (wide / 2))
window_frame.y = target_screen_frame.y + ((target_screen_frame.h / 2) - (high / 2))
window_frame.w = wide
window_frame.h = high
specialSetFrame(window, window_frame)
end
-- focused window moved to the next screen (if any) and centered
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "N", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local focused_screen = focused_window:screen()
local all_screens = hs.screen.allScreens()
local all_screens_count = #all_screens
local window_screen_position = 1
local target_screen_position = 1
-- if there's more than one screen...
if all_screens_count > 1 then
-- find the screen the window's in
for key, value in pairs(all_screens) do
if value == focused_screen then
window_screen_position = key
break
end
end
-- and pick the next screen in line
if window_screen_position >= all_screens_count then
target_screen_position = 1
else
target_screen_position = window_screen_position + 1
end
-- move the window to the next screen
moveWindowToScreen(focused_window, all_screens[target_screen_position])
end
end)
-- all the frontmost application's windows moved to the next screen (if any) and centered
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "B", function()
hs.window.animationDuration = 0
local all_screens = hs.screen.allScreens()
local all_screens_count = #all_screens
-- if there's more than one screen...
if all_screens_count > 1 then
local focused_window = hs.window.focusedWindow()
local focused_screen = focused_window:screen()
local window_screen_position = 1
local target_screen_position = 1
-- find the position of the screen the front-most window's in
for key, value in pairs(all_screens) do
if value == focused_screen then
window_screen_position = key
break
end
end
-- and pick the next screen in line
if window_screen_position >= all_screens_count then
target_screen_position = 1
else
target_screen_position = window_screen_position + 1
end
-- step through the windows and move them to the next screen
local app = hs.application.frontmostApplication()
local app_windows = app:allWindows()
for _, win in pairs(app_windows) do
-- ignore minimized windows
if win.isMinimized ~= true then
-- move the window to the next screen
moveWindowToScreen(win, all_screens[target_screen_position])
end
end
end
end)
-- focused window moves to left edge of screen, then fills the left half of the screen
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "H", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local window_frame = focused_window:frame()
local screen_frame = focused_window:screen():frame()
if window_frame.x == screen_frame.x then
-- fill the left half of the screen
window_frame.y = screen_frame.y
window_frame.w = screen_frame.w / 2
window_frame.h = screen_frame.h
else
-- just move to the left edge of the screen
window_frame.x = screen_frame.x
end
specialSetFrame(focused_window, window_frame)
end)
-- move the focused window and all other windows belonging to the same app and on the
-- same screen to the left half of the screen
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "U", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local focused_screen = focused_window:screen()
local app = hs.application.frontmostApplication()
local app_windows = app:allWindows()
local screen_frame, window_frame
for _, win in pairs(app_windows) do
if win:screen() == focused_screen then
screen_frame = win:screen():frame()
window_frame = win:frame()
window_frame.x = screen_frame.x
window_frame.y = screen_frame.y
window_frame.w = screen_frame.w / 2
window_frame.h = screen_frame.h
specialSetFrame(win, window_frame)
end
end
end)
-- focused window moves to right edge of screen, then fills the right half of the screen
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "L", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local window_frame = focused_window:frame()
local screen_frame = focused_window:screen():frame()
if window_frame.x == screen_frame.x + screen_frame.w - window_frame.w then
-- fill the right half of the screen
local half_width = math.floor(screen_frame.w / 2)
window_frame.x = screen_frame.x + screen_frame.w - half_width
window_frame.y = screen_frame.y
window_frame.w = half_width
window_frame.h = screen_frame.h
else
-- just move to the right edge of the screen
window_frame.x = screen_frame.x + screen_frame.w - window_frame.w
end
specialSetFrame(focused_window, window_frame)
end)
-- move the focused window and all other windows belonging to the same app and on the
-- same screen to the right half of the screen
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "O", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local focused_screen = focused_window:screen()
local app = hs.application.frontmostApplication()
local app_windows = app:allWindows()
local screen_frame, window_frame
for _, win in pairs(app_windows) do
if win:screen() == focused_screen then
screen_frame = win:screen():frame()
window_frame = win:frame()
local half_width = math.floor(screen_frame.w / 2)
window_frame.x = screen_frame.x + screen_frame.w - half_width
window_frame.y = screen_frame.y
window_frame.w = half_width
window_frame.h = screen_frame.h
specialSetFrame(win, window_frame)
end
end
end)
-- focused window moves to top edge of screen, then fills the top half of the screen
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "K", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local window_frame = focused_window:frame()
local screen_frame = focused_window:screen():frame()
if window_frame.y == screen_frame.y then
-- fill the top half of the screen
window_frame.x = screen_frame.x
window_frame.w = screen_frame.w
window_frame.h = math.floor(screen_frame.h / 2)
else
-- just move to the top edge of the screen
window_frame.y = screen_frame.y
end
specialSetFrame(focused_window, window_frame)
end)
-- focused window moves to bottom edge of screen, then fills the bottom half of the screen
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "J", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local window_frame = focused_window:frame()
local screen_frame = focused_window:screen():frame()
if window_frame.y == screen_frame.y + screen_frame.h - window_frame.h then
-- fill the bottom half of the screen
local half_height = math.floor(screen_frame.h / 2)
window_frame.y = screen_frame.y + screen_frame.h - half_height
window_frame.x = screen_frame.x
window_frame.w = screen_frame.w
window_frame.h = half_height
else
-- just move to the bottom edge of the screen
window_frame.y = screen_frame.y + screen_frame.h - window_frame.h
end
specialSetFrame(focused_window, window_frame)
end)
-- focused window's width increased by set amount
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "Right", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local window_frame = focused_window:frame()
local screen_frame = focused_window:screen():frame()
local grow_width = 60
window_frame.x = math.max(window_frame.x - (grow_width / 2), screen_frame.x)
window_frame.w = math.min(window_frame.w + grow_width, screen_frame.w)
specialSetFrame(focused_window, window_frame)
end)
-- focused window's width decreased by set amount
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "Left", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local window_frame = focused_window:frame()
local screen_frame = focused_window:screen():frame()
local shrink_width = 60
local min_width = 570
local new_width = math.max(window_frame.w - shrink_width, min_width)
-- stick to the edges of the screen
local window_not_on_left_edge = window_frame.x ~= screen_frame.x
local window_on_right_edge = window_frame.x + window_frame.w == screen_frame.x + screen_frame.w
local window_center = window_frame.x + (window_frame.w / 2)
if window_not_on_left_edge and window_on_right_edge then
window_frame.x = screen_frame.x + screen_frame.w - new_width
elseif window_not_on_left_edge then
window_frame.x = window_center - (new_width / 2)
end
window_frame.w = new_width
specialSetFrame(focused_window, window_frame)
end)
-- focused window's height increased by set amount
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "Up", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local window_frame = focused_window:frame()
local screen_frame = focused_window:screen():frame()
local grow_height = 60
window_frame.y = math.max(window_frame.y - (grow_height / 2), screen_frame.y)
window_frame.h = math.min(window_frame.h + grow_height, screen_frame.h)
specialSetFrame(focused_window, window_frame)
end)
-- focused window's height decreased by set amount
hs.hotkey.bind({ "cmd", "alt", "ctrl" }, "Down", function()
hs.window.animationDuration = 0
local focused_window = hs.window.focusedWindow()
local window_frame = focused_window:frame()
local screen_frame = focused_window:screen():frame()
local shrink_height = 60
local min_height = 570
local new_height = math.max(window_frame.h - shrink_height, min_height)
-- stick to the edges of the screen
local window_not_on_top_edge = window_frame.y ~= screen_frame.y
local window_on_bottom_edge = window_frame.y + window_frame.h == screen_frame.y + screen_frame.h
local window_center = window_frame.y + (window_frame.h / 2)
if window_on_bottom_edge then
window_frame.y = screen_frame.y + screen_frame.h - new_height
elseif window_not_on_top_edge then
window_frame.y = window_center - (new_height / 2)
end
window_frame.h = new_height
specialSetFrame(focused_window, window_frame)
end)