Think I fixed all the bugs reported, except mouse warping. New patch attached
-- Donald (Mon, Jan 19, 2009 at 02:37:13PM +0100) Julien Danjou <[email protected]>: > At 1232337086 time_t, Donald Ephraim Curtis wrote: > > +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() > > t = tag.selected(screen), or you will select the wrong tag > in multihead setup. (just fixed that in tile also). > > -- > Julien Danjou > // ᐰ <[email protected]> http://julien.danjou.info > // 9A0D 5FD9 EB42 22F6 8974 C95C A462 B51E C2FE E5CD
From 38fb85b3ae0b64e080f89cfcab0d74664187225e 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 a bug Fixed bug when closing the final window. pass screen when looking for tag selected. --- lib/awful/client.lua.in | 119 +++++++++++++++++++++++++ lib/awful/layout/init.lua.in | 8 ++ lib/awful/layout/suit/init.lua.in | 2 + lib/awful/layout/suit/vile.lua.in | 177 +++++++++++++++++++++++++++++++++++++ lib/awful/mouse.lua.in | 73 +++++++++++++++ 5 files changed, 379 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..49c9c8a 100644 --- a/lib/awful/client.lua.in +++ b/lib/awful/client.lua.in @@ -593,6 +593,125 @@ function floating.delete(c) data.floating[c] = nil end +local function normalize(set, max) + total = 0 + if max then + for i = 1,max do + total = total + set[i] + end + for i = 1,max 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 which {index, column} the client belongs to given the index +function idx(c) + local c = c or capi.client.focus + 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, max=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, max=percol} +end + + +-- Set the window by index (or the currently selected window) +function setwfact(wfact, c) + -- get the currently selected window + local c = c or capi.client.focus + 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.max do + if i ~= w.idx then + total = total + colfact[i] + end + end + + -- normalize the windows + for i = 1,w.max do + if i ~= w.idx then + colfact[i] = (colfact[i] * rest) / total + end + end +end + +-- Change the width factor of a window (indexed by number) +function incwfact(add, c) + local c = c or capi.client.focus + 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.max) + 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..70e8ea7 100644 --- a/lib/awful/layout/init.lua.in +++ b/lib/awful/layout/init.lua.in @@ -70,6 +70,14 @@ 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.adaptile] = "adaptile", + [suit.adaptile.left] = "adaptileleft", + [suit.adaptile.bottom] = "adaptilebottom", + [suit.adaptile.top] = "adaptiletop", [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..20e1550 100644 --- a/lib/awful/layout/suit/init.lua.in +++ b/lib/awful/layout/suit/init.lua.in @@ -1,5 +1,7 @@ require("awful.layout.suit.max") require("awful.layout.suit.tile") +require("awful.layout.suit.vile") +require("awful.layout.suit.adaptile") 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..45a5782 --- /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 2009 Maxime Coste +-- @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 = tag.getnmaster(t) + local nother = #cls - nmaster + + 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..ac2fb68 100644 --- a/lib/awful/mouse.lua.in +++ b/lib/awful/mouse.lua.in @@ -392,6 +392,73 @@ 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 + if lay == layout.suit.vile then + capi.mouse.coords({ x = wa.x + wa.width * mwfact }) + cursor = "sb_h_double_arrow" + elseif lay == layout.suit.vile.left then + capi.mouse.coords({ x = wa.x + wa.width * (1 - mwfact) }) + cursor = "sb_h_double_arrow" + elseif lay == layout.suit.vile.bottom then + capi.mouse.coords({ y = wa.y + wa.height * mwfact }) + cursor = "sb_v_double_arrow" + else + capi.mouse.coords({ y = wa.y + wa.height * (1 - mwfact) }) + cursor = "sb_v_double_arrow" + 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 +550,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
pgpdKk0O5FfSA.pgp
Description: PGP signature
