diff --git a/awesomerc.lua b/awesomerc.lua
index 69f78132..6934d522 100755
--- a/awesomerc.lua
+++ b/awesomerc.lua
@@ -141,12 +141,20 @@ mypromptbox = {}
mylayoutbox = {}
mytaglist = {}
mytaglist.buttons = awful.util.table.join(
- awful.button({ }, 1, awful.tag.viewonly),
- awful.button({ modkey }, 1, awful.client.movetotag),
+ 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)
+ end
+ end),
awful.button({ }, 3, awful.tag.viewtoggle),
- awful.button({ modkey }, 3, awful.client.toggletag),
- 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({ modkey }, 3, function(t)
+ if client.focus then
+ client.focus:toggle_tag(t)
+ end
+ end),
+ awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
+ awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end)
)
mytasklist = {}
@@ -158,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
@@ -335,7 +343,7 @@ clientkeys = awful.util.table.join(
{description = "toggle floating", group = "client"}),
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
{description = "move to master", group = "client"}),
- awful.key({ modkey, }, "o", awful.client.movetoscreen ,
+ awful.key({ modkey, }, "o", function (c) c:move_to_screen() end,
{description = "move to screen", group = "client"}),
awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
{description = "toggle keep on top", group = "client"}),
@@ -363,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"}),
@@ -373,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
@@ -383,9 +391,9 @@ 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
- awful.client.movetotag(tag)
+ client.focus:move_to_tag(tag)
end
end
end,
@@ -394,9 +402,9 @@ 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
- awful.client.toggletag(tag)
+ client.focus:toggle_tag(tag)
end
end
end,
diff --git a/docs/aliases/awful_client.lua b/docs/aliases/awful_client.lua
new file mode 100644
index 00000000..b8cd3b80
--- /dev/null
+++ b/docs/aliases/awful_client.lua
@@ -0,0 +1,6 @@
+---------------------------------------------------------------------------
+--- This module is deprecated, use `client`
+-- ===============================
+--
+-- @module awful.client
+---------------------------------------------------------------------------
diff --git a/docs/aliases/awful_screen.lua b/docs/aliases/awful_screen.lua
new file mode 100644
index 00000000..55df367a
--- /dev/null
+++ b/docs/aliases/awful_screen.lua
@@ -0,0 +1,6 @@
+---------------------------------------------------------------------------
+--- This module is deprecated, use `screen`
+-- ===============================
+--
+-- @module awful.screen
+---------------------------------------------------------------------------
diff --git a/docs/aliases/awful_tag.lua b/docs/aliases/awful_tag.lua
new file mode 100644
index 00000000..75e3bd2c
--- /dev/null
+++ b/docs/aliases/awful_tag.lua
@@ -0,0 +1,6 @@
+---------------------------------------------------------------------------
+--- This module is deprecated, use `tag`
+-- ===============================
+--
+-- @module awful.tag
+---------------------------------------------------------------------------
diff --git a/docs/config.ld b/docs/config.ld
index 994a6473..bec83fd4 100644
--- a/docs/config.ld
+++ b/docs/config.ld
@@ -28,8 +28,19 @@ tparam_alias('client', 'client.object')
tparam_alias('tag', 'tag')
-- Should be default, but is not. Sets up "@tab" => "@tparam table".
tparam_alias('tab', 'table')
+
+-- Hack to get the functions and method on top of the signals and properties
+new_type("function", "Functions")
+-- Documentation for objects properties
+new_type("property", "Object properties", false, "Type")
-- New type for signals
new_type("signal", "Signals", false, "Arguments")
+-- Allow objects to define a set of beautiful properties affecting them
+new_type("beautiful", "Theme variables", false, "Type")
+-- Put deprecated methods in their own section
+new_type("deprecated", "Deprecated functions", false, "param")
+-- For the legacy stateless layout related functions
+new_type("legacylayout", "Layout related functions", false, "param")
-- More fitting section names
kind_names={topic='Documentation', module='Libraries'}
@@ -52,6 +63,10 @@ file = {
'../objects/',
-- LUA libraries
'../lib/',
+ -- Old APIs the user should not longer use directly
+ '../../docs/aliases/awful_client.lua',
+ '../../docs/aliases/awful_screen.lua',
+ '../../docs/aliases/awful_tag.lua',
exclude = {
-- exclude these modules, as they do not contain any written
-- documentation
diff --git a/docs/images/client_geo.svg b/docs/images/client_geo.svg
new file mode 100644
index 00000000..34c970a2
--- /dev/null
+++ b/docs/images/client_geo.svg
@@ -0,0 +1,385 @@
+
+
diff --git a/docs/images/tag_props.svg b/docs/images/tag_props.svg
new file mode 100644
index 00000000..fa4a16a7
--- /dev/null
+++ b/docs/images/tag_props.svg
@@ -0,0 +1,273 @@
+
+
diff --git a/lib/awful/autofocus.lua b/lib/awful/autofocus.lua
index f0e9090a..f1117f15 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 41feccde..b6e0ef00 100644
--- a/lib/awful/client.lua
+++ b/lib/awful/client.lua
@@ -4,14 +4,13 @@
-- @author Julien Danjou <julien@danjou.info>
-- @copyright 2008 Julien Danjou
-- @release @AWESOME_VERSION@
--- @module awful.client
+-- @module client
---------------------------------------------------------------------------
-- Grab environment we need
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
@@ -41,205 +40,78 @@ do
__newindex = error -- Just to be sure in case anything ever does this
})
end
-local client = {}
+local client = {object={}}
-- Private data
client.data = {}
-client.data.focus = {}
-client.data.urgent = {}
client.data.marked = {}
client.data.properties = setmetatable({}, { __mode = 'k' })
client.data.persistent_properties_registered = {} -- keys are names of persistent properties, value always true
client.data.persistent_properties_loaded = setmetatable({}, { __mode = 'k' }) -- keys are clients, value always true
-- Functions
-client.urgent = {}
-client.focus = {}
-client.focus.history = {}
+client.urgent = require("awful.client.urgent")
client.swap = {}
client.floating = {}
client.dockable = {}
client.property = {}
client.shape = require("awful.client.shape")
+client.focus = require("awful.client.focus")
--- Jump to the given client.
-- Takes care of focussing the screen, the right tag, etc.
--
+-- @deprecated awful.client.jumpto
+-- @see client.jump_to
-- @client c the client to jump to
-- @tparam bool|function merge If true then merge tags (select the client's
-- first tag additionally) when the client is not visible.
-- If it is a function, it will be called with the client and its first
-- tag as arguments.
function client.jumpto(c, merge)
+ util.deprecate "Use c:jump_to(merge) instead of awful.client.jumpto"
+
+ client.object.jump_to(c, merge)
+end
+
+--- Jump to the given client.
+-- Takes care of focussing the screen, the right tag, etc.
+--
+-- @function client.jump_to
+-- @tparam bool|function merge If true then merge tags (select the client's
+-- first tag additionally) when the client is not visible.
+-- If it is a function, it will be called with the client and its first
+-- tag as arguments.
+function client.object.jump_to(self, merge)
local s = get_screen(screen.focused())
-- focus the screen
- if s ~= get_screen(c.screen) then
- screen.focus(c.screen)
+ if s ~= get_screen(self.screen) then
+ screen.focus(self.screen)
end
- c.minimized = false
+ self.minimized = false
-- Try to make client visible, this also covers e.g. sticky.
- if not c:isvisible() then
- local t = c.first_tag
+ if not self:isvisible() then
+ local t = self.first_tag
if merge then
if type(merge) == "function" then
- merge(c, t)
+ merge(self, t)
elseif t then
t.selected = true
end
elseif t then
- tag.viewonly(t)
+ t:view_only()
end
end
- c:emit_signal("request::activate", "client.jumpto", {raise=true})
-end
-
---- Get the first client that got the urgent hint.
---
--- @treturn client.object The first urgent client.
-function client.urgent.get()
- if #client.data.urgent > 0 then
- return client.data.urgent[1]
- else
- -- fallback behaviour: iterate through clients and get the first urgent
- local clients = capi.client.get()
- for _, cl in pairs(clients) do
- if cl.urgent then
- return cl
- end
- end
- end
-end
-
---- Jump to the client that received the urgent hint first.
---
--- @tparam bool|function merge If true then merge tags (select the client's
--- first tag additionally) when the client is not visible.
--- If it is a function, it will be called with the client as argument.
-function client.urgent.jumpto(merge)
- local c = client.urgent.get()
- if c then
- client.jumpto(c, merge)
- end
-end
-
---- Adds client to urgent stack.
---
--- @client c The client object.
--- @param prop The property which is updated.
-function client.urgent.add(c, prop)
- if type(c) == "client" and prop == "urgent" and c.urgent then
- table.insert(client.data.urgent, c)
- end
-end
-
---- Remove client from urgent stack.
---
--- @client c The client object.
-function client.urgent.delete(c)
- for k, cl in ipairs(client.data.urgent) do
- if c == cl then
- table.remove(client.data.urgent, k)
- break
- end
- end
-end
-
---- Remove a client from the focus history
---
--- @client c The client that must be removed.
-function client.focus.history.delete(c)
- for k, v in ipairs(client.data.focus) do
- if v == c then
- table.remove(client.data.focus, k)
- break
- end
- end
-end
-
---- Filter out window that we do not want handled by focus.
--- This usually means that desktop, dock and splash windows are
--- not registered and cannot get focus.
---
--- @client c A client.
--- @return The same client if it's ok, nil otherwise.
-function client.focus.filter(c)
- if c.type == "desktop"
- or c.type == "dock"
- or c.type == "splash"
- or not c.focusable then
- return nil
- end
- return c
-end
-
---- Update client focus history.
---
--- @client c The client that has been focused.
-function client.focus.history.add(c)
- -- Remove the client if its in stack
- client.focus.history.delete(c)
- -- Record the client has latest focused
- table.insert(client.data.focus, 1, c)
-end
-
---- Get the latest focused client for a screen in history.
---
--- @tparam int|screen s The screen to look for.
--- @tparam int idx The index: 0 will return first candidate,
--- 1 will return second, etc.
--- @tparam function filter An optional filter. If no client is found in the
--- first iteration, client.focus.filter is used by default to get any
--- client.
--- @treturn client.object A client.
-function client.focus.history.get(s, idx, filter)
- s = get_screen(s)
- -- When this counter is equal to idx, we return the client
- local counter = 0
- local vc = client.visible(s, true)
- for _, c in ipairs(client.data.focus) do
- if get_screen(c.screen) == s then
- if not filter or filter(c) then
- for _, vcc in ipairs(vc) do
- if vcc == c then
- if counter == idx then
- return c
- end
- -- We found one, increment the counter only.
- counter = counter + 1
- break
- end
- end
- end
- end
- end
- -- Argh nobody found in history, give the first one visible if there is one
- -- that passes the filter.
- filter = filter or client.focus.filter
- if counter == 0 then
- for _, v in ipairs(vc) do
- if filter(v) then
- return v
- end
- end
- end
-end
-
---- Focus the previous client in history.
-function client.focus.history.previous()
- local sel = capi.client.focus
- local s = sel and sel.screen or screen.focused()
- local c = client.focus.history.get(s, 1)
- if c then
- c:emit_signal("request::activate", "client.focus.history.previous",
- {raise=false})
- end
+ self:emit_signal("request::activate", "client.jumpto", {raise=true})
end
--- Get visible clients from a screen.
--
+-- @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.
@@ -256,6 +128,8 @@ end
--- Get visible and tiled clients
--
+-- @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.
@@ -264,7 +138,7 @@ function client.tiled(s, stacked)
local tclients = {}
-- Remove floating clients
for _, c in pairs(clients) do
- if not client.floating.get(c)
+ if not client.object.get_floating(c)
and not c.fullscreen
and not c.maximized_vertical
and not c.maximized_horizontal then
@@ -277,6 +151,7 @@ end
--- Get a client by its relative index to another client.
-- If no client is passed, the focused client will be used.
--
+-- @function awful.client.next
-- @tparam int i The index. Use 1 to get the next, -1 to get the previous.
-- @client[opt] sel The client.
-- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
@@ -310,76 +185,8 @@ function client.next(i, sel, stacked)
end
end
---- Focus a client by the given direction.
---
--- @tparam string dir The direction, can be either
--- `"up"`, `"down"`, `"left"` or `"right"`.
--- @client[opt] c The client.
--- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
-function client.focus.bydirection(dir, c, stacked)
- local sel = c or capi.client.focus
- if sel then
- local cltbl = client.visible(sel.screen, stacked)
- local geomtbl = {}
- for i,cl in ipairs(cltbl) do
- geomtbl[i] = cl:geometry()
- end
-
- local target = util.get_rectangle_in_direction(dir, geomtbl, sel:geometry())
-
- -- If we found a client to focus, then do it.
- if target then
- cltbl[target]:emit_signal("request::activate",
- "client.focus.bydirection", {raise=false})
- end
- end
-end
-
---- Focus a client by the given direction. Moves across screens.
---
--- @param dir The direction, can be either "up", "down", "left" or "right".
--- @client[opt] c The client.
--- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
-function client.focus.global_bydirection(dir, c, stacked)
- local sel = c or capi.client.focus
- local scr = get_screen(sel and sel.screen or screen.focused())
-
- -- change focus inside the screen
- client.focus.bydirection(dir, sel)
-
- -- if focus not changed, we must change screen
- if sel == capi.client.focus then
- screen.focus_bydirection(dir, scr)
- if scr ~= get_screen(screen.focused()) then
- local cltbl = client.visible(screen.focused(), stacked)
- local geomtbl = {}
- for i,cl in ipairs(cltbl) do
- geomtbl[i] = cl:geometry()
- end
- local target = util.get_rectangle_in_direction(dir, geomtbl, scr.geometry)
-
- if target then
- cltbl[target]:emit_signal("request::activate",
- "client.focus.global_bydirection",
- {raise=false})
- end
- end
- end
-end
-
---- Focus a client by its relative index.
---
--- @param i The index.
--- @client[opt] c The client.
-function client.focus.byidx(i, c)
- local target = client.next(i, c)
- if target then
- target:emit_signal("request::activate", "client.focus.byidx",
- {raise=true})
- end
-end
-
--- Swap a client with another client in the given direction.
+-- @function awful.client.swap.bydirection
-- @tparam string dir The direction, can be either "up", "down", "left" or "right".
-- @client[opt=focused] c The client.
-- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
@@ -401,6 +208,7 @@ function client.swap.bydirection(dir, c, stacked)
end
--- Swap a client with another client in the given direction. Swaps across screens.
+-- @function awful.client.swap.global_bydirection
-- @param dir The direction, can be either "up", "down", "left" or "right".
-- @client[opt] sel The client.
function client.swap.global_bydirection(dir, sel)
@@ -418,12 +226,12 @@ function client.swap.global_bydirection(dir, sel)
-- swapping to an empty screen
elseif get_screen(sel.screen) ~= get_screen(c.screen) and sel == c then
- client.movetoscreen(sel, screen.focused())
+ sel:move_to_screen(screen.focused())
-- swapping to a nonempty screen
elseif get_screen(sel.screen) ~= get_screen(c.screen) and sel ~= c then
- client.movetoscreen(sel, c.screen)
- client.movetoscreen(c, scr)
+ sel:move_to_screen(c.screen)
+ c:move_to_screen(scr)
end
screen.focus(sel.screen)
@@ -433,6 +241,7 @@ function client.swap.global_bydirection(dir, sel)
end
--- Swap a client by its relative index.
+-- @function awful.client.swap.byidx
-- @param i The index.
-- @client[opt] c The client, otherwise focused one is used.
function client.swap.byidx(i, c)
@@ -445,6 +254,7 @@ end
--- Cycle clients.
--
+-- @function awful.client.cycle
-- @param clockwise True to cycle clients clockwise.
-- @param[opt] s The screen where to cycle clients.
-- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
@@ -468,6 +278,7 @@ end
--- Get the master window.
--
+-- @legacylayout awful.client.getmaster
-- @param[opt] s The screen number, defaults to focused screen.
-- @return The master window.
function client.getmaster(s)
@@ -477,6 +288,7 @@ end
--- Set the client as master: put it at the beginning of other windows.
--
+-- @legacylayout awful.client.setmaster
-- @client c The window to set as master.
function client.setmaster(c)
local cls = util.table.reverse(capi.client.get(c.screen))
@@ -486,6 +298,7 @@ function client.setmaster(c)
end
--- Set the client as slave: put it at the end of other windows.
+-- @legacylayout awful.client.setslave
-- @client c The window to set as slave.
function client.setslave(c)
local cls = capi.client.get(c.screen)
@@ -495,45 +308,76 @@ function client.setslave(c)
end
--- Move/resize a client relative to current coordinates.
+-- @deprecated awful.client.moveresize
-- @param x The relative x coordinate.
-- @param y The relative y coordinate.
-- @param w The relative width.
-- @param h The relative height.
-- @client[opt] c The client, otherwise focused one is used.
+-- @see client.relative_move
function client.moveresize(x, y, w, h, c)
- local sel = c or capi.client.focus
- local geometry = sel:geometry()
+ 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.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.relative_move(self, x, y, w, h)
+ local geometry = self:geometry()
geometry['x'] = geometry['x'] + x
geometry['y'] = geometry['y'] + y
geometry['width'] = geometry['width'] + w
geometry['height'] = geometry['height'] + h
- sel:geometry(geometry)
+ self:geometry(geometry)
end
--- Move a client to a tag.
+-- @deprecated awful.client.movetotag
-- @param target The tag to move the client to.
-- @client[opt] c The client to move, otherwise the focused one is used.
+-- @see client.move_to_tag
function client.movetotag(target, c)
- local sel = c or capi.client.focus
- local s = tag.getscreen(target)
- if sel and s then
- if sel == capi.client.focus then
- sel:emit_signal("request::activate", "client.movetotag", {raise=true})
+ util.deprecate "Use c:move_to_tag(target) instead of awful.client.movetotag"
+ client.object.move_to_tag(c or capi.client.focus, target)
+end
+
+--- Move a client to a tag.
+-- @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 = target.screen
+ if self and s then
+ if self == capi.client.focus then
+ self:emit_signal("request::activate", "client.movetotag", {raise=true})
end
-- Set client on the same screen as the tag.
- sel.screen = s
- sel:tags({ target })
+ self.screen = s
+ self:tags({ target })
end
end
--- Toggle a tag on a client.
+-- @deprecated awful.client.toggletag
-- @param target The tag to toggle.
-- @client[opt] c The client to toggle, otherwise the focused one is used.
+-- @see client.toggle_tag
function client.toggletag(target, c)
- local sel = c or capi.client.focus
+ util.deprecate "Use c:toggle_tag(target) instead of awful.client.toggletag"
+ client.object.toggle_tag(c or capi.client.focus, target)
+end
+
+--- Toggle a tag on a client.
+-- @function client.toggle_tag
+-- @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 sel and get_screen(sel.screen) == get_screen(tag.getscreen(target)) then
- local tags = sel:tags()
+ 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
if v == target then
@@ -548,114 +392,184 @@ function client.toggletag(target, c)
else
tags[#tags + 1] = target
end
- sel:tags(tags)
+ self:tags(tags)
end
end
--- Move a client to a screen. Default is next screen, cycling.
+-- @deprecated awful.client.movetoscreen
-- @client c The client to move.
-- @param s The screen, default to current + 1.
+-- @see screen
+-- @see client.move_to_screen
function client.movetoscreen(c, s)
- local sel = c or capi.client.focus
- if sel then
+ util.deprecate "Use c:move_to_screen(s) instead of awful.client.movetoscreen"
+
+ client.object.move_to_screen(c or capi.client.focus, s)
+end
+
+--- Move a client to a screen. Default is next screen, cycling.
+-- @function client.move_to_screen
+-- @tparam[opt=c.screen.index+1] screen s The screen, default to current + 1.
+-- @see screen
+-- @see request::activate
+function client.object.move_to_screen(self, s)
+ if self then
local sc = capi.screen.count()
if not s then
- s = sel.screen.index + 1
+ s = self.screen.index + 1
end
if type(s) == "number" then
if s > sc then s = 1 elseif s < 1 then s = sc end
end
s = get_screen(s)
- if get_screen(sel.screen) ~= s then
- local sel_is_focused = sel == capi.client.focus
- sel.screen = s
+ if get_screen(self.screen) ~= s then
+ local sel_is_focused = self == capi.client.focus
+ self.screen = s
screen.focus(s)
if sel_is_focused then
- sel:emit_signal("request::activate", "client.movetoscreen",
+ self:emit_signal("request::activate", "client.movetoscreen",
{raise=true})
end
end
end
end
---- Mark a client, and then call 'marked' hook.
--- @client c The client to mark, the focused one if not specified.
--- @return True if the client has been marked. False if the client was already marked.
-function client.mark(c)
- local cl = c or capi.client.focus
- if cl then
- for _, v in pairs(client.data.marked) do
- if cl == v then
- return false
+--- 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:**
+--
+-- * *marked* (for legacy reasons, use `property::marked`)
+-- * *unmarked* (for legacy reasons, use `property::marked`)
+-- * *property::marked*
+--
+-- @property marked
+-- @param boolean
+
+--- The border color when the client is focused.
+--
+-- @beautiful beautiful.border_marked
+-- @param string
+--
+
+function client.object.set_marked(self, value)
+ local is_marked = self.marked
+
+ if value == false and is_marked then
+ for k, v in pairs(client.data.marked) do
+ if self == v then
+ table.remove(client.data.marked, k)
end
end
-
- table.insert(client.data.marked, cl)
-
- -- Call callback
- cl:emit_signal("marked")
- return true
+ self:emit_signal("unmarked")
+ elseif not is_marked and value then
+ self:emit_signal("marked")
+ table.insert(client.data.marked, self)
end
+
+ client.property.set(self, "marked", value)
+end
+
+function client.object.get_marked(self)
+ return client.property.get(self, "marked")
+end
+
+--- Mark a client, and then call 'marked' hook.
+-- @deprecated awful.client.mark
+-- @client c The client to mark, the focused one if not specified.
+function client.mark(c)
+ util.deprecate "Use c.marked = true instead of awful.client.mark"
+
+ client.object.set_marked(c or capi.client.focus, true)
end
--- Unmark a client and then call 'unmarked' hook.
+-- @deprecated awful.client.unmark
-- @client c The client to unmark, or the focused one if not specified.
--- @return True if the client has been unmarked. False if the client was not marked.
function client.unmark(c)
- local cl = c or capi.client.focus
+ util.deprecate "Use c.marked = false instead of awful.client.unmark"
- for k, v in pairs(client.data.marked) do
- if cl == v then
- table.remove(client.data.marked, k)
- cl:emit_signal("unmarked")
- return true
- end
- end
-
- return false
+ client.object.set_marked(c or capi.client.focus, false)
end
--- Check if a client is marked.
+-- @deprecated awful.client.ismarked
-- @client c The client to check, or the focused one otherwise.
function client.ismarked(c)
- local cl = c or capi.client.focus
- if cl then
- for _, v in pairs(client.data.marked) do
- if cl == v then
- return true
- end
- end
- end
- return false
+ util.deprecate "Use c.marked instead of awful.client.ismarked"
+
+ return client.object.get_marked(c or capi.client.focus)
end
--- Toggle a client as marked.
+-- @deprecated awful.client.togglemarked
-- @client c The client to toggle mark.
function client.togglemarked(c)
+ util.deprecate "Use c.marked = not c.marked instead of awful.client.togglemarked"
+
c = c or capi.client.focus
- if not client.mark(c) then
- client.unmark(c)
+ if c then
+ c.marked = not c.marked
end
end
--- Return the marked clients and empty the marked table.
+-- @function awful.client.getmarked
-- @return A table with all marked clients.
function client.getmarked()
- for _, v in pairs(client.data.marked) do
+ local copy = util.table.clone(client.data.marked, false)
+
+ for _, v in pairs(copy) do
+ client.property.set(v, "marked", false)
v:emit_signal("unmarked")
end
- local t = client.data.marked
client.data.marked = {}
- return t
+
+ return copy
end
--- Set a client floating state, overriding auto-detection.
-- Floating client are not handled by tiling layouts.
+-- @deprecated awful.client.floating.set
-- @client c A client.
-- @param s True or false.
function client.floating.set(c, s)
+ util.deprecate "Use c.floating = true instead of awful.client.floating.set"
+ client.object.set_floating(c, s)
+end
+
+-- Set a client floating state, overriding auto-detection.
+-- Floating client are not handled by tiling layouts.
+-- @client c A client.
+-- @param s True or false.
+function client.object.set_floating(c, s)
c = c or capi.client.focus
if c and client.property.get(c, "floating") ~= s then
client.property.set(c, "floating", s)
@@ -668,7 +582,7 @@ function client.floating.set(c, s)
end
local function store_floating_geometry(c)
- if client.floating.get(c) then
+ if client.object.get_floating(c) then
client.property.set(c, "floating_geometry", c:geometry())
end
end
@@ -684,10 +598,31 @@ end)
capi.client.connect_signal("property::geometry", store_floating_geometry)
---- Return if a client has a fixe size or not.
+--- Return if a client has a fixed size or not.
+-- This function is deprecated, use `c.is_fixed`
-- @client c The client.
+-- @deprecated awful.client.isfixed
+-- @see is_fixed
+-- @see size_hints_honor
function client.isfixed(c)
+ util.deprecate "Use c.is_fixed instead of awful.client.isfixed"
c = c or capi.client.focus
+ return client.object.is_fixed(c)
+end
+
+--- Return if a client has a fixed size or not.
+--
+-- **Signal:**
+--
+-- * *property::is_fixed*
+--
+-- This property is read only.
+-- @property is_fixed
+-- @param boolean The floating state
+-- @see size_hints
+-- @see size_hints_honor
+
+function client.object.is_fixed(c)
if not c then return end
local h = c.size_hints
if h.min_width and h.max_width
@@ -703,10 +638,31 @@ end
--- Get a client floating state.
-- @client c A client.
+-- @see floating
+-- @deprecated awful.client.floating.get
-- @return True or false. Note that some windows might be floating even if you
-- did not set them manually. For example, windows with a type different than
-- normal.
function client.floating.get(c)
+ util.deprecate "Use c.floating instead of awful.client.floating.get"
+ return client.object.get_floating(c)
+end
+
+--- The client floating state.
+-- If the client is part of the tiled layout or free floating.
+--
+-- Note that some windows might be floating even if you
+-- did not set them manually. For example, windows with a type different than
+-- normal.
+--
+-- **Signal:**
+--
+-- * *property::floating*
+--
+-- @property floating
+-- @param boolean The floating state
+
+function client.object.get_floating(c)
c = c or capi.client.focus
if c then
local value = client.property.get(c, "floating")
@@ -717,7 +673,7 @@ function client.floating.get(c)
or c.fullscreen
or c.maximized_vertical
or c.maximized_horizontal
- or client.isfixed(c) then
+ or client.object.is_fixed(c) then
return true
end
return false
@@ -725,30 +681,30 @@ function client.floating.get(c)
end
--- Toggle the floating state of a client between 'auto' and 'true'.
+-- Use `c.floating = not c.floating`
+-- @deprecated awful.client.floating.toggle
-- @client c A client.
+-- @see floating
function client.floating.toggle(c)
c = c or capi.client.focus
-- If it has been set to floating
- if client.floating.get(c) then
- client.floating.set(c, false)
- else
- client.floating.set(c, true)
- end
+ client.object.set_floating(c, not client.object.get_floating(c))
end
---- Remove the floating information on a client.
+-- Remove the floating information on a client.
-- @client c The client.
function client.floating.delete(c)
- client.floating.set(c, nil)
+ client.object.set_floating(c, nil)
end
--- Restore (=unminimize) a random client.
+-- @function awful.client.restore
-- @param s The screen to use.
-- @return The restored client if some client was restored, otherwise nil.
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
@@ -790,6 +746,7 @@ end
--- Calculate a client's column number, index in that column, and
-- number of visible clients in this column.
--
+-- @legacylayout awful.client.idx
-- @client c the client
-- @return col the column number
-- @return idx index of the client in the column
@@ -808,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.master_count
-- This will happen for floating or maximized clients
if not idx then return nil end
@@ -824,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.column_count
-- minimum number of clients per column
local percol = math.floor(nother / ncol)
-- number of columns with an extra client
@@ -850,6 +807,7 @@ end
--- Set the window factor of a client
--
+-- @legacylayout awful.client.setwfact
-- @param wfact the window factor value
-- @client c the client
function client.setwfact(wfact, c)
@@ -861,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
@@ -902,17 +860,18 @@ end
--- Increment a client's window factor
--
+-- @legacylayout awful.client.incwfact
-- @param add amount to increase the client's window
-- @client c the client
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
@@ -929,7 +888,25 @@ end
-- @return True or false. Note that some windows might be dockable even if you
-- did not set them manually. For example, windows with a type "utility",
-- "toolbar" or "dock"
+-- @deprecated awful.client.dockable.get
function client.dockable.get(c)
+ util.deprecate "Use c.dockable instead of awful.client.dockable.get"
+
+ return client.object.get_dockable(c)
+end
+
+--- If the client is dockable.
+-- A dockable client is an application confined to the edge of the screen. The
+-- space it occupy is substracted from the `screen.workarea`.
+--
+-- **Signal:**
+--
+-- * *property::dockable*
+--
+-- @property dockable
+-- @param boolean The dockable state
+
+function client.object.get_dockable(c)
local value = client.property.get(c, "dockable")
-- Some sane defaults
@@ -950,15 +927,20 @@ end
--
-- @client c A client.
-- @param value True or false.
+-- @deprecated awful.client.dockable.set
function client.dockable.set(c, value)
+ util.deprecate "Use c.dockable = value instead of awful.client.dockable.set"
client.property.set(c, "dockable", value)
end
--- Get a client property.
--
+-- This method is deprecated. It is now possible to use `c.value` directly.
+--
-- @client c The client.
-- @param prop The property name.
-- @return The property.
+-- @deprecated awful.client.property.get
function client.property.get(c, prop)
if not client.data.persistent_properties_loaded[c] then
client.data.persistent_properties_loaded[c] = true
@@ -975,11 +957,14 @@ function client.property.get(c, prop)
end
--- Set a client property.
--- These properties are internal to awful. Some are used to move clients, etc.
+--
+-- This method is deprecated. It is now possible to use `c.value = value`
+-- directly.
--
-- @client c The client.
-- @param prop The property name.
-- @param value The value.
+-- @deprecated awful.client.property.set
function client.property.set(c, prop, value)
if not client.data.properties[c] then
client.data.properties[c] = {}
@@ -995,6 +980,7 @@ end
--- Set a client property to be persistent across restarts (via X properties).
--
+-- @function awful.client.property.persist
-- @param prop The property name.
-- @param kind The type (used for register_xproperty).
-- One of "string", "number" or "boolean".
@@ -1020,6 +1006,7 @@ end
-- index of the currently focused client.
-- @param s which screen to use. nil means all screens.
--
+-- @function awful.client.iterate
-- @usage -- un-minimize all urxvt instances
-- local urxvt = function (c)
-- return awful.rules.match(c, {class = "URxvt"})
@@ -1045,6 +1032,7 @@ end
-- first tag additionally) when the client is not visible.
-- If it is a function, it will be called with the client as argument.
--
+-- @function awful.client.run_or_raise
-- @usage -- run or raise urxvt (perhaps, with tabs) on modkey + semicolon
-- awful.key({ modkey, }, 'semicolon', function ()
-- local matcher = function (c)
@@ -1067,12 +1055,26 @@ function client.run_or_raise(cmd, matcher, merge)
end
--- Get a matching transient_for client (if any).
+-- @deprecated awful.client.get_transient_for_matching
+-- @see client.get_transient_for_matching
-- @client c The client.
-- @tparam function matcher A function that should return true, if
-- a matching parent client is found.
-- @treturn client.client|nil The matching parent client or nil.
function client.get_transient_for_matching(c, matcher)
- local tc = c.transient_for
+ util.deprecate ("Use c:get_transient_for_matching(matcher) instead of"..
+ "awful.client.get_transient_for_matching")
+
+ return client.object.get_transient_for_matching(c, matcher)
+end
+
+--- Get a matching transient_for client (if any).
+-- @function client.get_transient_for_matching
+-- @tparam function matcher A function that should return true, if
+-- a matching parent client is found.
+-- @treturn client.client|nil The matching parent client or nil.
+function client.object.get_transient_for_matching(self, matcher)
+ local tc = self.transient_for
while tc do
if matcher(tc) then
return tc
@@ -1083,11 +1085,24 @@ function client.get_transient_for_matching(c, matcher)
end
--- Is a client transient for another one?
+-- @deprecated awful.client.is_transient_for
+-- @see client.is_transient_for
-- @client c The child client (having transient_for).
-- @client c2 The parent client to check.
-- @treturn client.client|nil The parent client or nil.
function client.is_transient_for(c, c2)
- local tc = c
+ util.deprecate ("Use c:is_transient_for(c2) instead of"..
+ "awful.client.is_transient_for")
+
+ return client.object.is_transient_for(c, c2)
+end
+
+--- Is a client transient for another one?
+-- @function client.is_transient_for
+-- @client c2 The parent client to check.
+-- @treturn client.client|nil The parent client or nil.
+function client.object.is_transient_for(self, c2)
+ local tc = self
while tc.transient_for do
if tc.transient_for == c2 then
return tc
@@ -1098,10 +1113,21 @@ function client.is_transient_for(c, c2)
end
-- Register standards signals
+
+--- The last geometry when client was floating.
+-- @signal property::floating_geometry
capi.client.add_signal("property::floating_geometry")
+
capi.client.add_signal("property::floating")
+
capi.client.add_signal("property::dockable")
+
+--- The client marked signal (deprecated).
+-- @signal .marked
capi.client.add_signal("marked")
+
+--- The client unmarked signal (deprecated).
+-- @signal unmarked
capi.client.add_signal("unmarked")
capi.client.connect_signal("focus", client.focus.history.add)
@@ -1116,9 +1142,6 @@ capi.client.connect_signal("manage", function (c)
end)
capi.client.connect_signal("unmanage", client.focus.history.delete)
-capi.client.connect_signal("property::urgent", client.urgent.add)
-capi.client.connect_signal("focus", client.urgent.delete)
-capi.client.connect_signal("unmanage", client.urgent.delete)
capi.client.connect_signal("unmanage", client.floating.delete)
@@ -1127,8 +1150,8 @@ client.property.persist("floating", "boolean")
-- Extend the luaobject
object.properties(capi.client, {
- getter_class = client,
- setter_class = client,
+ getter_class = client.object,
+ setter_class = client.object,
getter_fallback = client.property.get,
setter_fallback = client.property.set,
})
diff --git a/lib/awful/client/focus.lua b/lib/awful/client/focus.lua
new file mode 100644
index 00000000..1b826b1e
--- /dev/null
+++ b/lib/awful/client/focus.lua
@@ -0,0 +1,218 @@
+---------------------------------------------------------------------------
+--- Keep track of the focused clients.
+--
+-- @author Julien Danjou <julien@danjou.info>
+-- @copyright 2008 Julien Danjou
+-- @release @AWESOME_VERSION@
+-- @submodule client
+---------------------------------------------------------------------------
+local util = require("awful.util")
+
+local capi =
+{
+ screen = screen,
+ client = client,
+}
+
+-- We use a metatable to prevent circular dependency loops.
+local screen
+do
+ screen = setmetatable({}, {
+ __index = function(_, k)
+ screen = require("awful.screen")
+ return screen[k]
+ end,
+ __newindex = error -- Just to be sure in case anything ever does this
+ })
+end
+
+local client
+do
+ client = setmetatable({}, {
+ __index = function(_, k)
+ client = require("awful.client")
+ return client[k]
+ end,
+ __newindex = error -- Just to be sure in case anything ever does this
+ })
+end
+
+local focus = {history = {}}
+
+local internal = {}
+
+local function get_screen(s)
+ return s and capi.screen[s]
+end
+
+--- Remove a client from the focus history
+--
+-- @client c The client that must be removed.
+-- @function awful.client.focus.history.delete
+function focus.history.delete(c)
+ for k, v in ipairs(internal) do
+ if v == c then
+ table.remove(internal, k)
+ break
+ end
+ end
+end
+
+--- Focus a client by its relative index.
+--
+-- @function awful.client.focus.byidx
+-- @param i The index.
+-- @client[opt] c The client.
+function focus.byidx(i, c)
+ local target = client.next(i, c)
+ if target then
+ target:emit_signal("request::activate", "client.focus.byidx",
+ {raise=true})
+ end
+end
+
+--- Filter out window that we do not want handled by focus.
+-- This usually means that desktop, dock and splash windows are
+-- not registered and cannot get focus.
+--
+-- @client c A client.
+-- @return The same client if it's ok, nil otherwise.
+-- @function awful.client.focus.filter
+function focus.filter(c)
+ if c.type == "desktop"
+ or c.type == "dock"
+ or c.type == "splash"
+ or not c.focusable then
+ return nil
+ end
+ return c
+end
+
+--- Update client focus history.
+--
+-- @client c The client that has been focused.
+-- @function awful.client.focus.history.add
+function focus.history.add(c)
+ -- Remove the client if its in stack
+ focus.history.delete(c)
+ -- Record the client has latest focused
+ table.insert(internal, 1, c)
+end
+
+--- Get the latest focused client for a screen in history.
+--
+-- @tparam int|screen s The screen to look for.
+-- @tparam int idx The index: 0 will return first candidate,
+-- 1 will return second, etc.
+-- @tparam function filter An optional filter. If no client is found in the
+-- first iteration, `awful.client.focus.filter` is used by default to get any
+-- client.
+-- @treturn client.object A client.
+-- @function awful.client.focus.history.get
+function focus.history.get(s, idx, filter)
+ s = get_screen(s)
+ -- When this counter is equal to idx, we return the client
+ local counter = 0
+ local vc = client.visible(s, true)
+ for _, c in ipairs(internal) do
+ if get_screen(c.screen) == s then
+ if not filter or filter(c) then
+ for _, vcc in ipairs(vc) do
+ if vcc == c then
+ if counter == idx then
+ return c
+ end
+ -- We found one, increment the counter only.
+ counter = counter + 1
+ break
+ end
+ end
+ end
+ end
+ end
+ -- Argh nobody found in history, give the first one visible if there is one
+ -- that passes the filter.
+ filter = filter or focus.filter
+ if counter == 0 then
+ for _, v in ipairs(vc) do
+ if filter(v) then
+ return v
+ end
+ end
+ end
+end
+
+--- Focus the previous client in history.
+-- @function awful.client.focus.history.previous
+function focus.history.previous()
+ local sel = capi.client.focus
+ local s = sel and sel.screen or screen.focused()
+ local c = focus.history.get(s, 1)
+ if c then
+ c:emit_signal("request::activate", "client.focus.history.previous",
+ {raise=false})
+ end
+end
+
+--- Focus a client by the given direction.
+--
+-- @tparam string dir The direction, can be either
+-- `"up"`, `"down"`, `"left"` or `"right"`.
+-- @client[opt] c The client.
+-- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
+-- @function awful.client.focus.bydirection
+function focus.bydirection(dir, c, stacked)
+ local sel = c or capi.client.focus
+ if sel then
+ local cltbl = client.visible(sel.screen, stacked)
+ local geomtbl = {}
+ for i,cl in ipairs(cltbl) do
+ geomtbl[i] = cl:geometry()
+ end
+
+ local target = util.get_rectangle_in_direction(dir, geomtbl, sel:geometry())
+
+ -- If we found a client to focus, then do it.
+ if target then
+ cltbl[target]:emit_signal("request::activate",
+ "client.focus.bydirection", {raise=false})
+ end
+ end
+end
+
+--- Focus a client by the given direction. Moves across screens.
+--
+-- @param dir The direction, can be either "up", "down", "left" or "right".
+-- @client[opt] c The client.
+-- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
+-- @function awful.client.focus.global_bydirection
+function focus.global_bydirection(dir, c, stacked)
+ local sel = c or capi.client.focus
+ local scr = get_screen(sel and sel.screen or screen.focused())
+
+ -- change focus inside the screen
+ focus.bydirection(dir, sel)
+
+ -- if focus not changed, we must change screen
+ if sel == capi.client.focus then
+ screen.focus_bydirection(dir, scr)
+ if scr ~= get_screen(screen.focused()) then
+ local cltbl = client.visible(screen.focused(), stacked)
+ local geomtbl = {}
+ for i,cl in ipairs(cltbl) do
+ geomtbl[i] = cl:geometry()
+ end
+ local target = util.get_rectangle_in_direction(dir, geomtbl, scr.geometry)
+
+ if target then
+ cltbl[target]:emit_signal("request::activate",
+ "client.focus.global_bydirection",
+ {raise=false})
+ end
+ end
+ end
+end
+
+return focus
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/lib/awful/client/shape.lua b/lib/awful/client/shape.lua
index e1280e0e..e21fe238 100644
--- a/lib/awful/client/shape.lua
+++ b/lib/awful/client/shape.lua
@@ -4,7 +4,7 @@
-- @author Uli Schlachter <psychon@znc.in>
-- @copyright 2014 Uli Schlachter
-- @release @AWESOME_VERSION@
--- @module awful.client.shape
+-- @submodule client
---------------------------------------------------------------------------
-- Grab environment we need
@@ -18,7 +18,8 @@ local capi =
local shape = {}
shape.update = {}
---- Get one of a client's shapes and transform it to include window decorations
+--- Get one of a client's shapes and transform it to include window decorations.
+-- @function awful.shape.get_transformed
-- @client c The client whose shape should be retrieved
-- @tparam string shape_name Either "bounding" or "clip"
function shape.get_transformed(c, shape_name)
@@ -51,7 +52,8 @@ function shape.get_transformed(c, shape_name)
return result
end
---- Update a client's bounding shape from the shape the client set itself
+--- Update a client's bounding shape from the shape the client set itself.
+-- @function awful.shape.update.bounding
-- @client c The client to act on
function shape.update.bounding(c)
local res = shape.get_transformed(c, "bounding")
@@ -62,7 +64,8 @@ function shape.update.bounding(c)
end
end
---- Update a client's clip shape from the shape the client set itself
+--- Update a client's clip shape from the shape the client set itself.
+-- @function awful.shape.update.clip
-- @client c The client to act on
function shape.update.clip(c)
local res = shape.get_transformed(c, "clip")
@@ -73,7 +76,8 @@ function shape.update.clip(c)
end
end
---- Update all of a client's shapes from the shapes the client set itself
+--- Update all of a client's shapes from the shapes the client set itself.
+-- @function awful.shape.update.all
-- @client c The client to act on
function shape.update.all(c)
shape.update.bounding(c)
diff --git a/lib/awful/client/urgent.lua b/lib/awful/client/urgent.lua
new file mode 100644
index 00000000..051bc2ee
--- /dev/null
+++ b/lib/awful/client/urgent.lua
@@ -0,0 +1,89 @@
+---------------------------------------------------------------------------
+--- Keep track of the urgent clients.
+--
+-- @author Julien Danjou <julien@danjou.info>
+-- @copyright 2008 Julien Danjou
+-- @release @AWESOME_VERSION@
+-- @submodule client
+---------------------------------------------------------------------------
+
+local urgent = {}
+
+local capi =
+{
+ client = client,
+}
+
+local client
+do
+ client = setmetatable({}, {
+ __index = function(_, k)
+ client = require("awful.client")
+ return client[k]
+ end,
+ __newindex = error -- Just to be sure in case anything ever does this
+ })
+end
+
+local data = setmetatable({}, { __mode = 'k' })
+
+--- Get the first client that got the urgent hint.
+--
+-- @function awful.urgent.get
+-- @treturn client.object The first urgent client.
+function urgent.get()
+ if #data > 0 then
+ return data[1]
+ else
+ -- fallback behaviour: iterate through clients and get the first urgent
+ local clients = capi.client.get()
+ for _, cl in pairs(clients) do
+ if cl.urgent then
+ return cl
+ end
+ end
+ end
+end
+
+--- Jump to the client that received the urgent hint first.
+--
+-- @function awful.urgent.jumpto
+-- @tparam bool|function merge If true then merge tags (select the client's
+-- first tag additionally) when the client is not visible.
+-- If it is a function, it will be called with the client as argument.
+function urgent.jumpto(merge)
+ local c = client.urgent.get()
+ if c then
+ client.jumpto(c, merge)
+ end
+end
+
+--- Adds client to urgent stack.
+--
+-- @function awful.urgent.add
+-- @client c The client object.
+-- @param prop The property which is updated.
+function urgent.add(c, prop)
+ if type(c) == "client" and prop == "urgent" and c.urgent then
+ table.insert(data, c)
+ end
+end
+
+--- Remove client from urgent stack.
+--
+-- @function awful.urgent.delete
+-- @client c The client object.
+function urgent.delete(c)
+ for k, cl in ipairs(data) do
+ if c == cl then
+ table.remove(data, k)
+ break
+ end
+ end
+end
+
+capi.client.connect_signal("property::urgent", urgent.add)
+capi.client.connect_signal("focus", urgent.delete)
+capi.client.connect_signal("unmanage", urgent.delete)
+
+return urgent
diff --git a/lib/awful/ewmh.lua b/lib/awful/ewmh.lua
index 0fffa6dd..de4af306 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/key.lua b/lib/awful/key.lua
index 30feb5dc..834f7198 100644
--- a/lib/awful/key.lua
+++ b/lib/awful/key.lua
@@ -10,7 +10,7 @@
-- Grab environment we need
local setmetatable = setmetatable
local ipairs = ipairs
-local capi = { key = key }
+local capi = { key = key, root = root }
local util = require("awful.util")
@@ -26,6 +26,40 @@ local key = { mt = {}, hotkeys = {} }
-- @class table
local ignore_modifiers = { "Lock", "Mod2" }
+--- Convert the modifiers into pc105 key names
+local conversion = {
+ mod4 = "Super_L",
+ control = "Control_L",
+ shift = "Shift_L",
+ mod1 = "Alt_L",
+}
+
+--- Execute a key combination.
+-- If an awesome keybinding is assigned to the combination, it should be
+-- executed.
+-- @see root.fake_input
+-- @tparam table mod A modified table. Valid modifiers are: Any, Mod1,
+-- Mod2, Mod3, Mod4, Mod5, Shift, Lock and Control.
+-- @tparam string k The key
+function key.execute(mod, k)
+ for _, v in ipairs(mod) do
+ local m = conversion[v:lower()]
+ if m then
+ root.fake_input("key_press", m)
+ end
+ end
+
+ root.fake_input("key_press" , k)
+ root.fake_input("key_release", k)
+
+ for _, v in ipairs(mod) do
+ local m = conversion[v:lower()]
+ if m then
+ root.fake_input("key_release", m)
+ end
+ end
+end
+
--- Create a new key to use as binding.
-- This function is useful to create several keys from one, because it will use
-- the ignore_modifier variable to create several keys with and without the
@@ -66,6 +100,7 @@ function key.new(mod, _key, press, release, data)
data.mod = mod
data.key = _key
table.insert(key.hotkeys, data)
+ data.execute = function(_) key.execute(mod, _key) end
return ret
end
diff --git a/lib/awful/layout/init.lua b/lib/awful/layout/init.lua
index 984fdde9..b1da60e6 100644
--- a/lib/awful/layout/init.lua
+++ b/lib/awful/layout/init.lua
@@ -11,7 +11,6 @@
local ipairs = ipairs
local type = type
local util = require("awful.util")
-local ascreen = require("awful.screen")
local capi = {
screen = screen,
mouse = mouse,
@@ -21,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)
@@ -64,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
@@ -78,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)
@@ -109,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
@@ -130,24 +131,24 @@ 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 = ascreen.get_bounding_geometry(screen, {
+ p.workarea = screen:get_bounding_geometry {
honor_padding = true,
honor_workarea = true,
margins = useless_gap,
- })
+ }
p.geometry = screen.geometry
p.clients = client.tiled(screen)
p.screen = screen.index
- p.padding = ascreen.padding(screen)
+ p.padding = screen.padding
p.useless_gap = useless_gap
return p
@@ -213,14 +214,14 @@ 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")
-capi.tag.connect_signal("property::mwfact", arrange_tag)
-capi.tag.connect_signal("property::nmaster", arrange_tag)
-capi.tag.connect_signal("property::ncol", arrange_tag)
+capi.tag.connect_signal("property::master_width_factor", arrange_tag)
+capi.tag.connect_signal("property::master_count", arrange_tag)
+capi.tag.connect_signal("property::column_count", arrange_tag)
capi.tag.connect_signal("property::layout", arrange_tag)
capi.tag.connect_signal("property::windowfact", arrange_tag)
capi.tag.connect_signal("property::selected", arrange_tag)
diff --git a/lib/awful/layout/suit/corner.lua b/lib/awful/layout/suit/corner.lua
index 6d740567..2327186a 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.master_count % 2) == 0)
- local master_factor = tag.getmwfact(tag.selected(cls[1].screen))
+ local master_factor = cls[1].screen.selected_tag.master_width_factor
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 32482369..7842f72a 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,
@@ -18,7 +17,6 @@ local capi =
mouse = mouse,
mousegrabber = mousegrabber
}
-local client = require("awful.client")
local magnifier = {}
@@ -41,7 +39,8 @@ 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.master_width_factor
+ = math.min(math.max(0.01, mwfact), 0.99)
return true
end
end
@@ -54,8 +53,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.master_width_factor
local fidx
-- Check that the focused window is on the right screen
@@ -67,7 +66,7 @@ function magnifier.arrange(p)
end
-- If focused window is not tiled, take the first one which is tiled.
- if client.floating.get(focus) then
+ if focus.floating then
focus = cls[1]
fidx = 1
end
diff --git a/lib/awful/layout/suit/tile.lua b/lib/awful/layout/suit/tile.lua
index 0071ff56..802fdce9 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.master_width_factor
local cursor
local g = c:geometry()
local offset = 0
@@ -126,7 +126,8 @@ 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.master_width_factor
+ = 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 +196,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 +209,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.master_count, #cls)
local nother = math.max(#cls - nmaster,0)
- local mwfact = tag.getmwfact(t)
+ local mwfact = t.master_width_factor
local wa = param.workarea
- local ncol = tag.getncol(t)
+ local ncol = t.column_count
local data = tag.getdata(t).windowfact
@@ -229,7 +230,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 e444c06b..0dc62269 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 285b3aec..b1e362e0 100644
--- a/lib/awful/mouse/init.lua
+++ b/lib/awful/mouse/init.lua
@@ -111,13 +111,13 @@ function mouse.client.snap(c, snap, x, y, fixed_x, fixed_y)
-- Allow certain windows to snap to the edge of the workarea.
-- Only allow docking to workarea for consistency/to avoid problems.
- if aclient.dockable.get(c) then
+ if c.dockable then
local struts = c:struts()
struts['left'] = 0
struts['right'] = 0
struts['top'] = 0
struts['bottom'] = 0
- if edge ~= "none" and aclient.floating.get(c) then
+ if edge ~= "none" and c.floating then
if edge == "left" or edge == "right" then
struts[edge] = cur_geom.width
elseif edge == "top" or edge == "bottom" then
@@ -177,7 +177,7 @@ function mouse.client.move(c, snap, finished_cb)
for _, v in ipairs(_mouse.buttons) do
if v then
local lay = layout.get(c.screen)
- if lay == layout.suit.floating or aclient.floating.get(c) then
+ if lay == layout.suit.floating or c.floating then
local x = _mouse.x - dist_x
local y = _mouse.y - dist_y
c:geometry(mouse.client.snap(c, snap, x, y, fixed_x, fixed_y))
@@ -195,7 +195,7 @@ function mouse.client.move(c, snap, finished_cb)
end
if layout.get(c.screen) ~= layout.suit.floating then
local c_u_m = mouse.client_under_pointer()
- if c_u_m and not aclient.floating.get(c_u_m) then
+ if c_u_m and not c_u_m.floating then
if c_u_m ~= c then
c:swap(c_u_m)
end
@@ -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
@@ -239,11 +239,11 @@ function mouse.client.dragtotag.border(c)
end
if _mouse.x > wa.x + wa.width - 10 then
local newtag = tags[util.cycle(#tags, idx + 1)]
- aclient.movetotag(newtag, c)
+ c:move_to_tag(newtag)
tag.viewnext()
elseif _mouse.x < wa.x + 10 then
local newtag = tags[util.cycle(#tags, idx - 1)]
- aclient.movetotag(newtag, c)
+ c:move_to_tag(newtag)
tag.viewprev()
end
return false
@@ -356,7 +356,7 @@ function mouse.client.resize(c, corner)
local lay = layout.get(c.screen)
local corner2, x, y = mouse.client.corner(c, corner)
- if lay == layout.suit.floating or aclient.floating.get(c) then
+ if lay == layout.suit.floating or c.floating then
return layout.suit.floating.mouse_resize_handler(c, corner2, x, y)
elseif lay.mouse_resize_handler then
return lay.mouse_resize_handler(c, corner2, x, y)
diff --git a/lib/awful/placement.lua b/lib/awful/placement.lua
index 9555afd8..95866995 100644
--- a/lib/awful/placement.lua
+++ b/lib/awful/placement.lua
@@ -19,7 +19,7 @@
--
-- **honor_padding** (*boolean*):
--
--- Take the screen padding into account (see `awful.screen.padding`)
+-- Take the screen padding into account (see `screen.padding`)
--
-- **tag** (*tag*):
--
@@ -158,7 +158,7 @@ local function geometry_common(obj, args, new_geo, ignore_border_width)
end
-- It is a screen, it doesn't support setting new sizes.
- return a_screen.get_bounding_geometry(obj, args)
+ return obj:get_bounding_geometry(args)
else
assert(false, "Invalid object")
end
@@ -453,7 +453,7 @@ function placement.no_overlap(c)
local curlay = layout.get()
local areas = { screen.workarea }
for _, cl in pairs(cls) do
- if cl ~= c and cl.type ~= "desktop" and (client.floating.get(cl) or curlay == layout.suit.floating) then
+ if cl ~= c and cl.type ~= "desktop" and (cl.floating or curlay == layout.suit.floating) then
areas = area_remove(areas, area_common(cl))
end
end
diff --git a/lib/awful/rules.lua b/lib/awful/rules.lua
index 26abc33e..42c6425b 100644
--- a/lib/awful/rules.lua
+++ b/lib/awful/rules.lua
@@ -13,8 +13,6 @@ local table = table
local type = type
local ipairs = ipairs
local pairs = pairs
-local aclient = require("awful.client")
-local atag = require("awful.tag")
local rules = {}
@@ -199,13 +197,11 @@ function rules.execute(c, props, callbacks)
if property ~= "focus" and type(value) == "function" then
value = value(c)
end
- if property == "floating" then
- aclient.floating.set(c, value)
- elseif property == "tag" then
- c.screen = atag.getscreen(value)
+ if property == "tag" then
+ 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 c6662670..69943679 100644
--- a/lib/awful/screen.lua
+++ b/lib/awful/screen.lua
@@ -4,7 +4,7 @@
-- @author Julien Danjou <julien@danjou.info>
-- @copyright 2008 Julien Danjou
-- @release @AWESOME_VERSION@
--- @module awful.screen
+-- @module screen
---------------------------------------------------------------------------
-- Grab environment we need
@@ -24,7 +24,7 @@ end
-- we use require("awful.client") inside functions to prevent circular dependencies.
local client
-local screen = {}
+local screen = {object={}}
local data = {}
data.padding = {}
@@ -44,13 +44,27 @@ local function apply_geometry_ajustments(geo, delta)
}
end
+--- Get the square distance between a `screen` and a point
+-- @deprecated awful.screen.getdistance_sq
-- @param s Screen
-- @param x X coordinate of point
-- @param y Y coordinate of point
-- @return The squared distance of the screen to the provided point
+-- @see screen.get_square_distance
function screen.getdistance_sq(s, x, y)
- s = get_screen(s)
- local geom = s.geometry
+ util.deprecate "Use s:get_square_distance(x, y) instead of awful.screen.getdistance_sq"
+
+ return screen.object.get_square_distance(s, x, y)
+end
+
+--- Get the square distance between a `screen` and a point
+-- @function screen.get_square_distance
+-- @tparam number x X coordinate of point
+-- @tparam number y Y coordinate of point
+-- @treturn number The squared distance of the screen to the provided point
+function screen.object.get_square_distance(self, x, y)
+ self = get_screen(self)
+ local geom = self.geometry
local dist_x, dist_y = 0, 0
if x < geom.x then
dist_x = geom.x - x
@@ -69,13 +83,14 @@ end
-- Return screen number corresponding to the given (pixel) coordinates.
-- The number returned can be used as an index into the global
-- `screen` table/object.
+-- @function awful.screen.getbycoord
-- @param x The x coordinate
-- @param y The y coordinate
function screen.getbycoord(x, y)
local s = capi.screen[1]
- local dist = screen.getdistance_sq(s, x, y)
+ local dist = screen.object.get_square_distance(s, x, y)
for i in capi.screen do
- local d = screen.getdistance_sq(i, x, y)
+ local d = screen.object.get_square_distance(i, x, y)
if d < dist then
s, dist = capi.screen[i], d
end
@@ -85,6 +100,7 @@ end
--- Give the focus to a screen, and move pointer to last known position on this
-- screen, or keep position relative to the current focused screen
+-- @function awful.screen.focus
-- @param _screen Screen number (defaults / falls back to mouse.screen).
function screen.focus(_screen)
client = client or require("awful.client")
@@ -123,6 +139,7 @@ end
--- Give the focus to a screen, and move pointer to last known position on this
-- screen, or keep position relative to the current focused screen
+-- @function awful.screen.focus_bydirection
-- @param dir The direction, can be either "up", "down", "left" or "right".
-- @param _screen Screen.
function screen.focus_bydirection(dir, _screen)
@@ -141,6 +158,7 @@ end
--- Give the focus to a screen, and move pointer to last known position on this
-- screen, or keep position relative to the current focused screen
+-- @function awful.screen.focus_relative
-- @param i Value to add to the current focused screen index. 1 will focus next
-- screen, -1 would focus the previous one.
function screen.focus_relative(i)
@@ -148,28 +166,40 @@ function screen.focus_relative(i)
end
--- Get or set the screen padding.
+-- @deprecated awful.screen.padding
-- @param _screen The screen object to change the padding on
-- @param[opt=nil] padding The padding, a table with 'top', 'left', 'right' and/or
-- 'bottom' or a number value to apply set the same padding on all sides. Can be
-- nil if you only want to retrieve padding
-- @treturn table A table with left, right, top and bottom number values.
+-- @see padding
function screen.padding(_screen, padding)
- if type(padding) == "number" then
- padding = {
- left = padding,
- right = padding,
- top = padding,
- bottom = padding,
- }
- end
+ util.deprecate "Use _screen.padding = value instead of awful.screen.padding"
- _screen = get_screen(_screen)
if padding then
- data.padding[_screen] = padding
- _screen:emit_signal("padding")
+ screen.object.set_padding(_screen, padding)
end
- local p = data.padding[_screen] or {}
+ return screen.object.get_padding(_screen)
+end
+
+--- The screen padding.
+-- Add a "buffer" section on each side of the screen where the tiled client
+-- wont be.
+--
+-- **Signal:**
+--
+-- * *property::padding*
+--
+-- @property padding
+-- @param table
+-- @tfield integer table.x The horizontal position
+-- @tfield integer table.y The vertical position
+-- @tfield integer table.width The width
+-- @tfield integer table.height The height
+
+function screen.object.get_padding(self)
+ local p = data.padding[self] or {}
-- Create a copy to avoid accidental mutation and nil values
return {
@@ -180,14 +210,36 @@ function screen.padding(_screen, padding)
}
end
+function screen.object.set_padding(self, padding)
+ if type(padding) == "number" then
+ padding = {
+ left = padding,
+ right = padding,
+ top = padding,
+ bottom = padding,
+ }
+ end
+
+ self = get_screen(self)
+ if padding then
+ data.padding[self] = padding
+ self:emit_signal("padding")
+ end
+end
+
+--- The defaults arguments for `awful.screen.focused`
+-- @tfield[opt=nil] table awful.screen.default_focused_args
+
--- Get the focused screen.
--
-- It is possible to set `awful.screen.default_focused_args` to override the
-- default settings.
--
+-- @function awful.screen.focused
-- @tparam[opt] table args
--- @tparam[opt=false] table args.client Use the client screen instead of the
+-- @tparam[opt=false] boolean args.client Use the client screen instead of the
-- mouse screen.
+-- @tparam[opt=true] boolean args.mouse Use the mouse screen
-- @treturn ?screen The focused screen object, or `nil` in case no screen is
-- present currently.
function screen.focused(args)
@@ -209,24 +261,31 @@ end
-- * **bounding_rect**: A bounding rectangle. This parameter is incompatible with
-- `honor_workarea`.
--
--- @tparam[opt=mouse.screen] screen s A screen
+-- @function screen.get_bounding_geometry
-- @tparam[opt={}] table args The arguments
-- @treturn table A table with *x*, *y*, *width* and *height*.
-function screen.get_bounding_geometry(s, args)
+-- @usage local geo = screen:get_bounding_geometry {
+-- honor_padding = true,
+-- honor_workarea = true,
+-- margins = {
+-- left = 20,
+-- },
+-- }
+function screen.object.get_bounding_geometry(self, args)
args = args or {}
-- If the tag has a geometry, assume it is right
if args.tag then
- s = args.tag.screen
+ self = args.tag.screen
end
- s = get_screen(s or capi.mouse.screen)
+ self = get_screen(self or capi.mouse.screen)
local geo = args.bounding_rect or (args.parent and args.parent:geometry()) or
- s[args.honor_workarea and "workarea" or "geometry"]
+ self[args.honor_workarea and "workarea" or "geometry"]
if (not args.parent) and (not args.bounding_rect) and args.honor_padding then
- local padding = screen.padding(s)
+ local padding = self.padding
geo = apply_geometry_ajustments(geo, padding)
end
@@ -242,7 +301,100 @@ function screen.get_bounding_geometry(s, args)
return geo
end
+--- Get the list of the screen visible clients.
+--
+-- 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)
+ local vcls = {}
+ for _, c in pairs(cls) do
+ if c:isvisible() then
+ table.insert(vcls, c)
+ end
+ end
+ return vcls
+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:
+--
+-- * fullscreen clients
+-- * maximized clients
+-- * floating clients
+--
+-- @property tiled_clients
+-- @param table The clients list, ordered top to bottom
+
+function screen.object.get_tiled_clients(s)
+ local clients = s.clients
+ local tclients = {}
+ -- Remove floating clients
+ for _, c in pairs(clients) do
+ if not c.floating
+ and not c.fullscreen
+ and not c.maximized_vertical
+ and not c.maximized_horizontal then
+ table.insert(tclients, c)
+ end
+ end
+ return tclients
+end
+
+function screen.object.set_tiled_clients() end
+
--- Call a function for each existing and created-in-the-future screen.
+-- @function awful.screen.connect_for_each_screen
-- @tparam function func The function to call.
-- @tparam screen func.screen The screen
function screen.connect_for_each_screen(func)
@@ -253,15 +405,88 @@ function screen.connect_for_each_screen(func)
end
--- Undo the effect of connect_for_each_screen.
+-- @function awful.screen.disconnect_for_each_screen
-- @tparam function func The function that should no longer be called.
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
+
capi.screen.add_signal("padding")
-- Extend the luaobject
-object.properties(capi.screen, {auto_emit=true})
+object.properties(capi.screen, {
+ getter_class = screen.object,
+ setter_class = screen.object,
+ auto_emit = true,
+})
return screen
diff --git a/lib/awful/tag.lua b/lib/awful/tag.lua
index 1a8b0a7a..b892f0af 100644
--- a/lib/awful/tag.lua
+++ b/lib/awful/tag.lua
@@ -4,7 +4,7 @@
-- @author Julien Danjou <julien@danjou.info>
-- @copyright 2008 Julien Danjou
-- @release @AWESOME_VERSION@
--- @module awful.tag
+-- @module tag
---------------------------------------------------------------------------
-- Grab environment we need
@@ -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,54 +45,138 @@ data.tags = setmetatable({}, { __mode = 'k' })
tag.history = {}
tag.history.limit = 20
---- Move a tag to an absolute position in the screen[]:tags() table.
--- @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.
-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)
+-- 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
- if (not new_index) or (new_index < 1) or (new_index > #tmp_tags) then
+ 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 == target_tag then
+ if t == self 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
+ 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.setscreen(scr, tmp_tag)
+ tag.object.set_screen(tmp_tag, scr)
tag.setproperty(tmp_tag, "index", i)
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)
+ 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
+-- @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")
+
+ -- 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)
- 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 {}
@@ -100,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 }
@@ -112,13 +196,20 @@ 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
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.
@@ -140,45 +231,54 @@ function tag.new(names, screen, layout)
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 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.
--- @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.
@@ -197,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
@@ -206,21 +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.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] = {}
@@ -257,6 +374,7 @@ function tag.history.update(obj)
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
@@ -264,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
@@ -290,44 +408,41 @@ function tag.history.restore(screen, idx)
end
--- 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
--- @param s Screen
--- @param t tag object
-function tag.setscreen(s, t)
+--- The tag screen.
+--
+-- **Signal:**
+--
+-- * *property::screen*
+--
+-- @property screen
+-- @param screen
+-- @see screen
- -- 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
- tag.setproperty(t, "index", nil, true)
+ tag.setproperty(t, "index", nil)
-- Change the screen
- tag.setproperty(t, "screen", s, true)
+ tag.setproperty(t, "screen", s)
-- Make sure the client's screen matches its tags
for _,c in ipairs(t:clients()) do
@@ -337,8 +452,8 @@ 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
- tag.setproperty(t2, "index", i, true)
+ for i,t2 in ipairs(screen.tags) do
+ tag.setproperty(t2, "index", i)
end
end
@@ -348,66 +463,193 @@ 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
--- 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
+ 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)
- 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* (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, true)
+ 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 0.5
+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)
- tag.setmwfact(tag.getmwfact(t) + 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)
- t = t or tag.selected()
- return tag.getproperty(t, "mwfact") or 0.5
+ 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
---- Set 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"
@@ -421,7 +663,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
@@ -433,115 +675,248 @@ function tag.setlayout(layout, t)
layout = instance
end
- tag.setproperty(t, "layout", layout, true)
+ 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)
- tag.setproperty(t, "volatile", volatile, true)
+ 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
---- Set the spacing between clients
--- @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()
+--- 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::useless_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)
+ 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 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)
+ 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 "master_width_factor"
+
+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 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)
+-- "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)
- t = t or tag.selected()
- tag.setproperty(t, "master_fill_policy", policy, true)
+ 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 "mwfact"
+-- 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.setmfpol("mwfact", t)
+ tag.setproperty(t, "master_fill_policy", "master_width_factor")
else
- tag.setmfpol("expand", t)
+ 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
--- "mwfact" (fill only an area inside the master width factor)
+-- "master_width_factor" (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.
--- @param nmaster The number of master windows.
--- @param[opt] t The tag.
-function tag.setnmaster(nmaster, t)
- t = t or tag.selected()
+--
+-- **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, true)
+ 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 1
+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)
- t = t or tag.selected()
- return tag.getproperty(t, "nmaster") or 1
+ 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)
- 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_master_count(t)
if nmaster > ntiled then
nmaster = ntiled
end
@@ -550,59 +925,109 @@ function tag.incnmaster(add, t, sensible)
if newnmaster > ntiled then
newnmaster = ntiled
end
- tag.setnmaster(newnmaster, t)
+ tag.object.set_master_count(t, newnmaster)
else
- tag.setnmaster(tag.getnmaster(t) + add, t)
+ 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)
- _tag = _tag or tag.selected()
- tag.setproperty(_tag, "icon", icon, true)
+ 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)
- _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* (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 1
+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)
- t = t or tag.selected()
+ 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, true)
+ 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)
- t = t or tag.selected()
- return tag.getproperty(t, "ncol") or 1
+ 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 ncol based on the number of visible
+-- @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
- 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_master_count(t)
local nsecondary = ntiled - nmaster
- local ncol = tag.getncol(t)
+ local ncol = tag.object.get_column_count(t)
if ncol > nsecondary then
ncol = nsecondary
end
@@ -611,34 +1036,41 @@ function tag.incncol(add, t, sensible)
if newncol > nsecondary then
newncol = nsecondary
end
- tag.setncol(newncol, t)
+
+ tag.object.set_column_count(t, newncol)
else
- tag.setncol(tag.getncol(t) + add, t)
+ 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)
- 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
end
--- View a tag by its taglist index.
--- @param i The relative index to see.
+--
+-- 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 = 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
@@ -649,54 +1081,65 @@ function tag.viewidx(i, screen)
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)
- 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).
+-- @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.
--- @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.
+-- @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 = 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
@@ -709,13 +1152,19 @@ function tag.viewmore(tags, screen)
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.getscreen(t)]:emit_signal("tag::history::update")
+ 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)
@@ -723,6 +1172,10 @@ function tag.getdata(_tag)
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.
@@ -735,39 +1188,44 @@ 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.
--- @param ignore_setters Ignore the setter function for "prop" (boolean)
-function tag.setproperty(_tag, prop, value, ignore_setters)
+function tag.setproperty(_tag, prop, value)
if not data.tags[_tag] then
data.tags[_tag] = {}
end
- if (not ignore_setters) and tag["set"..prop] then
- tag["set"..prop](value, _tag)
- else
- if data.tags[_tag][prop] ~= value then
- data.tags[_tag][prop] = value
- _tag:emit_signal("property::" .. prop)
- end
+ if data.tags[_tag][prop] ~= value then
+ data.tags[_tag][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.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)
@@ -777,7 +1235,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)
@@ -785,6 +1243,8 @@ 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
-- @param screen The screen concerned, or all if nil.
function tag.attached_connect_signal(screen, ...)
if screen then
@@ -809,7 +1269,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.
@@ -834,7 +1294,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
@@ -846,28 +1306,41 @@ 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")
capi.tag.add_signal("property::icon_only")
capi.tag.add_signal("property::layout")
capi.tag.add_signal("property::mwfact")
+capi.tag.add_signal("property::master_width_factor")
capi.tag.add_signal("property::useless_gap")
capi.tag.add_signal("property::master_fill_policy")
capi.tag.add_signal("property::ncol")
+capi.tag.add_signal("property::column_count")
capi.tag.add_signal("property::nmaster")
+capi.tag.add_signal("property::master_count")
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")
capi.screen.add_signal("tag::history::update")
+
capi.screen.connect_signal("tag::history::update", tag.history.update)
function tag.mt:__call(...)
@@ -878,12 +1351,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/titlebar.lua b/lib/awful/titlebar.lua
index 3cb3305c..c44d1703 100644
--- a/lib/awful/titlebar.lua
+++ b/lib/awful/titlebar.lua
@@ -256,7 +256,7 @@ end
--- Create a new float button for a client.
-- @param c The client for which the button is wanted.
function titlebar.widget.floatingbutton(c)
- local widget = titlebar.widget.button(c, "floating", aclient.floating.get, aclient.floating.toggle)
+ local widget = titlebar.widget.button(c, "floating", aclient.object.get_floating, aclient.floating.toggle)
c:connect_signal("property::floating", widget.update)
return widget
end
diff --git a/lib/awful/widget/layoutbox.lua b/lib/awful/widget/layoutbox.lua
index a72aa088..b328aee8 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 b0cd32c0..47ae781d 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 130a6723..43a4b566 100644
--- a/lib/awful/widget/tasklist.lua
+++ b/lib/awful/widget/tasklist.lua
@@ -79,7 +79,7 @@ local function tasklist_label(c, args, tb)
else
if c.maximized_horizontal then name = name .. maximized_horizontal end
if c.maximized_vertical then name = name .. maximized_vertical end
- if client.floating.get(c) then name = name .. floating end
+ if c.floating then name = name .. floating end
end
end
@@ -88,6 +88,7 @@ local function tasklist_label(c, args, tb)
else
name = name .. (util.escape(c.name) or util.escape(""))
end
+
local focused = capi.client.focus == c
-- Handle transient_for: the first parent that does not skip the taskbar
-- is considered to be focused, if the real client has skip_taskbar.
@@ -98,6 +99,7 @@ local function tasklist_label(c, args, tb)
end) == c then
focused = true
end
+
if focused then
bg = bg_focus
text = text .. ""..name..""
@@ -274,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()
@@ -300,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/lib/gears/object/properties.lua b/lib/gears/object/properties.lua
index 7d05ca86..9b988682 100644
--- a/lib/gears/object/properties.lua
+++ b/lib/gears/object/properties.lua
@@ -53,13 +53,14 @@ function object.capi_index_fallback(class, args)
-- Look for a getter method
if args.getter_class and args.getter_class[getter_prefix..prop] then
return args.getter_class[getter_prefix..prop](cobj)
+ elseif args.getter_class and args.getter_class["is_"..prop] then
+ return args.getter_class["is_"..prop](cobj)
end
-- Make sure something like c:a_mutator() works
if args.getter_class and args.getter_class[prop] then
return args.getter_class[prop]
end
-
-- In case there is already a "dumb" getter like `awful.tag.getproperty'
if args.getter_fallback then
return args.getter_fallback(cobj, prop)
diff --git a/mouse.c b/mouse.c
index 5fe94568..75301b56 100644
--- a/mouse.c
+++ b/mouse.c
@@ -20,6 +20,9 @@
*/
/** awesome mouse API
+ *
+ * See also `mousegrabber`
+ *
* @author Julien Danjou <julien@danjou.info>
* @copyright 2008-2009 Julien Danjou
* @release @AWESOME_VERSION@
@@ -35,10 +38,14 @@
/** Mouse library.
*
- * @field screen Mouse screen.
* @table mouse
*/
+/**
+ * The `screen` under the cursor
+ * @field screen
+ */
+
/** A table with X and Y coordinates.
* @field x X coordinate.
* @field y Y coordinate.
diff --git a/objects/client.c b/objects/client.c
index eee3c103..d530376e 100644
--- a/objects/client.c
+++ b/objects/client.c
@@ -1,4 +1,4 @@
-/*
+/*
* client.c - client management
*
* Copyright © 2007-2009 Julien Danjou
@@ -19,7 +19,21 @@
*
*/
-/** awesome client API
+/** A process window.
+ *
+ * Clients are the name used by Awesome (and X11) to refer to a window. An
+ * application can have multiple clients (like for dialogs) or none at all
+ * (like command line applications). Clients are usually grouped by classes. A
+ * class is the name used by X11 to help window manager distinguish between
+ * window and write rules for them. See the `xprop` command line application. A
+ * client also have a `type` and `size_hints` used to define its behavior.
+ *
+ * ![Client geometry](../images/client_geo.svg)
+ *
+ * The client `:geometry()` return a table with *x*, *y*, *width* and *height*.
+ * The area returned **exclude the border width**. All clients also have a
+ * `shape_bounding` and `shape_clip` used to "crop" the client content. Finally,
+ * each clients can have titlebars (see `awful.titlebar`).
*
* Furthermore to the classes described here, one can also use signals as
* described in @{signals} and X properties as described in @{xproperties}.
@@ -28,6 +42,43 @@
* the documentation generation, you get the real signal name by
* removing the starting dot.
*
+ * Accessing client objects can be done in multiple ways depending on the
+ * context. To get the current focused client, use:
+ *
+ * local c = client.focus
+ *
+ * if c then
+ * -- do something
+ * end
+ *
+ * To get a list of all clients, use `client:get`
+ *
+ * for _, c in ipairs(client.get()) do
+ * -- do something
+ * end
+ *
+ * To get a callback when a new client is added, use the `manage` signal:
+ *
+ * client.connect_signal("manage", function(c)
+ * -- do something
+ * end
+ *
+ * To be notified a property changed in a client, use:
+ *
+ * client.connect_signal("property::name", function(c)
+ * -- do something
+ * end
+ *
+ * To be notified when a property change for a specific client (assuming it is
+ * stored in the variable `c`), use:
+ *
+ * c:connect_signal("property::name", function()
+ * -- do something
+ * end
+ *
+ * To get all the clients for a screen, use either `screen.clients` or
+ * `screen.tiled_clients`
+ *
* @author Julien Danjou <julien@danjou.info>
* @copyright 2008-2009 Julien Danjou
* @release @AWESOME_VERSION@
@@ -53,57 +104,529 @@
/** Client class.
*
- * @table class
- * @field focus The focused `client.object`.
+ * @table object
*/
-/** Client object.
+/**
+ * The focused `client` or nil (in case there is none).
*
- * @field window The X window id.
- * @field name The client title.
- * @field skip_taskbar True if the client does not want to be in taskbar.
- * @field type The window type (desktop, normal, dock, …).
- * @field class The client class.
- * @field instance The client instance.
- * @field pid The client PID, if available.
- * @field role The window role, if available.
- * @field machine The machine client is running on.
- * @field icon_name The client name when iconified.
- * @field icon The client icon.
- * @field screen Client screen.
- * @field hidden Define if the client must be hidden, i.e. never mapped,
+ * @tfield client focus
+ */
+
+/**
+ * The X window id.
+ *
+ * **Signal:**
+ *
+ * * *property::window*
+ *
+ * @property window
+ * @param string
+ */
+
+/**
+ * The client title.
+ *
+ * **Signal:**
+ *
+ * * *property::name*
+ *
+ * @property name
+ * @param string
+ */
+
+/**
+ * True if the client does not want to be in taskbar.
+ *
+ * **Signal:**
+ *
+ * * *property::skip\_taskbar*
+ *
+ * @property skip_taskbar
+ * @param boolean
+ */
+
+/**
+ * The window type.
+ *
+ * Valid types are:
+ *
+ * * **desktop**: The root client, it cannot be moved or resized.
+ * * **dock**: A client attached to the side of the screen.
+ * * **splash**: A client, usually without titlebar shown when an application starts.
+ * * **dialog**: A dialog, see `transient_for`.
+ * * **menu**: A context menu.
+ * * **toolbar**: A floating toolbar.
+ * * **utility**:
+ * * **dropdown_menu**: A context menu attached to a parent position.
+ * * **popup_menu**: A context menu.
+ * * **notification**: A notification popup.
+ * * **combo**: A combobox list menu.
+ * * **dnd**: A drag and drop indicator.
+ * * **normal**: A normal application main window.
+ *
+ * More information can be found [here](https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472629520)
+ *
+ * **Signal:**
+ *
+ * * *property::type*
+ *
+ * @property type
+ * @param string
+ */
+
+/**
+ * The client class.
+ *
+ * If the client has multiple classes, the first one is used.
+ *
+ * To get a client class from the command line, use te `xprop` command.
+ *
+ * **Signal:**
+ *
+ * * *property::class*
+ *
+ * @property class
+ * @param string
+ */
+
+/**
+ * The client instance.
+ *
+ * **Signal:**
+ *
+ * * *property::instance*
+ *
+ * @property instance
+ * @param string
+ */
+
+/**
+ * The client PID, if available.
+ *
+ * **Signal:**
+ *
+ * * *property::pid*
+ *
+ * @property pid
+ * @param number
+ */
+
+/**
+ * The window role, if available.
+ *
+ * **Signal:**
+ *
+ * * *property::role*
+ *
+ * @property role
+ * @param string
+ */
+
+/**
+ * The machine client is running on.
+ *
+ * **Signal:**
+ *
+ * * *property::machine*
+ *
+ * @property machine
+ * @param string
+ */
+
+/**
+ * The client name when iconified.
+ *
+ * **Signal:**
+ *
+ * * *property::icon\_name*
+ *
+ * @property icon_name
+ * @param string
+ */
+
+/**
+ * The client icon.
+ *
+ * **Signal:**
+ *
+ * * *property::icon*
+ *
+ * @property icon
+ * @param surface
+ */
+
+/**
+ * Client screen.
+ *
+ * **Signal:**
+ *
+ * * *property::screen*
+ *
+ * @property screen
+ * @param screen
+ */
+
+/**
+ * Define if the client must be hidden, i.e. never mapped,
* invisible in taskbar.
- * @field minimized Define it the client must be iconify, i.e. only visible in
+ *
+ * **Signal:**
+ *
+ * * *property::hidden*
+ *
+ * @property hidden
+ * @param boolean
+ */
+
+/**
+ * Define it the client must be iconify, i.e. only visible in
* taskbar.
- * @field size_hints_honor Honor size hints, i.e. respect size ratio.
- * @field border_width The client border width.
- * @field border_color The client border color.
- * @field urgent The client urgent state.
- * @field content An image representing the client window content (screenshot).
- * @field opacity The client opacity between 0 and 1.
- * @field ontop The client is on top of every other windows.
- * @field above The client is above normal windows.
- * @field below The client is below normal windows.
- * @field fullscreen The client is fullscreen or not.
- * @field maximized The client is maximized (horizontally and vertically) or not.
- * @field maximized_horizontal The client is maximized horizontally or not.
- * @field maximized_vertical The client is maximized vertically or not.
- * @field transient_for The client the window is transient for.
- * @field group_window Window identification unique to a group of windows.
- * @field leader_window Identification unique to windows spawned by the same command.
- * @field size_hints A table with size hints of the client: `user_position`,
- * `user_size`, `program_position`, `program_size`, etc.
- * @field sticky Set the client sticky, i.e. available on all tags.
- * @field modal Indicate if the client is modal.
- * @field focusable True if the client can receive the input focus.
- * @field shape_bounding The client's bounding shape as set by awesome as a (native) cairo surface.
- * @field shape_clip The client's clip shape as set by awesome as a (native) cairo surface.
- * @field shape_client_bounding The client's bounding shape as set by the program as a (native) cairo surface.
- * @field shape_client_clip The client's clip shape as set by the program as a (native) cairo surface.
- * @field startup_id The FreeDesktop StartId.
- * @field valid If the client that this object refers to is still managed by awesome.
- * @field first_tag The first tag of the client. Optimized form of `c:tags()[1]`.
- * @table object
+ *
+ * **Signal:**
+ *
+ * * *property::minimized*
+ *
+ * @property minimized
+ * @param boolean
+ */
+
+/**
+ * Honor size hints, e.g. respect size ratio.
+ *
+ * For example, a terminal such as `xterm` require the client size to be a
+ * multiple of the character size. Honoring size hints will cause the terminal
+ * window to have a small gap at the bottom.
+ *
+ * This is enabled by default. To disable it by default, see `awful.rules`.
+ *
+ * **Signal:**
+ *
+ * * *property::size\_hints\_honor*
+ *
+ * @property size_hints_honor
+ * @param boolean
+ * @see size_hints
+ */
+
+/**
+ * The client border width.
+ * @property border_width
+ * @param integer
+ */
+
+/**
+ * The client border color.
+ *
+ * **Signal:**
+ *
+ * * *property::border\_color*
+ *
+ * @see gears.color
+ *
+ * @property border_color
+ * @param pattern Any string, gradients and patterns will be converted to a
+ * cairo pattern.
+ */
+
+/**
+ * The client urgent state.
+ *
+ * **Signal:**
+ *
+ * * *property::urgent*
+ *
+ * @property urgent
+ * @param boolean
+ */
+
+/**
+ * A cairo surface for the client window content.
+ *
+ * To get the screenshot, use:
+ *
+ * gears.surface(c.content)
+ *
+ * To save it, use:
+ *
+ * gears.surface(c.content):write_to_png(path)
+ *
+ * @property content
+ * @param surface
+ */
+
+/**
+ * The client opacity.
+ *
+ * **Signal:**
+ *
+ * * *property::opacity*
+ *
+ * @property opacity
+ * @param number Between 0 (transparent) to 1 (opaque)
+ */
+
+/**
+ * The client is on top of every other windows.
+ * @property ontop
+ * @param boolean
+ */
+
+/**
+ * The client is above normal windows.
+ *
+ * **Signal:**
+ *
+ * * *property::above*
+ *
+ * @property above
+ * @param boolean
+ */
+
+/**
+ * The client is below normal windows.
+ *
+ * **Signal:**
+ *
+ * * *property::below*
+ *
+ * @property below
+ * @param boolean
+ */
+
+/**
+ * The client is fullscreen or not.
+ *
+ * **Signal:**
+ *
+ * * *property::fullscreen*
+ *
+ * @property fullscreen
+ * @param boolean
+ */
+
+/**
+ * The client is maximized (horizontally and vertically) or not.
+ *
+ * **Signal:**
+ *
+ * * *property::maximized*
+ *
+ * @property maximized
+ * @param boolean
+ */
+
+/**
+ * The client is maximized horizontally or not.
+ *
+ * **Signal:**
+ *
+ * * *property::maximized\_horizontal*
+ *
+ * @property maximized_horizontal
+ * @param boolean
+ */
+
+/**
+ * The client is maximized vertically or not.
+ *
+ * **Signal:**
+ *
+ * * *property::maximized\_vertical*
+ *
+ * @property maximized_vertical
+ * @param boolean
+ */
+
+/**
+ * The client the window is transient for.
+ *
+ * **Signal:**
+ *
+ * * *property::transient\_for*
+ *
+ * @property transient_for
+ * @param client
+ */
+
+/**
+ * Window identification unique to a group of windows.
+ *
+ * **Signal:**
+ *
+ * * *property::group\_window*
+ *
+ * @property group_window
+ * @param client
+ */
+
+/**
+ * Identification unique to windows spawned by the same command.
+ * @property leader_window
+ * @param client
+ */
+
+/**
+ * A table with size hints of the client.
+ *
+ * **Signal:**
+ *
+ * * *property::size\_hints*
+ *
+ * @property size_hints
+ * @param table
+ * @tfield integer table.user_position
+ * @tfield integer table.user_size
+ * @tfield integer table.program_position
+ * @tfield integer table.program_size
+ * @tfield integer table.max_width
+ * @tfield integer table.max_height
+ * @tfield integer table.min_width
+ * @tfield integer table.min_height
+ * @tfield integer table.width_inc
+ * @tfield integer table.height_inc
+ * @see size_hints_honor
+ */
+
+/**
+ * Set the client sticky, i.e. available on all tags.
+ *
+ * **Signal:**
+ *
+ * * *property::sticky*
+ *
+ * @property sticky
+ * @param boolean
+ */
+
+/**
+ * Indicate if the client is modal.
+ *
+ * **Signal:**
+ *
+ * * *property::modal*
+ *
+ * @property modal
+ * @param boolean
+ */
+
+/**
+ * True if the client can receive the input focus.
+ *
+ * **Signal:**
+ *
+ * * *property::focusable*
+ *
+ * @property focusable
+ * @param boolean
+ */
+
+/**
+ * The client's bounding shape as set by awesome as a (native) cairo surface.
+ *
+ * **Signal:**
+ *
+ * * *property::shape\_bounding*
+ *
+ * @see gears.surface.apply_shape_bounding
+ * @property shape_bounding
+ * @param surface
+ */
+
+/**
+ * The client's clip shape as set by awesome as a (native) cairo surface.
+ *
+ * **Signal:**
+ *
+ * * *property::shape\_clip*
+ *
+ * @property shape_clip
+ * @param surface
+ */
+
+/**
+ * The client's bounding shape as set by the program as a (native) cairo surface.
+ *
+ * **Signal:**
+ *
+ * * *property::shape\_client\_bounding*
+ *
+ * @property shape_client_bounding
+ * @param surface
+ */
+
+/**
+ * The client's clip shape as set by the program as a (native) cairo surface.
+ *
+ * **Signal:**
+ *
+ * * *property::shape\_client\_clip*
+ *
+ * @property shape_client_clip
+ * @param surface
+ */
+
+/**
+ * The FreeDesktop StartId.
+ *
+ * When a client is spawned (like using a terminal or `awful.spawn`, a startup
+ * notification identifier is created. When the client is created, this
+ * identifier remain the same. This allow to match a spawn event to an actual
+ * client.
+ *
+ * **Signal:**
+ *
+ * * *property::startup\_id*
+ *
+ * @property startup_id
+ * @param string
+ */
+
+/**
+ * If the client that this object refers to is still managed by awesome.
+ *
+ * To avoid errors, use:
+ *
+ * local is_valid = pcall(function() return c.valid end) and c.valid
+ *
+ * **Signal:**
+ *
+ * * *property::valid*
+ *
+ * @property valid
+ * @param boolean
+ */
+
+/**
+ * The first tag of the client. Optimized form of `c:tags()[1]`.
+ *
+ * **Signal:**
+ *
+ * * *property::first\_tag*
+ *
+ * @property first_tag
+ * @param tag
+ */
+
+/**
+ * The border color when the client is focused.
+ *
+ * @beautiful beautiful.border_focus
+ * @param string
+ */
+
+/**
+ * The border color when the client is not focused.
+ *
+ * @beautiful beautiful.border_normal
+ * @param string
+ */
+
+/**
+ * The client border width.
+ *
+ * @beautiful beautiful.border_width
+ * @param integer
*/
/** Return client struts (reserved space at the edge of the screen).
@@ -126,12 +649,12 @@
* @function instances
*/
-/** Set a __index metamethod for all client instances.
+/* Set a __index metamethod for all client instances.
* @tparam function cb The meta-method
* @function set_index_miss_handler
*/
-/** Set a __newindex metamethod for all client instances.
+/* Set a __newindex metamethod for all client instances.
* @tparam function cb The meta-method
* @function set_newindex_miss_handler
*/
@@ -2854,161 +3377,46 @@ client_class_setup(lua_State *L)
* @signal mouse::move
*/
signal_add(&client_class.signals, "mouse::move");
- /**
- * @signal property::above
- */
+
+ /* Those signals are documented elsewhere */
signal_add(&client_class.signals, "property::above");
- /**
- * @signal property::below
- */
signal_add(&client_class.signals, "property::below");
- /**
- * @signal property::class
- */
signal_add(&client_class.signals, "property::class");
- /**
- * @signal property::focusable
- */
signal_add(&client_class.signals, "property::focusable");
- /**
- * @signal property::fullscreen
- */
signal_add(&client_class.signals, "property::fullscreen");
- /**
- * @signal property::geometry
- */
signal_add(&client_class.signals, "property::geometry");
- /**
- * @signal property::group_window
- */
signal_add(&client_class.signals, "property::group_window");
- /**
- * @signal property::height
- */
signal_add(&client_class.signals, "property::height");
- /**
- * @signal property::hidden
- */
signal_add(&client_class.signals, "property::hidden");
- /**
- * @signal property::icon
- */
signal_add(&client_class.signals, "property::icon");
- /**
- * @signal property::icon_name
- */
signal_add(&client_class.signals, "property::icon_name");
- /**
- * @signal property::instance
- */
signal_add(&client_class.signals, "property::instance");
- /**
- * @signal property::keys
- */
signal_add(&client_class.signals, "property::keys");
- /**
- * @signal property::machine
- */
signal_add(&client_class.signals, "property::machine");
- /**
- * @signal property::maximized
- */
signal_add(&client_class.signals, "property::maximized");
- /**
- * @signal property::maximized_horizontal
- */
signal_add(&client_class.signals, "property::maximized_horizontal");
- /**
- * @signal property::maximized_vertical
- */
signal_add(&client_class.signals, "property::maximized_vertical");
- /**
- * @signal property::minimized
- */
signal_add(&client_class.signals, "property::minimized");
- /**
- * @signal property::modal
- */
signal_add(&client_class.signals, "property::modal");
- /**
- * @signal property::name
- */
signal_add(&client_class.signals, "property::name");
- /**
- * @signal property::ontop
- */
signal_add(&client_class.signals, "property::ontop");
- /**
- * @signal property::pid
- */
signal_add(&client_class.signals, "property::pid");
- /**
- * @signal property::role
- */
signal_add(&client_class.signals, "property::role");
- /**
- * @signal property::screen
- */
signal_add(&client_class.signals, "property::screen");
- /**
- * @signal property::shape_bounding
- */
signal_add(&client_class.signals, "property::shape_bounding");
- /**
- * @signal property::shape_client_bounding
- */
signal_add(&client_class.signals, "property::shape_client_bounding");
- /**
- * @signal property::shape_client_clip
- */
signal_add(&client_class.signals, "property::shape_client_clip");
- /**
- * @signal property::shape_clip
- */
signal_add(&client_class.signals, "property::shape_clip");
- /**
- * @signal property::size_hints_honor
- */
signal_add(&client_class.signals, "property::size_hints_honor");
- /**
- * @signal property::skip_taskbar
- */
signal_add(&client_class.signals, "property::skip_taskbar");
- /**
- * @signal property::sticky
- */
signal_add(&client_class.signals, "property::sticky");
- /**
- * @signal property::struts
- */
signal_add(&client_class.signals, "property::struts");
- /**
- * @signal property::titlebar_bottom
- */
signal_add(&client_class.signals, "property::titlebar_bottom");
- /**
- * @signal property::titlebar_left
- */
signal_add(&client_class.signals, "property::titlebar_left");
- /**
- * @signal property::titlebar_right
- */
signal_add(&client_class.signals, "property::titlebar_right");
- /**
- * @signal property::titlebar_top
- */
signal_add(&client_class.signals, "property::titlebar_top");
- /**
- * @signal property::transient_for
- */
signal_add(&client_class.signals, "property::transient_for");
- /**
- * @signal property::type
- */
signal_add(&client_class.signals, "property::type");
- /**
- * @signal property::urgent
- */
signal_add(&client_class.signals, "property::urgent");
/**
* @signal property::width
diff --git a/objects/screen.c b/objects/screen.c
index a41fb152..dd29394e 100644
--- a/objects/screen.c
+++ b/objects/screen.c
@@ -20,6 +20,22 @@
*/
/** awesome screen API
+ *
+ * Screen objects can be added and removed over time. To get a callback for all
+ * current and future screens, use `awful.screen.connect_for_each_screen`:
+ *
+ * awful.screen.connect_for_each_screen(function(s)
+ * -- do something
+ * end)
+ *
+ * It is also possible loop over all current screens using:
+ *
+ * for s, screen do
+ * -- do something
+ * end
+ *
+ * Most basic Awesome objects also have a screen property, see `mouse.screen`
+ * `client.screen`, `wibox.screen` and `tag.screen`.
*
* Furthermore to the classes described here, one can also use signals as
* described in @{signals}.
@@ -47,26 +63,91 @@
* The primary screen can be accessed as `screen.primary`.
* Each screen has a set of properties.
*
- * @tfield table geometry The screen coordinates. Immutable.
- * @tfield table workarea The screen workarea.
- * @tfield int index The screen number.
- * @tfield table outputs If RANDR information is available, a list of outputs
- * for this screen and their size in mm.
- * @table screen
*/
+ /**
+ * The primary screen.
+ *
+ * @tfield screen primary
+ */
+
+/**
+ * The screen coordinates.
+ *
+ * **Immutable:** true
+ * @property geometry
+ * @param table
+ * @tfield integer table.x The horizontal position
+ * @tfield integer table.y The vertical position
+ * @tfield integer table.width The width
+ * @tfield integer table.height The height
+ */
+
+/**
+ * The screen number.
+ *
+ * An integer greater than 1 and smaller than `screen.count()`. Please note that
+ * the screen order isn't always mirroring the screen logical position.
+ *
+ * **Immutable:** true
+ * @property index
+ * @param integer
+ */
+
+/**
+ * If RANDR information is available, a list of outputs
+ * for this screen and their size in mm.
+ *
+ * Please note that the table content may vary.
+ *
+ * **Signal:**
+ *
+ * * *property::outputs*
+ *
+ * **Immutable:** true
+ * @property outputs
+ * @param table
+ * @tfield table table.name A table with the screen name as key (like `eDP1` on a laptop)
+ * @tfield integer table.name.mm_width The screen physical width
+ * @tfield integer table.name.mm_height The screen physical height
+ */
+
+/**
+ * The screen workarea.
+ *
+ * The workarea is a subsection of the screen where clients can be placed. It
+ * usually excludes the toolbars (see `awful.wibox`) and dockable clients
+ * (see `client.dockable`) like WindowMaker DockAPP.
+ *
+ * It can be modified be altering the `wibox` or `client` struts.
+ *
+ * **Signal:**
+ *
+ * * *property::workarea*
+ *
+ * @property workarea
+ * @see client.struts
+ * @see drawin.struts
+ * @param table
+ * @tfield integer table.x The horizontal position
+ * @tfield integer table.y The vertical position
+ * @tfield integer table.width The width
+ * @tfield integer table.height The height
+ */
+
+
/** Get the number of instances.
*
* @return The number of screen objects alive.
* @function instances
*/
-/** Set a __index metamethod for all screen instances.
+/* Set a __index metamethod for all screen instances.
* @tparam function cb The meta-method
* @function set_index_miss_handler
*/
-/** Set a __newindex metamethod for all screen instances.
+/* Set a __newindex metamethod for all screen instances.
* @tparam function cb The meta-method
* @function set_newindex_miss_handler
*/
@@ -752,17 +833,15 @@ screen_class_setup(lua_State *L)
NULL,
(lua_class_propfunc_t) luaA_screen_get_workarea,
NULL);
- /**
- * @signal property::workarea
- */
+
signal_add(&screen_class.signals, "property::workarea");
/**
- * @signal primary_changed
+ * @signal .primary_changed
*/
signal_add(&screen_class.signals, "primary_changed");
/**
* This signal is emitted when a new screen is added to the current setup.
- * @signal added
+ * @signal .added
*/
signal_add(&screen_class.signals, "added");
}
diff --git a/objects/tag.c b/objects/tag.c
index 590413d4..92396dec 100644
--- a/objects/tag.c
+++ b/objects/tag.c
@@ -24,6 +24,8 @@
* Furthermore to the classes described here, one can also use signals as
* described in @{signals}.
*
+ * ![Client geometry](../images/tag_props.svg)
+ *
* Some signal names are starting with a dot. These dots are artefacts from
* the documentation generation, you get the real signal name by
* removing the starting dot.
@@ -40,12 +42,37 @@
#include "ewmh.h"
#include "luaa.h"
-/** Tag object.
+/**
+ * Tag name.
*
- * @field name Tag name.
- * @field selected True if the tag is selected to be viewed.
- * @field activated True if the tag is active and can be used.
- * @table tag
+ * **Signal:**
+ *
+ * * *property::name*
+ *
+ * @property name
+ * @param string
+ */
+
+/**
+ * True if the tag is selected to be viewed
+ *
+ * **Signal:**
+ *
+ * * *property::selected*
+ *
+ * @property selected
+ * @param boolean
+ */
+
+/**
+ * True if the tag is active and can be used.
+ *
+ * **Signal:**
+ *
+ * * *property::activated*
+ *
+ * @property activated
+ * @param boolean
*/
/** Get the number of instances.
@@ -54,12 +81,12 @@
* @function instances
*/
-/** Set a __index metamethod for all tag instances.
+/* Set a __index metamethod for all tag instances.
* @tparam function cb The meta-method
* @function set_index_miss_handler
*/
-/** Set a __newindex metamethod for all tag instances.
+/* Set a __newindex metamethod for all tag instances.
* @tparam function cb The meta-method
* @function set_newindex_miss_handler
*/
@@ -389,17 +416,8 @@ tag_class_setup(lua_State *L)
(lua_class_propfunc_t) luaA_tag_get_activated,
(lua_class_propfunc_t) luaA_tag_set_activated);
- /**
- * @signal property::name
- */
signal_add(&tag_class.signals, "property::name");
- /**
- * @signal property::selected
- */
signal_add(&tag_class.signals, "property::selected");
- /**
- * @signal property::activated
- */
signal_add(&tag_class.signals, "property::activated");
/**
* @signal request::select
diff --git a/tests/examples/shims/awesome.lua b/tests/examples/shims/awesome.lua
index 30c2c39b..41c458a9 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 f4f78d1d..f2dd0d38 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 6fe43a82..a0d4eb6b 100644
--- a/tests/examples/shims/screen.lua
+++ b/tests/examples/shims/screen.lua
@@ -1,6 +1,6 @@
local gears_obj = require("gears.object")
-local screen = awesome._shim_fake_class()
+local screen, meta = awesome._shim_fake_class()
screen.count = 1
@@ -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
@@ -42,8 +43,11 @@ local function create_screen(args)
width = geo.width - 2*wa,
height = geo.height - 2*wa,
}
+ else
+ return meta.__index(_, key)
end
end,
+ __newindex = function(...) return meta.__newindex(...) end
})
end
diff --git a/tests/examples/shims/tag.lua b/tests/examples/shims/tag.lua
index fe10da12..e8fd463e 100644
--- a/tests/examples/shims/tag.lua
+++ b/tests/examples/shims/tag.lua
@@ -9,8 +9,11 @@ local function new_tag(_, args)
ret:add_signal("property::name")
ret:add_signal("property::geometry")
ret:add_signal("property::screen")
+ ret:add_signal("property::master_width_factor")
ret:add_signal("property::mwfact")
ret:add_signal("property::ncol")
+ ret:add_signal("property::column_count")
+ ret:add_signal("property::master_count")
ret:add_signal("property::nmaster")
ret:add_signal("property::index")
ret:add_signal("property::useless_gap")
@@ -35,7 +38,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-awesomerc.lua b/tests/test-awesomerc.lua
new file mode 100644
index 00000000..012fda0d
--- /dev/null
+++ b/tests/test-awesomerc.lua
@@ -0,0 +1,236 @@
+local awful = require("awful")
+
+-- luacheck: globals modkey
+
+local old_c = nil
+
+local function get_callback(mod, key)
+ local inf = {}
+ awful.key(mod, key, nil, nil, inf)
+
+ return inf.execute
+end
+
+-- Get a tag and a client
+local function get_c_and_t()
+ client.focus = old_c or client.get()[1]
+ local c = client.focus
+
+ local t = c.screen.selected_tag
+
+ return c, t
+end
+
+-- display deprecated warnings
+--awful.util.deprecate = function() end
+
+local has_spawned = false
+
+local steps = {
+
+function(count)
+ if count <= 1 and not has_spawned and #client.get() < 2 then
+ for _=1, 5 do awful.spawn("xterm") end
+ has_spawned = true
+ elseif #client.get() >= 5 then
+ local c, _ = get_c_and_t()
+ old_c = c
+
+ return true
+ end
+end,
+
+-- Wait for the focus to change
+function()
+ if has_spawned then
+ has_spawned = false
+ return nil
+ end
+
+ assert(old_c)
+
+ -- Test layout
+ -- local cb = get_callback({modkey}, " ")
+ -- assert(cb)
+
+ --TODO use the key once the bug is fixed
+ local l = old_c.screen.selected_tag.layout
+ assert(l)
+
+ -- cb()
+ awful.layout.inc(1)
+
+ assert(old_c.screen.selected_tag.layout ~= l)
+
+ -- Test ontop
+
+ assert(not old_c.ontop)
+ get_callback({modkey}, "t")()
+
+ return true
+end,
+
+-- Ok, no now ontop should be true
+function()
+ local _, t = get_c_and_t()
+
+ -- Give awesome some time
+ if not old_c.ontop then return nil end
+
+ assert(old_c.ontop)
+
+ -- Now, test the master_width_factor
+ assert(t.master_width_factor == 0.5)
+
+ get_callback({modkey}, "l")()
+
+ return true
+end,
+
+-- The master width factor should now be bigger
+function()
+ local _, t = get_c_and_t()
+
+ assert(t.master_width_factor == 0.55)
+
+ -- Now, test the master_count
+ assert(t.master_count == 1)
+
+ get_callback({modkey, "Shift"}, "h")()
+
+ return true
+end,
+
+-- The number of master client should now be 2
+function()
+ local _, t = get_c_and_t()
+
+ assert(t.master_count == 2)
+
+ -- Now, test the column_count
+ assert(t.column_count == 1)
+
+ get_callback({modkey, "Control"}, "h")()
+ get_callback({modkey, "Shift" }, "l")()
+
+ return true
+end,
+
+-- The number of columns should now be 2
+function()
+ local _, t = get_c_and_t()
+
+ assert(t.column_count == 2)
+
+ -- Now, test the switching tag
+ assert(t.index == 1)
+
+ get_callback({modkey, }, "Right")()
+
+ return true
+end,
+
+-- The tag index should now be 2
+function()
+ local tags = mouse.screen.tags
+-- local t = awful.screen.focused().selected_tag
+
+-- assert(t.index == 2)--FIXME
+
+ assert(tags[1].index == 1)
+ tags[1]:view_only()
+
+ return true
+end,
+
+-- Before testing tags, lets make sure everything is still right
+function()
+ local tags = mouse.screen.tags
+
+ assert(tags[1].selected)
+
+ local clients = mouse.screen.clients
+
+ -- Make sure the clients are all on the same screen, they should be
+ local c_scr = client.get()[1].screen
+
+ for _, c in ipairs(client.get()) do
+ assert(c_scr == c.screen)
+ end
+
+ -- Then this should be true
+ assert(#clients == #client.get())
+
+ assert(#mouse.screen.all_clients == #clients)
+
+ assert(#mouse.screen.all_clients - #mouse.screen.hidden_clients == #clients)
+
+ return true
+end,
+
+-- Now, test switching tags
+function()
+ local tags = mouse.screen.tags
+ local clients = mouse.screen.all_clients
+
+ assert(#tags == 9)
+
+ assert(#clients == 5)
+
+ assert(mouse.screen.selected_tag == tags[1])
+
+ for i=1, 9 do
+ -- Check that assertion, because if it's false, the other assert()
+ -- wont make any sense.
+ assert(tags[i].index == i)
+ end
+
+ for i=1, 9 do
+ tags[i]:view_only()
+ assert(tags[i].selected)
+ assert(#mouse.screen.selected_tags == 1)
+ end
+
+ tags[1]:view_only()
+
+ return true
+end,
+
+-- Lets shift some clients around
+function()
+ local tags = mouse.screen.tags
+
+ -- Given all tags have been selected, the selection should be back on
+ -- tags[1] and the client history should be kept
+ assert(client.focus == old_c)
+
+ --get_callback({modkey, "Shift" }, "#"..(9+i))() --FIXME
+ client.focus:move_to_tag(tags[2])
+
+ assert(not client.focus)
+
+ return true
+end,
+
+-- The client should be on tag 5
+function()
+ -- Confirm the move did happen
+ local tags = mouse.screen.tags
+ assert(tags[1].selected)
+ assert(#old_c:tags() == 1)
+ assert(old_c:tags()[1] ~= tags[1])
+ assert(not old_c:tags()[1].selected)
+
+ -- The focus should have changed by now, as the tag isn't visible
+ assert(client.focus ~= old_c)
+
+ assert(old_c:tags()[1] == tags[2])
+
+ assert(#tags[2]:clients() == 1)
+ assert(#tags[1]:clients() == 4)
+
+ return true
+end
+}
+
+require("_runner").run_steps(steps)
diff --git a/tests/test-awful-client.lua b/tests/test-awful-client.lua
new file mode 100644
index 00000000..b1897d44
--- /dev/null
+++ b/tests/test-awful-client.lua
@@ -0,0 +1,83 @@
+local awful = require("awful")
+
+awful.util.deprecate = function() end
+
+local has_spawned = false
+local steps = {
+
+function(count)
+
+if count <= 1 and not has_spawned and #client.get() < 2 then
+ awful.spawn("xterm")
+ awful.spawn("xterm")
+ has_spawned = true
+elseif #client.get() >= 2 then
+
+-- Test properties
+client.focus = client.get()[1]
+local c = client.focus
+-- local c2 = client.get()[2]
+
+client.add_signal("property::foo")
+c.foo = "bar"
+
+-- Check if the property system works
+assert(c.foo == "bar")
+assert(c.foo == awful.client.property.get(c, "foo"))
+
+-- Test jumpto
+
+--FIXME doesn't work
+-- c2:jump_to()
+-- assert(client.focus == c2)
+-- awful.client.jumpto(c)
+-- assert(client.focus == c)
+
+-- Test moveresize
+c.size_hints_honor = false
+c:geometry {x=0,y=0,width=50,height=50}
+c:relative_move( 100, 100, 50, 50 )
+for _,v in pairs(c:geometry()) do
+ assert(v == 100)
+end
+awful.client.moveresize(-25, -25, -25, -25, c )
+for _,v in pairs(c:geometry()) do
+ assert(v == 75)
+end
+
+-- Test movetotag
+
+local t = tags[mouse.screen][1]
+local t2 = tags[mouse.screen][2]
+
+c:tags{t}
+assert(c:tags()[1] == t)
+c:move_to_tag(t2)
+assert(c:tags()[1] == t2)
+awful.client.movetotag(t, c)
+assert(c:tags()[1] == t)
+
+-- Test toggletag
+
+c:tags{t}
+c:toggle_tag(t2)
+assert(c:tags()[1] == t2 or c:tags()[2] == t2)
+awful.client.toggletag(t2, c)
+assert(c:tags()[1] == t and c:tags()[1] ~= t2 and c:tags()[2] == nil)
+
+-- Test movetoscreen
+--FIXME I don't have the hardware to test
+
+-- Test floating
+assert(c.floating ~= nil and type(c.floating) == "boolean")
+c.floating = true
+assert(awful.client.floating.get(c))
+awful.client.floating.set(c, false)
+assert(not c.floating)
+
+return true
+end
+end
+}
+
+require("_runner").run_steps(steps)
diff --git a/tests/test-awful-screen.lua b/tests/test-awful-screen.lua
new file mode 100644
index 00000000..47a2d43f
--- /dev/null
+++ b/tests/test-awful-screen.lua
@@ -0,0 +1,89 @@
+local awful = require("awful")
+
+awful.util.deprecate = function() end
+
+local has_spawned = false
+local steps = {
+
+function(count)
+
+if count <= 1 and not has_spawned and #client.get() < 2 then
+ awful.spawn("xterm")
+ awful.spawn("xterm")
+ has_spawned = true
+elseif #client.get() >= 2 then
+
+-- Test properties
+client.focus = client.get()[1]
+
+local s = mouse.screen
+
+assert(s)
+
+assert(s == screen[s])
+
+-- Test padding
+
+s.padding = 42
+
+local counter = 0
+for _, v in pairs(s.padding) do
+ assert(v == 42)
+ counter = counter + 1
+end
+
+assert(counter == 4)
+
+awful.screen.padding(s, {
+ left = 1337,
+ right = 1337,
+ top = 1337,
+ bottom = 1337,
+})
+
+counter = 0
+for _, v in pairs(s.padding) do
+ assert(v == 1337)
+ counter = counter + 1
+end
+
+assert(counter == 4)
+
+counter = 0
+for _, v in pairs(awful.screen.padding(s)) do
+ assert(v == 1337)
+ counter = counter + 1
+end
+
+assert(counter == 4)
+
+-- Test square distance
+
+assert(s:get_square_distance(9999, 9999))
+
+assert(s:get_square_distance(9999, 9999)
+ == awful.screen.getdistance_sq(s, 9999, 9999))
+
+-- Test count
+
+counter = 0
+
+for _ in screen do
+ counter = counter + 1
+end
+
+assert(screen.count() == counter)
+
+counter = 0
+awful.screen.connect_for_each_screen(function()
+ counter = counter + 1
+end)
+
+assert(screen.count() == counter)
+
+return true
+end
+end
+}
+
+require("_runner").run_steps(steps)
diff --git a/tests/test-awful-tag.lua b/tests/test-awful-tag.lua
new file mode 100644
index 00000000..076cd0b3
--- /dev/null
+++ b/tests/test-awful-tag.lua
@@ -0,0 +1,111 @@
+local awful = require("awful")
+local beautiful = require("beautiful")
+
+awful.util.deprecate = function() end
+
+local has_spawned = false
+local steps = {
+
+function(count)
+
+if count <= 1 and not has_spawned and #client.get() < 2 then
+ awful.spawn("xterm")
+ awful.spawn("xterm")
+ has_spawned = true
+elseif #client.get() >= 2 then
+
+-- Test move, swap and index
+
+local tags = mouse.screen.tags
+
+assert(#mouse.screen.tags == 9)
+
+for k, v in ipairs(tags) do
+ assert(k == v.index)
+end
+
+tags[7].index = 9
+assert(tags[7].index == 9)
+
+tags[7].index = 4
+assert(tags[7].index == 4)
+
+awful.tag.move(5, tags[7])
+assert(tags[7].index == 5)
+
+tags[1]:swap(tags[3])
+
+assert(tags[1].index == 3)
+assert(tags[3].index == 1)
+
+awful.tag.swap(tags[1], tags[3])
+
+assert(tags[3].index == 3)
+assert(tags[1].index == 1)
+
+-- Test add, icon and delete
+
+client.focus = client.get()[1]
+local c = client.focus
+assert(c and client.focus == c)
+assert(beautiful.awesome_icon)
+
+local t = awful.tag.add("Test", {clients={c}, icon = beautiful.awesome_icon})
+
+local found = false
+
+tags = mouse.screen.tags
+
+assert(#tags == 10)
+
+for _, v in ipairs(tags) do
+ if t == v then
+ found = true
+ break
+ end
+end
+
+assert(found)
+
+assert(t:clients()[1] == c)
+assert(c:tags()[2] == t)
+assert(t.icon == beautiful.awesome_icon)
+
+t:delete()
+
+tags = mouse.screen.tags
+assert(#tags == 9)
+
+found = false
+
+for _, v in ipairs(tags) do
+ if t == v then
+ found = true
+ break
+ end
+end
+
+assert(not found)
+
+-- Test selected tags, view only and selected()
+
+t = tags[2]
+
+assert(not t.selected)
+
+assert(t.screen.selected_tag == tags[1])
+
+t:view_only()
+
+assert(t.selected)
+
+assert(not tags[1].selected)
+
+assert(#t.screen.selected_tags == 1)
+
+return true
+end
+end
+}
+
+require("_runner").run_steps(steps)
diff --git a/tests/test-urgent.lua b/tests/test-urgent.lua
index 2c471422..1f9706e2 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 }})