-
Notifications
You must be signed in to change notification settings - Fork 166
Expand file tree
/
Copy pathinit.lua
More file actions
161 lines (142 loc) · 5.1 KB
/
init.lua
File metadata and controls
161 lines (142 loc) · 5.1 KB
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
--- === RoundedCorners ===
---
--- Give your screens rounded corners
---
--- Download: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/RoundedCorners.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/RoundedCorners.spoon.zip)
local obj = {}
obj.__index = obj
-- Metadata
obj.name = "RoundedCorners"
obj.version = "1.1"
obj.author = "Chris Jones <cmsj@tenshu.net>"
obj.homepage = "https://github.com/Hammerspoon/Spoons"
obj.license = "MIT - https://opensource.org/licenses/MIT"
obj.corners = {}
obj.topCorners = {}
obj.screenWatcher = nil
obj.spacesWatcher = nil
--- RoundedCorners.allScreens
--- Variable
--- Controls whether corners are drawn on all screens or just the primary screen. Defaults to true
obj.allScreens = true
--- RoundedCorners.radius
--- Variable
--- Controls the radius of the rounded corners, in points. Defaults to 12
obj.radius = 12
--- RoundedCorners.fullscreenOffset
--- Variable
--- Controls the offset of the top corners when in fullscreen, in points. Defaults to 0
--- Place just under the MenuBar in Tahoe: 33
obj.fullscreenOffset = 0
--- RoundedCorners.level
--- Variable
--- Controls which level of the screens the corners are drawn at. See `hs.canvas.windowLevels` for more information. Defaults to `screenSaver + 1`
obj.level = hs.canvas.windowLevels["screenSaver"] + 1
-- Internal function used to find our location, so we know where to load files from
local function script_path()
local str = debug.getinfo(2, "S").source:sub(2)
return str:match("(.*/)")
end
obj.spoonPath = script_path()
function obj:init()
self.screenWatcher = hs.screen.watcher.new(function() self:screensChanged() end)
self.spacesWatcher = hs.spaces.watcher.new(function() self:spacesChanged() end)
end
--- RoundedCorners:start()
--- Method
--- Starts RoundedCorners
---
--- Parameters:
--- * None
---
--- Returns:
--- * The RoundedCorners object
---
--- Notes:
--- * This will draw the rounded screen corners and start watching for changes in screen sizes/layouts, reacting accordingly
function obj:start()
self.screenWatcher:start()
self.spacesWatcher:start()
self:render()
return self
end
--- RoundedCorners:stop()
--- Method
--- Stops RoundedCorners
---
--- Parameters:
--- * None
---
--- Returns:
--- * The RoundedCorners object
---
--- Notes:
--- * This will remove all rounded screen corners and stop watching for changes in screen sizes/layouts
function obj:stop()
self.screenWatcher:stop()
self.spacesWatcher:stop()
self:deleteAllCorners()
return self
end
-- Delete only the dynamic top corners
function obj:deleteTopCorners()
hs.fnutils.each(self.topCorners, function(corner) corner:delete() end)
self.topCorners = {}
end
-- React to the spaces having changed
function obj:spacesChanged()
self:deleteTopCorners()
self:render(true)
end
-- Delete all the corners
function obj:deleteAllCorners()
self:deleteTopCorners()
hs.fnutils.each(self.corners, function(corner) corner:delete() end)
self.corners = {}
end
-- React to the screens having changed
function obj:screensChanged()
self:deleteAllCorners()
self:render()
end
-- Get the screens to draw on, given the user's settings
function obj:getScreens()
if self.allScreens then
return hs.screen.allScreens()
else
return {hs.screen.primaryScreen()}
end
end
-- Draw a single corner
function obj:draw(data, radius, offset, behavior)
return hs.canvas.new({x=data.frame.x,y=data.frame.y+offset,w=radius,h=radius}):appendElements(
{ action="build", type="rectangle", },
{ action="clip", type="circle", center=data.center, radius=radius, reversePath=true, },
{ action="fill", type="rectangle", frame={x=0, y=0, w=radius, h=radius, }, fillColor={ alpha=1, }},
{ type="resetClip", }
):behavior({hs.canvas.windowBehaviors.stationary, behavior}):level(self.level):show()
end
-- Draw the corners
function obj:render(topOnly)
local radius = self.radius
local mission = hs.spaces.focusedSpace() == 1
hs.fnutils.each(self:getScreens(), function(screen)
local windows = hs.window.filter.new():setScreens(screen:id()):getWindows()
local offset = not mission and screen:id() == 1 and #windows > 0 and windows[1]:isFullscreen() and self.fullscreenOffset or 0
local screenFrame = screen:fullFrame()
local cornerData = {
{ frame={x=screenFrame.x, y=screenFrame.y}, center={x=radius,y=radius} },
{ frame={x=screenFrame.x + screenFrame.w - radius, y=screenFrame.y}, center={x=0,y=radius} },
{ frame={x=screenFrame.x, y=screenFrame.y + screenFrame.h - radius}, center={x=radius,y=0} },
{ frame={x=screenFrame.x + screenFrame.w - radius, y=screenFrame.y + screenFrame.h - radius}, center={x=0,y=0} },
}
for i, data in pairs(cornerData) do
if (offset > 0 and i < 3) then
self.topCorners[#self.topCorners+1] = obj:draw(data, radius, offset)
elseif (not topOnly) then
self.corners[#self.corners+1] = obj:draw(data, radius, 0, hs.canvas.windowBehaviors.canJoinAllSpaces)
end
end
end)
end
return obj