Actualizacion maquina principal
[dotfiles/.git] / .config / awesome / lain / util / quake.lua
1 --[[
2
3      Licensed under GNU General Public License v2
4       * (c) 2016, Luca CPZ
5       * (c) 2015, unknown
6
7 --]]
8
9 local awful        = require("awful")
10 local capi         = { client = client }
11 local math         = math
12 local string       = string
13 local pairs        = pairs
14 local screen       = screen
15 local setmetatable = setmetatable
16
17 -- Quake-like Dropdown application spawn
18 local quake = {}
19
20 -- If you have a rule like "awful.client.setslave" for your terminals,
21 -- ensure you use an exception for QuakeDD. Otherwise, you may
22 -- run into problems with focus.
23
24 function quake:display()
25     if self.followtag then self.screen = awful.screen.focused() end
26
27     -- First, we locate the client
28     local client = nil
29     local i = 0
30     for c in awful.client.iterate(function (c)
31         -- c.name may be changed!
32         return c.instance == self.name
33     end)
34     do
35         i = i + 1
36         if i == 1 then
37             client = c
38         else
39             -- Additional matching clients, let's remove the sticky bit
40             -- which may persist between awesome restarts. We don't close
41             -- them as they may be valuable. They will just turn into
42             -- normal clients.
43             c.sticky = false
44             c.ontop = false
45             c.above = false
46         end
47     end
48
49     if not client and not self.visible then return end
50
51     if not client then
52         -- The client does not exist, we spawn it
53         cmd = string.format("%s %s %s", self.app,
54               string.format(self.argname, self.name), self.extra)
55         awful.spawn(cmd, { tag = self.screen.selected_tag })
56         return
57     end
58
59     -- Set geometry
60     client.floating = true
61     client.border_width = self.border
62     client.size_hints_honor = false
63     client:geometry(self.geometry[self.screen.index] or self:compute_size())
64
65     -- Set not sticky and on top
66     client.sticky = false
67     client.ontop = true
68     client.above = true
69     client.skip_taskbar = true
70
71     -- Additional user settings
72     if self.settings then self.settings(client) end
73
74     -- Toggle display
75     if self.visible then
76         client.hidden = false
77         client:raise()
78         self.last_tag = self.screen.selected_tag
79         client:tags({self.screen.selected_tag})
80         capi.client.focus = client
81    else
82         client.hidden = true
83         local ctags = client:tags()
84         for i, t in pairs(ctags) do
85             ctags[i] = nil
86         end
87         client:tags(ctags)
88     end
89
90     return client
91 end
92
93 function quake:compute_size()
94     -- skip if we already have a geometry for this screen
95     if not self.geometry[self.screen.index] then
96         local geom
97         if not self.overlap then
98             geom = screen[self.screen.index].workarea
99         else
100             geom = screen[self.screen.index].geometry
101         end
102         local width, height = self.width, self.height
103         if width  <= 1 then width = math.floor(geom.width * width) - 2 * self.border end
104         if height <= 1 then height = math.floor(geom.height * height) end
105         local x, y
106         if     self.horiz == "left"  then x = geom.x
107         elseif self.horiz == "right" then x = geom.width + geom.x - width
108         else   x = geom.x + (geom.width - width)/2 end
109         if     self.vert == "top"    then y = geom.y
110         elseif self.vert == "bottom" then y = geom.height + geom.y - height
111         else   y = geom.y + (geom.height - height)/2 end
112         self.geometry[self.screen.index] = { x = x, y = y, width = width, height = height }
113     end
114     return self.geometry[self.screen.index]
115 end
116
117 function quake:new(config)
118     local conf = config or {}
119
120     conf.app        = conf.app       or "xterm"    -- application to spawn
121     conf.name       = conf.name      or "QuakeDD"  -- window name
122     conf.argname    = conf.argname   or "-name %s" -- how to specify window name
123     conf.extra      = conf.extra     or ""         -- extra arguments
124     conf.border     = conf.border    or 1          -- client border width
125     conf.visible    = conf.visible   or false      -- initially not visible
126     conf.followtag  = conf.followtag or false      -- spawn on currently focused screen
127     conf.overlap    = conf.overlap   or false      -- overlap wibox
128     conf.screen     = conf.screen    or awful.screen.focused()
129     conf.settings   = conf.settings
130
131     -- If width or height <= 1 this is a proportion of the workspace
132     conf.height     = conf.height    or 0.25       -- height
133     conf.width      = conf.width     or 1          -- width
134     conf.vert       = conf.vert      or "top"      -- top, bottom or center
135     conf.horiz      = conf.horiz     or "left"     -- left, right or center
136     conf.geometry   = {}                           -- internal use
137
138     local dropdown = setmetatable(conf, { __index = quake })
139
140     capi.client.connect_signal("manage", function(c)
141         if c.instance == dropdown.name and c.screen == dropdown.screen then
142             dropdown:display()
143         end
144     end)
145     capi.client.connect_signal("unmanage", function(c)
146         if c.instance == dropdown.name and c.screen == dropdown.screen then
147             dropdown.visible = false
148         end
149      end)
150
151     return dropdown
152 end
153
154 function quake:toggle()
155      if self.followtag then self.screen = awful.screen.focused() end
156      local current_tag = self.screen.selected_tag
157      if current_tag and self.last_tag ~= current_tag and self.visible then
158          local c=self:display()
159          if c then
160             c:move_to_tag(current_tag)
161         end
162      else
163          self.visible = not self.visible
164          self:display()
165      end
166 end
167
168 return setmetatable(quake, { __call = function(_, ...) return quake:new(...) end })