-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp_cycle.lua
189 lines (157 loc) · 5.6 KB
/
app_cycle.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
require("hs.mouse")
local fnutils = require("hs.fnutils")
local wf = require("hs.window.filter")
local scr = require("hs.screen");
local geometry = require "hs.geometry"
require('util')
require('mouse')
-- Local variables
local app_group = {
browser = {'Google Chrome', 'Firefox'},
editor = {'Atom', 'BBEdit'},
terminal = {'iTerm2', 'Terminal', 'iTerm'},
sql = {'Sequel Pro'}
}
local last_group_app = {
browser = 'Google Chrome',
editor = 'Atom',
terminal = 'iTerm2'
}
local appFilters = {
Atom = wf.new{'Atom'}:setAppFilter('Atom', {visible = true, currentSpace = nil, allowScreens = {'0,0', '1,0', '-1,0'}}),
iTerm = wf.new{'iTerm'},
Slack = wf.new{'Slack'}
}
-- Get window info
function win_info()
return function()
focused = hs.window.focusedWindow()
if not focused then return nil end
local app_list = hs.application.runningApplications()
print(hs.inspect(app_list))
-- hs.notify.new({
-- title=focused:key(),
-- informativeText=focused:title()
-- }):send()
-- print(string.format('Window [%s]', focused:key()))
-- print(string.format('Title: %s', focused:title()))
-- print(string.format('-- id: %s', focused:id()))
-- print(string.format('-- app: %s', focused:application():title()))
end
end
function filter_info(app_name)
app_filter = (app_group[app_name]
and wf.new{table.unpack(app_group[app_name])}
or wf.new{app_name})
print(app_name)
for i, v in ipairs(app_filter:getFilters()) do
print(string.format('filter: %s', v))
end
for i, v in ipairs(app_filter:getWindows()) do
print(string.format('win: %s', v:key()))
end
end
-- Create a unique string for a window
-- @returns string
function hs.window:key()
local app_name = compose(
getProperty("application"),
getProperty("title")
)(self)
return string.format("%s:%s", app_name, self:id())
end
-- Get the next safe index (start back at 1 if at end)
function get_next_index(_table, curr_index)
next_index = curr_index + 1
if next_index > #_table then
next_index = 1
end
return next_index
end
-- Get all window objects, regardless of space
function get_windows(app_name)
-- create a window filter based on app and return windows
app_filter = (appFilters[app_name] or wf.new{app_name})
-- app_filter = (app_group[app_name]
-- and wf.new{table.unpack(app_group[app_name])}
-- or wf.new{app_name})
return app_filter:getWindows()
end
-- Get the next window object
--
-- @param windows A table of window objects or an app name
-- @param last_window The last focused window (should be in windows)
-- @return The next window object
function get_next_window(windows, last_window)
-- make sure we actually have a table of window objects
if type(windows) == "string" then
windows = get_windows(windows)
end
-- check for only one option
-- > I think there is a hangup when there is only one window
if #windows == 1 then
return windows[1]
end
-- remove dialog boxes and minimized windows, etc.
windows = fnutils.filter(windows, hs.window.isStandard)
windows = fnutils.filter(windows, hs.window.isVisible)
-- check for only one option (again)
-- > I think there is a hangup when there is only one window
if #windows == 1 then
return windows[1]
end
-- sort by id (NOT key; descending)
table.sort(windows, function(w1, w2)
return w1:id() > w2:id()
end)
-- get index of last window
last_index = fnutils.indexOf(windows, last_window)
next_index = get_next_index(windows, last_index)
-- return the next window
return windows[next_index]
end
function hs.mouse.centerOnRect(rect)
hs.mouse.setAbsolutePosition(geometry.rectMidPoint(rect))
end
-- Launch app or go to next app window
function launch_or_cycle_focus(app_name)
return function()
-- ensure we have a focused window!
local focused_win = hs.window.focusedWindow()
if not focused_win then
alert('No active window')
return nil
end
-- get the name of the app for the focused window
local focused_app = focused_win:application():title()
-- if the focused window is from the desired app or group
local curr_app_is_desired = (app_group[app_name]
and fnutils.indexOf(app_group[app_name], focused_app))
or (focused_app == app_name)
if curr_app_is_desired then
-- find the next window within the desired app set
-- windows = (app_group[app_name]
-- and get_group_windows(app_name)
-- or app_name)
next_window = get_next_window(app_name, focused_win)
-- focus the window! (and become the main for next time)
next_window:becomeMain()
next_window:focus()
-- if app group, save the last used app group
if app_group[app_name] then
last_group_app[app_name] = next_window:application():title()
end
else
-- switching from different app
-- go to main (of last used)
last_used = last_group_app[app_name] or app_name
-- alert(string.format('not desired: %s (goto %s)', focused_app, last_used))
-- filter_info(app_name)
if last_used == 'iTerm2' then last_used = 'iTerm' end
hs.application.launchOrFocus(last_used)
end
frame = hs.window.focusedWindow():frame()
hs.mouse.centerOnRect(frame)
mouseHighlight()
end
end