Fallback to comparing layout names in awful.layout.inc
[awesome.git] / lib / awful / layout / init.lua.in
blobbd9de0d47f957060d7aba941722da57d13d1de3b
1 ---------------------------------------------------------------------------
2 -- @author Julien Danjou <julien@danjou.info>
3 -- @copyright 2008 Julien Danjou
4 -- @release @AWESOME_VERSION@
5 ---------------------------------------------------------------------------
7 -- Grab environment we need
8 local ipairs = ipairs
9 local type = type
10 local tag = require("awful.tag")
11 local util = require("awful.util")
12 local ascreen = require("awful.screen")
13 local capi = {
14 screen = screen,
15 awesome = awesome,
16 client = client
18 local client = require("awful.client")
20 --- Layout module for awful
21 -- awful.layout
22 local layout = {}
23 layout.suit = require("awful.layout.suit")
25 -- This is a special lock used by the arrange function.
26 -- This avoids recurring call by emitted signals.
27 local arrange_lock = false
29 --- Get the current layout.
30 -- @param screen The screen number.
31 -- @return The layout function.
32 function layout.get(screen)
33 local t = tag.selected(screen)
34 return tag.getproperty(t, "layout") or layout.suit.floating
35 end
37 --- Change the layout of the current tag.
38 -- @param layouts A table of layouts.
39 -- @param i Relative index.
40 -- @param s The screen number.
41 function layout.inc(layouts, i, s)
42 local t = tag.selected(s)
43 if t then
44 local curlayout = layout.get(s)
45 local curindex
46 for k, v in ipairs(layouts) do
47 if v == curlayout then
48 curindex = k
49 break
50 end
51 end
52 if not curindex then
53 -- Safety net: handle cases where another reference of the layout
54 -- might be given (e.g. when (accidentally) cloning it).
55 for k, v in ipairs(layouts) do
56 if v.name == curlayout.name then
57 curindex = k
58 break
59 end
60 end
61 end
62 if curindex then
63 local newindex = util.cycle(#layouts, curindex + i)
64 layout.set(layouts[newindex], t)
65 end
66 end
67 end
69 --- Set the layout function of the current tag.
70 -- @param _layout Layout name.
71 -- @param t The tag to modify, if null tag.selected() is used.
72 function layout.set(_layout, t)
73 t = t or tag.selected()
74 tag.setproperty(t, "layout", _layout)
75 end
77 --- Arrange a screen using its current layout.
78 -- @param screen The screen to arrange.
79 function layout.arrange(screen)
80 if arrange_lock then return end
81 arrange_lock = true
82 local p = {}
83 p.workarea = capi.screen[screen].workarea
84 -- Handle padding
85 local padding = ascreen.padding(capi.screen[screen])
86 if padding then
87 p.workarea.x = p.workarea.x + (padding.left or 0)
88 p.workarea.y = p.workarea.y + (padding.top or 0)
89 p.workarea.width = p.workarea.width - ((padding.left or 0 ) + (padding.right or 0))
90 p.workarea.height = p.workarea.height - ((padding.top or 0) + (padding.bottom or 0))
91 end
92 p.geometry = capi.screen[screen].geometry
93 p.clients = client.tiled(screen)
94 p.screen = screen
95 layout.get(screen).arrange(p)
96 capi.screen[screen]:emit_signal("arrange")
97 arrange_lock = false
98 end
100 --- Get the current layout name.
101 -- @param layout The layout.
102 -- @return The layout name.
103 function layout.getname(_layout)
104 local _layout = _layout or layout.get()
105 return _layout.name
108 local function arrange_prop(obj) layout.arrange(obj.screen) end
110 capi.client.connect_signal("property::size_hints_honor", arrange_prop)
111 capi.client.connect_signal("property::struts", arrange_prop)
112 capi.client.connect_signal("property::minimized", arrange_prop)
113 capi.client.connect_signal("property::sticky", arrange_prop)
114 capi.client.connect_signal("property::fullscreen", arrange_prop)
115 capi.client.connect_signal("property::maximized_horizontal", arrange_prop)
116 capi.client.connect_signal("property::maximized_vertical", arrange_prop)
117 capi.client.connect_signal("property::border_width", arrange_prop)
118 capi.client.connect_signal("property::hidden", arrange_prop)
119 capi.client.connect_signal("property::floating", arrange_prop)
120 capi.client.connect_signal("property::geometry", arrange_prop)
121 -- If prop is screen, we do not know what was the previous screen, so
122 -- let's arrange all screens :-(
123 capi.client.connect_signal("property::screen", function(c)
124 for screen = 1, capi.screen.count() do layout.arrange(screen) end end)
126 local function arrange_on_tagged(c, tag)
127 if not tag.screen then return end
128 layout.arrange(tag.screen)
129 if not capi.client.focus or not capi.client.focus:isvisible() then
130 local c = client.focus.history.get(tag.screen, 0)
131 if c then capi.client.focus = c end
134 local function arrange_tag(t)
135 layout.arrange(tag.getscreen(t))
138 for s = 1, capi.screen.count() do
139 capi.screen[s]:add_signal("arrange")
141 tag.attached_connect_signal(s, "property::mwfact", arrange_tag)
142 tag.attached_connect_signal(s, "property::nmaster", arrange_tag)
143 tag.attached_connect_signal(s, "property::ncol", arrange_tag)
144 tag.attached_connect_signal(s, "property::layout", arrange_tag)
145 tag.attached_connect_signal(s, "property::windowfact", arrange_tag)
146 tag.attached_connect_signal(s, "property::selected", arrange_tag)
147 tag.attached_connect_signal(s, "property::activated", arrange_tag)
148 tag.attached_connect_signal(s, "tagged", arrange_tag)
149 capi.screen[s]:connect_signal("property::workarea", function(screen)
150 layout.arrange(screen.index)
151 end)
152 capi.screen[s]:connect_signal("padding", function (screen)
153 layout.arrange(screen.index)
154 end)
157 capi.client.connect_signal("focus", function(c) layout.arrange(c.screen) end)
158 capi.client.connect_signal("list", function()
159 for screen = 1, capi.screen.count() do
160 layout.arrange(screen)
162 end)
164 return layout
166 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80