Added LUADoc. Here is the patch.
(Thu, Jan 22, 2009 at 04:00:46PM +0100) Julien Danjou <[email protected]>: > Hi Donald, > > I've take some time to review your patch finally. > > At 1232587540 time_t, Donald Ephraim Curtis wrote: > > +local function normalize(set, max) > > + total = 0 > > Please declare your variable as local. :) > > > +-- Calculate which {index, column} the client belongs to given the index > > If the function is meant to be exported, proper luadoc formatted > documentation is very welcome. > But well I'm not sure we want to export this one. > > > +function idx(c) > > + local c = c or capi.client.focus > > It misses: > if not c then return end > > which would avoid errors for people pressing a wrong key. ;) > > > +-- Set the window by index (or the currently selected window) > > luadoc also, otherwise people won't heard of it. > > > +function setwfact(wfact, c) > > + -- get the currently selected window > > + local c = c or capi.client.focus > > if not c then return end > :) > > > +-- Change the width factor of a window (indexed by number) > > luadoc ;) > > > Cheers, > -- > Julien Danjou > // ᐰ <[email protected]> http://julien.danjou.info > // 9A0D 5FD9 EB42 22F6 8974 C95C A462 B51E C2FE E5CD
From 5e6f355ca126f38e80e780e47ae042a6c12452ee Mon Sep 17 00:00:00 2001 From: [email protected] <[email protected]> Date: Tue, 13 Jan 2009 13:31:37 -0600 Subject: [PATCH] vile is a Variable tILE layout that allows the user to select a single client window and resize that in it's layout. This means that the slave windows do not necissarily need to be the same size all the time. Fixed the bug where having only master or other windows would not display full screen. Added mouse resizing to the layout. Updated vile to incorporate the style used by adaptile. Merged the vile layout with the adaptile layout and fixed mouse support. Fixed bug when closing the final window. pass screen when looking for tag selected. Fixed bug with nil values. Added mouse warping. Added LUADoc --- lib/awful/client.lua.in | 138 +++++++++++++++++++++++++++++ lib/awful/layout/init.lua.in | 4 + lib/awful/layout/suit/init.lua.in | 1 + lib/awful/layout/suit/vile.lua.in | 177 +++++++++++++++++++++++++++++++++++++ lib/awful/mouse.lua.in | 100 +++++++++++++++++++++ 5 files changed, 420 insertions(+), 0 deletions(-) create mode 100644 lib/awful/layout/suit/vile.lua.in diff --git a/lib/awful/client.lua.in b/lib/awful/client.lua.in index 65103a8..ae79462 100644 --- a/lib/awful/client.lua.in +++ b/lib/awful/client.lua.in @@ -593,6 +593,144 @@ function floating.delete(c) data.floating[c] = nil end +--- Normalize a set of numbers to 1 +-- @param set the set of numbers to normalize +-- @param num the number of numbers to normalize +local function normalize(set, num) + local num = num or #set + local total = 0 + if num then + for i = 1,num do + total = total + set[i] + end + for i = 1,num do + set[i] = set[i] / total + end + else + for i,v in ipairs(set) do + total = total + v + end + + for i,v in ipairs(set) do + set[i] = v / total + end + end +end + +--- Calculate a client's column number, index in that column, and +-- number of visible clients in this column. +-- @param c the client +-- @return col the column number +-- @return idx index of the client in the column +-- @return num the number of visible clients in the column +local function idx(c) + local c = c or capi.client.focus + if not c then return end + + local clients = tiled(c.screen) + local idx = nil + for k, cl in ipairs(clients) do + if cl == c then + idx = k + break + end + end + + local nmaster = tag.getnmaster(t) + if idx <= nmaster then + return {idx = idx, col=0, num=nmaster} + end + local nother = #clients - nmaster + idx = idx - nmaster + + -- rather than regenerate the column number we can calculate it + -- based on the how the tiling algorithm places clients we calculate + -- the column, we could easily use the for loop in the program but we can + -- calculate it. + local ncol = tag.getncol(t) + -- minimum number of clients per column + local percol = math.floor(nother / ncol) + -- number of columns with an extra client + local overcol = math.mod(nother, ncol) + -- number of columns filled with [percol] clients + local regcol = ncol - overcol + + local col = math.floor( (idx - 1) / percol) + 1 + if col > regcol then + -- col = math.floor( (idx - (percol*regcol) - 1) / (percol + 1) ) + regcol + 1 + -- simplified + col = math.floor( (idx + regcol + percol) / (percol+1) ) + -- calculate the index in the column + idx = idx - percol*regcol - (col - regcol - 1) * (percol+1) + percol = percol+1 + else + idx = idx - percol*(col-1) + end + + return {idx = idx, col=col, num=percol} +end + + +--- Set the window factor of a client +-- @param wfact the window factor value +-- @param c the client +function setwfact(wfact, c) + -- get the currently selected window + local c = c or capi.client.focus + if not c then return end + + local t = tag.selected(c.screen) + local w = idx(c) + + local cls = tiled(t.screen) + local nmaster = tag.getnmaster(t) + + -- n is the number of windows currently visible for which we have to be concerned with the properties + local data = tag.getproperty(t, "windowfact") or {} + local colfact = data[w.col] + + colfact[w.idx] = wfact + rest = 1-wfact + + -- calculate the current denominator + local total = 0 + for i = 1,w.num do + if i ~= w.idx then + total = total + colfact[i] + end + end + + -- normalize the windows + for i = 1,w.num do + if i ~= w.idx then + colfact[i] = (colfact[i] * rest) / total + end + end +end + +--- Increment a client's window factor +-- @param add amount to increase the client's window +-- @param c the client +function incwfact(add, c) + local c = c or capi.client.focus + if not c then return end + + local t = tag.selected(c.screen) + + local w = idx(c) + + local nmaster = tag.getnmaster(t) + local data = tag.getproperty(t, "windowfact") or {} + local colfact = data[w.col] + curr = colfact[w.idx] or 1 + colfact[w.idx] = curr + add + + -- keep our ratios normalized + normalize(colfact, w.num) + capi.hooks.arrange()(t.screen) +end + + -- Register standards hooks hooks.focus.register(focus.history.add) hooks.unmanage.register(focus.history.delete) diff --git a/lib/awful/layout/init.lua.in b/lib/awful/layout/init.lua.in index bf45763..c4b7fd9 100644 --- a/lib/awful/layout/init.lua.in +++ b/lib/awful/layout/init.lua.in @@ -70,6 +70,10 @@ local layouts_name = [suit.tile.left] = "tileleft", [suit.tile.bottom] = "tilebottom", [suit.tile.top] = "tiletop", + [suit.vile] = "vile", + [suit.vile.left] = "vileleft", + [suit.vile.bottom] = "vilebottom", + [suit.vile.top] = "viletop", [suit.fair] = "fairv", [suit.fair.horizontal] = "fairh", [suit.max] = "max", diff --git a/lib/awful/layout/suit/init.lua.in b/lib/awful/layout/suit/init.lua.in index ae83edf..8c57bf7 100644 --- a/lib/awful/layout/suit/init.lua.in +++ b/lib/awful/layout/suit/init.lua.in @@ -1,5 +1,6 @@ require("awful.layout.suit.max") require("awful.layout.suit.tile") +require("awful.layout.suit.vile") require("awful.layout.suit.fair") require("awful.layout.suit.floating") require("awful.layout.suit.magnifier") diff --git a/lib/awful/layout/suit/vile.lua.in b/lib/awful/layout/suit/vile.lua.in new file mode 100644 index 0000000..e3f1e5c --- /dev/null +++ b/lib/awful/layout/suit/vile.lua.in @@ -0,0 +1,177 @@ +--------------------------------------------------------------------------- +-- @author Donald Ephraim Curtis <[email protected]> +-- @author Julien Danjou <[email protected]> +-- @copyright 2009 Donald Ephraim Curtis +-- @copyright 2008 Julien Danjou +-- @release @AWESOME_VERSION@ +--------------------------------------------------------------------------- + +-- Grab environment we need +local setmetatable = setmetatable +local ipairs = ipairs +local math = math +local client = require("awful.client") +local tag = require("awful.tag") +local capi = +{ + screen = screen +} + +--- Tiled layouts module for awful +module("awful.layout.suit.vile") + +local function tile_group(cls, wa, orientation, fact, group) + -- get our orientation right + local height = "height" + local width = "width" + local x = "x" + local y = "y" + if orientation == "top" or orientation == "bottom" then + height = "width" + width = "height" + x = "y" + y = "x" + end + + -- make this more generic (not just width) + available = wa[width] - (group.coord - wa[x]) + + -- find our total values + local total_fact = 0 + local min_fact = 1 + local size = group.size + for c = group.first,group.last do + -- determine the width/height based on the size_hint + local i = c - group.first +1 + local size_hints = cls[c].size_hints + local size_hint = size_hints["min_"..width] or size_hints["base_"..width] or 0 + size_hint = size_hint + cls[c].border_width*2 + size = math.max(size_hint, size) + + -- calculate the height + if not fact[i] then + fact[i] = min_fact + else + min_fact = math.min(fact[i],min_fact) + end + total_fact = total_fact + fact[i] + end + size = math.min(size, available) + + local coord = wa[y] + local geom = {} + local used_size = 0 + local unused = wa[height] + for c = group.first,group.last do + local i = c - group.first +1 + geom[width] = size + geom[height] = math.floor(unused * fact[i] / total_fact) + geom[x] = group.coord + geom[y] = coord + geom = cls[c]:geometry(geom) + coord = coord + geom[height] + unused = unused - geom[height] + total_fact = total_fact - fact[i] + used_size = math.max(used_size, geom[width]) + end + + return used_size + +end + +local function vile(_, screen, orientation) + orientation = orientation or "right" + + -- this handles are different orientations + local height = "height" + local width = "width" + local x = "x" + local y = "y" + if orientation == "top" or orientation == "bottom" then + height = "width" + width = "height" + x = "y" + y = "x" + end + + local t = tag.selected(screen) + local cls = client.tiled(screen) + local nmaster = math.min(tag.getnmaster(t), #cls) + local nother = math.max(#cls - nmaster,0) + + local mwfact = tag.getmwfact(t) + local wa = capi.screen[screen].workarea + local ncol = tag.getncol(t) + + local data = tag.getproperty(t,"windowfact") + + if not data then + data = {} + tag.setproperty(t,"windowfact", data) + end + + -- + local coord = wa[x] + local place_master = true + if orientation == "left" or orientation == "top" then + -- if we are on the left or top we need to render the other windows first + place_master = false + end + + -- this was easier than writing functions because there is a lot of data we need + for d = 1,2 do + if place_master and nmaster > 0 then + local size = wa[width] + if nother > 0 then + size = math.min(wa[width] * mwfact, wa[width] - (coord - wa[x])) + end + if not data[0] then + data[0] = {} + end + coord = coord + tile_group(cls, wa, orientation, data[0], {first=1, last=nmaster, coord = coord, size = size}) + end + + if not place_master and nother > 0 then + local last = nmaster + + -- we have to modify the work area size to consider left and top views + local wasize = wa[width] + if nmaster > 0 and (orientation == "left" or orientation == "top") then + wasize = wa[width] - wa[width]*mwfact + end + for i = 1,ncol do + -- Try to get equal width among remaining columns + local size = math.min( (wasize - (coord - wa[x])) / (ncol - i + 1) ) + local first = last + 1 + last = last + math.floor((#cls - last)/(ncol - i + 1)) + -- tile the column and update our current x coordinate + if not data[i] then + data[i] = {} + end + coord = coord + tile_group(cls, wa, orientation, data[i], { first = first, last = last, coord = coord, size = size }) + end + end + place_master = not place_master + end + +end + +--- The main tile algo, on left. +-- @param screen The screen number to tile. +function left(screen) + return vile(nil, screen, "left") +end + +--- The main tile algo, on bottom. +-- @param screen The screen number to tile. +function bottom(screen) + return vile(nil, screen, "bottom") +end + +--- The main tile algo, on top. +-- @param screen The screen number to tile. +function top(screen) + return vile(nil, screen, "top") +end + +setmetatable(_M, { __call = vile }) diff --git a/lib/awful/mouse.lua.in b/lib/awful/mouse.lua.in index 4390506..29d2f8d 100644 --- a/lib/awful/mouse.lua.in +++ b/lib/awful/mouse.lua.in @@ -392,6 +392,100 @@ local function client_resize_tiled(c, lay) end, cursor) end +local function client_resize_viled(c, lay) + local wa = capi.screen[c.screen].workarea + local mwfact = tag.getmwfact() + local cursor + local g = c:geometry() + local offset = 0 + local x,y + if lay == layout.suit.vile then + cursor = "cross" + if g.height+15 > wa.height then + offset = g.height * .5 + cursor = "sb_h_double_arrow" + elseif not (g.y+g.height+15 > wa.y+wa.height) then + offset = g.height + end + capi.mouse.coords({ x = wa.x + wa.width * mwfact, y = g.y + offset }) + elseif lay == layout.suit.vile.left then + cursor = "cross" + if g.height+15 >= wa.height then + offset = g.height * .5 + cursor = "sb_h_double_arrow" + elseif not (g.y+g.height+15 > wa.y+wa.height) then + offset = g.height + end + capi.mouse.coords({ x = wa.x + wa.width * (1 - mwfact), y = g.y + offset }) + elseif lay == layout.suit.vile.bottom then + cursor = "cross" + if g.width+15 >= wa.width then + offset = g.width * .5 + cursor = "sb_v_double_arrow" + elseif not (g.x+g.width+15 > wa.x+wa.width) then + offset = g.width + end + capi.mouse.coords({ y = wa.y + wa.height * mwfact, x = g.x + offset}) + else + cursor = "cross" + if g.width+15 >= wa.width then + offset = g.width * .5 + cursor = "sb_v_double_arrow" + elseif not (g.x+g.width+15 > wa.x+wa.width) then + offset = g.width + end + capi.mouse.coords({ y = wa.y + wa.height * (1 - mwfact), x= g.x + offset }) + end + + capi.mousegrabber.run(function (mouse) + for k, v in ipairs(mouse.buttons) do + if v then + local fact_x = (mouse.x - wa.x) / wa.width + local fact_y = (mouse.y - wa.y) / wa.height + local mwfact + + local g = c:geometry() + + + -- we have to make sure we're not on the last visible client where we have to use different settings. + local wfact + local wfact_x, wfact_y + if (g.y+g.height+15) > (wa.y+wa.height) then + wfact_y = (g.y + g.height - mouse.y) / wa.height + else + wfact_y = (mouse.y - g.y) / wa.height + end + + if (g.x+g.width+15) > (wa.x+wa.width) then + wfact_x = (g.x + g.width - mouse.x) / wa.width + else + wfact_x = (mouse.x - g.x) / wa.width + end + + + if lay == layout.suit.vile then + mwfact = fact_x + wfact = wfact_y + elseif lay == layout.suit.vile.left then + mwfact = 1 - fact_x + wfact = wfact_y + elseif lay == layout.suit.vile.bottom then + mwfact = fact_y + wfact = wfact_x + else + mwfact = 1 - fact_y + wfact = wfact_x + end + + tag.setmwfact(math.min(math.max(mwfact, 0.01), 0.99), tag.selected(c.screen)) + aclient.setwfact(math.min(math.max(wfact,0.01), 0.99), c) + return true + end + end + return false + end, cursor) +end + local function client_resize_floating(c, corner, fixed_x, fixed_y) local corner, x, y = client.corner(c, corner) local g = c:geometry() @@ -483,6 +577,12 @@ function client.resize(c, corner) or lay == layout.suit.tile.top or lay == layout.suit.tile.bottom then return client_resize_tiled(c, lay) + elseif lay == layout.suit.vile + or lay == layout.suit.vile.left + or lay == layout.suit.vile.top + or lay == layout.suit.vile.bottom + then + return client_resize_viled(c, lay) elseif lay == layout.suit.magnifier then return client_resize_magnifier(c, corner) end -- 1.6.1
pgpKSRPiN0Vzl.pgp
Description: PGP signature
