From dd52f1ce864de096a820dd9f02bd75eba290cce9 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee Date: Tue, 5 Apr 2016 03:02:00 -0400 Subject: [PATCH] awful.tag: Move functions to awful.client and screen --- awesomerc.lua | 20 +- lib/awful/autofocus.lua | 3 +- lib/awful/client.lua | 66 ++- lib/awful/ewmh.lua | 3 +- lib/awful/layout/init.lua | 22 +- lib/awful/layout/suit/corner.lua | 7 +- lib/awful/layout/suit/magnifier.lua | 7 +- lib/awful/layout/suit/tile.lua | 14 +- lib/awful/menu.lua | 2 +- lib/awful/mouse/init.lua | 4 +- lib/awful/rules.lua | 5 +- lib/awful/screen.lua | 108 ++++ lib/awful/tag.lua | 757 +++++++++++++++++++++------- lib/awful/widget/layoutbox.lua | 2 +- lib/awful/widget/taglist.lua | 8 +- lib/awful/widget/tasklist.lua | 4 +- tests/examples/shims/awesome.lua | 4 +- tests/examples/shims/client.lua | 7 +- tests/examples/shims/screen.lua | 3 +- tests/examples/shims/tag.lua | 2 +- tests/test-urgent.lua | 4 +- 21 files changed, 787 insertions(+), 265 deletions(-) diff --git a/awesomerc.lua b/awesomerc.lua index e807fffcc..6934d522d 100755 --- a/awesomerc.lua +++ b/awesomerc.lua @@ -141,7 +141,7 @@ mypromptbox = {} mylayoutbox = {} mytaglist = {} mytaglist.buttons = awful.util.table.join( - awful.button({ }, 1, awful.tag.viewonly), + awful.button({ }, 1, function(t) t:view_only() end), awful.button({ modkey }, 1, function(t) if client.focus then client.focus:move_to_tag(t) @@ -153,8 +153,8 @@ mytaglist.buttons = awful.util.table.join( client.focus:toggle_tag(t) end end), - awful.button({ }, 4, function(t) awful.tag.viewnext(awful.tag.getscreen(t)) end), - awful.button({ }, 5, function(t) awful.tag.viewprev(awful.tag.getscreen(t)) end) + awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end), + awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end) ) mytasklist = {} @@ -166,8 +166,8 @@ mytasklist.buttons = awful.util.table.join( -- Without this, the following -- :isvisible() makes no sense c.minimized = false - if not c:isvisible() then - awful.tag.viewonly(c.first_tag) + if not c:isvisible() and c.first_tag then + c.first_tag:view_only() end -- This will also un-minimize -- the client, if needed @@ -371,9 +371,9 @@ for i = 1, 9 do awful.key({ modkey }, "#" .. i + 9, function () local screen = awful.screen.focused() - local tag = awful.tag.gettags(screen)[i] + local tag = screen.tags[i] if tag then - awful.tag.viewonly(tag) + tag:view_only() end end, {description = "view tag #"..i, group = "tag"}), @@ -381,7 +381,7 @@ for i = 1, 9 do awful.key({ modkey, "Control" }, "#" .. i + 9, function () local screen = awful.screen.focused() - local tag = awful.tag.gettags(screen)[i] + local tag = screen.tags[i] if tag then awful.tag.viewtoggle(tag) end @@ -391,7 +391,7 @@ for i = 1, 9 do awful.key({ modkey, "Shift" }, "#" .. i + 9, function () if client.focus then - local tag = awful.tag.gettags(client.focus.screen)[i] + local tag = client.focus.screen.tags[i] if tag then client.focus:move_to_tag(tag) end @@ -402,7 +402,7 @@ for i = 1, 9 do awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9, function () if client.focus then - local tag = awful.tag.gettags(client.focus.screen)[i] + local tag = client.focus.screen.tags[i] if tag then client.focus:toggle_tag(tag) end diff --git a/lib/awful/autofocus.lua b/lib/awful/autofocus.lua index f0e9090ab..f1117f15c 100644 --- a/lib/awful/autofocus.lua +++ b/lib/awful/autofocus.lua @@ -12,7 +12,6 @@ local client = client local aclient = require("awful.client") -local atag = require("awful.tag") local timer = require("gears.timer") --- Give focus when clients appear/disappear. @@ -39,7 +38,7 @@ end -- -- @param tag A tag object local function check_focus_tag(t) - local s = atag.getscreen(t) + local s = t.screen if not s then return end s = screen[s] check_focus({ screen = s }) diff --git a/lib/awful/client.lua b/lib/awful/client.lua index a322e0b6a..af305672a 100644 --- a/lib/awful/client.lua +++ b/lib/awful/client.lua @@ -11,7 +11,6 @@ local util = require("awful.util") local spawn = require("awful.spawn") local object = require("gears.object") -local tag = require("awful.tag") local pairs = pairs local type = type local ipairs = ipairs @@ -102,7 +101,7 @@ function client.object.jump_to(self, merge) t.selected = true end elseif t then - tag.viewonly(t) + t:view_only() end end @@ -111,7 +110,8 @@ end --- Get visible clients from a screen. -- --- @function awful.client.visible +-- @deprecated awful.client.visible +-- @see screen.clients -- @tparam[opt] integer|screen s The screen, or nil for all screens. -- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom) -- @treturn table A table with all visible clients. @@ -128,7 +128,8 @@ end --- Get visible and tiled clients -- --- @function awful.client.tiled +-- @deprecated awful.client.tiled +-- @see screen.tiled_clients -- @tparam integer|screen s The screen, or nil for all screens. -- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom) -- @treturn table A table with all visible and tiled clients. @@ -230,7 +231,7 @@ function client.swap.global_bydirection(dir, sel) -- swapping to a nonempty screen elseif get_screen(sel.screen) ~= get_screen(c.screen) and sel ~= c then sel:move_to_screen(c.screen) - sel:move_to_screen(scr) + c:move_to_screen(scr) end screen.focus(sel.screen) @@ -313,20 +314,20 @@ end -- @param w The relative width. -- @param h The relative height. -- @client[opt] c The client, otherwise focused one is used. --- @see client.move_resize +-- @see client.relative_move function client.moveresize(x, y, w, h, c) - util.deprecate "Use c:move_resize(x, y, w, h) instead of awful.client.moveresize" - client.object.move_resize(c or capi.client.focus, x, y, w, h) + util.deprecate "Use c:relative_move(x, y, w, h) instead of awful.client.moveresize" + client.object.relative_move(c or capi.client.focus, x, y, w, h) end --- Move/resize a client relative to current coordinates. --- @function client.move_resize +-- @function client.relative_move -- @see geometry -- @tparam[opt=c.x] number x The relative x coordinate. -- @tparam[opt=c.y] number y The relative y coordinate. -- @tparam[opt=c.width] number w The relative width. -- @tparam[opt=c.height] number h The relative height. -function client.object.move_resize(self, x, y, w, h) +function client.object.relative_move(self, x, y, w, h) local geometry = self:geometry() geometry['x'] = geometry['x'] + x geometry['y'] = geometry['y'] + y @@ -349,7 +350,7 @@ end -- @function client.move_to_tag -- @tparam tag target The tag to move the client to. function client.object.move_to_tag(self, target) - local s = tag.getscreen(target) + local s = target.screen if self and s then if self == capi.client.focus then self:emit_signal("request::activate", "client.movetotag", {raise=true}) @@ -375,7 +376,7 @@ end -- @tparam tag target The tag to move the client to. function client.object.toggle_tag(self, target) -- Check that tag and client screen are identical - if self and get_screen(self.screen) == get_screen(tag.getscreen(target)) then + if self and get_screen(self.screen) == get_screen(target.screen) then local tags = self:tags() local index = nil; for i, v in ipairs(tags) do @@ -435,6 +436,31 @@ function client.object.move_to_screen(self, s) end end +--- Tag a client with the set of current tags. +-- @function client.to_selected_tags +-- @see screen.selected_tags +function client.object.to_selected_tags(self) + local tags = {} + + for _, t in ipairs(self:tags()) do + if get_screen(t.screen) == get_screen(self.screen) then + table.insert(tags, t) + end + end + + if #tags == 0 then + tags = self.screen.selected_tags + end + + if #tags == 0 then + tags = self.screen.tags + end + + if #tags ~= 0 then + self:tags(tags) + end +end + --- If a client is marked or not. -- -- **Signal:** @@ -678,7 +704,7 @@ end function client.restore(s) s = s or screen.focused() local cls = capi.client.get(s) - local tags = tag.selectedlist(s) + local tags = s.selected_tags for _, c in pairs(cls) do local ctags = c:tags() if c.minimized then @@ -739,8 +765,8 @@ function client.idx(c) end end - local t = tag.selected(c.screen) - local nmaster = tag.getnmaster(t) + local t = c.screen.selected_tag + local nmaster = t.nmaster -- This will happen for floating or maximized clients if not idx then return nil end @@ -755,7 +781,7 @@ function client.idx(c) -- 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) + local ncol = t.ncol -- minimum number of clients per column local percol = math.floor(nother / ncol) -- number of columns with an extra client @@ -793,10 +819,10 @@ function client.setwfact(wfact, c) if not w then return end - local t = tag.selected(c.screen) + local t = c.screen.selected_tag -- 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 data = t.windowfact or {} local colfact = data[w.col] local need_normalize = colfact ~= nil @@ -841,11 +867,11 @@ function client.incwfact(add, c) c = c or capi.client.focus if not c then return end - local t = tag.selected(c.screen) + local t = c.screen.selected_tag local w = client.idx(c) - local data = tag.getproperty(t, "windowfact") or {} + local data = t.windowfact or {} local colfact = data[w.col] or {} local curr = colfact[w.idx] or 1 colfact[w.idx] = curr + add diff --git a/lib/awful/ewmh.lua b/lib/awful/ewmh.lua index 0fffa6dd7..de4af3064 100644 --- a/lib/awful/ewmh.lua +++ b/lib/awful/ewmh.lua @@ -12,7 +12,6 @@ local client = client local screen = screen local ipairs = ipairs local math = math -local atag = require("awful.tag") local aclient = require("awful.client") local ewmh = {} @@ -182,7 +181,7 @@ function ewmh.tag(c, t) if not t then c.sticky = true else - c.screen = atag.getscreen(t) + c.screen = t.screen c:tags({ t }) end end diff --git a/lib/awful/layout/init.lua b/lib/awful/layout/init.lua index cae3cecd1..46853af3d 100644 --- a/lib/awful/layout/init.lua +++ b/lib/awful/layout/init.lua @@ -20,6 +20,7 @@ local capi = { } local tag = require("awful.tag") local client = require("awful.client") +local ascreen = require("awful.screen") local timer = require("gears.timer") local function get_screen(s) @@ -63,7 +64,8 @@ local delayed_arrange = {} -- @param screen The screen. -- @return The layout function. function layout.get(screen) - local t = tag.selected(screen) + screen = screen or capi.mouse.screen + local t = get_screen(screen).selected_tag return tag.getproperty(t, "layout") or layout.suit.floating end @@ -77,8 +79,8 @@ function layout.inc(i, s, layouts) -- this was changed so that 'layouts' can be an optional parameter layouts, i, s = i, s, layouts end - s = get_screen(s) - local t = tag.selected(s) + s = get_screen(s or ascreen.focused()) + local t = s.selected_tag layouts = layouts or layout.layouts if t then local curlayout = layout.get(s) @@ -108,10 +110,10 @@ end --- Set the layout function of the current tag. -- @param _layout Layout name. --- @param t The tag to modify, if null tag.selected() is used. +-- @tparam[opt=mouse.screen.selected_tag] tag t The tag to modify. function layout.set(_layout, t) - t = t or tag.selected() - tag.setproperty(t, "layout", _layout) + t = t or capi.mouse.screen.selected_tag + t.layout = _layout end --- Get the layout parameters used for the screen @@ -129,13 +131,13 @@ end -- "geometries" table with client as keys and geometry as value function layout.parameters(t, screen) screen = get_screen(screen) - t = t or tag.selected(screen) + t = t or screen.selected_tag - screen = get_screen(t and tag.getscreen(t) or 1) + screen = get_screen(t and t.screen or 1) local p = {} - local useless_gap = t and tag.getgap(t, #client.tiled(screen)) or 0 + local useless_gap = t and t.gap or 0 p.workarea = screen:get_bounding_geometry { honor_padding = true, @@ -212,7 +214,7 @@ capi.client.connect_signal("property::screen", function(c, old_screen) end) local function arrange_tag(t) - layout.arrange(tag.getscreen(t)) + layout.arrange(t.screen) end capi.screen.add_signal("arrange") diff --git a/lib/awful/layout/suit/corner.lua b/lib/awful/layout/suit/corner.lua index 6d740567c..7932e65a2 100644 --- a/lib/awful/layout/suit/corner.lua +++ b/lib/awful/layout/suit/corner.lua @@ -11,6 +11,7 @@ -- Grab environment we need local ipairs = ipairs local math = math +local capi = {screen = screen} local tag = require("awful.tag") --- Actually arrange clients of p.clients for corner layout @@ -19,7 +20,7 @@ local tag = require("awful.tag") -- @param orientation String indicating in which corner is the master window. -- Available values are : NE, NW, SW, SE local function do_corner(p, orientation) - local t = p.tag or tag.selected(p.screen) + local t = p.tag or capi.screen[p.screen].selected_tag local wa = p.workarea local cls = p.clients @@ -29,9 +30,9 @@ local function do_corner(p, orientation) local column = {} local row = {} -- Use the nmaster field of the tag in a cheaty way - local row_privileged = ((tag.getnmaster(tag.selected(cls[1].screen)) % 2) == 0) + local row_privileged = ((cls[1].screen.selected_tag.nmaster % 2) == 0) - local master_factor = tag.getmwfact(tag.selected(cls[1].screen)) + local master_factor = cls[1].screen.selected_tag.mwfact master.width = master_factor * wa.width master.height = master_factor * wa.height diff --git a/lib/awful/layout/suit/magnifier.lua b/lib/awful/layout/suit/magnifier.lua index d0e460d72..979672fe8 100644 --- a/lib/awful/layout/suit/magnifier.lua +++ b/lib/awful/layout/suit/magnifier.lua @@ -10,7 +10,6 @@ -- Grab environment we need local ipairs = ipairs local math = math -local tag = require("awful.tag") local capi = { client = client, @@ -40,7 +39,7 @@ function magnifier.mouse_resize_handler(c, corner, x, y) -- New master width factor local mwfact = dist / maxdist_pow - tag.setmwfact(math.min(math.max(0.01, mwfact), 0.99), tag.selected(c.screen)) + c.screen.selected_tag.mwfact = math.min(math.max(0.01, mwfact), 0.99) return true end end @@ -53,8 +52,8 @@ function magnifier.arrange(p) local area = p.workarea local cls = p.clients local focus = p.focus or capi.client.focus - local t = p.tag or tag.selected(p.screen) - local mwfact = tag.getmwfact(t) + local t = p.tag or capi.screen[p.screen].selected_tag + local mwfact = t.mwfact local fidx -- Check that the focused window is on the right screen diff --git a/lib/awful/layout/suit/tile.lua b/lib/awful/layout/suit/tile.lua index 0071ff566..5637f7c19 100644 --- a/lib/awful/layout/suit/tile.lua +++ b/lib/awful/layout/suit/tile.lua @@ -29,7 +29,7 @@ tile.resize_jump_to_corner = true local function mouse_resize_handler(c, _, _, _, orientation) orientation = orientation or "tile" local wa = capi.screen[c.screen].workarea - local mwfact = tag.getmwfact() + local mwfact = c.screen.selected_tag.mwfact local cursor local g = c:geometry() local offset = 0 @@ -126,7 +126,7 @@ local function mouse_resize_handler(c, _, _, _, orientation) wfact = wfact_x end - tag.setmwfact(math.min(math.max(new_mwfact, 0.01), 0.99), tag.selected(c.screen)) + c.screen.selected_tag.mwfact = math.min(math.max(new_mwfact, 0.01), 0.99) client.setwfact(math.min(math.max(wfact,0.01), 0.99), c) return true end @@ -195,7 +195,7 @@ local function tile_group(gs, cls, wa, orientation, fact, group) end local function do_tile(param, orientation) - local t = param.tag or tag.selected(param.screen) + local t = param.tag or capi.screen[param.screen].selected_tag orientation = orientation or "right" -- This handles all different orientations. @@ -208,12 +208,12 @@ local function do_tile(param, orientation) local gs = param.geometries local cls = param.clients - local nmaster = math.min(tag.getnmaster(t), #cls) + local nmaster = math.min(t.nmaster, #cls) local nother = math.max(#cls - nmaster,0) - local mwfact = tag.getmwfact(t) + local mwfact = t.mwfact local wa = param.workarea - local ncol = tag.getncol(t) + local ncol = t.ncol local data = tag.getdata(t).windowfact @@ -229,7 +229,7 @@ local function do_tile(param, orientation) place_master = false end - local grow_master = tag.getmfpol(t) == "expand" + local grow_master = t.master_fill_policy == "expand" -- this was easier than writing functions because there is a lot of data we need for _ = 1,2 do if place_master and nmaster > 0 then diff --git a/lib/awful/menu.lua b/lib/awful/menu.lua index e444c06b5..0dc622696 100644 --- a/lib/awful/menu.lua +++ b/lib/awful/menu.lua @@ -609,7 +609,7 @@ end -- terms[i] = -- {c.name, -- function() --- awful.tag.viewonly(c.first_tag) +-- c.first_tag:view_only() -- client.focus = c -- end, -- c.icon diff --git a/lib/awful/mouse/init.lua b/lib/awful/mouse/init.lua index 69cf85d6c..b1e362e09 100644 --- a/lib/awful/mouse/init.lua +++ b/lib/awful/mouse/init.lua @@ -229,8 +229,8 @@ function mouse.client.dragtotag.border(c) capi.mouse.coords({ x = wa.x + 1 }) end if not button_down then - local tags = tag.gettags(c.screen) - local t = tag.selected() + local tags = c.screen.tags + local t = c.screen.selected_tag local idx for i, v in ipairs(tags) do if v == t then diff --git a/lib/awful/rules.lua b/lib/awful/rules.lua index ec4dfe50a..42c6425b6 100644 --- a/lib/awful/rules.lua +++ b/lib/awful/rules.lua @@ -13,7 +13,6 @@ local table = table local type = type local ipairs = ipairs local pairs = pairs -local atag = require("awful.tag") local rules = {} @@ -199,10 +198,10 @@ function rules.execute(c, props, callbacks) value = value(c) end if property == "tag" then - c.screen = atag.getscreen(value) + c.screen = value.screen c:tags({ value }) elseif property == "switchtotag" and value and props.tag then - atag.viewonly(props.tag) + props.tag:view_only() elseif property == "height" or property == "width" or property == "x" or property == "y" then local geo = c:geometry(); diff --git a/lib/awful/screen.lua b/lib/awful/screen.lua index c78d89860..699436796 100644 --- a/lib/awful/screen.lua +++ b/lib/awful/screen.lua @@ -306,8 +306,13 @@ end -- Minimized and unmanaged clients are not included in this list as they are -- technically not on the screen. -- +-- The clients on tags currently not visible are not part of this list. +-- -- @property clients -- @param table The clients list, ordered top to bottom +-- @see all_clients +-- @see hidden_clients +-- @see client.get function screen.object.get_clients(s) local cls = capi.client.get(s, true) @@ -322,6 +327,44 @@ end function screen.object.set_clients() end +--- Get the list of the clients assigned to the screen but not currently +-- visible. +-- +-- This include minimized clients and clients on hidden tags. +-- +-- @property hidden_clients +-- @param table The clients list, ordered top to bottom +-- @see clients +-- @see all_clients +-- @see client.get + +function screen.object.get_hidden_clients(s) + local cls = capi.client.get(s, true) + local vcls = {} + for _, c in pairs(cls) do + if not c:isvisible() then + table.insert(vcls, c) + end + end + return vcls +end + +function screen.object.set_hidden_clients() end + +--- Get all clients assigned to the screen. +-- +-- @property all_clients +-- @param table The clients list, ordered top to bottom +-- @see clients +-- @see hidden_clients +-- @see client.get + +function screen.object.get_all_clients(s) + return capi.client.get(s, true) +end + +function screen.object.set_all_clients() end + --- Get the list of the screen tiled clients. -- -- Same as s.clients, but excluding: @@ -368,6 +411,71 @@ function screen.disconnect_for_each_screen(func) capi.screen.disconnect_signal("added", func) end +--- A list of all tags on the screen. +-- +-- This property is read only, use `tag.screen`, `awful.tag.add`, `awful.tag.new` +-- or `t:delete()` to alter this list. +-- +-- @property tags +-- @param table +-- @treturn table A table with all available tags + +function screen.object.get_tags(s, unordered) + local tags = {} + + for _, t in ipairs(root.tags()) do + if get_screen(t.screen) == s then + table.insert(tags, t) + end + end + + -- Avoid infinite loop, + save some time + if not unordered then + table.sort(tags, function(a, b) + return (a.index or 9999) < (b.index or 9999) + end) + end + + return tags +end + +function screen.object.set_tags() end + +--- A list of all selected tags on the screen. +-- @property selected_tags +-- @param table +-- @treturn table A table with all selected tags. +-- @see tag.selected +-- @see client.to_selected_tags + +function screen.object.get_selected_tags(s) + local tags = screen.object.get_tags(s, true) + + local vtags = {} + for _, t in pairs(tags) do + if t.selected then + vtags[#vtags + 1] = t + end + end + return vtags +end + +function screen.object.set_selected_tags() end + +--- The first selected tag. +-- @property selected_tag +-- @param table +-- @treturn ?tag The first selected tag or nil +-- @see tag.selected +-- @see selected_tags + +function screen.object.get_selected_tag(s) + return screen.object.get_selected_tags(s)[1] +end + +function screen.object.set_selected_tag() end + + --- When the tag history changed. -- @signal tag::history::update diff --git a/lib/awful/tag.lua b/lib/awful/tag.lua index d3ca91e9a..399f41373 100644 --- a/lib/awful/tag.lua +++ b/lib/awful/tag.lua @@ -29,10 +29,11 @@ local function get_screen(s) return s and capi.screen[s] end --- we use require("awful.client") inside functions to prevent circular dependencies. +-- awful.client is required() at the end of this file so the miss_handler is set +-- before it is being required. local client -local tag = { mt = {} } +local tag = {object = {}, mt = {} } -- Private data local data = {} @@ -44,6 +45,78 @@ data.tags = setmetatable({}, { __mode = 'k' }) tag.history = {} tag.history.limit = 20 +-- screen.tags depend on index, it cannot be used by awful.tag +local function raw_tags(scr) + local tmp_tags = {} + for _, t in ipairs(root.tags()) do + if get_screen(t.screen) == scr then + table.insert(tmp_tags, t) + end + end + + return tmp_tags +end + +--- The number of elements kept in the history. +-- @tfield integer awful.tag.history.limit + +--- The tag index. +-- +-- The index is the position as shown in the `awful.widget.taglist`. +-- +-- **Signal:** +-- +-- * *property::index* +-- +-- @property index +-- @param integer +-- @treturn number The tag index. + +function tag.object.set_index(self, idx) + local scr = get_screen(tag.getproperty(self, "screen")) + + -- screen.tags cannot be used as it depend on index + local tmp_tags = raw_tags(scr) + + if (not idx) or (idx < 1) or (idx > #tmp_tags) then + return + end + + local rm_index = nil + + for i, t in ipairs(tmp_tags) do + if t == self then + table.remove(tmp_tags, i) + rm_index = i + break + end + end + + table.insert(tmp_tags, idx, self) + for i = idx < rm_index and idx or rm_index, #tmp_tags do + local tmp_tag = tmp_tags[i] + tag.object.set_screen(tmp_tag, scr) + tag.setproperty(tmp_tag, "index", i, true) + end +end + +function tag.object.get_index(query_tag) + -- Get an unordered list of tags + local tags = raw_tags(query_tag.screen) + + local idx = tag.getproperty(query_tag, "index") + + if idx then return idx end + + -- Too bad, lets compute it + for i, t in ipairs(tags) do + if t == query_tag then + tag.setproperty(t, "index", i, true) + return i + end + end +end + --- Move a tag to an absolute position in the screen[]:tags() table. -- @deprecated awful.tag.move -- @param new_index Integer absolute position in the table to insert. @@ -51,30 +124,31 @@ tag.history.limit = 20 -- selected tag is used. -- @see index function tag.move(new_index, target_tag) - target_tag = target_tag or tag.selected() - local scr = get_screen(tag.getscreen(target_tag)) - local tmp_tags = tag.gettags(scr) + util.deprecate("Use t.index = new_index instead of awful.tag.move") - if (not new_index) or (new_index < 1) or (new_index > #tmp_tags) then - return - end + target_tag = target_tag or ascreen.focused().selected_tag + tag.object.set_index(target_tag, new_index) +end - local rm_index = nil +--- Swap 2 tags +-- @function tag.swap +-- @see tag.swap +-- @param tag2 The second tag +-- @see client.swap +function tag.object.swap(self, tag2) + local idx1, idx2 = tag.object.get_index(self), tag.object.get_index(tag2) + local scr2, scr1 = tag.getproperty(tag2, "screen"), tag.getproperty(self, "screen") - for i, t in ipairs(tmp_tags) do - if t == target_tag then - table.remove(tmp_tags, i) - rm_index = i - break - end - end - - table.insert(tmp_tags, new_index, target_tag) - - for i=new_index < rm_index and new_index or rm_index, #tmp_tags do - local tmp_tag = tmp_tags[i] - tag.setscreen(scr, tmp_tag) - tag.setproperty(tmp_tag, "index", i) + -- If they are on the same screen, avoid recomputing the whole table + -- for nothing. + if scr1 == scr2 then + tag.setproperty(self, "index", idx2, true) + tag.setproperty(tag2, "index", idx1, true) + else + tag.object.set_screen(tag2, scr1) + tag.object.set_index (tag2, idx1) + tag.object.set_screen(self, scr2) + tag.object.set_index (self, idx2) end end @@ -84,19 +158,25 @@ end -- @param tag1 The first tag -- @param tag2 The second tag function tag.swap(tag1, tag2) - local idx1, idx2 = tag.getidx(tag1), tag.getidx(tag2) - local src2, src1 = tag.getscreen(tag2), tag.getscreen(tag1) - tag.setscreen(src1, tag2) - tag.move(idx1, tag2) - tag.setscreen(src2, tag1) - tag.move(idx2, tag1) + util.deprecate("Use t:swap(tag2) instead of awful.tag.swap") + + tag.object.swap(tag1, tag2) end --- Add a tag. +-- +-- This function allow to create tags from a set of properties: +-- +-- local t = awful.tag.add("my new tag", { +-- screen = screen.primary, +-- layout = awful.layout.suit.max, +-- }) +-- -- @function awful.tag.add -- @param name The tag name, a string -- @param props The tags inital properties, a table -- @return The created tag +-- @see tag.delete function tag.add(name, props) local properties = props or {} @@ -105,9 +185,8 @@ function tag.add(name, props) -- set properties cannot be used as this has to be set before the first -- signal is sent properties.screen = get_screen(properties.screen or ascreen.focused()) - -- Index is also required - properties.index = (#tag.gettags(properties.screen))+1 + properties.index = #raw_tags(properties.screen)+1 local newtag = capi.tag{ name = name } @@ -117,7 +196,13 @@ function tag.add(name, props) newtag.activated = true for k, v in pairs(properties) do - tag.setproperty(newtag, k, v) + -- `rawget` doesn't work on userdata, `:clients()` is the only relevant + -- entry. + if k == "clients" or tag.object[k] then + newtag[k](newtag, v) + else + newtag[k] = v + end end return newtag @@ -151,43 +236,49 @@ end -- @param invalids A table of tags we consider unacceptable. [selectedlist(scr)] function tag.find_fallback(screen, invalids) local scr = screen or ascreen.focused() - local t = invalids or tag.selectedlist(scr) + local t = invalids or scr.selected_tags - for _, v in pairs(tag.gettags(scr)) do + for _, v in pairs(scr.tags) do if not util.table.hasitem(t, v) then return v end end end --- Delete a tag. --- @deprecated awful.tag.delete --- @see tag.delete --- @param target_tag Optional tag object to delete. [selected()] --- @param fallback_tag Tag to assign stickied tags to. [~selected()] +-- +-- To delete the current tag: +-- +-- mouse.screen.selected_tag:delete() +-- +-- @function tag.delete +-- @see awful.tag.add +-- @see awful.tag.find_fallback +-- @tparam[opt=awful.tag.find_fallback()] tag fallback_tag Tag to assign +-- stickied tags to. -- @return Returns true if the tag is successfully deleted, nil otherwise. -- If there are no clients exclusively on this tag then delete it. Any -- stickied clients are assigned to the optional 'fallback_tag'. -- If after deleting the tag there is no selected tag, try and restore from -- history or select the first tag on the screen. -function tag.delete(target_tag, fallback_tag) - -- abort if no tag is passed or currently selected - target_tag = target_tag or tag.selected() - if target_tag == nil or target_tag.activated == false then return end +function tag.object.delete(self, fallback_tag) - local target_scr = get_screen(tag.getscreen(target_tag)) - local tags = tag.gettags(target_scr) - local idx = tag.getidx(target_tag) + -- abort if the taf isn't currently activated + if not self.activated then return end + + local target_scr = get_screen(tag.getproperty(self, "screen")) + local tags = target_scr.tags + local idx = tag.object.get_index(self) local ntags = #tags -- We can't use the target tag as a fallback. - if fallback_tag == target_tag then return end + if fallback_tag == self then return end -- No fallback_tag provided, try and get one. if fallback_tag == nil then - fallback_tag = tag.find_fallback(target_scr, {target_tag}) + fallback_tag = tag.find_fallback(target_scr, {self}) end -- Abort if we would have un-tagged clients. - local clients = target_tag:clients() + local clients = self:clients() if ( #clients > 0 and ntags <= 1 ) or fallback_tag == nil then return end -- Move the clients we can off of this tag. @@ -206,8 +297,8 @@ function tag.delete(target_tag, fallback_tag) end -- delete the tag - data.tags[target_tag].screen = nil - target_tag.activated = false + data.tags[self].screen = nil + self.activated = false -- Update all indexes for i=idx+1, #tags do @@ -215,22 +306,38 @@ function tag.delete(target_tag, fallback_tag) end -- If no tags are visible, try and view one. - if tag.selected(target_scr) == nil and ntags > 0 then + if target_scr.selected_tag == nil and ntags > 0 then tag.history.restore(nil, 1) - if tag.selected(target_scr) == nil then - tags[tags[1] == target_tag and 2 or 1].selected = true + if target_scr.selected_tag == nil then + tags[tags[1] == self and 2 or 1].selected = true end end return true end +--- Delete a tag. +-- @deprecated awful.tag.delete +-- @see tag.delete +-- @param target_tag Optional tag object to delete. [selected()] +-- @param fallback_tag Tag to assign stickied tags to. [~selected()] +-- @return Returns true if the tag is successfully deleted, nil otherwise. +-- If there are no clients exclusively on this tag then delete it. Any +-- stickied clients are assigned to the optional 'fallback_tag'. +-- If after deleting the tag there is no selected tag, try and restore from +-- history or select the first tag on the screen. +function tag.delete(target_tag, fallback_tag) + util.deprecate("Use t:delete(fallback_tag) instead of awful.tag.delete") + + return tag.object.delete(target_tag, fallback_tag) +end + --- Update the tag history. --- @function awful.history.update +-- @function awful.tag.history.update -- @param obj Screen object. function tag.history.update(obj) local s = get_screen(obj) - local curtags = tag.selectedlist(s) + local curtags = s.selected_tags -- create history table if not data.history[s] then data.history[s] = {} @@ -267,7 +374,7 @@ function tag.history.update(obj) end --- Revert tag history. --- @function awful.history.restore +-- @function awful.tag.history.restore -- @param screen The screen. -- @param idx Index in history. Defaults to "previous" which is a special index -- toggling between last two selected sets of tags. Number (eg 1) will go back @@ -275,7 +382,7 @@ end function tag.history.restore(screen, idx) local s = get_screen(screen or ascreen.focused()) local i = idx or "previous" - local sel = tag.selectedlist(s) + local sel = s.selected_tags -- do nothing if history empty if not data.history[s] or not data.history[s][i] then return end -- if all tags been deleted, try next entry @@ -300,42 +407,35 @@ function tag.history.restore(screen, idx) s:emit_signal("tag::history::update") end ---TODO move to screen - --- Get a list of all tags on a screen --- @param s Screen +-- @deprecated awful.tag.gettags +-- @tparam screen s Screen -- @return A table with all available tags +-- @see screen.tags function tag.gettags(s) - s = get_screen(s) - local tags = {} - for _, t in ipairs(root.tags()) do - if get_screen(tag.getscreen(t)) == s then - table.insert(tags, t) - end - end + util.deprecate("Use s.tags instead of awful.tag.gettags") - table.sort(tags, function(a, b) - return (tag.getproperty(a, "index") or 9999) < (tag.getproperty(b, "index") or 9999) - end) - return tags + s = get_screen(s) + + return s and s.tags or {} end ---- Set a tag's screen --- @deprecated awful.tag.setscreen +--- The tag screen. +-- +-- **Signal:** +-- +-- * *property::screen* +-- +-- @property screen +-- @param screen -- @see screen --- @param s Screen --- @param t tag object -function tag.setscreen(s, t) - -- For API consistency, the arguments have been swapped for Awesome 3.6 - if type(t) == "number" then - util.deprecate("tag.setscreen arguments are now (s, t) instead of (t, s)") - s, t = t, s - end +function tag.object.set_screen(t, s) s = get_screen(s or ascreen.focused()) local sel = tag.selected - local old_screen = tag.getproperty(t, "screen") + local old_screen = get_screen(tag.getproperty(t, "screen")) + if s == old_screen then return end -- Keeping the old index make very little sense when changing screen @@ -352,7 +452,7 @@ function tag.setscreen(s, t) -- Update all indexes for _,screen in ipairs {old_screen, s} do - for i,t2 in ipairs(tag.gettags(screen)) do + for i,t2 in ipairs(screen.tags) do tag.setproperty(t2, "index", i, true) end end @@ -363,58 +463,110 @@ function tag.setscreen(s, t) end end +--- Set a tag's screen +-- @deprecated awful.tag.setscreen +-- @see screen +-- @param s Screen +-- @param t tag object +function tag.setscreen(s, t) + -- For API consistency, the arguments have been swapped for Awesome 3.6 + -- this method is already deprecated, so be silent and swap the args + if type(t) == "number" then + s, t = t, s + end + + util.deprecate("Use t.screen = s instead of awful.tag.setscreen(t, s)") + + tag.object.set_screen(t, s) +end + --- Get a tag's screen -- @deprecated awful.tag.getscreen -- @see screen -- @param[opt] t tag object -- @return Screen number function tag.getscreen(t) - t = t or tag.selected() + util.deprecate("Use t.screen instead of awful.tag.setscreen(t, s)") + + -- A new getter is not required + + t = t or ascreen.focused().selected_tag local prop = tag.getproperty(t, "screen") return prop and prop.index end ---TODO move to screen - --- Return a table with all visible tags +-- @deprecated awful.tag.selectedlist -- @param s Screen. -- @return A table with all selected tags. +-- @see screen.selected_tags function tag.selectedlist(s) - local screen = s or ascreen.focused() - local tags = tag.gettags(screen) - local vtags = {} - for _, t in pairs(tags) do - if t.selected then - vtags[#vtags + 1] = t - end - end - return vtags -end + util.deprecate("Use s.selected_tags instead of awful.tag.selectedlist") ---TODO move to screen + s = get_screen(s or ascreen.focused()) + + return s.selected_tags +end --- Return only the first visible tag. +-- @deprecated awful.tag.selected -- @param s Screen. +-- @see screen.selected_tag function tag.selected(s) - return tag.selectedlist(s)[1] + util.deprecate("Use s.selected_tag instead of awful.tag.selected") + + s = get_screen(s or ascreen.focused()) + + return s.selected_tag end ---- Set master width factor. --- @param mwfact Master width factor. --- @param t The tag to modify, if null tag.selected() is used. -function tag.setmwfact(mwfact, t) - t = t or tag.selected() +--- The tag master width factor. +-- +-- The master width factor is one of the 5 main properties used to configure +-- the `layout`. Each layout interpret (or ignore) this property differenly. +-- +-- See the layout suit documentation for information about how the master width +-- factor is used. +-- +-- **Signal:** +-- +-- * *property::mwfact* +-- +-- @property mwfact +-- @param number Between 0 and 1 +-- @see nmaster +-- @see ncol +-- @see master_fill_policy +-- @see gap + +function tag.object.set_mwfact(t, mwfact) if mwfact >= 0 and mwfact <= 1 then tag.setproperty(t, "mwfact", mwfact, true) end end +function tag.object.get_mwfact(t) + return tag.getproperty(t, "mwfact") or 0.5 +end + +--- Set master width factor. +-- @deprecated awful.tag.setmwfact +-- @see master_fill_policy +-- @param mwfact Master width factor. +-- @param t The tag to modify, if null tag.selected() is used. +function tag.setmwfact(mwfact, t) + util.deprecate("Use t.mwfact = mwfact instead of awful.tag.setmwfact") + + tag.object.get_mwfact(t or ascreen.focused().selected_tag, mwfact) +end + --- Increase master width factor. -- @function awful.tag.incmwfact -- @param add Value to add to master width factor. -- @param t The tag to modify, if null tag.selected() is used. function tag.incmwfact(add, t) - tag.setmwfact(tag.getmwfact(t) + add, t) + t = t or t or ascreen.focused().selected_tag + tag.object.set_mwfact(t, tag.object.get_mwfact(t) + add) end --- Get master width factor. @@ -422,18 +574,77 @@ end -- @see mwfact -- @param[opt] t The tag. function tag.getmwfact(t) - t = t or tag.selected() - return tag.getproperty(t, "mwfact") or 0.5 + util.deprecate("Use t.mwfact instead of awful.tag.getmwfact") + + return tag.object.get_mwfact(t or ascreen.focused().selected_tag) end ---- Set layout --- @deprecated awful.tag.setlayout --- @see layout --- @param layout a layout table or a constructor function --- @param t The tag to modify --- @return The layout -function tag.setlayout(layout, t) +--- An ordered list of layouts. +-- `awful.tag.layout` Is usually defined in `rc.lua`. It store the list of +-- layouts used when selecting the previous and next layouts. This is the +-- default: +-- +-- -- Table of layouts to cover with awful.layout.inc, order matters. +-- awful.layout.layouts = { +-- awful.layout.suit.floating, +-- awful.layout.suit.tile, +-- awful.layout.suit.tile.left, +-- awful.layout.suit.tile.bottom, +-- awful.layout.suit.tile.top, +-- awful.layout.suit.fair, +-- awful.layout.suit.fair.horizontal, +-- awful.layout.suit.spiral, +-- awful.layout.suit.spiral.dwindle, +-- awful.layout.suit.max, +-- awful.layout.suit.max.fullscreen, +-- awful.layout.suit.magnifier, +-- awful.layout.suit.corner.nw, +-- -- awful.layout.suit.corner.ne, +-- -- awful.layout.suit.corner.sw, +-- -- awful.layout.suit.corner.se, +-- } +-- +-- @field awful.tag.layouts +--- The tag client layout. +-- +-- This property hold the layout. A layout can be either stateless or stateful. +-- Stateless layouts are used by default by Awesome. They tile clients without +-- any other overhead. They take an ordered list of clients and place them on +-- the screen. Stateful layouts create an object instance for each tags and +-- can store variables and metadata. Because of this, they are able to change +-- over time and be serialized (saved). +-- +-- Both types of layouts have valid usage scenarios. +-- +-- **Stateless layouts:** +-- +-- These layouts are stored in `awful.layout.suit`. They expose a table with 2 +-- fields: +-- +-- * **name** (*string*): The layout name. This should be unique. +-- * **arrange** (*function*): The function called when the clients need to be +-- placed. The only parameter is a table or arguments returned by +-- `awful.layout.parameters` +-- +-- **Stateful layouts:** +-- +-- The stateful layouts API is the same as stateless, but they are a function +-- returining a layout instead of a layout itself. They also should have an +-- `is_dynamic = true` property. If they don't, `awful.tag` will create a new +-- instance everytime the layout is set. If they do, the instance will be +-- cached and re-used. +-- +-- **Signal:** +-- +-- * *property::layout* +-- +-- @property layout +-- @see awful.tag.layouts +-- @tparam layout|function layout A layout table or a constructor function +-- @return The layout + +function tag.object.set_layout(t, layout) -- Check if the signature match a stateful layout if type(layout) == "function" or ( type(layout) == "table" @@ -447,7 +658,7 @@ function tag.setlayout(layout, t) local instance = data.dynamic_cache[t][layout] or layout(t) -- Always make sure the layout is notified it is enabled - if tag.selected(tag.getscreen(t)) == t and instance.wake_up then + if tag.getproperty(t, "screen").selected_tag == t and instance.wake_up then instance:wake_up() end @@ -464,12 +675,49 @@ function tag.setlayout(layout, t) return layout end +--- Set layout. +-- @deprecated awful.tag.setlayout +-- @see layout +-- @param layout a layout table or a constructor function +-- @param t The tag to modify +-- @return The layout +function tag.setlayout(layout, t) + util.deprecate("Use t.layout = layout instead of awful.tag.setlayout") + + return tag.object.set_layout(t, layout) +end + +--- Define if the tag must be deleted when the last client is untagged. +-- +-- This is useful to create "throw-away" tags for operation like 50/50 +-- side-by-side views. +-- +-- local t = awful.tag.add("Temporary", { +-- screen = client.focus.screen, +-- volatile = true, +-- clients = { +-- client.focus, +-- awful.client.focus.history.get(client.focus.screen, 1) +-- } +-- } +-- +-- **Signal:** +-- +-- * *property::volatile* +-- +-- @property volatile +-- @param boolean + +-- Volatile accessors are implicit + --- Set if the tag must be deleted when the last client is untagged -- @deprecated awful.tag.setvolatile -- @see volatile -- @tparam boolean volatile If the tag must be deleted when the last client is untagged -- @param t The tag to modify, if null tag.selected() is used. function tag.setvolatile(volatile, t) + util.deprecate("Use t.volatile = volatile instead of awful.tag.setvolatile") + tag.setproperty(t, "volatile", volatile, true) end @@ -479,89 +727,161 @@ end -- @param t The tag to modify, if null tag.selected() is used. -- @treturn boolean If the tag will be deleted when the last client is untagged function tag.getvolatile(t) + util.deprecate("Use t.volatile instead of awful.tag.getvolatile") + return tag.getproperty(t, "volatile") or false end +--- The default gap. +-- +-- @beautiful beautiful.useless_gap +-- @param number (default: 0) +-- @see gap + +--- The gap (spacing, also called `useless_gap`) between clients. +-- +-- This property allow to waste space on the screen in the name of style, +-- unicorns and readability. +-- +-- **Signal:** +-- +-- * *property::gap* +-- +-- @property gap +-- @param number The value has to be greater than zero. + +function tag.object.set_gap(t, useless_gap) + if useless_gap >= 0 then + tag.setproperty(t, "useless_gap", useless_gap, true) + end +end + +function tag.object.get_gap(t) + return tag.getproperty(t, "useless_gap") or beautiful.useless_gap or 0 +end + --- Set the spacing between clients -- @deprecated awful.tag.setgap -- @see gap -- @param useless_gap The spacing between clients -- @param t The tag to modify, if null tag.selected() is used. function tag.setgap(useless_gap, t) - t = t or tag.selected() - if useless_gap >= 0 then - tag.setproperty(t, "useless_gap", useless_gap, true) - end + util.deprecate("Use t.gap = useless_gap instead of awful.tag.setgap") + + tag.object.set_gap(t or ascreen.focused().selected_tag, useless_gap) end --- Increase the spacing between clients -- @function awful.tag.incgap +-- @see gap -- @param add Value to add to the spacing between clients -- @param t The tag to modify, if null tag.selected() is used. function tag.incgap(add, t) - tag.setgap(tag.getgap(t) + add, t) + t = t or t or ascreen.focused().selected_tag + tag.object.set_gap(t, tag.object.get_gap(t) + add) end --- Get the spacing between clients. +-- @deprecated awful.tag.getgap +-- @see gap -- @tparam[opt=tag.selected()] tag t The tag. -- @tparam[opt] int numclients Number of (tiled) clients. Passing this will -- return 0 for a single client. You can override this function to change -- this behavior. function tag.getgap(t, numclients) - t = t or tag.selected() + util.deprecate("Use t.gap instead of awful.tag.getgap") + if numclients == 1 then return 0 end - return tag.getproperty(t, "useless_gap") or beautiful.useless_gap or 0 + + return tag.object.get_gap(t or ascreen.focused().selected_tag) +end + +--- Set size fill policy for the master client(s). +-- +-- **Signal:** +-- +-- * *property::master_fill_policy* +-- +-- @property master_fill_policy +-- @param string "expand" or "mwfact" + +function tag.object.get_master_fill_policy(t) + return tag.getproperty(t, "master_fill_policy") or "expand" end --- Set size fill policy for the master client(s) -- @deprecated awful.tag.setmfpol --- @see mfpol +-- @see master_fill_policy -- @tparam string policy Can be set to -- "expand" (fill all the available workarea) or -- "mwfact" (fill only an area inside the master width factor) -- @tparam[opt=tag.selected()] tag t The tag to modify function tag.setmfpol(policy, t) - t = t or tag.selected() + util.deprecate("Use t.master_fill_policy = policy instead of awful.tag.setmfpol") + + t = t or ascreen.focused().selected_tag tag.setproperty(t, "master_fill_policy", policy, true) end --- Toggle size fill policy for the master client(s) --- @deprecated awful.tag.togglemfpol --- @see tag.toggle_mfpol --- between "expand" and "mwfact" +-- between "expand" and "mwfact". +-- @function awful.tag.togglemfpol +-- @see master_fill_policy -- @tparam tag t The tag to modify, if null tag.selected() is used. function tag.togglemfpol(t) + t = t or ascreen.focused().selected_tag + if tag.getmfpol(t) == "expand" then - tag.setmfpol("mwfact", t) + tag.setproperty(t, "master_fill_policy", "mwfact", true) else - tag.setmfpol("expand", t) + tag.setproperty(t, "master_fill_policy", "expand", true) end end --- Get size fill policy for the master client(s) -- @deprecated awful.tag.getmfpol --- @see mfpol +-- @see master_fill_policy -- @tparam[opt=tag.selected()] tag t The tag -- @treturn string Possible values are -- "expand" (fill all the available workarea, default one) or -- "mwfact" (fill only an area inside the master width factor) function tag.getmfpol(t) - t = t or tag.selected() + util.deprecate("Use t.master_fill_policy instead of awful.tag.getmfpol") + + t = t or ascreen.focused().selected_tag return tag.getproperty(t, "master_fill_policy") or "expand" end --- Set the number of master windows. +-- +-- **Signal:** +-- +-- * *property::nmaster* +-- +-- @property nmaster +-- @param integer nmaster Only positive values are accepted + +function tag.object.set_nmaster(t, nmaster) + if nmaster >= 0 then + tag.setproperty(t, "nmaster", nmaster, true) + end +end + +function tag.object.get_nmaster(t) + return tag.getproperty(t, "nmaster") or 1 +end + +--- -- @deprecated awful.tag.setnmaster -- @see nmaster -- @param nmaster The number of master windows. -- @param[opt] t The tag. function tag.setnmaster(nmaster, t) - t = t or tag.selected() - if nmaster >= 0 then - tag.setproperty(t, "nmaster", nmaster, true) - end + util.deprecate("Use t.nmaster = nmaster instead of awful.tag.setnmaster") + + tag.object.set_nmaster(t or ascreen.focused().selected_tag, nmaster) end --- Get the number of master windows. @@ -569,7 +889,9 @@ end -- @see nmaster -- @param[opt] t The tag. function tag.getnmaster(t) - t = t or tag.selected() + util.deprecate("Use t.nmaster instead of awful.tag.setnmaster") + + t = t or ascreen.focused().selected_tag return tag.getproperty(t, "nmaster") or 1 end @@ -580,12 +902,13 @@ end -- @tparam[opt=false] boolean sensible Limit nmaster based on the number of -- visible tiled windows? function tag.incnmaster(add, t, sensible) - if sensible then - client = client or require("awful.client") - local screen = get_screen(tag.getscreen(t)) - local ntiled = #client.tiled(screen) + t = t or ascreen.focused().selected_tag - local nmaster = tag.getnmaster(t) + if sensible then + local screen = get_screen(tag.getproperty(t, "screen")) + local ntiled = #screen.tiled_clients + + local nmaster = tag.object.get_nmaster(t) if nmaster > ntiled then nmaster = ntiled end @@ -594,12 +917,22 @@ function tag.incnmaster(add, t, sensible) if newnmaster > ntiled then newnmaster = ntiled end - tag.setnmaster(newnmaster, t) + tag.object.set_nmaster(t, newnmaster) else - tag.setnmaster(tag.getnmaster(t) + add, t) + tag.object.set_nmaster(t, tag.object.get_nmaster(t) + add) end end +--- Set the tag icon. +-- +-- **Signal:** +-- +-- * *property::icon* +-- +-- @property icon +-- @tparam path|surface icon The icon + +-- accessors are implicit. --- Set the tag icon -- @deprecated awful.tag.seticon @@ -607,7 +940,9 @@ end -- @param icon the icon to set, either path or image object -- @param _tag the tag function tag.seticon(icon, _tag) - _tag = _tag or tag.selected() + util.deprecate("Use t.icon = icon instead of awful.tag.seticon") + + _tag = _tag or ascreen.focused().selected_tag tag.setproperty(_tag, "icon", icon, true) end @@ -616,17 +951,40 @@ end -- @see icon -- @param _tag the tag function tag.geticon(_tag) - _tag = _tag or tag.selected() + util.deprecate("Use t.icon instead of awful.tag.geticon") + + _tag = _tag or ascreen.focused().selected_tag return tag.getproperty(_tag, "icon") end +--- Set the number of columns. +-- +-- **Signal:** +-- +-- * *property::ncol* +-- +-- @property ncol +-- @param integer ncol Has to be greater than 1 + +function tag.object.set_ncol(t, ncol) + if ncol >= 1 then + tag.setproperty(t, "ncol", ncol, true) + end +end + +function tag.object.get_ncol(t) + return tag.getproperty(t, "ncol") or 1 +end + --- Set number of column windows. -- @deprecated awful.tag.setncol -- @see ncol -- @param ncol The number of column. -- @param t The tag to modify, if null tag.selected() is used. function tag.setncol(ncol, t) - t = t or tag.selected() + util.deprecate("Use t.ncol = new_index instead of awful.tag.setncol") + + t = t or ascreen.focused().selected_tag if ncol >= 1 then tag.setproperty(t, "ncol", ncol, true) end @@ -637,7 +995,9 @@ end -- @see ncol -- @param[opt] t The tag. function tag.getncol(t) - t = t or tag.selected() + util.deprecate("Use t.ncol instead of awful.tag.getncol") + + t = t or ascreen.focused().selected_tag return tag.getproperty(t, "ncol") or 1 end @@ -648,14 +1008,15 @@ end -- @tparam[opt=false] boolean sensible Limit ncol based on the number of visible -- tiled windows? function tag.incncol(add, t, sensible) + t = t or ascreen.focused().selected_tag + if sensible then - client = client or require("awful.client") - local screen = get_screen(tag.getscreen(t)) - local ntiled = #client.tiled(screen) - local nmaster = tag.getnmaster(t) + local screen = get_screen(tag.getproperty(t, "screen")) + local ntiled = #screen.tiled_clients + local nmaster = tag.object.get_nmaster(t) local nsecondary = ntiled - nmaster - local ncol = tag.getncol(t) + local ncol = tag.object.get_ncol(t) if ncol > nsecondary then ncol = nsecondary end @@ -664,9 +1025,10 @@ function tag.incncol(add, t, sensible) if newncol > nsecondary then newncol = nsecondary end - tag.setncol(newncol, t) + + tag.object.set_ncol(t, newncol) else - tag.setncol(tag.getncol(t) + add, t) + tag.object.set_ncol(t, tag.object.get_ncol(t) + add) end end @@ -674,7 +1036,8 @@ end -- @function awful.tag.viewnone -- @tparam[opt] int|screen screen The screen. function tag.viewnone(screen) - local tags = tag.gettags(screen or ascreen.focused()) + screen = screen or ascreen.focused() + local tags = screen.tags for _, t in pairs(tags) do t.selected = false end @@ -689,14 +1052,14 @@ end -- @param[opt] screen The screen. function tag.viewidx(i, screen) screen = get_screen(screen or ascreen.focused()) - local tags = tag.gettags(screen) + local tags = screen.tags local showntags = {} for _, t in ipairs(tags) do if not tag.getproperty(t, "hide") then table.insert(showntags, t) end end - local sel = tag.selected(screen) + local sel = screen.selected_tag tag.viewnone(screen) for k, t in ipairs(showntags) do if t == sel then @@ -712,14 +1075,9 @@ end -- @param query_tag The tag object to find. [selected()] -- @return The index of the tag, nil if the tag is not found. function tag.getidx(query_tag) - query_tag = query_tag or tag.selected() - if query_tag == nil then return end + util.deprecate("Use t.index instead of awful.tag.getidx") - for i, t in ipairs(tag.gettags(tag.getscreen(query_tag))) do - if t == query_tag then - return i - end - end + return tag.object.get_index(query_tag or ascreen.focused().selected_tag) end --- View next tag. This is the same as tag.viewidx(1). @@ -737,22 +1095,31 @@ function tag.viewprev(screen) end --- View only a tag. --- @deprecated awful.tag.viewonly --- @see screen.view_only --- @param t The tag object. -function tag.viewonly(t) - local tags = tag.gettags(tag.getscreen(t)) +-- @function tag.view_only +-- @see selected +function tag.object.view_only(self) + local tags = self.screen.tags -- First, untag everyone except the viewed tag. for _, _tag in pairs(tags) do - if _tag ~= t then + if _tag ~= self then _tag.selected = false end end -- Then, set this one to selected. -- We need to do that in 2 operations so we avoid flickering and several tag -- selected at the same time. - t.selected = true - capi.screen[tag.getscreen(t)]:emit_signal("tag::history::update") + self.selected = true + capi.screen[self.screen]:emit_signal("tag::history::update") +end + +--- View only a tag. +-- @deprecated awful.tag.viewonly +-- @see tag.view_only +-- @param t The tag object. +function tag.viewonly(t) + util.deprecate("Use t:view_only() instead of awful.tag.viewonly") + + tag.object.view_only(t) end --- View only a set of tags. @@ -761,7 +1128,7 @@ end -- @param[opt] screen The screen of the tags. function tag.viewmore(tags, screen) screen = get_screen(screen or ascreen.focused()) - local screen_tags = tag.gettags(screen) + local screen_tags = screen.tags for _, _tag in ipairs(screen_tags) do if not util.table.hasitem(tags, _tag) then _tag.selected = false @@ -779,7 +1146,7 @@ end -- @tparam tag t Tag to be toggled function tag.viewtoggle(t) t.selected = not t.selected - capi.screen[tag.getscreen(t)]:emit_signal("tag::history::update") + capi.screen[tag.getproperty(t, "screen")]:emit_signal("tag::history::update") end --- Get tag data table. @@ -833,22 +1200,26 @@ function tag.setproperty(_tag, prop, value, ignore_setters) end end ---TODO move to client - --- Tag a client with the set of current tags. +-- @deprecated awful.tag.withcurrent -- @param c The client to tag. function tag.withcurrent(c) + util.deprecate("Use c:to_selected_tags() instead of awful.tag.selectedlist") + + -- It can't use c:to_selected_tags() because awful.tag is loaded before + -- awful.client + local tags = {} for _, t in ipairs(c:tags()) do - if get_screen(tag.getscreen(t)) == get_screen(c.screen) then + if get_screen(tag.getproperty(t, "screen")) == get_screen(c.screen) then table.insert(tags, t) end end if #tags == 0 then - tags = tag.selectedlist(c.screen) + tags = c.screen.selected_tags end if #tags == 0 then - tags = tag.gettags(c.screen) + tags = c.screen.tags end if #tags ~= 0 then c:tags(tags) @@ -858,7 +1229,7 @@ end local function attached_connect_signal_screen(screen, sig, func) screen = get_screen(screen) capi.tag.connect_signal(sig, function(_tag) - if get_screen(tag.getscreen(_tag)) == screen then + if get_screen(tag.getproperty(_tag, "screen")) == screen then func(_tag) end end) @@ -892,7 +1263,7 @@ capi.client.connect_signal("manage", function(c) c.screen = ascreen.focused() end end - c:connect_signal("property::screen", tag.withcurrent) + c:connect_signal("property::screen", function() c:to_selected_tags() end) end) -- Keep track of the number of urgent clients. @@ -917,7 +1288,7 @@ local function client_untagged(c, t) end if #t:clients() == 0 and tag.getproperty(t, "volatile") then - tag.delete(t) + tag.object.delete(t) end end @@ -929,10 +1300,9 @@ local function urgent_callback(c) end capi.client.connect_signal("property::urgent", urgent_callback) -capi.client.connect_signal("manage", tag.withcurrent) capi.client.connect_signal("untagged", client_untagged) capi.client.connect_signal("tagged", client_tagged) -capi.tag.connect_signal("request::select", tag.viewonly) +capi.tag.connect_signal("request::select", tag.object.view_only) capi.tag.add_signal("property::hide") capi.tag.add_signal("property::icon") @@ -946,7 +1316,17 @@ capi.tag.add_signal("property::nmaster") capi.tag.add_signal("property::windowfact") capi.tag.add_signal("property::screen") capi.tag.add_signal("property::index") + +--- True when a tagged client is urgent +-- @signal property::urgent +-- @see client.urgent + +--- The number of urgent tagged clients +-- @signal property::urgent_count +-- @see client.urgent + capi.tag.add_signal("property::urgent") + capi.tag.add_signal("property::urgent_count") capi.tag.add_signal("property::volatile") @@ -962,12 +1342,17 @@ end -- `awful.tag.setproperty` currently handle calling the setter method itself -- while `awful.tag.getproperty`. object.properties(capi.tag, { - getter_class = tag, - setter_class = tag, + getter_class = tag.object, + setter_class = tag.object, getter_fallback = tag.getproperty, - setter = tag.setproperty, + setter_fallback = tag.setproperty, }) +-- fix a load loop +client = require("awful.client") +capi.client.connect_signal("manage", function(c) client.object.to_selected_tags(c) end) + + return setmetatable(tag, tag.mt) -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/lib/awful/widget/layoutbox.lua b/lib/awful/widget/layoutbox.lua index a72aa0887..b328aee84 100644 --- a/lib/awful/widget/layoutbox.lua +++ b/lib/awful/widget/layoutbox.lua @@ -31,7 +31,7 @@ local function update(w, screen) end local function update_from_tag(t) - local screen = get_screen(tag.getscreen(t)) + local screen = get_screen(t.screen) local w = boxes[screen] if w then update(w, screen) diff --git a/lib/awful/widget/taglist.lua b/lib/awful/widget/taglist.lua index b0cd32c03..47ae781da 100644 --- a/lib/awful/widget/taglist.lua +++ b/lib/awful/widget/taglist.lua @@ -111,8 +111,8 @@ function taglist.taglist_label(t, args) text = text .. "" end if not taglist_disable_icon then - if tag.geticon(t) then - icon = surface.load(tag.geticon(t)) + if t.icon then + icon = surface.load(t.icon) end end @@ -121,7 +121,7 @@ end local function taglist_update(s, w, buttons, filter, data, style, update_function) local tags = {} - for _, t in ipairs(tag.gettags(s)) do + for _, t in ipairs(s.tags) do if not tag.getproperty(t, "hide") and filter(t) then table.insert(tags, t) end @@ -185,7 +185,7 @@ function taglist.new(screen, filter, buttons, style, update_function, base_widge end end local uc = function (c) return u(c.screen) end - local ut = function (t) return u(tag.getscreen(t)) end + local ut = function (t) return u(t.screen) end capi.client.connect_signal("focus", uc) capi.client.connect_signal("unfocus", uc) tag.attached_connect_signal(nil, "property::selected", ut) diff --git a/lib/awful/widget/tasklist.lua b/lib/awful/widget/tasklist.lua index 1e2a51366..43a4b5667 100644 --- a/lib/awful/widget/tasklist.lua +++ b/lib/awful/widget/tasklist.lua @@ -276,7 +276,7 @@ function tasklist.filter.currenttags(c, screen) if get_screen(c.screen) ~= screen then return false end -- Include sticky client too if c.sticky then return true end - local tags = tag.gettags(screen) + local tags = screen.tags for _, t in ipairs(tags) do if t.selected then local ctags = c:tags() @@ -302,7 +302,7 @@ function tasklist.filter.minimizedcurrenttags(c, screen) if not c.minimized then return false end -- Include sticky client if c.sticky then return true end - local tags = tag.gettags(screen) + local tags = screen.tags for _, t in ipairs(tags) do -- Select only minimized clients if t.selected then diff --git a/tests/examples/shims/awesome.lua b/tests/examples/shims/awesome.lua index 30c2c39b4..41c458a9f 100644 --- a/tests/examples/shims/awesome.lua +++ b/tests/examples/shims/awesome.lua @@ -8,7 +8,7 @@ local function _shim_fake_class() local meta = { __index = function()end, - __new_index = function()end, + __newindex = function()end, } obj._connect_signal = obj.connect_signal @@ -28,7 +28,7 @@ local function _shim_fake_class() end function obj.set_newindex_miss_handler(handler) - meta.__new_index = handler + meta.__newindex = handler end function obj.emit_signal(name, c, ...) diff --git a/tests/examples/shims/client.lua b/tests/examples/shims/client.lua index f4f78d1db..f2dd0d383 100644 --- a/tests/examples/shims/client.lua +++ b/tests/examples/shims/client.lua @@ -2,7 +2,7 @@ local gears_obj = require("gears.object") local clients = {} -local client = awesome._shim_fake_class() +local client, meta = awesome._shim_fake_class() local function add_signals(c) c:add_signal("property::width") @@ -119,7 +119,10 @@ function client.gen_fake(args) client.emit_signal("manage", ret) assert(not args.screen or (args.screen == ret.screen)) - return ret + return setmetatable(ret, { + __index = function(...) return meta.__index(...) end, + __newindex = function(...) return meta.__newindex(...) end + }) end function client.get(s) diff --git a/tests/examples/shims/screen.lua b/tests/examples/shims/screen.lua index 40ecd3562..a0d4eb6b9 100644 --- a/tests/examples/shims/screen.lua +++ b/tests/examples/shims/screen.lua @@ -8,6 +8,7 @@ local function create_screen(args) local s = gears_obj() s:add_signal("property::workarea") + s:add_signal("property::index") s:add_signal("padding") -- Copy the geo in case the args are mutated @@ -46,7 +47,7 @@ local function create_screen(args) return meta.__index(_, key) end end, - __new_index = function(...) return meta.__new_index(...) end + __newindex = function(...) return meta.__newindex(...) end }) end diff --git a/tests/examples/shims/tag.lua b/tests/examples/shims/tag.lua index fe10da121..c7bec1753 100644 --- a/tests/examples/shims/tag.lua +++ b/tests/examples/shims/tag.lua @@ -35,7 +35,7 @@ local function new_tag(_, args) return setmetatable(ret, { __index = function(...) return meta.__index(...) end, - __new_index = function(...) return meta.__new_index(...) end + __newindex = function(...) return meta.__newindex(...) end }) end diff --git a/tests/test-urgent.lua b/tests/test-urgent.lua index 2c4714228..1f9706e22 100644 --- a/tests/test-urgent.lua +++ b/tests/test-urgent.lua @@ -32,7 +32,7 @@ local steps = { if count == 1 then -- Setup. urgent_cb_done = false -- Select first tag. - awful.tag.viewonly(tags[awful.screen.focused()][1]) + tags[awful.screen.focused()][1]:view_only() runner.add_to_default_rules({ rule = { class = "XTerm" }, properties = { tag = tags[awful.screen.focused()][2], focus = true } }) @@ -72,7 +72,7 @@ local steps = { urgent_cb_done = false -- Select first tag. - awful.tag.viewonly(tags[awful.screen.focused()][1]) + tags[awful.screen.focused()][1]:view_only() runner.add_to_default_rules({ rule = { class = "XTerm" }, properties = { tag = tags[awful.screen.focused()][2], focus = true, switchtotag = true }})