]> git.decadent.org.uk Git - ion3.git/blob - ioncore/ioncore_winprops.lua
b74ed63c0dda546717ed0d54a3473834f710b3ce
[ion3.git] / ioncore / ioncore_winprops.lua
1 --
2 -- ion/share/ioncore_winprops.lua
3 -- 
4 -- Copyright (c) Tuomo Valkonen 2004-2008.
5 --
6 -- See the included file LICENSE for details.
7 --
8
9 local ioncore=_G.ioncore
10
11 local winprops={}
12
13 local function ifnil(...)
14     local arg={...}
15     local n=#arg
16     local function nxt(_, i)
17         local j=i+1
18         if i==n then
19             return nil
20         else
21             local j=i+1
22             if not arg[j] then
23                 return nxt(nil, j)
24             else
25                 return j, arg[j]
26             end
27         end
28     end
29             
30     return nxt, nil, 0
31 end
32
33 local function ipairs_r(tab)
34     local function nxt(_, n)
35         if n==1 then
36             return nil
37         else
38             return n-1, tab[n-1]
39         end
40     end
41     return nxt, nil, #tab+1
42 end
43
44 --DOC
45 -- Find winprop table for \var{cwin}.
46 function ioncore.getwinprop(cwin)
47     local id=cwin:get_ident()
48     local props, prop
49
50     for _, c in ifnil(id.class, "*") do
51         for _, r in ifnil(id.role, "*") do
52             for _, i in ifnil(id.instance, "*") do
53                 --printpp(c, r, i)
54                 props={}
55                 pcall(function() props=winprops[c][r][i] or {} end)
56                 for idx, prop in ipairs_r(props) do
57                     if prop:match(cwin, id) then
58                         if prop.oneshot then
59                             table.remove(props, idx)
60                         end
61                         return prop
62                     end
63                 end
64             end
65         end
66     end
67 end
68
69 ioncore.set{_get_winprop=ioncore.getwinprop}
70
71 local function ensure_winproptab(class, role, instance)
72     if not winprops[class] then
73         winprops[class]={}
74     end
75     if not winprops[class][role] then
76         winprops[class][role]={}
77     end
78     if not winprops[class][role][instance] then
79         winprops[class][role][instance]={}
80     end
81 end    
82
83 local function do_add_winprop(class, role, instance, prop)
84     ensure_winproptab(class, role, instance)
85     table.insert(winprops[class][role][instance], prop)
86 end
87
88
89 --DOC
90 -- The basic name-based winprop matching criteria.
91 function ioncore.match_winprop_dflt(prop, cwin, id)
92     local function chkf(p, i)
93         if p==nil then
94             return true
95         else
96             return (p==(i and true or false)) 
97                            -- hack for nil i
98         end
99     end
100     
101     if not chkf(prop.is_transient, id.is_transient) then
102         return false
103     end
104     
105     if not chkf(prop.is_dockapp, id.is_dockapp) then
106         return false
107     end
108     
109     if prop.name then
110         local nm=cwin:name()
111         if nm then
112             local st, en=string.find(nm, prop.name)
113             return (st and en)
114         else
115             return false
116         end
117     end
118     
119     return true
120 end
121
122
123 --DOC
124 -- Define a winprop. For more information, see section \ref{sec:winprops}.
125 function ioncore.defwinprop(list)
126     local list2 = {}
127     local class, role, instance = "*", "*", "*"
128     
129     for k, v in pairs(list) do
130         if k == "class" then
131             class = v
132         elseif k == "role" then
133             role = v
134         elseif k == "instance" then
135             instance = v
136         end
137         list2[k] = v
138     end
139     
140     if not list2.match then
141         list2.match=ioncore.match_winprop_dflt
142     end
143     
144     do_add_winprop(class, role, instance, list2)
145 end
146