-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquake.lua
168 lines (143 loc) · 5.04 KB
/
quake.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
-- Quake like console on top
-- Similar to:
-- http://git.sysphere.org/awesome-configs/tree/scratch/drop.lua
-- But uses a different implementation. The main difference is that we
-- are able to detect the Quake console from its name
-- (QuakeConsoleNeedsUniqueName by default).
-- Use:
-- local quake = require("quake")
-- local quakeconsole = {}
-- for s = 1, screen.count() do
-- quakeconsole[s] = quake({ terminal = config.terminal,
-- height = 0.3,
-- screen = s })
-- end
-- config.keys.global = awful.util.table.join(
-- config.keys.global,
-- awful.key({ modkey }, "`",
-- function () quakeconsole[mouse.screen]:toggle() end)
-- If you have a rule like "awful.client.setslave" for your terminals,
-- ensure you use an exception for
-- QuakeConsoleNeedsUniqueName. Otherwise, you may run into problems
-- with focus.
local setmetatable = setmetatable
local string = string
local awful = require("awful")
local capi = { mouse = mouse,
screen = screen,
client = client,
timer = timer }
-- I use a namespace for my modules...
module("quake")
local QuakeConsole = {}
-- Display
function QuakeConsole:display()
-- First, we locate the terminal
local client = nil
local i = 0
for c in awful.client.iterate(
function (c)
-- c.name may be changed!
return c.instance == self.name
end,
nil, self.screen) do
i = i + 1
if i == 1 then
client = c
else
-- Additional matching clients, let's remove the sticky bit
-- which may persist between awesome restarts. We don't close
-- them as they may be valuable. They will just turn into a
-- classic terminal.
c.sticky = false
c.ontop = false
c.above = false
end
end
if not client and not self.visible then
-- The terminal is not here yet but we don't want it yet. Just do nothing.
return
end
if not client then
-- The client does not exist, we spawn it
awful.util.spawn(self.terminal .. " " .. string.format(self.argname, self.name), false, self.screen)
return
end
-- Comptute size
local geom = capi.screen[self.screen].workarea
local width, height = self.width, self.height
if width <= 1 then width = geom.width * width end
if height <= 1 then height = geom.height * height end
local x, y
if self.horiz == "left" then x = geom.x
elseif self.horiz == "right" then x = geom.width + geom.x - width
else x = geom.x + (geom.width - width)/2 end
if self.vert == "top" then y = geom.y
elseif self.vert == "bottom" then y = geom.height + geom.y - height
else y = geom.y + (geom.height - height)/2 end
-- Resize
awful.client.floating.set(client, true)
client.border_width = 0
client.size_hints_honor = false
client:geometry({ x = x, y = y, width = width, height = height })
-- Sticky and on top
client.ontop = true
client.above = true
client.skip_taskbar = true
client.sticky = true
-- This is not a normal window, don't apply any specific keyboard stuff
client:buttons({})
client:keys({})
-- Toggle display
if self.visible then
client.hidden = false
client:raise()
capi.client.focus = client
else
client.hidden = true
end
end
-- Create a console
function QuakeConsole:new(config)
-- The "console" object is just its configuration.
-- The application to be invoked is:
-- config.terminal .. " " .. string.format(config.argname, config.name)
config.terminal = config.terminal or "xterm" -- application to spawn
config.name = config.name or "QuakeConsoleNeedsUniqueName" -- window name
config.argname = config.argname or "-name %s" -- how to specify window name
-- If width or height <= 1 this is a proportion of the workspace
config.height = config.height or 0.25 -- height
config.width = config.width or 1 -- width
config.vert = config.vert or "top" -- top, bottom or center
config.horiz = config.horiz or "center" -- left, right or center
config.screen = config.screen or capi.mouse.screen
config.visible = config.visible or false -- Initially, not visible
local console = setmetatable(config, { __index = QuakeConsole })
capi.client.connect_signal("manage",
function(c)
if c.instance == console.name and c.screen == console.screen then
console:display()
end
end)
capi.client.connect_signal("unmanage",
function(c)
if c.instance == console.name and c.screen == console.screen then
console.visible = false
end
end)
-- "Reattach" currently running QuakeConsole. This is in case awesome is restarted.
local reattach = capi.timer { timeout = 0 }
reattach:connect_signal("timeout",
function()
reattach:stop()
console:display()
end)
reattach:start()
return console
end
-- Toggle the console
function QuakeConsole:toggle()
self.visible = not self.visible
self:display()
end
setmetatable(_M, { __call = function(_, ...) return QuakeConsole:new(...) end })