diff options
Diffstat (limited to 'awesome/lib/awful/tag.lua')
-rw-r--r-- | awesome/lib/awful/tag.lua | 1505 |
1 files changed, 0 insertions, 1505 deletions
diff --git a/awesome/lib/awful/tag.lua b/awesome/lib/awful/tag.lua deleted file mode 100644 index dbf3a60..0000000 --- a/awesome/lib/awful/tag.lua +++ /dev/null @@ -1,1505 +0,0 @@ ---------------------------------------------------------------------------- ---- Useful functions for tag manipulation. --- --- @author Julien Danjou <julien@danjou.info> --- @copyright 2008 Julien Danjou --- @module tag ---------------------------------------------------------------------------- - --- Grab environment we need -local util = require("awful.util") -local ascreen = require("awful.screen") -local beautiful = require("beautiful") -local object = require("gears.object") -local timer = require("gears.timer") -local pairs = pairs -local ipairs = ipairs -local table = table -local setmetatable = setmetatable -local capi = -{ - tag = tag, - screen = screen, - mouse = mouse, - client = client, - root = root -} - -local function get_screen(s) - return s and capi.screen[s] -end - -local tag = {object = {}, mt = {} } - --- Private data -local data = {} -data.history = {} - --- History functions -tag.history = {} -tag.history.limit = 20 - --- Default values -local defaults = {} - --- The gap between clients (in points). -defaults.gap = 0 - --- The default gap_count. -defaults.gap_single_client = true - --- The default master fill policy. -defaults.master_fill_policy = "expand" - --- The default master width factor. -defaults.master_width_factor = 0.5 - --- The default master count. -defaults.master_count = 1 - --- The default column count. -defaults.column_count = 1 - --- 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 --- @tparam[opt=20] integer 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) - - -- sort the tags by index - table.sort(tmp_tags, function(a, b) - local ia, ib = tag.getproperty(a, "index"), tag.getproperty(b, "index") - return (ia or math.huge) < (ib or math.huge) - end) - - 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) - end -end - -function tag.object.get_index(query_tag) - - local idx = tag.getproperty(query_tag, "index") - - if idx then return idx end - - -- Get an unordered list of tags - local tags = raw_tags(query_tag.screen) - - -- Too bad, lets compute it - for i, t in ipairs(tags) do - if t == query_tag then - tag.setproperty(t, "index", i) - 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. --- @param target_tag The tag that should be moved. If null, the currently --- selected tag is used. --- @see index -function tag.move(new_index, target_tag) - util.deprecate("Use t.index = new_index instead of awful.tag.move") - - target_tag = target_tag or ascreen.focused().selected_tag - tag.object.set_index(target_tag, new_index) -end - ---- Swap 2 tags --- @function 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") - - -- If they are on the same screen, avoid recomputing the whole table - -- for nothing. - if scr1 == scr2 then - tag.setproperty(self, "index", idx2) - tag.setproperty(tag2, "index", idx1) - 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 - ---- Swap 2 tags --- @deprecated awful.tag.swap --- @see tag.swap --- @param tag1 The first tag --- @param tag2 The second tag -function tag.swap(tag1, tag2) - 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 {} - - -- Be sure to set the screen before the tag is activated to avoid function - -- connected to property::activated to be called without a valid tag. - -- 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 = properties.index or #raw_tags(properties.screen)+1 - - local newtag = capi.tag{ name = name } - - -- Start with a fresh property table to avoid collisions with unsupported data - newtag.data.awful_tag_properties = {screen=properties.screen, index=properties.index} - - newtag.activated = true - - for k, v in pairs(properties) do - -- `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 -end - ---- Create a set of tags and attach it to a screen. --- @function awful.tag.new --- @param names The tag name, in a table --- @param screen The tag screen, or 1 if not set. --- @param layout The layout or layout table to set for this tags by default. --- @return A table with all created tags. -function tag.new(names, screen, layout) - screen = get_screen(screen or 1) - local tags = {} - for id, name in ipairs(names) do - table.insert(tags, id, tag.add(name, {screen = screen, - layout = (layout and layout[id]) or - layout})) - -- Select the first tag. - if id == 1 then - tags[id].selected = true - end - end - - return tags -end - ---- Find a suitable fallback tag. --- @function awful.tag.find_fallback --- @param screen The screen to look for a tag on. [awful.screen.focused()] --- @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 scr.selected_tags - - for _, v in pairs(scr.tags) do - if not util.table.hasitem(t, v) then return v end - end -end - ---- Delete a tag. --- --- 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. --- @tparam[opt=false] boolean force Move even non-sticky clients to the fallback --- tag. --- @return Returns true if the tag is successfully deleted. --- 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.object.delete(self, fallback_tag, force) - -- abort if the taf isn't currently activated - if not self.activated then return false 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 == self then return false end - - -- No fallback_tag provided, try and get one. - if fallback_tag == nil then - fallback_tag = tag.find_fallback(target_scr, {self}) - end - - -- Abort if we would have un-tagged clients. - local clients = self:clients() - if #clients > 0 and fallback_tag == nil then return false end - - -- Move the clients we can off of this tag. - for _, c in pairs(clients) do - local nb_tags = #c:tags() - - -- If a client has only this tag, or stickied clients with - -- nowhere to go, abort. - if (not c.sticky and nb_tags == 1 and not force) then - return - -- If a client has multiple tags, then do not move it to fallback - elseif nb_tags < 2 then - c:tags({fallback_tag}) - end - end - - -- delete the tag - self.data.awful_tag_properties.screen = nil - self.activated = false - - -- Update all indexes - for i=idx+1, #tags do - tag.setproperty(tags[i], "index", i-1) - end - - -- If no tags are visible (and we did not delete the lasttag), try and - -- view one. The > 1 is because ntags is no longer synchronized with the - -- current count. - if target_scr.selected_tag == nil and ntags > 1 then - tag.history.restore(target_scr, 1) - if target_scr.selected_tag == nil then - local other_tag = tags[tags[1] == self and 2 or 1] - if other_tag then - other_tag.selected = true - end - 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.tag.history.update --- @param obj Screen object. -function tag.history.update(obj) - local s = get_screen(obj) - local curtags = s.selected_tags - -- create history table - if not data.history[s] then - data.history[s] = {} - else - if data.history[s].current then - -- Check that the list is not identical - local identical = #data.history[s].current == #curtags - if identical then - for idx, _tag in ipairs(data.history[s].current) do - if curtags[idx] ~= _tag then - identical = false - break - end - end - end - - -- Do not update history the table are identical - if identical then return end - end - - -- Limit history - if #data.history[s] >= tag.history.limit then - for i = tag.history.limit, #data.history[s] do - data.history[s][i] = nil - end - end - end - - -- store previously selected tags in the history table - table.insert(data.history[s], 1, data.history[s].current) - data.history[s].previous = data.history[s][1] - -- store currently selected tags - data.history[s].current = setmetatable(curtags, { __mode = 'v' }) -end - ---- Revert tag history. --- @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 --- to the given index in history. -function tag.history.restore(screen, idx) - local s = get_screen(screen or ascreen.focused()) - local i = idx or "previous" - 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 - if #data.history[s][i] == 0 then - if i == "previous" then i = 0 end - tag.history.restore(s, i + 1) - return - end - -- deselect all tags - tag.viewnone(s) - -- select tags from the history entry - for _, t in ipairs(data.history[s][i]) do - if t.activated and t.screen then - t.selected = true - end - end - -- update currently selected tags table - data.history[s].current = data.history[s][i] - -- store previously selected tags - data.history[s].previous = setmetatable(sel, { __mode = 'v' }) - -- remove the reverted history entry - if i ~= "previous" then table.remove(data.history[s], i) end - - s:emit_signal("tag::history::update") -end - ---- Get a list of all tags on a screen --- @deprecated awful.tag.gettags --- @tparam screen s Screen --- @return A table with all available tags --- @see screen.tags -function tag.gettags(s) - util.deprecate("Use s.tags instead of awful.tag.gettags") - - s = get_screen(s) - - return s and s.tags or {} -end - ---- Find a tag by name --- @tparam[opt] screen s The screen of the tag --- @tparam string name The name of the tag --- @return The tag found, or `nil` -function tag.find_by_name(s, name) - local tags = s and s.tags or root.tags() - for _, t in ipairs(tags) do - if name == t.name then - return t - end - end -end - ---- The tag screen. --- --- **Signal:** --- --- * *property::screen* --- --- @property screen --- @param screen --- @see screen - -function tag.object.set_screen(t, s) - - s = get_screen(s or ascreen.focused()) - local sel = tag.selected - 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 - tag.setproperty(t, "index", nil) - - -- Change the screen - tag.setproperty(t, "screen", s) - tag.setproperty(t, "index", #s:get_tags(true)) - - -- Make sure the client's screen matches its tags - for _,c in ipairs(t:clients()) do - c.screen = s --Move all clients - c:tags({t}) - end - - -- Update all indexes - for i,t2 in ipairs(old_screen.tags) do - tag.setproperty(t2, "index", i) - end - - -- Restore the old screen history if the tag was selected - if sel then - tag.history.restore(old_screen, 1) - 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) - util.deprecate("Use t.screen instead of awful.tag.getscreen(t)") - - -- 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 - ---- 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) - util.deprecate("Use s.selected_tags instead of awful.tag.selectedlist") - - 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) - util.deprecate("Use s.selected_tag instead of awful.tag.selected") - - s = get_screen(s or ascreen.focused()) - - return s.selected_tag -end - ---- The default master width factor --- --- @beautiful beautiful.master_width_factor --- @param number (default: 0.5) --- @see master_width_factor --- @see gap - ---- 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* (deprecated) --- * *property::master_width_factor* --- --- @property master_width_factor --- @param number Between 0 and 1 --- @see master_count --- @see column_count --- @see master_fill_policy --- @see gap - -function tag.object.set_master_width_factor(t, mwfact) - if mwfact >= 0 and mwfact <= 1 then - tag.setproperty(t, "mwfact", mwfact) - tag.setproperty(t, "master_width_factor", mwfact) - end -end - -function tag.object.get_master_width_factor(t) - return tag.getproperty(t, "master_width_factor") - or beautiful.master_width_factor - or defaults.master_width_factor -end - ---- Set master width factor. --- @deprecated awful.tag.setmwfact --- @see master_fill_policy --- @see 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) - util.deprecate("Use t.master_width_factor = mwfact instead of awful.tag.setmwfact") - - tag.object.get_master_width_factor(t or ascreen.focused().selected_tag, mwfact) -end - ---- Increase master width factor. --- @function awful.tag.incmwfact --- @see master_width_factor --- @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) - t = t or t or ascreen.focused().selected_tag - tag.object.set_master_width_factor(t, tag.object.get_master_width_factor(t) + add) -end - ---- Get master width factor. --- @deprecated awful.tag.getmwfact --- @see master_width_factor --- @see master_fill_policy --- @param[opt] t The tag. -function tag.getmwfact(t) - util.deprecate("Use t.master_width_factor instead of awful.tag.getmwfact") - - return tag.object.get_master_width_factor(t or ascreen.focused().selected_tag) -end - ---- 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" - and getmetatable(layout) - and getmetatable(layout).__call - ) then - if not t.dynamic_layout_cache then - t.dynamic_layout_cache = {} - end - - local instance = t.dynamic_layout_cache[layout] or layout(t) - - -- Always make sure the layout is notified it is enabled - if tag.getproperty(t, "screen").selected_tag == t and instance.wake_up then - instance:wake_up() - end - - -- Avoid creating the same layout twice, use layout:reset() to reset - if instance.is_dynamic then - t.dynamic_layout_cache[layout] = instance - end - - layout = instance - end - - tag.setproperty(t, "layout", layout) - - 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) -end - ---- Get if the tag must be deleted when the last client closes --- @deprecated awful.tag.getvolatile --- @see volatile --- @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 --- @see gap_single_client - ---- 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::useless_gap* --- --- @property gap --- @param number The value has to be greater than zero. --- @see gap_single_client - -function tag.object.set_gap(t, useless_gap) - if useless_gap >= 0 then - tag.setproperty(t, "useless_gap", useless_gap) - end -end - -function tag.object.get_gap(t) - return tag.getproperty(t, "useless_gap") - or beautiful.useless_gap - or defaults.gap -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) - 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) - t = t or t or ascreen.focused().selected_tag - tag.object.set_gap(t, tag.object.get_gap(t) + add) -end - ---- Enable gaps for a single client. --- --- @beautiful beautiful.gap_single_client --- @param boolean (default: true) --- @see gap --- @see gap_single_client - ---- Enable gaps for a single client. --- --- **Signal:** --- --- * *property::gap\_single\_client* --- --- @property gap_single_client --- @param boolean Enable gaps for a single client - -function tag.object.set_gap_single_client(t, gap_single_client) - tag.setproperty(t, "gap_single_client", gap_single_client == true) -end - -function tag.object.get_gap_single_client(t) - local val = tag.getproperty(t, "gap_single_client") - if val ~= nil then - return val - end - val = beautiful.gap_single_client - if val ~= nil then - return val - end - return defaults.gap_single_client -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) - util.deprecate("Use t.gap instead of awful.tag.getgap") - - if numclients == 1 then - return 0 - end - - return tag.object.get_gap(t or ascreen.focused().selected_tag) -end - ---- The default fill policy. --- --- ** Possible values**: --- --- * *expand*: Take all the space --- * *master_width_factor*: Only take the ratio defined by the --- `master_width_factor` --- --- @beautiful beautiful.master_fill_policy --- @param string (default: "expand") --- @see master_fill_policy - ---- Set size fill policy for the master client(s). --- --- ** Possible values**: --- --- * *expand*: Take all the space --- * *master_width_factor*: Only take the ratio defined by the --- `master_width_factor` --- --- **Signal:** --- --- * *property::master_fill_policy* --- --- @property master_fill_policy --- @param string "expand" or "master_width_factor" - -function tag.object.get_master_fill_policy(t) - return tag.getproperty(t, "master_fill_policy") - or beautiful.master_fill_policy - or defaults.master_fill_policy -end - ---- Set size fill policy for the master client(s) --- @deprecated awful.tag.setmfpol --- @see master_fill_policy --- @tparam string policy Can be set to --- "expand" (fill all the available workarea) or --- "master_width_factor" (fill only an area inside the master width factor) --- @tparam[opt=tag.selected()] tag t The tag to modify -function tag.setmfpol(policy, t) - 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) -end - ---- Toggle size fill policy for the master client(s) --- between "expand" and "master_width_factor". --- @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.setproperty(t, "master_fill_policy", "master_width_factor") - else - tag.setproperty(t, "master_fill_policy", "expand") - end -end - ---- Get size fill policy for the master client(s) --- @deprecated awful.tag.getmfpol --- @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 --- "master_width_factor" (fill only an area inside the master width factor) -function tag.getmfpol(t) - 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 beautiful.master_fill_policy - or defaults.master_fill_policy -end - ---- The default number of master windows. --- --- @beautiful beautiful.master_count --- @param integer (default: 1) --- @see master_count - ---- Set the number of master windows. --- --- **Signal:** --- --- * *property::nmaster* (deprecated) --- * *property::master_count* (deprecated) --- --- @property master_count --- @param integer nmaster Only positive values are accepted - -function tag.object.set_master_count(t, nmaster) - if nmaster >= 0 then - tag.setproperty(t, "nmaster", nmaster) - tag.setproperty(t, "master_count", nmaster) - end -end - -function tag.object.get_master_count(t) - return tag.getproperty(t, "master_count") - or beautiful.master_count - or defaults.master_count -end - ---- --- @deprecated awful.tag.setnmaster --- @see master_count --- @param nmaster The number of master windows. --- @param[opt] t The tag. -function tag.setnmaster(nmaster, t) - util.deprecate("Use t.master_count = nmaster instead of awful.tag.setnmaster") - - tag.object.set_master_count(t or ascreen.focused().selected_tag, nmaster) -end - ---- Get the number of master windows. --- @deprecated awful.tag.getnmaster --- @see master_count --- @param[opt] t The tag. -function tag.getnmaster(t) - util.deprecate("Use t.master_count instead of awful.tag.setnmaster") - - t = t or ascreen.focused().selected_tag - return tag.getproperty(t, "master_count") or 1 -end - ---- Increase the number of master windows. --- @function awful.tag.incnmaster --- @see master_count --- @param add Value to add to number of master windows. --- @param[opt] t The tag to modify, if null tag.selected() is used. --- @tparam[opt=false] boolean sensible Limit nmaster based on the number of --- visible tiled windows? -function tag.incnmaster(add, t, sensible) - t = t or ascreen.focused().selected_tag - - if sensible then - local screen = get_screen(tag.getproperty(t, "screen")) - local ntiled = #screen.tiled_clients - - local nmaster = tag.object.get_master_count(t) - if nmaster > ntiled then - nmaster = ntiled - end - - local newnmaster = nmaster + add - if newnmaster > ntiled then - newnmaster = ntiled - end - tag.object.set_master_count(t, newnmaster) - else - tag.object.set_master_count(t, tag.object.get_master_count(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 --- @see icon --- @param icon the icon to set, either path or image object --- @param _tag the tag -function tag.seticon(icon, _tag) - util.deprecate("Use t.icon = icon instead of awful.tag.seticon") - - _tag = _tag or ascreen.focused().selected_tag - tag.setproperty(_tag, "icon", icon) -end - ---- Get the tag icon --- @deprecated awful.tag.geticon --- @see icon --- @param _tag the tag -function tag.geticon(_tag) - util.deprecate("Use t.icon instead of awful.tag.geticon") - - _tag = _tag or ascreen.focused().selected_tag - return tag.getproperty(_tag, "icon") -end - ---- The default number of columns. --- --- @beautiful beautiful.column_count --- @param integer (default: 1) --- @see column_count - ---- Set the number of columns. --- --- **Signal:** --- --- * *property::ncol* (deprecated) --- * *property::column_count* --- --- @property column_count --- @tparam integer ncol Has to be greater than 1 - -function tag.object.set_column_count(t, ncol) - if ncol >= 1 then - tag.setproperty(t, "ncol", ncol) - tag.setproperty(t, "column_count", ncol) - end -end - -function tag.object.get_column_count(t) - return tag.getproperty(t, "column_count") - or beautiful.column_count - or defaults.column_count -end - ---- Set number of column windows. --- @deprecated awful.tag.setncol --- @see column_count --- @param ncol The number of column. --- @param t The tag to modify, if null tag.selected() is used. -function tag.setncol(ncol, t) - util.deprecate("Use t.column_count = new_index instead of awful.tag.setncol") - - t = t or ascreen.focused().selected_tag - if ncol >= 1 then - tag.setproperty(t, "ncol", ncol) - tag.setproperty(t, "column_count", ncol) - end -end - ---- Get number of column windows. --- @deprecated awful.tag.getncol --- @see column_count --- @param[opt] t The tag. -function tag.getncol(t) - util.deprecate("Use t.column_count instead of awful.tag.getncol") - - t = t or ascreen.focused().selected_tag - return tag.getproperty(t, "column_count") or 1 -end - ---- Increase number of column windows. --- @function awful.tag.incncol --- @param add Value to add to number of column windows. --- @param[opt] t The tag to modify, if null tag.selected() is used. --- @tparam[opt=false] boolean sensible Limit column_count based on the number --- of visible tiled windows? -function tag.incncol(add, t, sensible) - t = t or ascreen.focused().selected_tag - - if sensible then - local screen = get_screen(tag.getproperty(t, "screen")) - local ntiled = #screen.tiled_clients - local nmaster = tag.object.get_master_count(t) - local nsecondary = ntiled - nmaster - - local ncol = tag.object.get_column_count(t) - if ncol > nsecondary then - ncol = nsecondary - end - - local newncol = ncol + add - if newncol > nsecondary then - newncol = nsecondary - end - - tag.object.set_column_count(t, newncol) - else - tag.object.set_column_count(t, tag.object.get_column_count(t) + add) - end -end - ---- View no tag. --- @function awful.tag.viewnone --- @tparam[opt] int|screen screen The screen. -function tag.viewnone(screen) - screen = screen or ascreen.focused() - local tags = screen.tags - for _, t in pairs(tags) do - t.selected = false - end -end - ---- View a tag by its taglist index. --- --- This is equivalent to `screen.tags[i]:view_only()` --- @function awful.tag.viewidx --- @see screen.tags --- @param i The **relative** index to see. --- @param[opt] screen The screen. -function tag.viewidx(i, screen) - screen = get_screen(screen or ascreen.focused()) - 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 = screen.selected_tag - tag.viewnone(screen) - for k, t in ipairs(showntags) do - if t == sel then - showntags[util.cycle(#showntags, k + i)].selected = true - end - end - screen:emit_signal("tag::history::update") -end - ---- Get a tag's index in the gettags() table. --- @deprecated awful.tag.getidx --- @see index --- @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) - util.deprecate("Use t.index instead of awful.tag.getidx") - - return tag.object.get_index(query_tag or ascreen.focused().selected_tag) -end - ---- View next tag. This is the same as tag.viewidx(1). --- @function awful.tag.viewnext --- @param screen The screen. -function tag.viewnext(screen) - return tag.viewidx(1, screen) -end - ---- View previous tag. This is the same a tag.viewidx(-1). --- @function awful.tag.viewprev --- @param screen The screen. -function tag.viewprev(screen) - return tag.viewidx(-1, screen) -end - ---- View only a tag. --- @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 ~= 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. - 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. --- @function awful.tag.viewmore --- @param tags A table with tags to view only. --- @param[opt] screen The screen of the tags. -function tag.viewmore(tags, screen) - screen = get_screen(screen or ascreen.focused()) - local screen_tags = screen.tags - for _, _tag in ipairs(screen_tags) do - if not util.table.hasitem(tags, _tag) then - _tag.selected = false - end - end - for _, _tag in ipairs(tags) do - _tag.selected = true - end - screen:emit_signal("tag::history::update") -end - ---- Toggle selection of a tag --- @function awful.tag.viewtoggle --- @see selected --- @tparam tag t Tag to be toggled -function tag.viewtoggle(t) - t.selected = not t.selected - capi.screen[tag.getproperty(t, "screen")]:emit_signal("tag::history::update") -end - ---- Get tag data table. --- --- Do not use. --- --- @deprecated awful.tag.getdata --- @tparam tag _tag The tag. --- @return The data table. -function tag.getdata(_tag) - return _tag.data.awful_tag_properties -end - ---- Get a tag property. --- --- Use `_tag.prop` directly. --- --- @deprecated awful.tag.getproperty --- @tparam tag _tag The tag. --- @tparam string prop The property name. --- @return The property. -function tag.getproperty(_tag, prop) - if not _tag then return end -- FIXME: Turn this into an error? - if _tag.data.awful_tag_properties then - return _tag.data.awful_tag_properties[prop] - end -end - ---- Set a tag property. --- This properties are internal to awful. Some are used to draw taglist, or to --- handle layout, etc. --- --- Use `_tag.prop = value` --- --- @deprecated awful.tag.setproperty --- @param _tag The tag. --- @param prop The property name. --- @param value The value. -function tag.setproperty(_tag, prop, value) - if not _tag.data.awful_tag_properties then - _tag.data.awful_tag_properties = {} - end - - if _tag.data.awful_tag_properties[prop] ~= value then - _tag.data.awful_tag_properties[prop] = value - _tag:emit_signal("property::" .. prop) - end -end - ---- 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.getproperty(t, "screen")) == get_screen(c.screen) then - table.insert(tags, t) - end - end - if #tags == 0 then - tags = c.screen.selected_tags - end - if #tags == 0 then - tags = c.screen.tags - end - if #tags ~= 0 then - c:tags(tags) - end -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.getproperty(_tag, "screen")) == screen then - func(_tag) - end - end) -end - ---- Add a signal to all attached tags and all tags that will be attached in the --- future. When a tag is detached from the screen, its signal is removed. --- --- @function awful.tag.attached_connect_signal --- @screen The screen concerned, or all if nil. --- @tparam[opt] string Signal --- @tparam[opt] function Callback -function tag.attached_connect_signal(screen, ...) - if screen then - attached_connect_signal_screen(screen, ...) - else - capi.tag.connect_signal(...) - end -end - --- Register standard signals. -capi.client.connect_signal("property::screen", function(c) - -- First, the delayed timer is necessary to avoid a race condition with - -- awful.rules. It is also messing up the tags before the user have a chance - -- to set them manually. - timer.delayed_call(function() - local tags, new_tags = c:tags(), {} - - for _, t in ipairs(tags) do - if t.screen == c.screen then - table.insert(new_tags, t) - end - end - - if #new_tags == 0 then - c:emit_signal("request::tag", nil, {reason="screen"}) - elseif #new_tags < #tags then - c:tags(new_tags) - end - end) -end) - --- Keep track of the number of urgent clients. -local function update_urgent(t, modif) - local count = tag.getproperty(t, "urgent_count") or 0 - count = (count + modif) >= 0 and (count + modif) or 0 - tag.setproperty(t, "urgent" , count > 0) - tag.setproperty(t, "urgent_count", count ) -end - --- Update the urgent counter when a client is tagged. -local function client_tagged(c, t) - if c.urgent then - update_urgent(t, 1) - end -end - --- Update the urgent counter when a client is untagged. -local function client_untagged(c, t) - if c.urgent then - update_urgent(t, -1) - end - - if #t:clients() == 0 and tag.getproperty(t, "volatile") then - tag.object.delete(t) - end -end - --- Count the urgent clients. -local function urgent_callback(c) - for _,t in ipairs(c:tags()) do - update_urgent(t, c.urgent and 1 or -1) - end -end - -capi.client.connect_signal("property::urgent", urgent_callback) -capi.client.connect_signal("untagged", client_untagged) -capi.client.connect_signal("tagged", client_tagged) -capi.tag.connect_signal("request::select", tag.object.view_only) - ---- 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.screen.connect_signal("tag::history::update", tag.history.update) - -capi.screen.connect_signal("removed", function(s) - -- First give other code a chance to move the tag to another screen - for _, t in pairs(s.tags) do - t:emit_signal("request::screen") - end - -- Everything that's left: Tell everyone that these tags go away (other code - -- could e.g. save clients) - for _, t in pairs(s.tags) do - t:emit_signal("removal-pending") - end - -- Give other code yet another change to save clients - for _, c in pairs(capi.client.get(s)) do - c:emit_signal("request::tag", nil, { reason = "screen-removed" }) - end - -- Then force all clients left to go somewhere random - local fallback = nil - for other_screen in capi.screen do - if #other_screen.tags > 0 then - fallback = other_screen.tags[1] - break - end - end - for _, t in pairs(s.tags) do - t:delete(fallback, true) - end - -- If any tag survived until now, forcefully get rid of it - for _, t in pairs(s.tags) do - t.activated = false - - if t.data.awful_tag_properties then - t.data.awful_tag_properties.screen = nil - end - end -end) - -function tag.mt:__call(...) - return tag.new(...) -end - --- Extend the luaobject --- `awful.tag.setproperty` currently handle calling the setter method itself --- while `awful.tag.getproperty`. -object.properties(capi.tag, { - getter_class = tag.object, - setter_class = tag.object, - getter_fallback = tag.getproperty, - setter_fallback = tag.setproperty, -}) - -return setmetatable(tag, tag.mt) - --- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 |