diff --git a/README.rst b/README.rst index 4072d35..2bb89a8 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,7 @@ Layouts, widgets and utilities for Awesome WM 4.x Warning ------- -If you still have to use branch 3.5.x, you can refer to the commit 301faf5_. Be aware that it's no longer supported, so update to 4.x ASAP. +If you still have to use branch 3.5.x, you can refer to the commit 301faf5_, but be aware that it's no longer supported. Description ----------- diff --git a/icons/layout/default/cascadebrowse.png b/icons/layout/default/cascadetile.png similarity index 100% rename from icons/layout/default/cascadebrowse.png rename to icons/layout/default/cascadetile.png diff --git a/icons/layout/default/cascadebrowsew.png b/icons/layout/default/cascadetilew.png similarity index 100% rename from icons/layout/default/cascadebrowsew.png rename to icons/layout/default/cascadetilew.png diff --git a/icons/layout/default/centerhwork.png b/icons/layout/default/centerhwork.png deleted file mode 100644 index 59c90f8..0000000 Binary files a/icons/layout/default/centerhwork.png and /dev/null differ diff --git a/icons/layout/default/centerhworkw.png b/icons/layout/default/centerhworkw.png deleted file mode 100644 index 6866f44..0000000 Binary files a/icons/layout/default/centerhworkw.png and /dev/null differ diff --git a/icons/layout/zenburn/cascadebrowse.png b/icons/layout/zenburn/cascadetile.png similarity index 100% rename from icons/layout/zenburn/cascadebrowse.png rename to icons/layout/zenburn/cascadetile.png diff --git a/icons/layout/zenburn/centerworkh.png b/icons/layout/zenburn/centerworkh.png new file mode 100644 index 0000000..00beeb5 Binary files /dev/null and b/icons/layout/zenburn/centerworkh.png differ diff --git a/layout/cascade.lua b/layout/cascade.lua index 3d7598b..2397a1d 100644 --- a/layout/cascade.lua +++ b/layout/cascade.lua @@ -8,72 +8,186 @@ --]] -local tag = require("awful.tag") -local beautiful = require("beautiful") +local tag = require("awful.tag") +local tonumber = tonumber -local cascade = -{ +local cascade = { name = "cascade", nmaster = 0, offset_x = 32, - offset_y = 8 + offset_y = 8, + tile = { + name = "cascadetile", + nmaster = 0, + ncol = 0, + mwfact = 0, + offset_x = 5, + offset_y = 32, + extra_padding = 0 + } } -function cascade.arrange(p) - - -- Cascade windows. - - -- A global border can be defined with - -- beautiful.global_border_width. - local global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end - +local function do_cascade(p, tiling) -- Screen. - local wa = p.workarea + local wa = p.workarea local cls = p.clients - wa.height = wa.height - (global_border * 2) - wa.width = wa.width - (global_border * 2) - wa.x = wa.x + global_border - wa.y = wa.y + global_border + if #cls <= 0 then return end - -- Opening a new window will usually force all existing windows to - -- get resized. This wastes a lot of CPU time. So let's set a lower - -- bound to "how_many": This wastes a little screen space but you'll - -- get a much better user experience. - local t = tag.selected(p.screen) - local num_c - if cascade.nmaster > 0 - then - num_c = cascade.nmaster + -- Useless gaps. + local useless_gap = tag.gap or 0 + + if not tiling then + -- Cascade windows. + + local num_c + if cascade.nmaster > 0 then + num_c = cascade.nmaster + else + num_c = tag.master_count + end + + -- Opening a new window will usually force all existing windows to + -- get resized. This wastes a lot of CPU time. So let's set a lower + -- bound to "how_many": This wastes a little screen space but you'll + -- get a much better user experience. + local how_many = (#cls >= num_c and #cls) or num_c + + local current_offset_x = cascade.offset_x * (how_many - 1) + local current_offset_y = cascade.offset_y * (how_many - 1) + + -- Iterate. + for i = 1,#cls,1 do + local c = cls[i] + local g = {} + + g.x = wa.x + (how_many - i) * cascade.offset_x + g.y = wa.y + (i - 1) * cascade.offset_y + g.width = wa.width - current_offset_x - 2*c.border_width + g.height = wa.height - current_offset_y - 2*c.border_width + + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + + c:geometry(g) + end else - num_c = tag.getnmaster(t) - end + -- Layout with one fixed column meant for a master window. Its + -- width is calculated according to mwfact. Other clients are + -- cascaded or "tabbed" in a slave column on the right. - local how_many = #cls - if how_many < num_c - then - how_many = num_c - end + -- (1) (2) (3) (4) + -- +----------+---+ +----------+---+ +----------+---+ +----------+---+ + -- | | | | | 3 | | | 4 | | +---+| + -- | | | -> | | | -> | +---++ -> | +---+|+ + -- | 1 | 2 | | 1 +---++ | 1 | 3 || | 1 +---+|+| + -- | | | | | 2 || | +---++| | +---+|+ | + -- | | | | | || | | 2 | | | | 2 |+ | + -- +----------+---+ +---------+---++ +--------+---+-+ +------+---+---+ - local current_offset_x = cascade.offset_x * (how_many - 1) - local current_offset_y = cascade.offset_y * (how_many - 1) + local mwfact + if cascade.tile.mwfact > 0 then + mwfact = cascade.tile.mwfact + else + mwfact = tag.getmwfact(t) + end - -- Iterate. - for i = 1,#cls,1 - do - local c = cls[i] + -- Make slave windows overlap main window? Do this if ncol is 1. + local overlap_main + if cascade.tile.ncol > 0 then + overlap_main = cascade.tile.ncol + else + overlap_main = tag.column_count + end + + -- Minimum space for slave windows? See cascade.tile.lua. + local num_c + if cascade.tile.nmaster > 0 then + num_c = cascade.tile.nmaster + else + num_c = tag.master_count + end + + local how_many = (#cls - 1 >= num_c and (#cls - 1)) or num_c + + local current_offset_x = cascade.tile.offset_x * (how_many - 1) + local current_offset_y = cascade.tile.offset_y * (how_many - 1) + + if #cls <= 0 then return end + + -- Main column, fixed width and height. + local c = cls[1] local g = {} + -- Subtracting the useless_gap width from the work area width here + -- makes this mwfact calculation work the same as in uselesstile. + -- Rounding is necessary to prevent the rendered size of slavewid + -- from being 1 pixel off when the result is not an integer. + local mainwid = math.floor((wa.width - useless_gap) * mwfact) + local slavewid = wa.width - mainwid - g.x = wa.x + (how_many - i) * cascade.offset_x - g.y = wa.y + (i - 1) * cascade.offset_y - g.width = wa.width - current_offset_x - 2*c.border_width - g.height = wa.height - current_offset_y - 2*c.border_width + if overlap_main == 1 then + g.width = wa.width - 2*c.border_width + + -- The size of the main window may be reduced a little bit. + -- This allows you to see if there are any windows below the + -- main window. + -- This only makes sense, though, if the main window is + -- overlapping everything else. + g.width = g.width - cascade.tile.extra_padding + else + g.width = mainwid - 2*c.border_width + end + + g.height = wa.height - 2*c.border_width + g.x = wa.x + g.y = wa.y + if useless_gap > 0 then + -- Reduce width once and move window to the right. + -- Reduce height twice, however. + g.width = g.width - useless_gap + g.height = g.height - 2 * useless_gap + g.x = g.x + useless_gap + g.y = g.y + useless_gap + + -- When there's no window to the right, add an additional gap. + if overlap_main == 1 then g.width = g.width - useless_gap end + end if g.width < 1 then g.width = 1 end if g.height < 1 then g.height = 1 end - c:geometry(g) + + -- Remaining clients stacked in slave column, new ones on top. + if #cls > 1 then + for i = 2,#cls do + c = cls[i] + g = {} + g.width = slavewid - current_offset_x - 2*c.border_width + g.height = wa.height - current_offset_y - 2*c.border_width + g.x = wa.x + mainwid + (how_many - (i - 1)) * cascade.tile.offset_x + g.y = wa.y + (i - 2) * cascade.tile.offset_y + + if useless_gap > 0 then + g.width = g.width - 2 * useless_gap + g.height = g.height - 2 * useless_gap + g.x = g.x + useless_gap + g.y = g.y + useless_gap + end + + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + + c:geometry(g) + end + end end end +function cascade.tile.arrange(p) + return do_cascade(p, true) +end + +function cascade.arrange(p) + return do_cascade(p, false) +end + return cascade diff --git a/layout/cascadetile.lua b/layout/cascadetile.lua deleted file mode 100644 index 3baf3e9..0000000 --- a/layout/cascadetile.lua +++ /dev/null @@ -1,174 +0,0 @@ - ---[[ - - Licensed under GNU General Public License v2 - * (c) 2014, projektile - * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann - ---]] - -local tag = require("awful.tag") -local beautiful = require("beautiful") -local tonumber = tonumber - -local cascadetile = -{ - name = "cascadetile", - nmaster = 0, - ncol = 0, - mwfact = 0, - offset_x = 5, - offset_y = 32, - extra_padding = 0 -} - -function cascadetile.arrange(p) - - -- Layout with one fixed column meant for a master window. Its - -- width is calculated according to mwfact. Other clients are - -- cascaded or "tabbed" in a slave column on the right. - - -- It's a bit hard to demonstrate the behaviour with ASCII-images... - -- - -- (1) (2) (3) (4) - -- +----------+---+ +----------+---+ +----------+---+ +----------+---+ - -- | | | | | 3 | | | 4 | | +---+| - -- | | | -> | | | -> | +---++ -> | +---+|+ - -- | 1 | 2 | | 1 +---++ | 1 | 3 || | 1 +---+|+| - -- | | | | | 2 || | +---++| | +---+|+ | - -- | | | | | || | | 2 | | | | 2 |+ | - -- +----------+---+ +---------+---++ +--------+---+-+ +------+---+---+ - - -- A useless gap (like the dwm patch) can be defined with - -- beautiful.useless_gap_width. - local useless_gap = tonumber(beautiful.useless_gap_width) or 0 - if useless_gap < 0 then useless_gap = 0 end - - -- A global border can be defined with - -- beautiful.global_border_width - local global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end - - -- Screen. - local wa = p.workarea - local cls = p.clients - - -- Borders are factored in. - wa.height = wa.height - (global_border * 2) - wa.width = wa.width - (global_border * 2) - wa.x = wa.x + global_border - wa.y = wa.y + global_border - - -- Width of main column? - local t = tag.selected(p.screen) - local mwfact - if cascadetile.mwfact > 0 - then - mwfact = cascadetile.mwfact - else - mwfact = tag.getmwfact(t) - end - - -- Make slave windows overlap main window? Do this if ncol is 1. - local overlap_main - if cascadetile.ncol > 0 - then - overlap_main = cascadetile.ncol - else - overlap_main = tag.getncol(t) - end - - -- Minimum space for slave windows? See cascade.lua. - local num_c - if cascadetile.nmaster > 0 - then - num_c = cascadetile.nmaster - else - num_c = tag.getnmaster(t) - end - - local how_many = #cls - 1 - if how_many < num_c - then - how_many = num_c - end - local current_offset_x = cascadetile.offset_x * (how_many - 1) - local current_offset_y = cascadetile.offset_y * (how_many - 1) - - if #cls > 0 - then - -- Main column, fixed width and height. - local c = cls[1] - local g = {} - -- Subtracting the useless_gap width from the work area width here - -- makes this mwfact calculation work the same as in uselesstile. - -- Rounding is necessary to prevent the rendered size of slavewid - -- from being 1 pixel off when the result is not an integer. - local mainwid = math.floor((wa.width - useless_gap) * mwfact) - local slavewid = wa.width - mainwid - - if overlap_main == 1 - then - g.width = wa.width - 2*c.border_width - - -- The size of the main window may be reduced a little bit. - -- This allows you to see if there are any windows below the - -- main window. - -- This only makes sense, though, if the main window is - -- overlapping everything else. - g.width = g.width - cascadetile.extra_padding - else - g.width = mainwid - 2*c.border_width - end - - g.height = wa.height - 2*c.border_width - g.x = wa.x - g.y = wa.y - if useless_gap > 0 - then - -- Reduce width once and move window to the right. Reduce - -- height twice, however. - g.width = g.width - useless_gap - g.height = g.height - 2 * useless_gap - g.x = g.x + useless_gap - g.y = g.y + useless_gap - - -- When there's no window to the right, add an additional - -- gap. - if overlap_main == 1 - then - g.width = g.width - useless_gap - end - end - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - c:geometry(g) - - -- Remaining clients stacked in slave column, new ones on top. - if #cls > 1 - then - for i = 2,#cls - do - c = cls[i] - g = {} - g.width = slavewid - current_offset_x - 2*c.border_width - g.height = wa.height - current_offset_y - 2*c.border_width - g.x = wa.x + mainwid + (how_many - (i - 1)) * cascadetile.offset_x - g.y = wa.y + (i - 2) * cascadetile.offset_y - if useless_gap > 0 - then - g.width = g.width - 2 * useless_gap - g.height = g.height - 2 * useless_gap - g.x = g.x + useless_gap - g.y = g.y + useless_gap - end - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - c:geometry(g) - end - end - end -end - -return cascadetile diff --git a/layout/centerfair.lua b/layout/centerfair.lua deleted file mode 100644 index 5022726..0000000 --- a/layout/centerfair.lua +++ /dev/null @@ -1,164 +0,0 @@ - ---[[ - - Licensed under GNU General Public License v2 - * (c) 2014, projektile - * (c) 2013, Luke Bonham - * (c) 2010, Nicolas Estibals - * (c) 2010-2012, Peter Hofmann - ---]] - -local tag = require("awful.tag") -local beautiful = require("beautiful") -local math = { ceil = math.ceil, - floor = math.floor, - max = math.max } -local tonumber = tonumber - -local centerfair = { name = "centerfair" } - -function centerfair.arrange(p) - -- Layout with fixed number of vertical columns (read from nmaster). - -- Cols are centerded until there is nmaster columns, then windows - -- are stacked in the slave columns, with at most ncol clients per - -- column if possible. - - -- with nmaster=3 and ncol=1 you'll have - -- (1) (2) (3) - -- +---+---+---+ +-+---+---+-+ +---+---+---+ - -- | | | | | | | | | | | | | - -- | | 1 | | -> | | 1 | 2 | | -> | 1 | 2 | 3 | -> - -- | | | | | | | | | | | | | - -- +---+---+---+ +-+---+---+-+ +---+---+---+ - - -- (4) (5) - -- +---+---+---+ +---+---+---+ - -- | | | 3 | | | 2 | 4 | - -- + 1 + 2 +---+ -> + 1 +---+---+ - -- | | | 4 | | | 3 | 5 | - -- +---+---+---+ +---+---+---+ - - -- A useless gap (like the dwm patch) can be defined with - -- beautiful.useless_gap_width . - local useless_gap = tonumber(beautiful.useless_gap_width) or 0 - if useless_gap < 0 then useless_gap = 0 end - - -- A global border can be defined with - -- beautiful.global_border_width - local global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end - - -- Screen. - local wa = p.workarea - local cls = p.clients - - -- Borders are factored in. - wa.height = wa.height - (global_border * 2) - wa.width = wa.width - (global_border * 2) - wa.x = wa.x + global_border - wa.y = wa.y + global_border - - -- How many vertical columns? Read from nmaster on the tag. - local t = tag.selected(p.screen) - local num_x = centerfair.nmaster or tag.getnmaster(t) - local ncol = centerfair.ncol or tag.getncol(t) - if num_x <= 2 then num_x = 2 end - - local width = math.floor((wa.width - (num_x + 1)*useless_gap) / num_x) - - if #cls < num_x - then - -- Less clients than the number of columns, let's center it! - local offset_x = wa.x + (wa.width - #cls*width - (#cls - 1)*useless_gap) / 2 - local g = {} - g.y = wa.y + useless_gap - for i = 1, #cls do - local c = cls[i] - g.width = width - 2*c.border_width - g.height = wa.height - 2*useless_gap - 2*c.border_width - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - g.x = offset_x + (i - 1) * (width + useless_gap) - c:geometry(g) - end - else - -- More clients than the number of columns, let's arrange it! - -- Master client deserves a special treatement - local c = cls[1] - local g = {} - g.width = wa.width - (num_x - 1)*width - (num_x + 1)*useless_gap - 2*c.border_width - g.height = wa.height - 2*useless_gap - 2*c.border_width - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - g.x = wa.x + useless_gap - g.y = wa.y + useless_gap - - c:geometry(g) - - -- Treat the other clients - - -- Compute distribution of clients among columns - local num_y ={} - do - local remaining_clients = #cls-1 - local ncol_min = math.ceil(remaining_clients/(num_x-1)) - if ncol >= ncol_min - then - for i = (num_x-1), 1, -1 do - if (remaining_clients-i+1) < ncol - then - num_y[i] = remaining_clients-i + 1 - else - num_y[i] = ncol - end - remaining_clients = remaining_clients - num_y[i] - end - else - local rem = remaining_clients % (num_x-1) - if rem ==0 - then - for i = 1, num_x-1 do - num_y[i] = ncol_min - end - else - for i = 1, num_x-1 do - num_y[i] = ncol_min - 1 - end - for i = 0, rem-1 do - num_y[num_x-1-i] = num_y[num_x-1-i] + 1 - end - end - end - end - - -- Compute geometry of the other clients - local nclient = 2 -- we start with the 2nd client - g.x = g.x + g.width + useless_gap + 2*c.border_width - - for i = 1, (num_x-1) do - local height = math.floor((wa.height - (num_y[i] + 1)*useless_gap) / num_y[i]) - g.y = wa.y + useless_gap - for j = 0, (num_y[i]-2) do - local c = cls[nclient] - g.height = height - 2*c.border_width - g.width = width - 2*c.border_width - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - c:geometry(g) - nclient = nclient + 1 - g.y = g.y + height + useless_gap - end - local c = cls[nclient] - g.height = wa.height - (num_y[i] + 1)*useless_gap - (num_y[i] - 1)*height - 2*c.border_width - g.width = width - 2*c.border_width - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - c:geometry(g) - nclient = nclient + 1 - g.x = g.x + width + useless_gap - end - end -end - -return centerfair diff --git a/layout/centerhwork.lua b/layout/centerhwork.lua deleted file mode 100644 index 14b1b01..0000000 --- a/layout/centerhwork.lua +++ /dev/null @@ -1,136 +0,0 @@ - ---[[ - - Licensed under GNU General Public License v2 - * (c) 2015, Joerg Jaspert - * (c) 2014, projektile - * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann - ---]] - -local awful = require("awful") -local beautiful = require("beautiful") -local tonumber = tonumber - -local centerhwork = -{ - name = "centerhwork", - top_left = 0, - top_right = 1, - bottom_left = 2, - bottom_right = 3 -} - -function centerhwork.arrange(p) - -- A useless gap (like the dwm patch) can be defined with - -- beautiful.useless_gap_width . - local useless_gap = tonumber(beautiful.useless_gap_width) or 0 - - -- A global border can be defined with - -- beautiful.global_border_width - local global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end - - -- Screen. - local wa = p.workarea - local cls = p.clients - - -- Borders are factored in. - wa.height = wa.height - (global_border * 2) - wa.width = wa.width - (global_border * 2) - wa.x = wa.x + global_border - wa.y = wa.y + global_border - - -- Width of main column? - local t = awful.tag.selected(p.screen) - local mwfact = awful.tag.getmwfact(t) - - if #cls > 0 - then - -- Main column, fixed width and height. - local c = cls[1] - local g = {} - local mainhei = math.floor(wa.height * mwfact) - local slaveLwid = math.floor(wa.width / 2 ) - local slaveRwid = wa.width - slaveLwid - local slavehei = wa.height - mainhei - local slaveThei = math.floor(slavehei / 2) - local slaveBhei = slavehei - slaveThei - local Lhalfgap = math.floor(useless_gap / 2) - local Rhalfgap = useless_gap - Lhalfgap - - g.height = mainhei - 2*c.border_width - g.width = wa.width - 2*useless_gap - 2*c.border_width - g.x = wa.x + useless_gap - g.y = wa.y + slaveThei - - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - c:geometry(g) - - -- Auxiliary windows. - if #cls > 1 - then - local at = 0 - for i = 2,#cls - do - -- It's all fixed. If there are more than 5 clients, - -- those additional clients will float. This is - -- intentional. - if at == 4 - then - break - end - - c = cls[i] - g = {} - - if i - 2 == centerhwork.top_left - then - -- top left - g.x = wa.x + useless_gap - g.y = wa.y + useless_gap - g.width = slaveLwid - useless_gap - Lhalfgap - 2*c.border_width - g.height = slaveThei - 2*useless_gap - 2*c.border_width - elseif i - 2 == centerhwork.top_right - then - -- top right - g.x = wa.x + slaveLwid + Rhalfgap - g.y = wa.y + useless_gap - g.width = slaveRwid - useless_gap - Rhalfgap - 2*c.border_width - g.height = slaveThei - 2*useless_gap - 2*c.border_width - elseif i - 2 == centerhwork.bottom_left - then - -- bottom left - g.x = wa.x + useless_gap - g.y = wa.y + mainhei + slaveThei + useless_gap - g.width = slaveLwid - useless_gap - Lhalfgap - 2*c.border_width - g.height = slaveBhei - 2*useless_gap - 2*c.border_width - elseif i - 2 == centerhwork.bottom_right - then - -- bottom right - g.x = wa.x + slaveLwid + Rhalfgap - g.y = wa.y + mainhei + slaveThei + useless_gap - g.width = slaveRwid - useless_gap - Rhalfgap - 2*c.border_width - g.height = slaveBhei - 2*useless_gap - 2*c.border_width - end - - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - c:geometry(g) - - at = at + 1 - end - - -- Set remaining clients to floating. - for i = (#cls - 1 - 4),1,-1 - do - c = cls[i] - awful.client.floating.set(c, true) - end - end - end -end - -return centerhwork diff --git a/layout/centerwork.lua b/layout/centerwork.lua index 954826e..ce3d9e8 100644 --- a/layout/centerwork.lua +++ b/layout/centerwork.lua @@ -2,135 +2,157 @@ --[[ Licensed under GNU General Public License v2 + * (c) 2016, Henrik Antonsson + * (c) 2015, Joerg Jaspert * (c) 2014, projektile * (c) 2013, Luke Bonham * (c) 2010-2012, Peter Hofmann --]] -local awful = require("awful") -local beautiful = require("beautiful") +local tag = require("awful.tag") local tonumber = tonumber local math = { floor = math.floor } -local centerwork = -{ +local centerwork = { name = "centerwork", - top_right = 0, - bottom_right = 1, - bottom_left = 2, - top_left = 3 + horizontal = { name = "centerworkh" } } -function centerwork.arrange(p) - -- A useless gap (like the dwm patch) can be defined with - -- beautiful.useless_gap_width . - local useless_gap = tonumber(beautiful.useless_gap_width) or 0 - - -- A global border can be defined with - -- beautiful.global_border_width - local global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end - +local function do_centerwork(p, orientation) -- Screen. - local wa = p.workarea + local wa = p.workarea local cls = p.clients - -- Borders are factored in. - wa.height = wa.height - (global_border * 2) - wa.width = wa.width - (global_border * 2) - wa.x = wa.x + global_border - wa.y = wa.y + global_border + if #cls <= 0 then return end - -- Width of main column? - local t = awful.tag.selected(p.screen) - local mwfact = awful.tag.getmwfact(t) + -- Useless gaps. + local useless_gap = tag.gap or 0 - if #cls > 0 - then - -- Main column, fixed width and height. - local c = cls[1] - local g = {} - local mainwid = math.floor(wa.width * mwfact) - local slavewid = wa.width - mainwid - local slaveLwid = math.floor(slavewid / 2) - local slaveRwid = slavewid - slaveLwid - local slaveThei = math.floor(wa.height / 2) - local slaveBhei = wa.height - slaveThei - local Thalfgap = math.floor(useless_gap / 2) - local Bhalfgap = useless_gap - Thalfgap + local c = cls[1] + local g = {} + + -- Main column, fixed width and height. + local mwfact = tag.object.get_master_width_factor(t) + local mainhei = math.floor(wa.height * mwfact) + local mainwid = math.floor(wa.width * mwfact) + local slavewid = wa.width - mainwid + local slaveLwid = math.floor(slavewid / 2) + local slaveRwid = slavewid - slaveLwid + local slavehei = wa.height - mainhei + local slaveThei = math.floor(slavehei / 2) + local slaveBhei = slavehei - slaveThei + local nbrFirstSlaves = math.floor(#cls / 2) + local nbrSecondSlaves = math.floor((#cls - 1) / 2) + + local slaveFirstDim, slaveSecondDim = 0, 0 + + if orientation == "vertical" then + if nbrFirstSlaves > 0 then slaveFirstDim = math.floor(wa.height / nbrFirstSlaves) end + if nbrSecondSlaves > 0 then slaveSecondDim = math.floor(wa.height / nbrSecondSlaves) end g.height = wa.height - 2*useless_gap - 2*c.border_width - g.width = mainwid - 2*c.border_width + g.width = mainwid - 2*c.border_width + g.x = wa.x + slaveLwid g.y = wa.y + useless_gap + else + if nbrFirstSlaves > 0 then slaveFirstDim = math.floor(wa.width / nbrFirstSlaves) end + if nbrSecondSlaves > 0 then slaveSecondDim = math.floor(wa.width / nbrSecondSlaves) end - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - c:geometry(g) + g.height = mainhei - 2*c.border_width + g.width = wa.width - 2*useless_gap - 2*c.border_width - -- Auxiliary windows. - if #cls > 1 - then - local at = 0 - for i = 2,#cls - do - -- It's all fixed. If there are more than 5 clients, - -- those additional clients will float. This is - -- intentional. - if at == 4 - then - break + g.x = wa.x + useless_gap + g.y = wa.y + slaveThei + end + + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + + c:geometry(g) + + -- Auxiliary windows. + if #cls <= 1 then return end + for i = 2,#cls do + local c = cls[i] + local g = {} + + local rowIndex = math.floor(i/2) + + if orientation == "vertical" then + if i % 2 == 0 then + -- left slave + g.x = wa.x + useless_gap + g.y = wa.y + useless_gap + (rowIndex-1)*slaveFirstDim + + g.width = slaveLwid - 2*useless_gap - 2*c.border_width + + -- if last slave in left row use remaining space for that slave + if rowIndex == nbrFirstSlaves then + g.height = wa.y + wa.height - g.y - useless_gap - 2*c.border_width + else + g.height = slaveFirstDim - useless_gap - 2*c.border_width end + else + -- right slave + g.x = wa.x + slaveLwid + mainwid + useless_gap + g.y = wa.y + useless_gap + (rowIndex-1)*slaveSecondDim - c = cls[i] - g = {} + g.width = slaveRwid - 2*useless_gap - 2*c.border_width - if i - 2 == centerwork.top_left - then - -- top left - g.x = wa.x + useless_gap - g.y = wa.y + useless_gap - g.width = slaveLwid - 2*useless_gap - 2*c.border_width - g.height = slaveThei - useless_gap - Thalfgap - 2*c.border_width - elseif i - 2 == centerwork.top_right - then - -- top right - g.x = wa.x + slaveLwid + mainwid + useless_gap - g.y = wa.y + useless_gap - g.width = slaveRwid - 2*useless_gap - 2*c.border_width - g.height = slaveThei - useless_gap - Thalfgap - 2*c.border_width - elseif i - 2 == centerwork.bottom_left - then - -- bottom left - g.x = wa.x + useless_gap - g.y = wa.y + slaveThei + Bhalfgap - g.width = slaveLwid - 2*useless_gap - 2*c.border_width - g.height = slaveBhei - useless_gap - Bhalfgap - 2*c.border_width - elseif i - 2 == centerwork.bottom_right - then - -- bottom right - g.x = wa.x + slaveLwid + mainwid + useless_gap - g.y = wa.y + slaveThei + Bhalfgap - g.width = slaveRwid - 2*useless_gap - 2*c.border_width - g.height = slaveBhei - useless_gap - Bhalfgap - 2*c.border_width + -- if last slave in right row use remaining space for that slave + if rowIndex == nbrSecondSlaves then + g.height = wa.y + wa.height - g.y - useless_gap - 2*c.border_width + else + g.height = slaveSecondDim - useless_gap - 2*c.border_width end - - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - c:geometry(g) - - at = at + 1 end + else + if i % 2 == 0 then + -- top slave + g.x = wa.x + useless_gap + (rowIndex-1)*slaveFirstDim + g.y = wa.y + useless_gap + + g.height = slaveThei - 2*useless_gap - 2*c.border_width + + -- if last slave in top row use remaining space for that slave + if rowIndex == nbrFirstSlaves then + g.width = wa.x + wa.width - g.x - useless_gap - 2*c.border_width + else + g.width = slaveFirstDim - useless_gap - 2*c.border_width + end + else + -- bottom slave + g.x = wa.x + useless_gap + (rowIndex-1)*slaveFirstDim + g.y = wa.y + slaveThei + mainhei + useless_gap + + g.height = slaveBhei - 2*useless_gap - 2*c.border_width + + -- if last slave in bottom row use remaining space for that slave + if rowIndex == nbrSecondSlaves then + g.width = wa.x + wa.width - g.x - useless_gap - 2*c.border_width + else + g.width = slaveSecondDim - useless_gap - 2*c.border_width + end - -- Set remaining clients to floating. - for i = (#cls - 1 - 4),1,-1 - do - c = cls[i] - awful.client.floating.set(c, true) end end + + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + + c:geometry(g) end end + +function centerwork.horizontal.arrange(p) + return do_centerwork(p, "horizontal") +end + +function centerwork.arrange(p) + return do_centerwork(p, "vertical") +end + return centerwork diff --git a/layout/centerworkd.lua b/layout/centerworkd.lua deleted file mode 100644 index e66a15a..0000000 --- a/layout/centerworkd.lua +++ /dev/null @@ -1,123 +0,0 @@ - ---[[ - - Licensed under GNU General Public License v2 - * (c) 2016, Henrik Antonsson - * (c) 2014, projektile - * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann - - Based on centerwork.lua ---]] - -local awful = require("awful") -local beautiful = require("beautiful") -local tonumber = tonumber -local math = { floor = math.floor } - -local centerworkd = -{ - name = "centerworkd", -} - -function centerworkd.arrange(p) - -- A useless gap (like the dwm patch) can be defined with - -- beautiful.useless_gap_width . - local useless_gap = tonumber(beautiful.useless_gap_width) or 0 - - -- A global border can be defined with - -- beautiful.global_border_width - local global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end - - -- Screen. - local wa = p.workarea - local cls = p.clients - - -- Borders are factored in. - wa.height = wa.height - (global_border * 2) - wa.width = wa.width - (global_border * 2) - wa.x = wa.x + global_border - wa.y = wa.y + global_border - - -- Width of main column? - local t = awful.tag.selected(p.screen) - local mwfact = awful.tag.getmwfact(t) - - if #cls > 0 - then - -- Main column, fixed width and height. - local c = cls[1] - local g = {} - local mainwid = math.floor(wa.width * mwfact) - local slavewid = wa.width - mainwid - local slaveLwid = math.floor(slavewid / 2) - local slaveRwid = slavewid - slaveLwid - local nbrLeftSlaves = math.floor(#cls / 2) - local nbrRightSlaves = math.floor((#cls - 1) / 2) - - local slaveLeftHeight = 0 - if nbrLeftSlaves > 0 then slaveLeftHeight = math.floor(wa.height / nbrLeftSlaves) end - if nbrRightSlaves > 0 then slaveRightHeight = math.floor(wa.height / nbrRightSlaves) end - - g.height = wa.height - 2*useless_gap - 2*c.border_width - g.width = mainwid - 2*c.border_width - g.x = wa.x + slaveLwid - g.y = wa.y + useless_gap - - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - c:geometry(g) - - -- Auxiliary windows. - if #cls > 1 - then - for i = 2,#cls - do - c = cls[i] - g = {} - - local rowIndex = math.floor(i/2) - - -- If i is even it should be placed on the left side - if i % 2 == 0 - then - -- left slave - g.x = wa.x + useless_gap - g.y = wa.y + useless_gap + (rowIndex-1)*slaveLeftHeight - - g.width = slaveLwid - 2*useless_gap - 2*c.border_width - - -- if last slave in left row use remaining space for that slave - if rowIndex == nbrLeftSlaves - then - g.height = wa.y + wa.height - g.y - useless_gap - 2*c.border_width - else - g.height = slaveLeftHeight - useless_gap - 2*c.border_width - end - else - -- right slave - g.x = wa.x + slaveLwid + mainwid + useless_gap - g.y = wa.y + useless_gap + (rowIndex-1)*slaveRightHeight - - g.width = slaveRwid - 2*useless_gap - 2*c.border_width - - -- if last slave in right row use remaining space for that slave - if rowIndex == nbrRightSlaves - then - g.height = wa.y + wa.height - g.y - useless_gap - 2*c.border_width - else - g.height = slaveRightHeight - useless_gap - 2*c.border_width - end - - end - - if g.width < 1 then g.width = 1 end - if g.height < 1 then g.height = 1 end - c:geometry(g) - end - end - end -end - -return centerworkd diff --git a/layout/termfair.lua b/layout/termfair.lua index 6aca99d..ec127e2 100644 --- a/layout/termfair.lua +++ b/layout/termfair.lua @@ -4,100 +4,89 @@ Licensed under GNU General Public License v2 * (c) 2014, projektile * (c) 2013, Luke Bonham + * (c) 2010, Nicolas Estibals * (c) 2010-2012, Peter Hofmann --]] local tag = require("awful.tag") -local beautiful = require("beautiful") local math = { ceil = math.ceil, floor = math.floor, max = math.max } local tonumber = tonumber local termfair = { name = "termfair" } +termfair.center = { name = "centerfair" } -function termfair.arrange(p) - -- Layout with fixed number of vertical columns (read from nmaster). - -- New windows align from left to right. When a row is full, a now - -- one above it is created. Like this: - - -- (1) (2) (3) - -- +---+---+---+ +---+---+---+ +---+---+---+ - -- | | | | | | | | | | | | - -- | 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | -> - -- | | | | | | | | | | | | - -- +---+---+---+ +---+---+---+ +---+---+---+ - - -- (4) (5) (6) - -- +---+---+---+ +---+---+---+ +---+---+---+ - -- | 4 | | | | 5 | 4 | | | 6 | 5 | 4 | - -- +---+---+---+ -> +---+---+---+ -> +---+---+---+ - -- | 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 | - -- +---+---+---+ +---+---+---+ +---+---+---+ - - -- A useless gap (like the dwm patch) can be defined with - -- beautiful.useless_gap_width. - local useless_gap = tonumber(beautiful.useless_gap_width) or 0 - if useless_gap < 0 then useless_gap = 0 end - - -- A global border can be defined with - -- beautiful.global_border_width - local global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end - +local function do_fair(p, orientation) -- Screen. - local wa = p.workarea + local wa = p.workarea local cls = p.clients - -- Borders are factored in. - wa.height = wa.height - (global_border * 2) - wa.width = wa.width - (global_border * 2) - wa.x = wa.x + global_border - wa.y = wa.y + global_border + if #cls <= 0 then return end - -- How many vertical columns? - local t = tag.selected(p.screen) - local num_x = termfair.nmaster or tag.getnmaster(t) + -- Useless gaps. + local useless_gap = tag.gap or 0 - -- Do at least "desired_y" rows. - local desired_y = termfair.ncol or tag.getncol(t) + if orientation == "west" then + -- Layout with fixed number of vertical columns (read from nmaster). + -- New windows align from left to right. When a row is full, a now + -- one above it is created. Like this: - if #cls > 0 - then - local num_y = math.max(math.ceil(#cls / num_x), desired_y) - local cur_num_x = num_x - local at_x = 0 - local at_y = 0 - local remaining_clients = #cls + -- (1) (2) (3) + -- +---+---+---+ +---+---+---+ +---+---+---+ + -- | | | | | | | | | | | | + -- | 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | -> + -- | | | | | | | | | | | | + -- +---+---+---+ +---+---+---+ +---+---+---+ + + -- (4) (5) (6) + -- +---+---+---+ +---+---+---+ +---+---+---+ + -- | 4 | | | | 5 | 4 | | | 6 | 5 | 4 | + -- +---+---+---+ -> +---+---+---+ -> +---+---+---+ + -- | 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 | + -- +---+---+---+ +---+---+---+ +---+---+---+ + + if #cls <= 0 then return end + + -- How many vertical columns? Read from nmaster on the tag. + local num_x = tonumber(termfair.nmaster) or tag.master_count + local ncol = tonumber(termfair.ncol) or tag.column_count local width = math.floor((wa.width - (num_x + 1)*useless_gap) / num_x) - local height = math.floor((wa.height - (num_y + 1)*useless_gap) / num_y) + + if num_x <= 2 then num_x = 2 end + if ncol <= 1 then ncol = 1 end + + local num_y = math.max(math.ceil(#cls / num_x), ncol) + local height = math.floor((wa.height - (num_y + 1)*useless_gap) / num_y) + local cur_num_x = num_x + local at_x = 0 + local at_y = 0 + + local remaining_clients = #cls -- We start the first row. Left-align by limiting the number of -- available slots. - if remaining_clients < num_x - then + if remaining_clients < num_x then cur_num_x = remaining_clients end -- Iterate in reversed order. - for i = #cls,1,-1 - do + for i = #cls,1,-1 do -- Get x and y position. local c = cls[i] local this_x = cur_num_x - at_x - 1 local this_y = num_y - at_y - 1 - -- Calc geometry. + -- Calculate geometry. local g = {} - if this_x == (num_x - 1) - then + if this_x == (num_x - 1) then g.width = wa.width - (num_x - 1)*width - (num_x + 1)*useless_gap - 2*c.border_width else g.width = width - 2*c.border_width end - if this_y == (num_y - 1) - then + + if this_y == (num_y - 1) then g.height = wa.height - (num_y - 1)*height - (num_y + 1)*useless_gap - 2*c.border_width else g.height = height - 2*c.border_width @@ -106,34 +95,158 @@ function termfair.arrange(p) g.x = wa.x + this_x*width g.y = wa.y + this_y*height - if useless_gap > 0 - then + if useless_gap > 0 then -- All clients tile evenly. g.x = g.x + (this_x + 1)*useless_gap g.y = g.y + (this_y + 1)*useless_gap - end + if g.width < 1 then g.width = 1 end if g.height < 1 then g.height = 1 end + c:geometry(g) + remaining_clients = remaining_clients - 1 -- Next grid position. at_x = at_x + 1 - if at_x == num_x - then + if at_x == num_x then -- Row full, create a new one above it. at_x = 0 at_y = at_y + 1 -- We start a new row. Left-align. - if remaining_clients < num_x - then + if remaining_clients < num_x then cur_num_x = remaining_clients end end end + elseif orientation == "center" then + -- Layout with fixed number of vertical columns (read from nmaster). + -- Cols are centerded until there is nmaster columns, then windows + -- are stacked in the slave columns, with at most ncol clients per + -- column if possible. + + -- with nmaster=3 and ncol=1 you'll have + -- (1) (2) (3) + -- +---+---+---+ +-+---+---+-+ +---+---+---+ + -- | | | | | | | | | | | | | + -- | | 1 | | -> | | 1 | 2 | | -> | 1 | 2 | 3 | -> + -- | | | | | | | | | | | | | + -- +---+---+---+ +-+---+---+-+ +---+---+---+ + + -- (4) (5) + -- +---+---+---+ +---+---+---+ + -- | | | 3 | | | 2 | 4 | + -- + 1 + 2 +---+ -> + 1 +---+---+ + -- | | | 4 | | | 3 | 5 | + -- +---+---+---+ +---+---+---+ + + -- How many vertical columns? Read from nmaster on the tag. + local num_x = tonumber(termfair.center.nmaster) or tag.master_count + local ncol = tonumber(termfair.center.ncol) or tag.column_count + local width = math.floor((wa.width - (num_x + 1)*useless_gap) / num_x) + + if num_x <= 2 then num_x = 2 end + if ncol <= 1 then ncol = 1 end + + if #cls < num_x then + -- Less clients than the number of columns, let's center it! + local offset_x = wa.x + (wa.width - #cls*width - (#cls - 1)*useless_gap) / 2 + local g = {} + g.y = wa.y + useless_gap + for i = 1, #cls do + local c = cls[i] + g.width = width - 2*c.border_width + g.height = wa.height - 2*useless_gap - 2*c.border_width + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + g.x = offset_x + (i - 1) * (width + useless_gap) + c:geometry(g) + end + else + -- More clients than the number of columns, let's arrange it! + -- Master client deserves a special treatement + local c = cls[1] + local g = {} + g.width = wa.width - (num_x - 1)*width - (num_x + 1)*useless_gap - 2*c.border_width + g.height = wa.height - 2*useless_gap - 2*c.border_width + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + g.x = wa.x + useless_gap + g.y = wa.y + useless_gap + + c:geometry(g) + + -- Treat the other clients + + -- Compute distribution of clients among columns + local num_y ={} + do + local remaining_clients = #cls-1 + local ncol_min = math.ceil(remaining_clients/(num_x-1)) + if ncol >= ncol_min then + for i = (num_x-1), 1, -1 do + if (remaining_clients-i+1) < ncol then + num_y[i] = remaining_clients-i + 1 + else + num_y[i] = ncol + end + remaining_clients = remaining_clients - num_y[i] + end + else + local rem = remaining_clients % (num_x-1) + if rem == 0 then + for i = 1, num_x-1 do + num_y[i] = ncol_min + end + else + for i = 1, num_x-1 do + num_y[i] = ncol_min - 1 + end + for i = 0, rem-1 do + num_y[num_x-1-i] = num_y[num_x-1-i] + 1 + end + end + end + end + + -- Compute geometry of the other clients + local nclient = 2 -- we start with the 2nd client + g.x = g.x + g.width + useless_gap + 2*c.border_width + + for i = 1, (num_x-1) do + local height = math.floor((wa.height - (num_y[i] + 1)*useless_gap) / num_y[i]) + g.y = wa.y + useless_gap + for j = 0, (num_y[i]-2) do + local c = cls[nclient] + g.height = height - 2*c.border_width + g.width = width - 2*c.border_width + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + nclient = nclient + 1 + g.y = g.y + height + useless_gap + end + local c = cls[nclient] + g.height = wa.height - (num_y[i] + 1)*useless_gap - (num_y[i] - 1)*height - 2*c.border_width + g.width = width - 2*c.border_width + if g.width < 1 then g.width = 1 end + if g.height < 1 then g.height = 1 end + c:geometry(g) + nclient = nclient + 1 + g.x = g.x + width + useless_gap + end + end end end +function termfair.center.arrange(p) + return do_fair(p, "center") +end + +function termfair.arrange(p) + return do_fair(p, "west") +end + return termfair diff --git a/wiki b/wiki index 006cb79..cf17caf 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 006cb79c302aef03dd064430dd2ceba2689dacc7 +Subproject commit cf17caf2b889d58d4f00a47cd168f53ae85b6d9f