Merge pull request #2895 from Elv13/ruled_client

Move `awful.rules` to `ruled.client`.
This commit is contained in:
Emmanuel Lepage Vallée 2020-01-19 20:15:52 -05:00 committed by GitHub
commit 2f905f2522
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 6208 additions and 1205 deletions

View File

@ -13,6 +13,8 @@ local wibox = require("wibox")
local beautiful = require("beautiful") local beautiful = require("beautiful")
-- Notification library -- Notification library
local naughty = require("naughty") local naughty = require("naughty")
-- Declarative object management
local ruled = require("ruled")
local menubar = require("menubar") local menubar = require("menubar")
local hotkeys_popup = require("awful.hotkeys_popup") local hotkeys_popup = require("awful.hotkeys_popup")
-- Enable hotkeys help widget for VIM and other apps -- Enable hotkeys help widget for VIM and other apps
@ -439,60 +441,60 @@ end)
-- {{{ Rules -- {{{ Rules
-- Rules to apply to new clients. -- Rules to apply to new clients.
-- @DOC_RULES@ -- @DOC_RULES@
awful.rules.rules = { ruled.client.connect_signal("request::rules", function()
-- @DOC_GLOBAL_RULE@ -- @DOC_GLOBAL_RULE@
-- All clients will match this rule. -- All clients will match this rule.
{ rule = { }, ruled.client.append_rule {
properties = { focus = awful.client.focus.filter, id = "global",
raise = true, rule = { },
screen = awful.screen.preferred, properties = {
placement = awful.placement.no_overlap+awful.placement.no_offscreen focus = awful.client.focus.filter,
} raise = true,
}, screen = awful.screen.preferred,
placement = awful.placement.no_overlap+awful.placement.no_offscreen
}
}
-- @DOC_FLOATING_RULE@ -- @DOC_FLOATING_RULE@
-- Floating clients. -- Floating clients.
{ rule_any = { ruled.client.append_rule {
instance = { id = "floating",
"DTA", -- Firefox addon DownThemAll. rule_any = {
"copyq", -- Includes session name in class. instance = { "copyq", "pinentry" },
"pinentry", class = {
"Arandr", "Blueman-manager", "Gpick", "Kruler", "Sxiv",
"Tor Browser", "Wpa_gui", "veromix", "xtightvncviewer"
},
-- Note that the name property shown in xprop might be set slightly after creation of the client
-- and the name shown there might not match defined rules here.
name = {
"Event Tester", -- xev.
},
role = {
"AlarmWindow", -- Thunderbird's calendar.
"ConfigManager", -- Thunderbird's about:config.
"pop-up", -- e.g. Google Chrome's (detached) Developer Tools.
}
}, },
class = { properties = { floating = true }
"Arandr", }
"Blueman-manager",
"Gpick",
"Kruler",
"MessageWin", -- kalarm.
"Sxiv",
"Tor Browser", -- Needs a fixed window size to avoid fingerprinting by screen size.
"Wpa_gui",
"veromix",
"xtightvncviewer"},
-- Note that the name property shown in xprop might be set slightly after creation of the client
-- and the name shown there might not match defined rules here.
name = {
"Event Tester", -- xev.
},
role = {
"AlarmWindow", -- Thunderbird's calendar.
"ConfigManager", -- Thunderbird's about:config.
"pop-up", -- e.g. Google Chrome's (detached) Developer Tools.
}
}, properties = { floating = true }},
-- @DOC_DIALOG_RULE@ -- @DOC_DIALOG_RULE@
-- Add titlebars to normal clients and dialogs -- Add titlebars to normal clients and dialogs
{ rule_any = {type = { "normal", "dialog" } ruled.client.append_rule {
-- @DOC_CSD_TITLEBARS@ -- @DOC_CSD_TITLEBARS@
}, properties = { titlebars_enabled = true } id = "titlebars",
}, rule_any = { type = { "normal", "dialog" } },
properties = { titlebars_enabled = true }
}
-- Set Firefox to always map on the tag named "2" on screen 1. -- Set Firefox to always map on the tag named "2" on screen 1.
-- { rule = { class = "Firefox" }, -- ruled.tag.append_rule {
-- properties = { screen = 1, tag = "2" } }, -- rule = { class = "Firefox" },
} -- properties = { screen = 1, tag = "2" }
-- }
end)
-- }}} -- }}}
-- {{{ Titlebars -- {{{ Titlebars

View File

@ -34,7 +34,10 @@ local allowed_deps = {
wibox = true, wibox = true,
-- Necessary to lazy-load the deprecated modules. -- Necessary to lazy-load the deprecated modules.
["awful.*"] = true ["awful.*"] = true,
-- For legacy reasons.
ruled = true
}, },
naughty = { naughty = {
awful = true, awful = true,
@ -50,6 +53,14 @@ local allowed_deps = {
lgi = true, lgi = true,
wibox = true, wibox = true,
}, },
ruled = {
awful = true,
beautiful = true,
gears = true,
lgi = true,
wibox = true,
naughty = true,
},
-- TODO: Get rid of these -- TODO: Get rid of these
["gears.surface"] = { ["wibox.hierarchy"] = true }, ["gears.surface"] = { ["wibox.hierarchy"] = true },
} }

View File

@ -83,11 +83,6 @@ Parameters of functions should be documented using
For a more comprehensive description of the available tags see the [LDoc For a more comprehensive description of the available tags see the [LDoc
documentation](https://stevedonovan.github.io/ldoc/manual/doc.md.html). documentation](https://stevedonovan.github.io/ldoc/manual/doc.md.html).
In addition to the regular tags provided by LDoc there are also some aliases
for typed parameters defined in `docs/config.ld`, e.g. `@client` for
`@tparam client.object`, `@tag` for `@tparam tag` and `@tab` for
`@tparam table`).
## Patches ## Patches
If you plan to submit patches, you should follow the following guidelines. If you plan to submit patches, you should follow the following guidelines.

View File

@ -70,6 +70,9 @@ This document was last updated at commit v4.3-197-g9085ed631.
slightly. The border is now applied before the titlebar offset. This should slightly. The border is now applied before the titlebar offset. This should
not affect most users unless you had mitigated the bug it fixes by adding not affect most users unless you had mitigated the bug it fixes by adding
the titlebar offset in your rules. the titlebar offset in your rules.
* Setting `awful.rules.rules` now append the rules to the existing set.
Clearing the rules was never officially supported. If you *really* want the
old behavior, use `awful.rules.rules = {}; awful.rules.rules = my_new_rules`.
<a name="v43"></a> <a name="v43"></a>
# Awesome window manager framework version 4.3 changes # Awesome window manager framework version 4.3 changes

View File

@ -147,7 +147,7 @@ additions to the path you want to use in Awesome.
### How to remove gaps between windows? ### How to remove gaps between windows?
You can add `size_hints_honor = false` to the `properties` section in your You can add `size_hints_honor = false` to the `properties` section in your
`awful.rules.rules` table in your `rc.lua`. It will match and apply this rule `ruled.client.rules` table in your `rc.lua`. It will match and apply this rule
to all clients. to all clients.
See [the mailing list archive](http://www.mail-archive.com/awesome@naquadah.org/msg01767.html) See [the mailing list archive](http://www.mail-archive.com/awesome@naquadah.org/msg01767.html)
@ -173,8 +173,8 @@ your `globalkeys`:
### How to control titlebars? ### How to control titlebars?
To disable titlebars on all clients remove the `titlebars_enabled=true` from the To disable titlebars on all clients remove the `titlebars_enabled=true` from the
`awful.rules.rules` table in your config. If you want a titlebar only on `ruled.client.rules` table in your config. If you want a titlebar only on
certain clients, you can use `awful.rules` to set this property only for certain certain clients, you can use `ruled.client` to set this property only for certain
clients. clients.
### How to toggle titlebar visibility? ### How to toggle titlebar visibility?
@ -208,7 +208,7 @@ their last invocation. The default key binding to toggle maximized state is
"Mod4 + m". "Mod4 + m".
You can ensure no application ever starts maximized in the first rule of your You can ensure no application ever starts maximized in the first rule of your
`awful.rules.rules` table, which applies to all clients, by adding: `ruled.client.rules` table, which applies to all clients, by adding:
-- Search for this rule, -- Search for this rule,
keys = clientkeys, keys = clientkeys,
@ -267,14 +267,14 @@ terminal output you can use the following to match clients in Awesome:
|--- name |--- name
You can use the above identifiers (instance, class and name) in your You can use the above identifiers (instance, class and name) in your
`awful.rules.rules` table to do matching, tagging and other client manipulation. `ruled.client.rules` table to do matching, tagging and other client manipulation.
See the next FAQ answer for some examples. See the next FAQ answer for some examples.
### How to start clients on specific tags and others as floating? ### How to start clients on specific tags and others as floating?
You can add matching rules to your `awful.rules.rules` table. The default You can add matching rules to your `ruled.client.rules` table. The default
`rc.lua` already has several examples, but some more can be found in the `rc.lua` already has several examples, but some more can be found in the
@{awful.rules.rules|documentation}. @{ruled.client.rules|documentation}.
### How to start clients as slave windows instead of master? ### How to start clients as slave windows instead of master?
@ -299,7 +299,7 @@ layout and allows to change it by clicking on it.
### How to make windows spawn under the mouse cursor? ### How to make windows spawn under the mouse cursor?
In the default `awful.rules`-rule, the following placement is specified: In the default `ruled.client`-rule, the following placement is specified:
placement = awful.placement.no_overlap+awful.placement.no_offscreen placement = awful.placement.no_overlap+awful.placement.no_offscreen

View File

@ -1,6 +1,6 @@
--- ---
--- A table which content will be used to set the target object properties. --- A table whose content will be used to set the target object properties.
-- --
-- @rulecomponent properties -- @rulecomponent properties
-- @param table -- @param table
@ -14,7 +14,7 @@
-- @param table -- @param table
-- @see properties -- @see properties
--- A table which content will be compared to the target object current properties. --- A table whose content will be compared to the target object current properties.
-- --
-- @rulecomponent rule -- @rulecomponent rule
-- @param table -- @param table
@ -50,6 +50,24 @@
-- @see rule -- @see rule
-- @see except -- @see except
--- A table whose content will be compared to the target object current properties.
--
-- The comparison will be made using the lesser (`<`) operator.
--
-- @rulecomponent rule_lesser
-- @param table
-- @see rule
-- @see except
--- A table whose content will be compared to the target object current properties.
--
-- The comparison will be made using the greater (`>`) operator.
--
-- @rulecomponent rule_greater
-- @param table
-- @see rule
-- @see except
--- An identifier for this rule. --- An identifier for this rule.
-- --
-- It can be anything. It will be compared with the `==` operator. Strings are -- It can be anything. It will be compared with the `==` operator. Strings are
@ -60,4 +78,4 @@
-- modify or disable a rule. -- modify or disable a rule.
-- --
-- @rulecomponent id -- @rulecomponent id
-- @param table|string|number|function -- @tparam table|string|number|function id

View File

@ -25,6 +25,7 @@
-- <tr><td><a href='../core_components/client.html#dockable'>dockable</a></td><td>If the client is dockable</td></tr> -- <tr><td><a href='../core_components/client.html#dockable'>dockable</a></td><td>If the client is dockable</td></tr>
-- <tr><td><a href='../core_components/client.html#requests_no_titlebar'>requests\_no\_titlebar</a></td><td>If the client requests not to be decorated with a titlebar</td></tr> -- <tr><td><a href='../core_components/client.html#requests_no_titlebar'>requests\_no\_titlebar</a></td><td>If the client requests not to be decorated with a titlebar</td></tr>
-- <tr><td><a href='../core_components/client.html#shape'>shape</a></td><td>Set the client shape</td></tr> -- <tr><td><a href='../core_components/client.html#shape'>shape</a></td><td>Set the client shape</td></tr>
-- <tr><td><a href='../core_components/client.html#active'>active</a></td><td>Return true if the client is active (has focus)</td></tr>
-- <tr><td><a href='../core_components/client.html#window'>window</a></td><td>The X window id</td></tr> -- <tr><td><a href='../core_components/client.html#window'>window</a></td><td>The X window id</td></tr>
-- <tr><td><a href='../core_components/client.html#name'>name</a></td><td>The client title</td></tr> -- <tr><td><a href='../core_components/client.html#name'>name</a></td><td>The client title</td></tr>
-- <tr><td><a href='../core_components/client.html#skip_taskbar'>skip\_taskbar</a></td><td>True if the client does not want to be in taskbar</td></tr> -- <tr><td><a href='../core_components/client.html#skip_taskbar'>skip\_taskbar</a></td><td>True if the client does not want to be in taskbar</td></tr>

View File

@ -44,14 +44,6 @@ topics={
'89-NEWS.md', '89-NEWS.md',
} }
-- Setup @client to be an alias for "@tparam client.object"
tparam_alias('client', 'client.object')
tparam_alias('tag', 'tag')
-- Should be default, but is not. Sets up "@tab" => "@tparam table".
tparam_alias('tab', 'table')
tparam_alias('screen', 'screen')
tparam_alias('screen_or_idx', 'screen|int')
-- The first stereotype are the constructors. -- The first stereotype are the constructors.
new_type("constructorfct", "Constructors", false, "Parameters") new_type("constructorfct", "Constructors", false, "Parameters")
new_type("constructorfct2", "ldoc_skip", false, "Parameters") new_type("constructorfct2", "ldoc_skip", false, "Parameters")
@ -93,7 +85,9 @@ new_type("rulecomponent", "Rule components", false, "Type")
-- Filter functions for the taglist/tasklist/layoutlist -- Filter functions for the taglist/tasklist/layoutlist
new_type("filterfunction", "List filters", false) new_type("filterfunction", "List filters", false)
-- Extra client properties available only in awful.rules/spawn constructs -- Extra client properties available only in awful.rules/spawn constructs
new_type("clientruleproperty", "Extra properties available in awful.rules and awful.spawn", false, "Type") new_type("clientruleproperty", "Extra properties available in the rules", false, "Type")
-- Extra *matching* properties for rules.
new_type("matchingproperty", "Extra matching properties used in rules", false, "Type")
-- Simulate the default "params" parser format, except the optional "[]" section -- Simulate the default "params" parser format, except the optional "[]" section
-- needs a space. -- needs a space.
@ -424,8 +418,9 @@ sort_modules=true
-- Add more project level (left side index) types. -- Add more project level (left side index) types.
new_type("coreclassmod", "Core_components" , true) new_type("coreclassmod", "Core_components" , true)
new_type("inputmodule" , "Input handling" , true) new_type("inputmodule" , "Input_handling" , true)
new_type("widgetmod" , "Widgets" , true) new_type("ruleslib" , "Declarative_rules", true)
new_type("widgetmod" , "Widgets" , true)
new_type("containermod", "Widget_containers", true) new_type("containermod", "Widget_containers", true)
new_type("layoutmod" , "Widget_layouts" , true) new_type("layoutmod" , "Widget_layouts" , true)
new_type("popupmod" , "Popups_and_bars" , true) new_type("popupmod" , "Popups_and_bars" , true)
@ -471,6 +466,7 @@ file = {
'../lib/naughty/constants.lua', '../lib/naughty/constants.lua',
'../lib/naughty/dbus.lua', '../lib/naughty/dbus.lua',
'../lib/beautiful/gtk.lua', '../lib/beautiful/gtk.lua',
'../lib/ruled/init.lua',
-- Ignore some parts of the widget library -- Ignore some parts of the widget library
'../lib/awful/widget/init.lua', '../lib/awful/widget/init.lua',
@ -518,11 +514,12 @@ local named_args = {
-- Sections which are hidden by default, but visible when clicked. -- Sections which are hidden by default, but visible when clicked.
local summarize = { local summarize = {
emits = {index = 1, title = "signals" }, emits = {index = 1, title = "signal" , count = true },
propemits = {index = 2, title = "signals" }, propemits = {index = 2, title = "signal" , count = true },
usebeautiful = {index = 3, title = "theme variables"}, usebeautiful = {index = 3, title = "theme variable" , count = true },
propbeautiful = {index = 4, title = "theme variables"}, propbeautiful = {index = 4, title = "theme variable" , count = true },
request = {index = 5, title = "permissions" }, request = {index = 5, title = "permission" , count = true },
classsignal = {index = 6, title = "Class level only", count = false},
} }
local delimiter_for_tag = { local delimiter_for_tag = {
@ -549,24 +546,31 @@ local function generate_summary(item)
local tgs = {} local tgs = {}
for k, v in pairs(summarize) do for k, v in pairs(summarize) do
tgs[v.index] = {title=v.title, count=0} tgs[v.index] = {title=v.title, count=0, showcount=v.count}
end end
for tag, value in pairs(item.tags) do for tag, value in pairs(item.tags) do
if summarize[tag] then if summarize[tag] then
tgs[summarize[tag].index].count = tgs[summarize[tag].index].count + 1 tgs[summarize[tag].index].count = #value
end end
end end
local ret = {} local ret, has_show_more = {}, false
for k, v in ipairs(tgs) do for k, v in ipairs(tgs) do
if v.count > 0 then if v.count > 0 then
if v.count > 1 then
v.title = v.title .. "s"
end
ret[#ret+1] = v ret[#ret+1] = v
has_show_more = v.showcount or has_show_more
end end
end end
item.extra_summary = #ret > 0 and ret or nil item.extra_summary = #ret > 0 and ret or nil
item.has_show_more = has_show_more
end end
-- We have custom types, sub-types and different rendering. -- We have custom types, sub-types and different rendering.
@ -750,6 +754,9 @@ local display_type = {
beautiful = true, beautiful = true,
field = true, field = true,
deprecatedproperty = true, deprecatedproperty = true,
clientruleproperty = true,
matchingproperty = true,
rulecomponent = true,
} }
-- Show return values. -- Show return values.

Binary file not shown.

4155
docs/images/client_rules.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 159 KiB

View File

@ -225,7 +225,7 @@
# end # end
# if item.extra_summary then # if item.extra_summary then
# for _, col in ldoc.ipairs(item.extra_summary) do # for _, col in ldoc.ipairs(item.extra_summary) do
&middot $(col.count.." "..col.title) &middot $((col.showcount and col.count.." " or "")..col.title)
# end -- summary col # end -- summary col
# end -- summary # end -- summary
</span> </span>
@ -324,7 +324,7 @@
</ul> </ul>
# end -- if usage # end -- if usage
# if item.extra_summary then # if item.has_show_more then
<br /> <br />
<center id=button$(item.uid)> <center id=button$(item.uid)>
<a class="show_more_button" onclick="show_extra('$(item.uid)')"> <a class="show_more_button" onclick="show_extra('$(item.uid)')">

View File

@ -67,12 +67,14 @@ client.focus = require("awful.client.focus")
-- --
-- awful.placement.no_overlap+awful.placement.no_offscreen -- awful.placement.no_overlap+awful.placement.no_offscreen
-- --
-- @DOC_sequences_client_rules_placement_EXAMPLE@
--
-- @clientruleproperty placement -- @clientruleproperty placement
-- @see awful.placement -- @see awful.placement
--- When applying the placement, honor the screen padding. --- When applying the placement, honor the screen padding.
-- @clientruleproperty honor_padding -- @clientruleproperty honor_padding
-- @param[opt=true] boolean -- @tparam[opt=true] boolean honor_padding
-- @see awful.placement -- @see awful.placement
--- When applying the placement, honor the screen work area. --- When applying the placement, honor the screen work area.
@ -80,12 +82,15 @@ client.focus = require("awful.client.focus")
-- The workarea is the part of the screen that excludes the bars and docks. -- The workarea is the part of the screen that excludes the bars and docks.
-- --
-- @clientruleproperty honor_workarea -- @clientruleproperty honor_workarea
-- @param[opt=true] boolean -- @tparam[opt=true] boolean honor_workarea
-- @see awful.placement -- @see awful.placement
--- The client default tag. --- The client default tag.
--
-- @DOC_sequences_client_rules_tags_EXAMPLE@
--
-- @clientruleproperty tag -- @clientruleproperty tag
-- @param tag -- @tparam tag tag
-- @see tag -- @see tag
-- @see new_tag -- @see new_tag
-- @see tags -- @see tags
@ -97,7 +102,7 @@ client.focus = require("awful.client.focus")
-- issues. -- issues.
-- --
-- @clientruleproperty tags -- @clientruleproperty tags
-- @param[opt={tag}] table -- @tparam[opt={tag}] table tags
-- @see tag -- @see tag
-- @see new_tag -- @see new_tag
-- @see tags -- @see tags
@ -111,11 +116,7 @@ client.focus = require("awful.client.focus")
-- If a table is used, all of its properties will be passed to the tag -- If a table is used, all of its properties will be passed to the tag
-- constructor: -- constructor:
-- --
-- new_tag = { -- @DOC_sequences_client_rules_new_tag_EXAMPLE@
-- name = "My new tag!", -- The tag name.
-- layout = awful.layout.suit.max, -- Set the tag layout.
-- volatile = true, -- Remove the tag when the client is closed.
-- }
-- --
-- @tparam[opt=false] table|string|boolean new_tag -- @tparam[opt=false] table|string|boolean new_tag
-- @clientruleproperty new_tag -- @clientruleproperty new_tag
@ -125,8 +126,11 @@ client.focus = require("awful.client.focus")
--- Unselect the current tags and select this client tags. --- Unselect the current tags and select this client tags.
-- Note that this property was called `switchtotag` in previous Awesome versions. -- Note that this property was called `switchtotag` in previous Awesome versions.
--
-- @DOC_sequences_client_rules_switch_to_tags_EXAMPLE@
--
-- @clientruleproperty switch_to_tags -- @clientruleproperty switch_to_tags
-- @param[opt=false] boolean -- @tparam[opt=false] boolean switch_to_tags
-- @see tag.selected -- @see tag.selected
--- Define if the client should grab focus by default. --- Define if the client should grab focus by default.
@ -134,11 +138,11 @@ client.focus = require("awful.client.focus")
-- The `request::activate` context for this call is `rules`. -- The `request::activate` context for this call is `rules`.
-- --
-- @clientruleproperty focus -- @clientruleproperty focus
-- @param[opt=false] boolean -- @tparam[opt=false] boolean focus
--- Should this client have a titlebar by default. --- Should this client have a titlebar by default.
-- @clientruleproperty titlebars_enabled -- @clientruleproperty titlebars_enabled
-- @param[opt=false] boolean -- @tparam[opt=false] boolean titlebars_enabled
-- @see awful.titlebar -- @see awful.titlebar
--- A function to call when this client is ready. --- A function to call when this client is ready.
@ -153,7 +157,7 @@ client.focus = require("awful.client.focus")
-- --
-- @deprecated awful.client.jumpto -- @deprecated awful.client.jumpto
-- @see client.jump_to -- @see client.jump_to
-- @client c the client to jump to -- @tparam client c the client to jump to
-- @tparam bool|function merge If true then merge tags (select the client's -- @tparam bool|function merge If true then merge tags (select the client's
-- first tag additionally) when the client is not visible. -- first tag additionally) when the client is not visible.
-- If it is a function, it will be called with the client and its first -- If it is a function, it will be called with the client and its first
@ -173,6 +177,8 @@ end
-- tag as arguments. -- tag as arguments.
-- @request client activate client.jumpto granted When a client is activated -- @request client activate client.jumpto granted When a client is activated
-- because `c:jump_to()` is called. -- because `c:jump_to()` is called.
-- @see activate
-- @see active
function client.object.jump_to(self, merge) function client.object.jump_to(self, merge)
local s = get_screen(screen.focused()) local s = get_screen(screen.focused())
-- focus the screen -- focus the screen
@ -245,9 +251,9 @@ end
-- --
-- @staticfct awful.client.next -- @staticfct awful.client.next
-- @tparam int i The index. Use 1 to get the next, -1 to get the previous. -- @tparam int i The index. Use 1 to get the next, -1 to get the previous.
-- @client[opt] sel The client. -- @tparam[opt] client sel The client.
-- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom) -- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
-- @return A client, or nil if no client is available. -- @treturn[opt] client|nil A client, or nil if no client is available.
-- --
-- @usage -- focus the next window in the index -- @usage -- focus the next window in the index
-- awful.client.next(1) -- awful.client.next(1)
@ -278,10 +284,16 @@ function client.next(i, sel, stacked)
end end
--- Swap a client with another client in the given direction. --- Swap a client with another client in the given direction.
--
-- @staticfct awful.client.swap.bydirection -- @staticfct awful.client.swap.bydirection
-- @tparam string dir The direction, can be either "up", "down", "left" or "right". -- @tparam string dir The direction, can be either "up", "down", "left" or "right".
-- @client[opt=focused] c The client. -- @tparam[opt=focused] client c The client.
-- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom) -- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
-- @see swap
-- @see swapped
-- @see awful.client.swap.global_bydirection
-- @see awful.client.swap.byidx
-- @see awful.client.cycle
function client.swap.bydirection(dir, c, stacked) function client.swap.bydirection(dir, c, stacked)
local sel = c or capi.client.focus local sel = c or capi.client.focus
if sel then if sel then
@ -300,12 +312,18 @@ function client.swap.bydirection(dir, c, stacked)
end end
--- Swap a client with another client in the given direction. --- Swap a client with another client in the given direction.
--
-- Swaps across screens. -- Swaps across screens.
-- @staticfct awful.client.swap.global_bydirection -- @staticfct awful.client.swap.global_bydirection
-- @param dir The direction, can be either "up", "down", "left" or "right". -- @tparam string dir The direction, can be either "up", "down", "left" or "right".
-- @client[opt] sel The client. -- @tparam[opt] client sel The client.
-- @request client activate client.swap.global_bydirection granted When a client -- @request client activate client.swap.global_bydirection granted When a client
-- could be activated because `awful.client.swap.global_bydirection` was called. -- could be activated because `awful.client.swap.global_bydirection` was called.
-- @see swap
-- @see swapped
-- @see awful.client.swap.bydirection
-- @see awful.client.swap.byidx
-- @see awful.client.cycle
function client.swap.global_bydirection(dir, sel) function client.swap.global_bydirection(dir, sel)
sel = sel or capi.client.focus sel = sel or capi.client.focus
local scr = get_screen(sel and sel.screen or screen.focused()) local scr = get_screen(sel and sel.screen or screen.focused())
@ -336,9 +354,15 @@ function client.swap.global_bydirection(dir, sel)
end end
--- Swap a client by its relative index. --- Swap a client by its relative index.
--
-- @staticfct awful.client.swap.byidx -- @staticfct awful.client.swap.byidx
-- @param i The index. -- @tparam integer i The index.
-- @client[opt] c The client, otherwise focused one is used. -- @tparam[opt] client c The client, otherwise focused one is used.
-- @see swap
-- @see swapped
-- @see awful.client.swap.bydirection
-- @see awful.client.swap.global_bydirection
-- @see awful.client.cycle
function client.swap.byidx(i, c) function client.swap.byidx(i, c)
local sel = c or capi.client.focus local sel = c or capi.client.focus
local target = client.next(i, sel) local target = client.next(i, sel)
@ -347,12 +371,20 @@ function client.swap.byidx(i, c)
end end
end end
--- Cycle clients. --- Cycle through the clients to change the focus.
--
-- This will swap the client from one position to the next
-- in the layout.
-- --
-- @staticfct awful.client.cycle -- @staticfct awful.client.cycle
-- @param clockwise True to cycle clients clockwise. -- @tparam boolean clockwise True to cycle clients clockwise.
-- @param[opt] s The screen where to cycle clients. -- @tparam[opt] screen s The screen where to cycle clients.
-- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom) -- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
-- @see swap
-- @see swapped
-- @see awful.client.swap.bydirection
-- @see awful.client.swap.global_bydirection
-- @see awful.client.swap.byidx
function client.cycle(clockwise, s, stacked) function client.cycle(clockwise, s, stacked)
s = s or screen.focused() s = s or screen.focused()
local cls = client.visible(s, stacked) local cls = client.visible(s, stacked)
@ -397,8 +429,8 @@ end
--- Get the master window. --- Get the master window.
-- --
-- @legacylayout awful.client.getmaster -- @legacylayout awful.client.getmaster
-- @screen_or_idx[opt=awful.screen.focused()] s The screen. -- @tparam[opt=awful.screen.focused()] screen s The screen.
-- @return The master window. -- @treturn client The master client.
function client.getmaster(s) function client.getmaster(s)
s = s or screen.focused() s = s or screen.focused()
return client.visible(s)[1] return client.visible(s)[1]
@ -407,7 +439,7 @@ end
--- Set the client as master: put it at the beginning of other windows. --- Set the client as master: put it at the beginning of other windows.
-- --
-- @legacylayout awful.client.setmaster -- @legacylayout awful.client.setmaster
-- @client c The window to set as master. -- @tparam client c The window to set as master.
function client.setmaster(c) function client.setmaster(c)
local cls = gtable.reverse(capi.client.get(c.screen)) local cls = gtable.reverse(capi.client.get(c.screen))
for _, v in pairs(cls) do for _, v in pairs(cls) do
@ -417,7 +449,7 @@ end
--- Set the client as slave: put it at the end of other windows. --- Set the client as slave: put it at the end of other windows.
-- @legacylayout awful.client.setslave -- @legacylayout awful.client.setslave
-- @client c The window to set as slave. -- @tparam client c The window to set as slave.
function client.setslave(c) function client.setslave(c)
local cls = capi.client.get(c.screen) local cls = capi.client.get(c.screen)
for _, v in pairs(cls) do for _, v in pairs(cls) do
@ -427,11 +459,11 @@ end
--- Move/resize a client relative to current coordinates. --- Move/resize a client relative to current coordinates.
-- @deprecated awful.client.moveresize -- @deprecated awful.client.moveresize
-- @param x The relative x coordinate. -- @tparam integer x The relative x coordinate.
-- @param y The relative y coordinate. -- @tparam integer y The relative y coordinate.
-- @param w The relative width. -- @tparam integer w The relative width.
-- @param h The relative height. -- @tparam integer h The relative height.
-- @client[opt] c The client, otherwise focused one is used. -- @tparam[opt] client c The client, otherwise focused one is used.
-- @see client.relative_move -- @see client.relative_move
function client.moveresize(x, y, w, h, c) function client.moveresize(x, y, w, h, c)
gdebug.deprecate("Use c:relative_move(x, y, w, h) instead of awful.client.moveresize", {deprecated_in=4}) gdebug.deprecate("Use c:relative_move(x, y, w, h) instead of awful.client.moveresize", {deprecated_in=4})
@ -456,8 +488,8 @@ end
--- Move a client to a tag. --- Move a client to a tag.
-- @deprecated awful.client.movetotag -- @deprecated awful.client.movetotag
-- @param target The tag to move the client to. -- @tparam tag target The tag to move the client to.
-- @client[opt] c The client to move, otherwise the focused one is used. -- @tparam[opt] client c The client to move, otherwise the focused one is used.
-- @see client.move_to_tag -- @see client.move_to_tag
function client.movetotag(target, c) function client.movetotag(target, c)
gdebug.deprecate("Use c:move_to_tag(target) instead of awful.client.movetotag", {deprecated_in=4}) gdebug.deprecate("Use c:move_to_tag(target) instead of awful.client.movetotag", {deprecated_in=4})
@ -465,10 +497,12 @@ function client.movetotag(target, c)
end end
--- Move a client to a tag. --- Move a client to a tag.
--
-- @method move_to_tag -- @method move_to_tag
-- @tparam tag target The tag to move the client to. -- @tparam tag target The tag to move the client to.
-- @request client activate client.movetotag granted When a client could be -- @request client activate client.movetotag granted When a client could be
-- activated because `c:move_to_tag()` was called. -- activated because `c:move_to_tag()` was called.
-- @see tags
function client.object.move_to_tag(self, target) function client.object.move_to_tag(self, target)
local s = target.screen local s = target.screen
if self and s then if self and s then
@ -482,18 +516,22 @@ function client.object.move_to_tag(self, target)
end end
--- Toggle a tag on a client. --- Toggle a tag on a client.
--
-- @deprecated awful.client.toggletag -- @deprecated awful.client.toggletag
-- @param target The tag to toggle. -- @tparam tag target The tag to toggle.
-- @client[opt] c The client to toggle, otherwise the focused one is used. -- @tparam[opt] client c The client to toggle, otherwise the focused one is used.
-- @see client.toggle_tag -- @see client.toggle_tag
-- @see tags
function client.toggletag(target, c) function client.toggletag(target, c)
gdebug.deprecate("Use c:toggle_tag(target) instead of awful.client.toggletag", {deprecated_in=4}) gdebug.deprecate("Use c:toggle_tag(target) instead of awful.client.toggletag", {deprecated_in=4})
client.object.toggle_tag(c or capi.client.focus, target) client.object.toggle_tag(c or capi.client.focus, target)
end end
--- Toggle a tag on a client. --- Toggle a tag on a client.
--
-- @method toggle_tag -- @method toggle_tag
-- @tparam tag target The tag to move the client to. -- @tparam tag target The tag to move the client to.
-- @see tags
function client.object.toggle_tag(self, target) function client.object.toggle_tag(self, target)
-- Check that tag and client screen are identical -- Check that tag and client screen are identical
if self and get_screen(self.screen) == get_screen(target.screen) then if self and get_screen(self.screen) == get_screen(target.screen) then
@ -518,8 +556,8 @@ end
--- Move a client to a screen. Default is next screen, cycling. --- Move a client to a screen. Default is next screen, cycling.
-- @deprecated awful.client.movetoscreen -- @deprecated awful.client.movetoscreen
-- @client c The client to move. -- @tparam client c The client to move.
-- @param s The screen, default to current + 1. -- @tparam screen s The screen, default to current + 1.
-- @see screen -- @see screen
-- @see client.move_to_screen -- @see client.move_to_screen
function client.movetoscreen(c, s) function client.movetoscreen(c, s)
@ -586,14 +624,11 @@ end
--- If a client is marked or not. --- 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 -- @property marked
-- @param boolean -- @tparam boolean marked
-- @emits marked (for legacy reasons, use `property::marked`)
-- @emits unmarker (for legacy reasons, use `property::marked`)
-- @emits property::marked
--- The border color when the client is focused. --- The border color when the client is focused.
-- --
@ -625,7 +660,7 @@ end
--- Mark a client, and then call 'marked' hook. --- Mark a client, and then call 'marked' hook.
-- @deprecated awful.client.mark -- @deprecated awful.client.mark
-- @client c The client to mark, the focused one if not specified. -- @tparam client c The client to mark, the focused one if not specified.
function client.mark(c) function client.mark(c)
gdebug.deprecate("Use c.marked = true instead of awful.client.mark", {deprecated_in=4}) gdebug.deprecate("Use c.marked = true instead of awful.client.mark", {deprecated_in=4})
client.object.set_marked(c or capi.client.focus, true) client.object.set_marked(c or capi.client.focus, true)
@ -633,7 +668,7 @@ end
--- Unmark a client and then call 'unmarked' hook. --- Unmark a client and then call 'unmarked' hook.
-- @deprecated awful.client.unmark -- @deprecated awful.client.unmark
-- @client c The client to unmark, or the focused one if not specified. -- @tparam client c The client to unmark, or the focused one if not specified.
function client.unmark(c) function client.unmark(c)
gdebug.deprecate("Use c.marked = false instead of awful.client.unmark", {deprecated_in=4}) gdebug.deprecate("Use c.marked = false instead of awful.client.unmark", {deprecated_in=4})
client.object.set_marked(c or capi.client.focus, false) client.object.set_marked(c or capi.client.focus, false)
@ -641,7 +676,7 @@ end
--- Check if a client is marked. --- Check if a client is marked.
-- @deprecated awful.client.ismarked -- @deprecated awful.client.ismarked
-- @client c The client to check, or the focused one otherwise. -- @tparam client c The client to check, or the focused one otherwise.
function client.ismarked(c) function client.ismarked(c)
gdebug.deprecate("Use c.marked instead of awful.client.ismarked", {deprecated_in=4}) gdebug.deprecate("Use c.marked instead of awful.client.ismarked", {deprecated_in=4})
return client.object.get_marked(c or capi.client.focus) return client.object.get_marked(c or capi.client.focus)
@ -649,7 +684,7 @@ end
--- Toggle a client as marked. --- Toggle a client as marked.
-- @deprecated awful.client.togglemarked -- @deprecated awful.client.togglemarked
-- @client c The client to toggle mark. -- @tparam client c The client to toggle mark.
function client.togglemarked(c) function client.togglemarked(c)
gdebug.deprecate("Use c.marked = not c.marked instead of awful.client.togglemarked", {deprecated_in=4}) gdebug.deprecate("Use c.marked = not c.marked instead of awful.client.togglemarked", {deprecated_in=4})
c = c or capi.client.focus c = c or capi.client.focus
@ -660,7 +695,7 @@ end
--- Return the marked clients and empty the marked table. --- Return the marked clients and empty the marked table.
-- @deprecated awful.client.getmarked -- @deprecated awful.client.getmarked
-- @return A table with all marked clients. -- @treturn table A table with all marked clients.
function client.getmarked() function client.getmarked()
local copy = gtable.clone(client.data.marked, false) local copy = gtable.clone(client.data.marked, false)
@ -677,8 +712,8 @@ end
--- Set a client floating state, overriding auto-detection. --- Set a client floating state, overriding auto-detection.
-- Floating client are not handled by tiling layouts. -- Floating client are not handled by tiling layouts.
-- @deprecated awful.client.floating.set -- @deprecated awful.client.floating.set
-- @client c A client. -- @tparam client c A client.
-- @param s True or false. -- @tparam boolean s True or false.
function client.floating.set(c, s) function client.floating.set(c, s)
gdebug.deprecate("Use c.floating = true instead of awful.client.floating.set", {deprecated_in=4}) gdebug.deprecate("Use c.floating = true instead of awful.client.floating.set", {deprecated_in=4})
client.object.set_floating(c, s) client.object.set_floating(c, s)
@ -686,8 +721,8 @@ end
-- Set a client floating state, overriding auto-detection. -- Set a client floating state, overriding auto-detection.
-- Floating client are not handled by tiling layouts. -- Floating client are not handled by tiling layouts.
-- @client c A client. -- @tparam client c A client.
-- @param s True or false. -- @tparam boolan s True or false.
function client.object.set_floating(c, s) function client.object.set_floating(c, s)
c = c or capi.client.focus c = c or capi.client.focus
if c and client.property.get(c, "floating") ~= s then if c and client.property.get(c, "floating") ~= s then
@ -725,7 +760,7 @@ capi.client.connect_signal("property::geometry", store_floating_geometry)
--- Return if a client has a fixed size or not. --- Return if a client has a fixed size or not.
-- This function is deprecated, use `c.is_fixed` -- This function is deprecated, use `c.is_fixed`
-- @client c The client. -- @tparam client c The client.
-- @deprecated awful.client.isfixed -- @deprecated awful.client.isfixed
-- @see is_fixed -- @see is_fixed
-- @see size_hints_honor -- @see size_hints_honor
@ -737,13 +772,10 @@ end
--- Return if a client has a fixed size or not. --- Return if a client has a fixed size or not.
-- --
-- **Signal:**
--
-- * *property::is_fixed*
--
-- This property is read only. -- This property is read only.
-- @property is_fixed -- @property is_fixed
-- @param boolean The fixed size state -- @tparam[opt=false] boolean is_fixed The fixed size state
-- @propemits false false
-- @see size_hints -- @see size_hints
-- @see size_hints_honor -- @see size_hints_honor
@ -768,7 +800,7 @@ end
-- --
-- This property is read only. -- This property is read only.
-- @property immobilized_horizontal -- @property immobilized_horizontal
-- @param boolean The immobilized state -- @tparam[opt=false] boolean immobilized_horizontal The immobilized state
-- @see maximized -- @see maximized
-- @see maximized_horizontal -- @see maximized_horizontal
-- @see fullscreen -- @see fullscreen
@ -784,7 +816,7 @@ end
-- --
-- This property is read only. -- This property is read only.
-- @property immobilized_vertical -- @property immobilized_vertical
-- @param boolean The immobilized state -- @tparam[opt=false] boolean immobilized_vertical The immobilized state
-- @see maximized -- @see maximized
-- @see maximized_vertical -- @see maximized_vertical
-- @see fullscreen -- @see fullscreen
@ -794,10 +826,10 @@ function client.object.is_immobilized_vertical(c)
end end
--- Get a client floating state. --- Get a client floating state.
-- @client c A client. -- @tparam client c A client.
-- @see floating -- @see floating
-- @deprecated awful.client.floating.get -- @deprecated awful.client.floating.get
-- @return True or false. Note that some windows might be floating even if you -- @treturn boolean 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 -- did not set them manually. For example, windows with a type different than
-- normal. -- normal.
function client.floating.get(c) function client.floating.get(c)
@ -813,10 +845,6 @@ end
-- did not set them manually. For example, windows with a type different than -- did not set them manually. For example, windows with a type different than
-- normal. -- normal.
-- --
-- **Signal:**
--
-- * *property::floating*
--
-- @property floating -- @property floating
-- @tparam boolean floating The floating state. -- @tparam boolean floating The floating state.
-- @request client border floating granted When a border update is required -- @request client border floating granted When a border update is required
@ -825,6 +853,7 @@ end
-- floating. -- floating.
-- @request client border inactive granted When a client stop being active and -- @request client border inactive granted When a client stop being active and
-- is not floating. -- is not floating.
-- @propemits false false
function client.object.get_floating(c) function client.object.get_floating(c)
c = c or capi.client.focus c = c or capi.client.focus
@ -881,7 +910,7 @@ capi.client.connect_signal("request::manage", update_implicitly_floating)
--- Toggle the floating state of a client between 'auto' and 'true'. --- Toggle the floating state of a client between 'auto' and 'true'.
-- Use `c.floating = not c.floating` -- Use `c.floating = not c.floating`
-- @deprecated awful.client.floating.toggle -- @deprecated awful.client.floating.toggle
-- @client c A client. -- @tparam client c A client.
-- @see floating -- @see floating
function client.floating.toggle(c) function client.floating.toggle(c)
c = c or capi.client.focus c = c or capi.client.focus
@ -890,46 +919,50 @@ function client.floating.toggle(c)
end end
-- Remove the floating information on a client. -- Remove the floating information on a client.
-- @client c The client. -- @tparam client c The client.
function client.floating.delete(c) function client.floating.delete(c)
client.object.set_floating(c, nil) client.object.set_floating(c, nil)
end end
--- The x coordinates. --- The x coordinates.
-- --
-- **Signal:**
--
-- * *property::x*
--
-- @property x -- @property x
-- @param integer -- @tparam integer x
-- @emits property::geometry
-- @emitstparam property::geometry table geo The
-- geometry (with `x`, `y`, `width`, `height`).
-- @emits property::x
-- @emits property::position
--- The y coordinates. --- The y coordinates.
-- --
-- **Signal:**
--
-- * *property::y*
--
-- @property y -- @property y
-- @param integer -- @tparam integer y
-- @emits property::geometry
-- @emitstparam property::geometry table geo The
-- geometry (with `x`, `y`, `width`, `height`).
-- @emits property::y
-- @emits property::position
--- The width of the client. --- The width of the client.
-- --
-- **Signal:**
--
-- * *property::width*
--
-- @property width -- @property width
-- @param width -- @tparam integer width
-- @emits property::geometry
-- @emitstparam property::geometry table geo The
-- geometry (with `x`, `y`, `width`, `height`).
-- @emits property::width
-- @emits property::size
--- The height of the client. --- The height of the client.
-- --
-- **Signal:**
--
-- * *property::height*
--
-- @property height -- @property height
-- @param height -- @tparam integer height
-- @emits property::geometry
-- @emitstparam property::geometry table geo The
-- geometry (with `x`, `y`, `width`, `height`).
-- @emits property::height
-- @emits property::size
-- Add the geometry helpers to match the wibox API -- Add the geometry helpers to match the wibox API
for _, v in ipairs {"x", "y", "width", "height"} do for _, v in ipairs {"x", "y", "width", "height"} do
@ -945,8 +978,8 @@ end
--- Restore (=unminimize) a random client. --- Restore (=unminimize) a random client.
-- @staticfct awful.client.restore -- @staticfct awful.client.restore
-- @param s The screen to use. -- @tparam screen s The screen to use.
-- @return The restored client if some client was restored, otherwise nil. -- @treturn client The restored client if some client was restored, otherwise nil.
function client.restore(s) function client.restore(s)
s = s or screen.focused() s = s or screen.focused()
local cls = capi.client.get(s) local cls = capi.client.get(s)
@ -966,8 +999,8 @@ function client.restore(s)
end end
--- Normalize a set of numbers to 1. --- Normalize a set of numbers to 1.
-- @param set the set of numbers to normalize -- @tparam table set the set of numbers to normalize.
-- @param num the number of numbers to normalize -- @tparam number num the number of numbers to normalize.
local function normalize(set, num) local function normalize(set, num)
num = num or #set num = num or #set
local total = 0 local total = 0
@ -993,10 +1026,10 @@ end
-- number of visible clients in this column. -- number of visible clients in this column.
-- --
-- @legacylayout awful.client.idx -- @legacylayout awful.client.idx
-- @client c the client -- @tparam client c the client
-- @return col the column number -- @treturn integer col The column number.
-- @return idx index of the client in the column -- @treturn integer idx Index of the client in the column.
-- @return num the number of visible clients in the column -- @treturn integer num The number of visible clients in the column.
function client.idx(c) function client.idx(c)
c = c or capi.client.focus c = c or capi.client.focus
if not c then return end if not c then return end
@ -1054,8 +1087,9 @@ end
--- Set the window factor of a client --- Set the window factor of a client
-- --
-- @legacylayout awful.client.setwfact -- @legacylayout awful.client.setwfact
-- @param wfact the window factor value -- @tparam number wfact the window factor value
-- @client c the client -- @tparam client c the client
-- @emits property::windowfact
function client.setwfact(wfact, c) function client.setwfact(wfact, c)
-- get the currently selected window -- get the currently selected window
c = c or capi.client.focus c = c or capi.client.focus
@ -1110,7 +1144,8 @@ end
-- @tparam number add Amount to increase/decrease the client's window factor. -- @tparam number add Amount to increase/decrease the client's window factor.
-- Should be between `-current_window_factor` and something close to -- Should be between `-current_window_factor` and something close to
-- infinite. The normalisation then ensures that the sum of all factors is 1. -- infinite. The normalisation then ensures that the sum of all factors is 1.
-- @client c the client -- @tparam client c the client.
-- @emits property::windowfact
function client.incwfact(add, c) function client.incwfact(add, c)
c = c or capi.client.focus c = c or capi.client.focus
if not c then return end if not c then return end
@ -1132,7 +1167,7 @@ end
--- Get a client's dockable state. --- Get a client's dockable state.
-- --
-- @client c A client. -- @tparam client c A client.
-- @treturn bool -- @treturn bool
-- @deprecated awful.client.dockable.get -- @deprecated awful.client.dockable.get
function client.dockable.get(c) function client.dockable.get(c)
@ -1148,12 +1183,9 @@ end
-- Clients with a type of "utility", "toolbar" or "dock" are dockable by -- Clients with a type of "utility", "toolbar" or "dock" are dockable by
-- default. -- default.
-- --
-- **Signal:**
--
-- * *property::dockable*
--
-- @property dockable -- @property dockable
-- @param boolean The dockable state -- @tparam boolean dockable The dockable state
-- @propemits false false
function client.object.get_dockable(c) function client.object.get_dockable(c)
local value = client.property.get(c, "dockable") local value = client.property.get(c, "dockable")
@ -1175,8 +1207,8 @@ end
-- With this enabled you can dock windows by moving them from the center -- With this enabled you can dock windows by moving them from the center
-- to the edge of the workarea. -- to the edge of the workarea.
-- --
-- @client c A client. -- @tparam client c A client.
-- @param value True or false. -- @tparam boolean value True or false.
-- @deprecated awful.client.dockable.set -- @deprecated awful.client.dockable.set
function client.dockable.set(c, value) function client.dockable.set(c, value)
gdebug.deprecate("Use c.dockable = value instead of awful.client.dockable.set", {deprecated_in=4}) gdebug.deprecate("Use c.dockable = value instead of awful.client.dockable.set", {deprecated_in=4})
@ -1189,12 +1221,10 @@ end
-- various ways. This property uses the motif MWM_DECOR_TITLE hint and -- various ways. This property uses the motif MWM_DECOR_TITLE hint and
-- interprets it as the client (not) wanting a titlebar. -- interprets it as the client (not) wanting a titlebar.
-- --
-- **Signal:**
--
-- * *property::requests_no_titlebar*
--
-- @property requests_no_titlebar -- @property requests_no_titlebar
-- @param boolean Whether the client requests not to get a titlebar -- @tparam boolean requests_no_titlebar Whether the client
-- requests not to get a titlebar.
-- @propemits false false
function client.object.get_requests_no_titlebar(c) function client.object.get_requests_no_titlebar(c)
local hints = c.motif_wm_hints local hints = c.motif_wm_hints
@ -1219,9 +1249,9 @@ end)
-- --
-- This method is deprecated. It is now possible to use `c.value` directly. -- This method is deprecated. It is now possible to use `c.value` directly.
-- --
-- @client c The client. -- @tparam client c The client.
-- @param prop The property name. -- @tparam string prop The property name.
-- @return The property. -- @return The property value.
-- @deprecated awful.client.property.get -- @deprecated awful.client.property.get
function client.property.get(c, prop) function client.property.get(c, prop)
if not c._private._persistent_properties_loaded then if not c._private._persistent_properties_loaded then
@ -1243,9 +1273,9 @@ end
-- This method is deprecated. It is now possible to use `c.value = value` -- This method is deprecated. It is now possible to use `c.value = value`
-- directly. -- directly.
-- --
-- @client c The client. -- @tparam client c The client.
-- @param prop The property name. -- @tparam string prop The property name.
-- @param value The value. -- @param value The property value.
-- @deprecated awful.client.property.set -- @deprecated awful.client.property.set
function client.property.set(c, prop, value) function client.property.set(c, prop, value)
if not c._private.awful_client_properties then if not c._private.awful_client_properties then
@ -1263,8 +1293,8 @@ end
--- Set a client property to be persistent across restarts (via X properties). --- Set a client property to be persistent across restarts (via X properties).
-- --
-- @staticfct awful.client.property.persist -- @staticfct awful.client.property.persist
-- @param prop The property name. -- @tparam string prop The property name.
-- @param kind The type (used for register_xproperty). -- @tparam string kind The type (used for register_xproperty).
-- One of "string", "number" or "boolean". -- One of "string", "number" or "boolean".
function client.property.persist(prop, kind) function client.property.persist(prop, kind)
local xprop = "awful.client.property." .. prop local xprop = "awful.client.property." .. prop
@ -1284,15 +1314,15 @@ end
-- Starting from the client in focus or the given index, all clients that match -- Starting from the client in focus or the given index, all clients that match
-- a given criteria. -- a given criteria.
-- --
-- @param filter a function that returns true to indicate a positive match -- @tparam function filter a function that returns true to indicate a positive match.
-- @param start what index to start iterating from. Defaults to using the -- @tparam integer start what index to start iterating from. Defaults to using the
-- index of the currently focused client. -- index of the currently focused client.
-- @param s which screen to use. nil means all screens. -- @tparam screen s which screen to use. nil means all screens.
-- --
-- @staticfct awful.client.iterate -- @staticfct awful.client.iterate
-- @usage -- un-minimize all urxvt instances -- @usage -- un-minimize all urxvt instances
-- local urxvt = function (c) -- local urxvt = function (c)
-- return awful.rules.match(c, {class = "URxvt"}) -- return ruled.client.match(c, {class = "URxvt"})
-- end -- end
-- --
-- for c in awful.client.iterate(urxvt) do -- for c in awful.client.iterate(urxvt) do
@ -1309,8 +1339,8 @@ end
-- If multiple clients match the given condition then the next one is -- If multiple clients match the given condition then the next one is
-- focussed. -- focussed.
-- --
-- @param cmd the command to execute -- @tparam string cmd the command to execute
-- @param matcher a function that returns true to indicate a matching client -- @tparam function matcher a function that returns true to indicate a matching client
-- @tparam bool|function merge If true then merge tags (select the client's -- @tparam bool|function merge If true then merge tags (select the client's
-- first tag additionally) when the client is not visible. -- first tag additionally) when the client is not visible.
-- If it is a function, it will be called with the client as argument. -- If it is a function, it will be called with the client as argument.
@ -1322,7 +1352,7 @@ end
-- @usage -- run or raise urxvt (perhaps, with tabs) on modkey + semicolon -- @usage -- run or raise urxvt (perhaps, with tabs) on modkey + semicolon
-- awful.key({ modkey, }, 'semicolon', function () -- awful.key({ modkey, }, 'semicolon', function ()
-- local matcher = function (c) -- local matcher = function (c)
-- return awful.rules.match(c, {class = 'URxvt'}) -- return ruled.client.match(c, {class = 'URxvt'})
-- end -- end
-- awful.client.run_or_raise('urxvt', matcher) -- awful.client.run_or_raise('urxvt', matcher)
-- end); -- end);
@ -1347,10 +1377,10 @@ end
--- Get a matching transient_for client (if any). --- Get a matching transient_for client (if any).
-- @deprecated awful.client.get_transient_for_matching -- @deprecated awful.client.get_transient_for_matching
-- @see client.get_transient_for_matching -- @see client.get_transient_for_matching
-- @client c The client. -- @tparam client c The client.
-- @tparam function matcher A function that should return true, if -- @tparam function matcher A function that should return true, if
-- a matching parent client is found. -- a matching parent client is found.
-- @treturn client.client|nil The matching parent client or nil. -- @treturn client|nil The matching parent client or nil.
function client.get_transient_for_matching(c, matcher) function client.get_transient_for_matching(c, matcher)
gdebug.deprecate("Use c:get_transient_for_matching(matcher) instead of".. gdebug.deprecate("Use c:get_transient_for_matching(matcher) instead of"..
"awful.client.get_transient_for_matching", {deprecated_in=4}) "awful.client.get_transient_for_matching", {deprecated_in=4})
@ -1362,7 +1392,10 @@ end
-- @method get_transient_for_matching -- @method get_transient_for_matching
-- @tparam function matcher A function that should return true, if -- @tparam function matcher A function that should return true, if
-- a matching parent client is found. -- a matching parent client is found.
-- @treturn client.client|nil The matching parent client or nil. -- @treturn client|nil The matching parent client or nil.
-- @see transient_for
-- @see modal
-- @see is_transient_for
function client.object.get_transient_for_matching(self, matcher) function client.object.get_transient_for_matching(self, matcher)
local tc = self.transient_for local tc = self.transient_for
while tc do while tc do
@ -1375,11 +1408,12 @@ function client.object.get_transient_for_matching(self, matcher)
end end
--- Is a client transient for another one? --- Is a client transient for another one?
--
-- @deprecated awful.client.is_transient_for -- @deprecated awful.client.is_transient_for
-- @see client.is_transient_for -- @see client.is_transient_for
-- @client c The child client (having transient_for). -- @tparam client c The child client (having transient_for).
-- @client c2 The parent client to check. -- @tparam client c2 The parent client to check.
-- @treturn client.client|nil The parent client or nil. -- @treturn client|nil The parent client or nil.
function client.is_transient_for(c, c2) function client.is_transient_for(c, c2)
gdebug.deprecate("Use c:is_transient_for(c2) instead of".. gdebug.deprecate("Use c:is_transient_for(c2) instead of"..
"awful.client.is_transient_for", {deprecated_in=4}) "awful.client.is_transient_for", {deprecated_in=4})
@ -1387,9 +1421,20 @@ function client.is_transient_for(c, c2)
end end
--- Is a client transient for another one? --- Is a client transient for another one?
--
-- This will traverse the chain formed by the `transient_for` property of `self`
-- until a client `c` with `c.transient_for == c2` is found. The found client
-- `c` is returned. If no client is found, `nil` is returned.
--
-- While `transient_for` chains are technically possible, they are unlikely, so
-- the most likely return values are `self` and `nil`.
--
-- @method is_transient_for -- @method is_transient_for
-- @client c2 The parent client to check. -- @tparam client c2 The parent client to check.
-- @treturn client.client|nil The parent client or nil. -- @treturn client|nil The parent client or nil.
-- @see transient_for
-- @see modal
-- @see client.get_transient_for_matching
function client.object.is_transient_for(self, c2) function client.object.is_transient_for(self, c2)
local tc = self local tc = self
while tc.transient_for do while tc.transient_for do
@ -1414,12 +1459,15 @@ object.properties._legacy_accessors(client, "keys", "_keys", true, function(new_
end, true, true, "keybinding") end, true, true, "keybinding")
--- Set the client shape. --- Set the client shape.
--
-- @property shape -- @property shape
-- @tparam gears.shape A gears.shape compatible function. -- @tparam gears.shape A gears.shape compatible function.
-- @propemits true false
-- @see gears.shape -- @see gears.shape
function client.object.set_shape(self, shape) function client.object.set_shape(self, shape)
client.property.set(self, "_shape", shape) client.property.set(self, "_shape", shape)
set_shape(self) set_shape(self)
self:emit_signal("property::shape", shape)
end end
-- Proxy those properties to decorate their accessors with an extra flag to -- Proxy those properties to decorate their accessors with an extra flag to
@ -1606,6 +1654,7 @@ end)
-- @signal request::titlebars -- @signal request::titlebars
-- @tparam[opt=nil] string content The context (like "rules") -- @tparam[opt=nil] string content The context (like "rules")
-- @tparam[opt=nil] table hints Some hints. -- @tparam[opt=nil] table hints Some hints.
-- @classsignal
--- The client marked signal. --- The client marked signal.
-- @deprecatedsignal marked -- @deprecatedsignal marked
@ -1626,6 +1675,9 @@ end)
-- * **floating**: When the floating or maximization state changes. -- * **floating**: When the floating or maximization state changes.
-- --
-- @signal request::border -- @signal request::border
-- @tparam string context The context.
-- @tparam table hints The hints.
-- @classsignal
-- @see awful.permissions.update_border -- @see awful.permissions.update_border
-- Add clients during startup to focus history. -- Add clients during startup to focus history.
@ -1639,7 +1691,7 @@ capi.client.connect_signal("request::manage", function (c)
require("awful.placement").no_offscreen(c) require("awful.placement").no_offscreen(c)
end end
if awesome.startup then if capi.awesome.startup then
client.focus.history.add(c) client.focus.history.add(c)
end end
@ -1664,6 +1716,15 @@ capi.client.connect_signal("unmanage::connected", function()
) )
end) end)
for _, sig in ipairs {"marked", "unmarked"} do
capi.client.connect_signal(sig.."::connected", function()
gdebug.deprecate(
"Use `property::marked` rather than `".. sig .. "`",
{deprecated_in=4}
)
end)
end
-- Connect to "focus" signal, and allow to disable tracking. -- Connect to "focus" signal, and allow to disable tracking.
do do
local disabled_count = 1 local disabled_count = 1

View File

@ -44,7 +44,7 @@ end
--- Remove a client from the focus history --- Remove a client from the focus history
-- --
-- @client c The client that must be removed. -- @tparam client c The client that must be removed.
-- @function awful.client.focus.history.delete -- @function awful.client.focus.history.delete
function focus.history.delete(c) function focus.history.delete(c)
for k, v in ipairs(focus.history.list) do for k, v in ipairs(focus.history.list) do
@ -59,7 +59,7 @@ end
-- --
-- @function awful.client.focus.byidx -- @function awful.client.focus.byidx
-- @param i The index. -- @param i The index.
-- @client[opt] c The client. -- @tparam[opt] client c The client.
-- @request client activate client.focus.byidx granted When `awful.focus.byidx` -- @request client activate client.focus.byidx granted When `awful.focus.byidx`
-- is called. -- is called.
function focus.byidx(i, c) function focus.byidx(i, c)
@ -74,7 +74,7 @@ end
-- This usually means that desktop, dock and splash windows are -- This usually means that desktop, dock and splash windows are
-- not registered and cannot get focus. -- not registered and cannot get focus.
-- --
-- @client c A client. -- @tparam client c A client.
-- @return The same client if it's ok, nil otherwise. -- @return The same client if it's ok, nil otherwise.
-- @function awful.client.focus.filter -- @function awful.client.focus.filter
function focus.filter(c) function focus.filter(c)
@ -89,7 +89,7 @@ end
--- Update client focus history. --- Update client focus history.
-- --
-- @client c The client that has been focused. -- @tparam client c The client that has been focused.
-- @function awful.client.focus.history.add -- @function awful.client.focus.history.add
function focus.history.add(c) function focus.history.add(c)
-- Remove the client if its in stack -- Remove the client if its in stack
@ -159,7 +159,7 @@ end
-- --
-- @tparam string dir The direction, can be either -- @tparam string dir The direction, can be either
-- `"up"`, `"down"`, `"left"` or `"right"`. -- `"up"`, `"down"`, `"left"` or `"right"`.
-- @client[opt] c The client. -- @tparam[opt] client c The client.
-- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom) -- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
-- @function awful.client.focus.bydirection -- @function awful.client.focus.bydirection
-- @request client activate client.focus.bydirection granted When -- @request client activate client.focus.bydirection granted When
@ -186,7 +186,7 @@ end
--- Focus a client by the given direction. Moves across screens. --- Focus a client by the given direction. Moves across screens.
-- --
-- @param dir The direction, can be either "up", "down", "left" or "right". -- @param dir The direction, can be either "up", "down", "left" or "right".
-- @client[opt] c The client. -- @tparam[opt] client c The client.
-- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom) -- @tparam[opt=false] boolean stacked Use stacking order? (top to bottom)
-- @function awful.client.focus.global_bydirection -- @function awful.client.focus.global_bydirection
-- @request client activate client.focus.global_bydirection granted When -- @request client activate client.focus.global_bydirection granted When

View File

@ -19,7 +19,7 @@ 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.client.shape.get_transformed -- @function awful.client.shape.get_transformed
-- @client c The client whose shape should be retrieved -- @tparam client c The client whose shape should be retrieved
-- @tparam string shape_name Either "bounding" or "clip" -- @tparam string shape_name Either "bounding" or "clip"
function shape.get_transformed(c, shape_name) function shape.get_transformed(c, shape_name)
local border = shape_name == "bounding" and c.border_width or 0 local border = shape_name == "bounding" and c.border_width or 0
@ -91,7 +91,7 @@ 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.client.shape.update.all -- @function awful.client.shape.update.all
-- @client c The client to act on -- @tparam client c The client to act on
function shape.update.all(c) function shape.update.all(c)
shape.update.bounding(c) shape.update.bounding(c)
shape.update.clip(c) shape.update.clip(c)
@ -99,7 +99,7 @@ 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.client.shape.update.bounding -- @function awful.client.shape.update.bounding
-- @client c The client to act on -- @tparam client c The client to act on
function shape.update.bounding(c) function shape.update.bounding(c)
local res = shape.get_transformed(c, "bounding") local res = shape.get_transformed(c, "bounding")
c.shape_bounding = res and res._native c.shape_bounding = res and res._native
@ -111,7 +111,7 @@ 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.client.shape.update.clip -- @function awful.client.shape.update.clip
-- @client c The client to act on -- @tparam client c The client to act on
function shape.update.clip(c) function shape.update.clip(c)
local res = shape.get_transformed(c, "clip") local res = shape.get_transformed(c, "clip")
c.shape_clip = res and res._native c.shape_clip = res and res._native

View File

@ -60,7 +60,7 @@ end
--- Adds client to urgent stack. --- Adds client to urgent stack.
-- --
-- @function awful.urgent.add -- @function awful.urgent.add
-- @client c The client object. -- @tparam client c The client object.
-- @param prop The property which is updated. -- @param prop The property which is updated.
-- @request client border active granted When a client becomes active and is no -- @request client border active granted When a client becomes active and is no
-- longer urgent. -- longer urgent.
@ -91,7 +91,7 @@ end
--- Remove client from urgent stack. --- Remove client from urgent stack.
-- --
-- @function awful.urgent.delete -- @function awful.urgent.delete
-- @client c The client object. -- @tparam client c The client object.
function urgent.delete(c) function urgent.delete(c)
for k, cl in ipairs(data) do for k, cl in ipairs(data) do
if c == cl then if c == cl then

View File

@ -19,7 +19,7 @@ local tmux = {}
-- will show tmux hotkeys for any window that has 'tmux' in its title. -- will show tmux hotkeys for any window that has 'tmux' in its title.
-- If no rules are provided then tmux hotkeys will be shown always! -- If no rules are provided then tmux hotkeys will be shown always!
-- @function add_rules_for_terminal -- @function add_rules_for_terminal
-- @see awful.rules.rules -- @see ruled.client.rules
-- @tparam table rule Rules to match a window containing a tmux session. -- @tparam table rule Rules to match a window containing a tmux session.
function tmux.add_rules_for_terminal(rule) function tmux.add_rules_for_terminal(rule)
for group_name, group_data in pairs({ for group_name, group_data in pairs({

View File

@ -17,6 +17,7 @@ local wibox = require("wibox")
local beautiful = require("beautiful") local beautiful = require("beautiful")
local dpi = beautiful.xresources.apply_dpi local dpi = beautiful.xresources.apply_dpi
local matcher = require("gears.matcher")()
-- Stripped copy of this module https://github.com/copycat-killer/lain/blob/master/util/markup.lua: -- Stripped copy of this module https://github.com/copycat-killer/lain/blob/master/util/markup.lua:
local markup = {} local markup = {}
@ -522,7 +523,7 @@ function widget.new(args)
if group_name==group and ( if group_name==group and (
data.rule or data.rule_any or data.except or data.except_any data.rule or data.rule_any or data.except or data.except_any
) then ) then
if not c or not awful.rules.matches(c, { if not c or not matcher:matches_rule(c, {
rule=data.rule, rule=data.rule,
rule_any=data.rule_any, rule_any=data.rule_any,
except=data.except, except=data.except,

View File

@ -687,13 +687,13 @@ end
-- -- a particular rule. -- -- a particular rule.
-- -- Bound to a key, it can be used to select from dozens of terminals open on -- -- Bound to a key, it can be used to select from dozens of terminals open on
-- -- several tags. -- -- several tags.
-- -- When using @{awful.rules.match_any} instead of @{awful.rules.match}, -- -- When using @{ruled.client.match_any} instead of @{ruled.client.match},
-- -- a menu of clients with different classes could be build. -- -- a menu of clients with different classes could be build.
-- --
-- function terminal_menu () -- function terminal_menu ()
-- terms = {} -- terms = {}
-- for i, c in pairs(client.get()) do -- for i, c in pairs(client.get()) do
-- if awful.rules.match(c, {class = "URxvt"}) then -- if ruled.client.match(c, {class = "URxvt"}) then
-- terms[i] = -- terms[i] =
-- {c.name, -- {c.name,
-- function() -- function()

View File

@ -137,7 +137,7 @@ end
-- It is the default signal handler for `request::activate` on a `client`. -- It is the default signal handler for `request::activate` on a `client`.
-- --
-- @signalhandler awful.permissions.activate -- @signalhandler awful.permissions.activate
-- @client c A client to use -- @tparam client c A client to use
-- @tparam string context The context where this signal was used. -- @tparam string context The context where this signal was used.
-- @tparam[opt] table hints A table with additional hints: -- @tparam[opt] table hints A table with additional hints:
-- @tparam[opt=false] boolean hints.raise should the client be raised? -- @tparam[opt=false] boolean hints.raise should the client be raised?
@ -283,7 +283,7 @@ end
-- It is the default signal handler for `request::tag` on a `client`. -- It is the default signal handler for `request::tag` on a `client`.
-- --
-- @signalhandler awful.permissions.tag -- @signalhandler awful.permissions.tag
-- @client c A client to tag -- @tparam client c A client to tag
-- @tparam[opt] tag|boolean t A tag to use. If true, then the client is made sticky. -- @tparam[opt] tag|boolean t A tag to use. If true, then the client is made sticky.
-- @tparam[opt={}] table hints Extra information -- @tparam[opt={}] table hints Extra information
function permissions.tag(c, t, hints) --luacheck: no unused function permissions.tag(c, t, hints) --luacheck: no unused
@ -310,7 +310,7 @@ end
--- Handle client urgent request --- Handle client urgent request
-- @signalhandler awful.permissions.urgent -- @signalhandler awful.permissions.urgent
-- @client c A client -- @tparam client c A client
-- @tparam boolean urgent If the client should be urgent -- @tparam boolean urgent If the client should be urgent
function permissions.urgent(c, urgent) function permissions.urgent(c, urgent)
if c ~= client.focus and not aclient.property.get(c,"ignore_urgent") then if c ~= client.focus and not aclient.property.get(c,"ignore_urgent") then

View File

@ -849,7 +849,7 @@ end
--- Place the client so no part of it will be outside the screen (workarea). --- Place the client so no part of it will be outside the screen (workarea).
--@DOC_awful_placement_no_offscreen_EXAMPLE@ --@DOC_awful_placement_no_offscreen_EXAMPLE@
-- @client c The client. -- @tparam client c The client.
-- @tparam[opt={}] table args The arguments -- @tparam[opt={}] table args The arguments
-- @tparam[opt=client's screen] integer args.screen The screen. -- @tparam[opt=client's screen] integer args.screen The screen.
-- @treturn table The new client geometry. -- @treturn table The new client geometry.

View File

@ -1,668 +1,15 @@
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
--- Rules for clients. --- This module has been moved to `ruled.client`
--
-- This module applies @{rules} to clients during startup (via @{client.manage},
-- but its functions can be used for client matching in general.
--
-- All existing `client` properties can be used in rules. It is also possible
-- to add random properties that will be later accessible as `c.property_name`
-- (where `c` is a valid client object)
--
-- Syntax
-- ===
-- You should fill this table with your rule and properties to apply.
-- For example, if you want to set xterm maximized at startup, you can add:
--
-- { rule = { class = "xterm" },
-- properties = { maximized_vertical = true, maximized_horizontal = true } }
--
-- If you want to set mplayer floating at startup, you can add:
--
-- { rule = { name = "MPlayer" },
-- properties = { floating = true } }
--
-- If you want to put Firefox on a specific tag at startup, you can add:
--
-- { rule = { instance = "firefox" },
-- properties = { tag = mytagobject } }
--
-- Alternatively, you can specify the tag by name:
--
-- { rule = { instance = "firefox" },
-- properties = { tag = "3" } }
--
-- If you want to put Thunderbird on a specific screen at startup, use:
--
-- { rule = { instance = "Thunderbird" },
-- properties = { screen = 1 } }
--
-- Assuming that your X11 server supports the RandR extension, you can also specify
-- the screen by name:
--
-- { rule = { instance = "Thunderbird" },
-- properties = { screen = "VGA1" } }
--
-- If you want to put Emacs on a specific tag at startup, and immediately switch
-- to that tag you can add:
--
-- { rule = { class = "Emacs" },
-- properties = { tag = mytagobject, switchtotag = true } }
--
-- If you want to apply a custom callback to execute when a rule matched,
-- for example to pause playing music from mpd when you start dosbox, you
-- can add:
--
-- { rule = { class = "dosbox" },
-- callback = function(c)
-- awful.spawn('mpc pause')
-- end }
--
-- Note that all "rule" entries need to match. If any of the entry does not
-- match, the rule won't be applied.
--
-- If a client matches multiple rules, they are applied in the order they are
-- put in this global rules table. If the value of a rule is a string, then the
-- match function is used to determine if the client matches the rule.
--
-- If the value of a property is a function, that function gets called and
-- function's return value is used for the property.
--
-- To match multiple clients to a rule one need to use slightly different
-- syntax:
--
-- { rule_any = { class = { "MPlayer", "Nitrogen" }, instance = { "xterm" } },
-- properties = { floating = true } }
--
-- To match multiple clients with an exception one can couple `rules.except` or
-- `rules.except_any` with the rules:
--
-- { rule = { class = "Firefox" },
-- except = { instance = "Navigator" },
-- properties = {floating = true},
-- },
--
-- { rule_any = { class = { "Pidgin", "Xchat" } },
-- except_any = { role = { "conversation" } },
-- properties = { tag = "1" }
-- }
--
-- { rule = {},
-- except_any = { class = { "Firefox", "Vim" } },
-- properties = { floating = true }
-- }
--
-- Applicable client properties
-- ===
--
-- The table below holds the list of default client properties along with
-- some extra properties that are specific to the rules. Note that any property
-- can be set in the rules and interpreted by user provided code. This table
-- only represent those offered by default.
--
--@DOC_rules_index_COMMON@
-- --
-- @author Julien Danjou &lt;julien@danjou.info&gt; -- @author Julien Danjou &lt;julien@danjou.info&gt;
-- @copyright 2009 Julien Danjou -- @copyright 2009 Julien Danjou
-- @module awful.rules -- @module awful.rules
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
-- Grab environment we need
local client = client
local awesome = awesome
local screen = screen
local table = table
local type = type
local ipairs = ipairs
local pairs = pairs
local atag = require("awful.tag")
local gtable = require("gears.table")
local a_place = require("awful.placement")
local protected_call = require("gears.protected_call")
local aspawn = require("awful.spawn")
local gdebug = require("gears.debug") local gdebug = require("gears.debug")
local gmatcher = require("gears.matcher")
local amouse = require("awful.mouse")
local akeyboard = require("awful.keyboard")
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
local rules = {} return gdebug.deprecate_class(
require("ruled.client"),
--- This is the global rules table. "awful.rules",
rules.rules = {} "ruled.client",
{ deprecated_in = 5}
local crules = gmatcher() )
--- Check if a client matches a rule.
-- @client c The client.
-- @tab rule The rule to check.
-- @treturn bool True if it matches, false otherwise.
-- @staticfct awful.rules.match
function rules.match(c, rule)
return crules:_match(c, rule)
end
--- Check if a client matches any part of a rule.
-- @client c The client.
-- @tab rule The rule to check.
-- @treturn bool True if at least one rule is matched, false otherwise.
-- @staticfct awful.rules.match_any
function rules.match_any(c, rule)
return crules:_match_any(c, rule)
end
--- Does a given rule entry match a client?
-- @client c The client.
-- @tab entry Rule entry (with keys `rule`, `rule_any`, `except` and/or
-- `except_any`).
-- @treturn bool
-- @staticfct awful.rules.matches
function rules.matches(c, entry)
return crules:matches_rule(c, entry)
end
--- Get list of matching rules for a client.
-- @client c The client.
-- @tab _rules The rules to check. List with "rule", "rule_any", "except" and
-- "except_any" keys.
-- @treturn table The list of matched rules.
-- @staticfct awful.rules.matching_rules
function rules.matching_rules(c, _rules)
return crules:matching_rules(c, _rules)
end
--- Check if a client matches a given set of rules.
-- @client c The client.
-- @tab _rules The rules to check. List of tables with `rule`, `rule_any`,
-- `except` and `except_any` keys.
-- @treturn bool True if at least one rule is matched, false otherwise.
-- @staticfct awful.rules.matches_list
function rules.matches_list(c, _rules)
return crules:matches_rules(c, _rules)
end
--- Remove a source.
-- @tparam string name The source name.
-- @treturn boolean If the source was removed.
-- @staticfct awful.rules.remove_rule_source
function rules.remove_rule_source(name)
return crules:remove_matching_source(name)
end
--- Apply awful.rules.rules to a client.
-- @client c The client.
-- @staticfct awful.rules.apply
function rules.apply(c)
return crules:apply(c)
end
--- Add a new rule source.
--
-- A rule source is a provider called when a client is managed (started). It
-- allows to configure the client by providing properties that should be applied.
-- By default, Awesome provides 2 sources:
--
-- * `awful.rules`: A declarative matcher
-- * `awful.spawn`: Launch clients with pre-defined properties
--
-- It is possible to register new callbacks to modify the properties table
-- before it is applied. Each provider is executed sequentially and modifies the
-- same table. If the first provider set a property, then the second can
-- override it, then the third, etc. Once the providers are exhausted, the
-- properties are applied on the client.
--
-- It is important to note that properties themselves have their own
-- dependencies. For example, a `tag` property implies a `screen`. Therefor, if
-- a `screen` is already specified, then it will be ignored when the rule is
-- executed. Properties also have their own priorities. For example, the
-- `titlebar` and `border_width` need to be applied before the `x` and `y`
-- positions are set. Otherwise, it will be off or the client will shift
-- upward everytime Awesome is restarted. A rule source *cannot* change this.
-- It is up to the callback to be aware of the dependencies and avoid to
-- introduce issues. For example, if the source wants to set a `screen`, it has
-- to check if the `tag`, `tags` or `new_tag` are on that `screen` or remove
-- those properties. Otherwise, they will be ignored once the rule is applied.
--
-- @tparam string name The provider name. It must be unique.
-- @tparam function callback The callback that is called to produce properties.
-- @tparam client callback.c The client
-- @tparam table callback.properties The current properties. The callback should
-- add to and overwrite properties in this table
-- @tparam table callback.callbacks A table of all callbacks scheduled to be
-- executed after the main properties are applied.
-- @tparam[opt={}] table depends_on A list of names of sources this source depends on
-- (sources that must be executed *before* `name`.
-- @tparam[opt={}] table precede A list of names of sources this source have a
-- priority over.
-- @treturn boolean Returns false if a dependency conflict was found.
-- @staticfct awful.rules.add_rule_source
function rules.add_rule_source(name, cb, ...)
local function callback(_, ...)
cb(...)
end
return crules:add_matching_function(name, callback, ...)
end
-- Add the rules properties
local function apply_awful_rules(c, props, callbacks)
for _, entry in ipairs(rules.matching_rules(c, rules.rules)) do
gtable.crush(props,entry.properties or {})
if entry.callback then
table.insert(callbacks, entry.callback)
end
end
end
--- The default `awful.rules` source.
--
-- **Has priority over:**
--
-- *nothing*
--
-- @rulesources awful.rules
rules.add_rule_source("awful.rules", apply_awful_rules, {"awful.spawn"}, {})
-- Add startup_id overridden properties
local function apply_spawn_rules(c, props, callbacks)
if c.startup_id and aspawn.snid_buffer[c.startup_id] then
local snprops, sncb = unpack(aspawn.snid_buffer[c.startup_id])
-- The SNID tag(s) always have precedence over the rules one(s)
if snprops.tag or snprops.tags or snprops.new_tag then
props.tag, props.tags, props.new_tag = nil, nil, nil
end
gtable.crush(props, snprops)
gtable.merge(callbacks, sncb)
end
end
--- The rule source for clients spawned by `awful.spawn`.
--
-- **Has priority over:**
--
-- * `awful.rules`
--
-- @rulesources awful.spawn
rules.add_rule_source("awful.spawn", apply_spawn_rules, {}, {"awful.rules"})
local function apply_singleton_rules(c, props, callbacks)
local persis_id, info = c.single_instance_id, nil
-- This is a persistent property set by `awful.spawn`
if awesome.startup and persis_id then
info = aspawn.single_instance_manager.by_uid[persis_id]
elseif c.startup_id then
info = aspawn.single_instance_manager.by_snid[c.startup_id]
aspawn.single_instance_manager.by_snid[c.startup_id] = nil
elseif aspawn.single_instance_manager.by_pid[c.pid] then
info = aspawn.single_instance_manager.by_pid[c.pid].matcher(c) and
aspawn.single_instance_manager.by_pid[c.pid] or nil
end
if info then
c.single_instance_id = info.hash
if info.rules then
gtable.crush(props, info.rules)
end
table.insert(callbacks, info.callback)
table.insert(info.instances, c)
-- Prevent apps with multiple clients from re-using this too often in
-- the first 30 seconds before the PID is cleared.
aspawn.single_instance_manager.by_pid[c.pid] = nil
end
end
--- The rule source for clients spawned by `awful.spawn.once` and `single_instance`.
--
-- **Has priority over:**
--
-- * `awful.rules`
--
-- **Depends on:**
--
-- * `awful.spawn`
--
-- @rulesources awful.spawn_once
rules.add_rule_source("awful.spawn_once", apply_singleton_rules, {"awful.spawn"}, {"awful.rules"})
local function add_to_tag(c, t)
if not t then return end
local tags = c:tags()
table.insert(tags, t)
c:tags(tags)
end
--- Extra rules properties.
--
-- These properties are used in the rules only and are not sent to the client
-- afterward.
--
-- To add a new properties, just do:
--
-- function awful.rules.extra_properties.my_new_property(c, value, props)
-- -- do something
-- end
--
-- By default, the table has the following functions:
--
-- * geometry
-- * placement
--
-- @tfield table awful.rules.extra_properties
rules.extra_properties = {}
--- Extra high priority properties.
--
-- Some properties, such as anything related to tags, geometry or focus, will
-- cause a race condition if set in the main property section. This is why
-- they have a section for them.
--
-- To add a new properties, just do:
--
-- function awful.rules.high_priority_properties.my_new_property(c, value, props)
-- -- do something
-- end
--
-- By default, the table has the following functions:
--
-- * tag
-- * new_tag
--
-- @tfield table awful.rules.high_priority_properties
rules.high_priority_properties = {}
--- Delayed properties.
-- Properties applied after all other categories.
-- @tfield table awful.rules.delayed_properties
-- By default, the table has the following functions:
--
-- * switch_to_tags
rules.delayed_properties = {}
local force_ignore = {
titlebars_enabled=true, focus=true, screen=true, x=true,
y=true, width=true, height=true, geometry=true,placement=true,
border_width=true,floating=true,size_hints_honor=true
}
function rules.high_priority_properties.tag(c, value, props)
if value then
if type(value) == "string" then
local name = value
value = atag.find_by_name(c.screen, value)
if not value and not props.screen then
value = atag.find_by_name(nil, name)
end
if not value then
require("gears.debug").print_error("awful.rules-rule specified "
.. "tag = '" .. name .. "', but no such tag exists")
return
end
end
-- In case the tag has been forced to another screen, move the client
if c.screen ~= value.screen then
c.screen = value.screen
props.screen = value.screen -- In case another rule query it
end
c:tags{ value }
end
end
function rules.delayed_properties.switch_to_tags(c, value)
if not value then return end
atag.viewmore(c:tags(), c.screen)
end
function rules.delayed_properties.switchtotag(c, value)
gdebug.deprecate("Use switch_to_tags instead of switchtotag", {deprecated_in=5})
rules.delayed_properties.switch_to_tags(c, value)
end
function rules.extra_properties.geometry(c, _, props)
local cur_geo = c:geometry()
local new_geo = type(props.geometry) == "function"
and props.geometry(c, props) or props.geometry or {}
for _, v in ipairs {"x", "y", "width", "height"} do
new_geo[v] = type(props[v]) == "function" and props[v](c, props)
or props[v] or new_geo[v] or cur_geo[v]
end
c:geometry(new_geo) --TODO use request::geometry
end
function rules.high_priority_properties.new_tag(c, value, props)
local ty = type(value)
local t = nil
if ty == "boolean" then
-- Create a new tag named after the client class
t = atag.add(c.class or "N/A", {screen=c.screen, volatile=true})
elseif ty == "string" then
-- Create a tag named after "value"
t = atag.add(value, {screen=c.screen, volatile=true})
elseif ty == "table" then
-- Assume a table of tags properties. Set the right screen, but
-- avoid editing the original table
local values = value.screen and value or gtable.clone(value)
values.screen = values.screen or c.screen
t = atag.add(value.name or c.class or "N/A", values)
-- In case the tag has been forced to another screen, move the client
c.screen = t.screen
props.screen = t.screen -- In case another rule query it
else
assert(false)
end
add_to_tag(c, t)
return t
end
function rules.extra_properties.placement(c, value, props)
-- Avoid problems
if awesome.startup and
(c.size_hints.user_position or c.size_hints.program_position) then
return
end
local ty = type(value)
local args = {
honor_workarea = props.honor_workarea ~= false,
honor_padding = props.honor_padding ~= false
}
if ty == "function" or (ty == "table" and
getmetatable(value) and getmetatable(value).__call
) then
value(c, args)
elseif ty == "string" and a_place[value] then
a_place[value](c, args)
end
end
function rules.high_priority_properties.tags(c, value, props)
local current = c:tags()
local tags, s = {}, nil
for _, t in ipairs(value) do
if type(t) == "string" then
t = atag.find_by_name(c.screen, t)
end
if t and ((not s) or t.screen == s) then
table.insert(tags, t)
s = s or t.screen
end
end
if s and s ~= c.screen then
c.screen = s
props.screen = s -- In case another rule query it
end
if #current == 0 or (value[1] and value[1].screen ~= current[1].screen) then
c:tags(tags)
else
c:tags(gtable.merge(current, tags))
end
end
--- Apply properties and callbacks to a client.
-- @client c The client.
-- @tab props Properties to apply.
-- @tab[opt] callbacks Callbacks to apply.
-- @staticfct awful.rules.execute
-- @request client titlebars rules granted The `titlebars_enabled` is set in the
-- rules.
crules._execute = function(_, c, props, callbacks)
-- Set the default buttons and keys
local btns = amouse._get_client_mousebindings()
local keys = akeyboard._get_client_keybindings()
props.keys = props.keys or keys
props.buttons = props.buttons or btns
-- Border width will also cause geometry related properties to fail
if props.border_width then
c.border_width = type(props.border_width) == "function" and
props.border_width(c, props) or props.border_width
end
-- This has to be done first, as it will impact geometry related props.
if props.titlebars_enabled and (type(props.titlebars_enabled) ~= "function"
or props.titlebars_enabled(c,props)) then
c:emit_signal("request::titlebars", "rules", {properties=props})
c._request_titlebars_called = true
end
-- Size hints will be re-applied when setting width/height unless it is
-- disabled first
if props.size_hints_honor ~= nil then
c.size_hints_honor = type(props.size_hints_honor) == "function" and props.size_hints_honor(c,props)
or props.size_hints_honor
end
-- Geometry will only work if floating is true, otherwise the "saved"
-- geometry will be restored.
if props.floating ~= nil then
c.floating = type(props.floating) == "function" and props.floating(c,props)
or props.floating
end
-- Before requesting a tag, make sure the screen is right
if props.screen then
c.screen = type(props.screen) == "function" and screen[props.screen(c,props)]
or screen[props.screen]
end
-- Some properties need to be handled first. For example, many properties
-- require that the client is tagged, this isn't yet the case.
for prop, handler in pairs(rules.high_priority_properties) do
local value = props[prop]
if value ~= nil then
if type(value) == "function" then
value = value(c, props)
end
handler(c, value, props)
end
end
-- Make sure the tag is selected before the main rules are called.
-- Otherwise properties like "urgent" or "focus" may fail (if they were
-- overridden by other callbacks).
-- Previously this was done in a second client.manage callback, but caused
-- a race condition where the order of modules being loaded would change
-- the outcome.
c:emit_signal("request::tag", nil, {reason="rules"})
-- By default, rc.lua uses no_overlap+no_offscreen placement. This has to
-- be executed before x/y/width/height/geometry as it would otherwise
-- always override the user specified position with the default rule.
if props.placement then
-- It may be a function, so this one doesn't execute it like others
rules.extra_properties.placement(c, props.placement, props)
end
-- Handle the geometry (since tags and screen are set).
if props.height or props.width or props.x or props.y or props.geometry then
rules.extra_properties.geometry(c, nil, props)
end
-- Apply the remaining properties (after known race conditions are handled).
for property, value in pairs(props) do
if property ~= "focus" and property ~= "shape" and type(value) == "function" then
value = value(c, props)
end
local ignore = rules.high_priority_properties[property] or
rules.delayed_properties[property] or force_ignore[property]
if not ignore then
if rules.extra_properties[property] then
rules.extra_properties[property](c, value, props)
elseif type(c[property]) == "function" then
c[property](c, value)
else
c[property] = value
end
end
end
-- Apply all callbacks.
if callbacks then
for _, callback in pairs(callbacks) do
protected_call(callback, c)
end
end
-- Apply the delayed properties
for prop, handler in pairs(rules.delayed_properties) do
if not force_ignore[prop] then
local value = props[prop]
if value ~= nil then
if type(value) == "function" then
value = value(c, props)
end
handler(c, value, props)
end
end
end
-- Do this at last so we do not erase things done by the focus signal.
if props.focus and (type(props.focus) ~= "function" or props.focus(c)) then
c:emit_signal('request::activate', "rules", {raise=not awesome.startup})
end
end
function rules.execute(...) crules:_execute(...) end
-- TODO v5 deprecate this
function rules.completed_with_payload_callback(c, props, callbacks)
rules.execute(c, props, callbacks)
end
client.connect_signal("request::manage", rules.apply)
--@DOC_rule_COMMON@
return rules
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

@ -88,7 +88,7 @@ end
-- This moves the mouse pointer to the last known position on the new screen, -- This moves the mouse pointer to the last known position on the new screen,
-- or keeps its position relative to the current focused screen. -- or keeps its position relative to the current focused screen.
-- @staticfct awful.screen.focus -- @staticfct awful.screen.focus
-- @screen _screen Screen number (defaults / falls back to mouse.screen). -- @tparam screen _screen Screen number (defaults / falls back to mouse.screen).
-- @request client activate screen.focus granted The most recent focused client -- @request client activate screen.focus granted The most recent focused client
-- for this screen should be re-activated. -- for this screen should be re-activated.
function screen.focus(_screen) function screen.focus(_screen)
@ -361,9 +361,9 @@ end
-- @tparam[opt] int|table args.margins Apply some margins on the output. -- @tparam[opt] int|table args.margins Apply some margins on the output.
-- This can either be a number or a table with *left*, *right*, *top* -- This can either be a number or a table with *left*, *right*, *top*
-- and *bottom* keys. -- and *bottom* keys.
-- @tag[opt] args.tag Use this tag's screen. -- @tparam[opt] tag args.tag Use this tag's screen.
-- @tparam[opt] drawable args.parent A parent drawable to use as base geometry. -- @tparam[opt] drawable args.parent A parent drawable to use as base geometry.
-- @tab[opt] args.bounding_rect A bounding rectangle. This parameter is -- @tparam[opt] table args.bounding_rect A bounding rectangle. This parameter is
-- incompatible with `honor_workarea`. -- incompatible with `honor_workarea`.
-- @treturn table A table with *x*, *y*, *width* and *height*. -- @treturn table A table with *x*, *y*, *width* and *height*.
-- @usage local geo = screen:get_bounding_geometry { -- @usage local geo = screen:get_bounding_geometry {
@ -516,7 +516,7 @@ end
-- --
-- @staticfct awful.screen.connect_for_each_screen -- @staticfct awful.screen.connect_for_each_screen
-- @tparam function func The function to call. -- @tparam function func The function to call.
-- @screen func.screen The screen. -- @tparam screen func.screen The screen.
function screen.connect_for_each_screen(func) function screen.connect_for_each_screen(func)
for s in capi.screen do for s in capi.screen do
func(s) func(s)

View File

@ -185,7 +185,7 @@
-- --
-- This should (if the program correctly implements the protocol) result in -- This should (if the program correctly implements the protocol) result in
-- `c.startup_id` to at least match `something`. -- `c.startup_id` to at least match `something`.
-- This identifier can then be used in `awful.rules` to configure the client. -- This identifier can then be used in `ruled.client` to configure the client.
-- --
-- Awesome can automatically set the `DESKTOP_STARTUP_ID` variable. This is used -- Awesome can automatically set the `DESKTOP_STARTUP_ID` variable. This is used
-- by `awful.spawn` to specify additional rules for the startup. For example: -- by `awful.spawn` to specify additional rules for the startup. For example:
@ -206,7 +206,7 @@
-- })' -- })'
-- --
-- This table contains the client properties that are valid when used the -- This table contains the client properties that are valid when used the
-- `sn_rules` or `prop` function argument. They are the same as in `awful.rules`. -- `sn_rules` or `prop` function argument. They are the same as in `ruled.client`.
-- --
--@DOC_rules_index_COMMON@ --@DOC_rules_index_COMMON@
-- --
@ -334,7 +334,7 @@ end
-- Applying properties or running a callback requires the program/client to -- Applying properties or running a callback requires the program/client to
-- support startup notifications. -- support startup notifications.
-- --
-- See `awful.rules.execute` for more details about the format of `sn_rules`. -- See `ruled.client.execute` for more details about the format of `sn_rules`.
-- --
-- @tparam string|table cmd The command. -- @tparam string|table cmd The command.
-- @tparam[opt=true] table|boolean sn_rules A table of properties to be applied -- @tparam[opt=true] table|boolean sn_rules A table of properties to be applied
@ -374,7 +374,7 @@ end
--- Spawn a program and asynchronously capture its output line by line. --- Spawn a program and asynchronously capture its output line by line.
-- @tparam string|table cmd The command. -- @tparam string|table cmd The command.
-- @tab callbacks Table containing callbacks that should be invoked on -- @tparam table callbacks Table containing callbacks that should be invoked on
-- various conditions. -- various conditions.
-- @tparam[opt] function callbacks.stdout Function that is called with each -- @tparam[opt] function callbacks.stdout Function that is called with each
-- line of output on stdout, e.g. `stdout(line)`. -- line of output on stdout, e.g. `stdout(line)`.
@ -428,7 +428,7 @@ end
--- Asynchronously spawn a program and capture its output. --- Asynchronously spawn a program and capture its output.
-- (wraps `spawn.with_line_callback`). -- (wraps `spawn.with_line_callback`).
-- @tparam string|table cmd The command. -- @tparam string|table cmd The command.
-- @tab callback Function with the following arguments -- @tparam table callback Function with the following arguments
-- @tparam string callback.stdout Output on stdout. -- @tparam string callback.stdout Output on stdout.
-- @tparam string callback.stderr Output on stderr. -- @tparam string callback.stderr Output on stderr.
-- @tparam string callback.exitreason Exit reason ("exit" or "signal"). -- @tparam string callback.exitreason Exit reason ("exit" or "signal").
@ -479,7 +479,7 @@ end
--- Call `spawn.easy_async` with a shell. --- Call `spawn.easy_async` with a shell.
-- This calls `cmd` with `$SHELL -c` (via `awful.util.shell`). -- This calls `cmd` with `$SHELL -c` (via `awful.util.shell`).
-- @tparam string cmd The command. -- @tparam string cmd The command.
-- @tab callback Function with the following arguments -- @tparam table callback Function with the following arguments
-- @tparam string callback.stdout Output on stdout. -- @tparam string callback.stdout Output on stdout.
-- @tparam string callback.stderr Output on stderr. -- @tparam string callback.stderr Output on stderr.
-- @tparam string callback.exitreason Exit reason ("exit" or "signal"). -- @tparam string callback.exitreason Exit reason ("exit" or "signal").
@ -636,7 +636,7 @@ end
-- command and rules, you need to specify an UID or only the first one will be -- command and rules, you need to specify an UID or only the first one will be
-- executed. -- executed.
-- --
-- The `rules` are standard `awful.rules`. -- The `rules` are standard `ruled.client`.
-- --
-- This function depends on the startup notification protocol to be correctly -- This function depends on the startup notification protocol to be correctly
-- implemented by the command. See `client.startup_id` for more information. -- implemented by the command. See `client.startup_id` for more information.
@ -649,7 +649,7 @@ end
-- @tparam[opt] string unique_id A string to identify the client so it isn't executed -- @tparam[opt] string unique_id A string to identify the client so it isn't executed
-- multiple time. -- multiple time.
-- @tparam[opt] function callback A callback function when the client is created. -- @tparam[opt] function callback A callback function when the client is created.
-- @see awful.rules -- @see ruled.client
-- @staticfct awful.spawn.once -- @staticfct awful.spawn.once
function spawn.once(cmd, rules, matcher, unique_id, callback) function spawn.once(cmd, rules, matcher, unique_id, callback)
local hash = unique_id or hash_command(cmd, rules) local hash = unique_id or hash_command(cmd, rules)
@ -666,7 +666,7 @@ end
-- This is like `awful.spawn.once`, but will spawn new instances if the previous -- This is like `awful.spawn.once`, but will spawn new instances if the previous
-- has finished. -- has finished.
-- --
-- The `rules` are standard `awful.rules`. -- The `rules` are standard `ruled.client`.
-- --
-- This function depends on the startup notification protocol to be correctly -- This function depends on the startup notification protocol to be correctly
-- implemented by the command. See `client.startup_id` for more information. -- implemented by the command. See `client.startup_id` for more information.
@ -682,7 +682,7 @@ end
-- @tparam[opt] string unique_id A string to identify the client so it isn't executed -- @tparam[opt] string unique_id A string to identify the client so it isn't executed
-- multiple time. -- multiple time.
-- @tparam[opt] function callback A callback function when the client is created. -- @tparam[opt] function callback A callback function when the client is created.
-- @see awful.rules -- @see ruled.client
-- @staticfct awful.spawn.single_instance -- @staticfct awful.spawn.single_instance
function spawn.single_instance(cmd, rules, matcher, unique_id, callback) function spawn.single_instance(cmd, rules, matcher, unique_id, callback)
local hash = unique_id or hash_command(cmd, rules) local hash = unique_id or hash_command(cmd, rules)
@ -709,7 +709,7 @@ local raise_rules = {focus = true, switch_to_tags = true, raise = true}
-- @tparam[opt] string unique_id A string to identify the client so it isn't executed -- @tparam[opt] string unique_id A string to identify the client so it isn't executed
-- multiple time. -- multiple time.
-- @tparam[opt] function callback A callback function when the client is created. -- @tparam[opt] function callback A callback function when the client is created.
-- @see awful.rules -- @see ruled.client
-- @treturn client The client if it already exists. -- @treturn client The client if it already exists.
-- @staticfct awful.spawn.raise_or_spawn -- @staticfct awful.spawn.raise_or_spawn
-- @request client activate spawn.raise_or_spawn granted Activate a client when -- @request client activate spawn.raise_or_spawn granted Activate a client when

View File

@ -1670,7 +1670,7 @@ end
-- future. When a tag is detached from the screen, its signal is removed. -- future. When a tag is detached from the screen, its signal is removed.
-- --
-- @staticfct awful.tag.attached_connect_signal -- @staticfct awful.tag.attached_connect_signal
-- @screen screen The screen concerned, or all if nil. -- @tparam screen screen The screen concerned, or all if nil.
-- @tparam[opt] string signal The signal name. -- @tparam[opt] string signal The signal name.
-- @tparam[opt] function Callback -- @tparam[opt] function Callback
function tag.attached_connect_signal(screen, ...) function tag.attached_connect_signal(screen, ...)
@ -1684,8 +1684,8 @@ end
-- Register standard signals. -- Register standard signals.
capi.client.connect_signal("property::screen", function(c) capi.client.connect_signal("property::screen", function(c)
-- First, the delayed timer is necessary to avoid a race condition with -- First, the delayed timer is necessary to avoid a race condition with
-- awful.rules. It is also messing up the tags before the user have a chance -- `ruled.client`. It is also messing up the tags before the user have a
-- to set them manually. -- chance to set them manually.
timer.delayed_call(function() timer.delayed_call(function()
if not c.valid then if not c.valid then
return return

View File

@ -17,7 +17,7 @@ local base = require("wibox.widget.base")
local common = {} local common = {}
--- Common method to create buttons. --- Common method to create buttons.
-- @tab buttons -- @tparam table buttons
-- @param object -- @param object
-- @treturn table -- @treturn table
function common.create_buttons(buttons, object) function common.create_buttons(buttons, object)
@ -112,12 +112,12 @@ end
--- Common update method. --- Common update method.
-- @param w The widget. -- @param w The widget.
-- @tab buttons -- @tparam table buttons
-- @func label Function to generate label parameters from an object. -- @func label Function to generate label parameters from an object.
-- The function gets passed an object from `objects`, and -- The function gets passed an object from `objects`, and
-- has to return `text`, `bg`, `bg_image`, `icon`. -- has to return `text`, `bg`, `bg_image`, `icon`.
-- @tab data Current data/cache, indexed by objects. -- @tparam table data Current data/cache, indexed by objects.
-- @tab objects Objects to be displayed / updated. -- @tparam table objects Objects to be displayed / updated.
-- @tparam[opt={}] table args -- @tparam[opt={}] table args
function common.list_update(w, buttons, label, data, objects, args) function common.list_update(w, buttons, label, data, objects, args)
-- update the widgets, creating them if needed -- update the widgets, creating them if needed

View File

@ -130,12 +130,23 @@ end
--- Create a class proxy with deprecation messages. --- Create a class proxy with deprecation messages.
-- This is useful when a class has moved somewhere else. -- This is useful when a class has moved somewhere else.
-- @tparam table fallback The new class -- @tparam table fallback The new class.
-- @tparam string old_name The old class name -- @tparam string old_name The old class name.
-- @tparam string new_name The new class name -- @tparam string new_name The new class name.
-- @tparam[opt={}] args The name.
-- @tparam[opt] number args.deprecated_in The version which deprecated this
-- class.
-- @treturn table A proxy class. -- @treturn table A proxy class.
-- @staticfct gears.debug.deprecate_class -- @staticfct gears.debug.deprecate_class
function debug.deprecate_class(fallback, old_name, new_name) function debug.deprecate_class(fallback, old_name, new_name, args)
args = args or {}
if args.deprecated_in then
local dep_ver = "v" .. tostring(args.deprecated_in)
if awesome.version < dep_ver then
return fallback
end
end
local message = old_name.." has been renamed to "..new_name local message = old_name.." has been renamed to "..new_name
local function call(_,...) local function call(_,...)

View File

@ -3,7 +3,7 @@
-- Sources -- Sources
-- ======= -- =======
-- --
-- This module holds the business logic used by `awful.rules`. It provides an -- This module holds the business logic used by `ruled.client`. It provides an
-- object on which one can add sets of rules or, alternatively, functions. -- object on which one can add sets of rules or, alternatively, functions.
-- In this module, the sets of rules or custom functions are called sources. -- In this module, the sets of rules or custom functions are called sources.
-- --
@ -29,11 +29,11 @@
-- --
-- @DOC_text_gears_matcher_types_EXAMPLE@ -- @DOC_text_gears_matcher_types_EXAMPLE@
-- --
-- More examples are available in `awful.rules`. -- More examples are available in `ruled.client`.
-- --
-- @author Julien Danjou &lt;julien@danjou.info&gt; -- @author Julien Danjou &lt;julien@danjou.info&gt;
-- @copyright 2009 Julien Danjou -- @copyright 2009 Julien Danjou
-- @see awful.rules -- @see ruled.client
-- @module gears.matcher -- @module gears.matcher
local gtable = require("gears.table") local gtable = require("gears.table")
@ -445,7 +445,7 @@ function matcher:remove_matching_source(name)
return false return false
end end
--- Apply awful.rules.rules to an object. --- Apply ruled.client.rules to an object.
-- --
-- Calling this will apply all properties provided by the matching functions -- Calling this will apply all properties provided by the matching functions
-- and rules. -- and rules.

View File

@ -611,7 +611,7 @@ end
-- --
-- local notif = naughty.notification(args) -- local notif = naughty.notification(args)
-- --
-- @tab args The argument table containing any of the arguments below. -- @tparam table args The argument table containing any of the arguments below.
-- @string[opt=""] args.text Text of the notification. -- @string[opt=""] args.text Text of the notification.
-- @string[opt] args.title Title of the notification. -- @string[opt] args.title Title of the notification.
-- @int[opt=5] args.timeout Time in seconds after which popup expires. -- @int[opt=5] args.timeout Time in seconds after which popup expires.

View File

@ -757,7 +757,7 @@ end
--- Create a notification. --- Create a notification.
-- --
-- @tab args The argument table containing any of the arguments below. -- @tparam table args The argument table containing any of the arguments below.
-- @string[opt=""] args.text Text of the notification. -- @string[opt=""] args.text Text of the notification.
-- @string[opt] args.title Title of the notification. -- @string[opt] args.title Title of the notification.
-- @int[opt=5] args.timeout Time in seconds after which popup expires. -- @int[opt=5] args.timeout Time in seconds after which popup expires.

717
lib/ruled/client.lua Normal file
View File

@ -0,0 +1,717 @@
---------------------------------------------------------------------------
--- Rules for clients.
--
-- This module applies @{rules} to clients during startup (via @{client.manage},
-- but its functions can be used for client matching in general.
--
-- All existing `client` properties can be used in rules. It is also possible
-- to add random properties that will be later accessible as `c.property_name`
-- (where `c` is a valid client object)
--
-- Syntax
-- ===
-- You should fill this table with your rule and properties to apply.
-- For example, if you want to set xterm maximized at startup, you can add:
--
-- @DOC_sequences_client_rules_maximized_EXAMPLE@
--
-- If you want to set mplayer floating at startup, you can add:
--
-- @DOC_sequences_client_rules_floating_EXAMPLE@
--
-- If you want to put Firefox on a specific tag at startup. It is possible to
-- specify the tag with it's object or by name:
--
-- @DOC_sequences_client_rules_tags_EXAMPLE@
--
-- If you want to put Thunderbird on a specific screen at startup, use:
--
-- @DOC_sequences_client_rules_screens_EXAMPLE@
--
-- If you want to put Emacs on a specific tag at startup, and immediately switch
-- to that tag you can add:
--
-- @DOC_sequences_client_rules_switch_to_tags_EXAMPLE@
--
-- If you want to apply a custom callback to execute when a rule matched,
-- for example to pause playing music from mpd when you start dosbox, you
-- can add:
--
-- { rule = { class = "dosbox" },
-- callback = function(c)
-- awful.spawn('mpc pause')
-- end }
--
-- Note that all "rule" entries need to match. If any of the entry does not
-- match, the rule won't be applied.
--
-- If a client matches multiple rules, they are applied in the order they are
-- put in this global rules table. If the value of a rule is a string, then the
-- match function is used to determine if the client matches the rule.
--
-- If the value of a property is a function, that function gets called and
-- function's return value is used for the property.
--
-- To match multiple clients to a rule one need to use slightly different
-- syntax:
--
-- { rule_any = { class = { "MPlayer", "Nitrogen" }, instance = { "xterm" } },
-- properties = { floating = true } }
--
-- To match multiple clients with an exception one can couple `rules.except` or
-- `rules.except_any` with the rules:
--
-- { rule = { class = "Firefox" },
-- except = { instance = "Navigator" },
-- properties = {floating = true},
-- },
--
-- { rule_any = { class = { "Pidgin", "Xchat" } },
-- except_any = { role = { "conversation" } },
-- properties = { tag = "1" }
-- }
--
-- { rule = {},
-- except_any = { class = { "Firefox", "Vim" } },
-- properties = { floating = true }
-- }
--
-- Note that all rules can have an `id` field. This can then be used to find
-- the rule. For example, it can be used in `remove_rule` instead of the table.
--
-- Flowchart
-- =========
--
-- ![Client rules](../images/client_rules.svg)
--
-- Applicable client properties
-- ===
--
-- The table below holds the list of default client properties along with
-- some extra properties that are specific to the rules. Note that any property
-- can be set in the rules and interpreted by user provided code. This table
-- only represent those offered by default.
--
--@DOC_client_rules_index_COMMON@
--
-- @author Julien Danjou &lt;julien@danjou.info&gt;
-- @copyright 2009 Julien Danjou
-- @ruleslib ruled.client
---------------------------------------------------------------------------
-- Grab environment we need
local capi = {client = client, awesome = awesome, screen = screen, tag = tag}
local table = table
local type = type
local ipairs = ipairs
local pairs = pairs
local atag = require("awful.tag")
local gobject = require("gears.object")
local gtable = require("gears.table")
local a_place = require("awful.placement")
local protected_call = require("gears.protected_call")
local aspawn = require("awful.spawn")
local gdebug = require("gears.debug")
local gmatcher = require("gears.matcher")
local amouse = require("awful.mouse")
local akeyboard = require("awful.keyboard")
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
local module = {}
local crules = gmatcher()
--- Check if a client matches a rule.
-- @tparam client c The client.
-- @tparam table rule The rule to check.
-- @treturn bool True if it matches, false otherwise.
-- @staticfct ruled.client.match
function module.match(c, rule)
return crules:_match(c, rule)
end
--- Check if a client matches any part of a rule.
-- @tparam client c The client.
-- @tparam table rule The rule to check.
-- @treturn bool True if at least one rule is matched, false otherwise.
-- @staticfct ruled.client.match_any
function module.match_any(c, rule)
return crules:_match_any(c, rule)
end
--- Does a given rule entry match a client?
-- @tparam client c The client.
-- @tparam table entry Rule entry (with keys `rule`, `rule_any`, `except` and/or
-- `except_any`).
-- @treturn bool
-- @staticfct ruled.client.matches
function module.matches(c, entry)
return crules:matches_rule(c, entry)
end
--- Get list of matching rules for a client.
-- @tparam client c The client.
-- @tparam table _rules The rules to check. List with "rule", "rule_any", "except" and
-- "except_any" keys.
-- @treturn table The list of matched rules.
-- @staticfct ruled.client.matching_rules
function module.matching_rules(c, _rules)
return crules:matching_rules(c, _rules)
end
--- Check if a client matches a given set of rules.
-- @tparam client c The client.
-- @tparam table _rules The rules to check. List of tables with `rule`, `rule_any`,
-- `except` and `except_any` keys.
-- @treturn bool True if at least one rule is matched, false otherwise.
-- @staticfct ruled.client.matches_list
function module.matches_list(c, _rules)
return crules:matches_rules(c, _rules)
end
--- Remove a source.
-- @tparam string name The source name.
-- @treturn boolean If the source was removed.
-- @staticfct ruled.client.remove_rule_source
function module.remove_rule_source(name)
return crules:remove_matching_source(name)
end
--- Apply ruled.client.rules to a client.
-- @tparam client c The client.
-- @staticfct ruled.client.apply
function module.apply(c)
return crules:apply(c)
end
--- Add a new rule to the default set.
--
-- @tparam table rule A valid rule.
function module.append_rule(rule)
crules:append_rule("awful.rules", rule)
end
--- Add a new rules to the default set.
-- @tparam table rules A table with rules.
function module.append_rules(rules)
crules:append_rules("awful.rules", rules)
end
--- Remove a new rule to the default set.
-- @tparam table|string rule A valid rule or a name passed in the `id` value
-- when calling `append_rule`.
function module.remove_rule(rule)
crules:remove_rule("awful.rules", rule)
end
--- Add a new rule source.
--
-- A rule source is a provider called when a client is managed (started). It
-- allows to configure the client by providing properties that should be applied.
-- By default, Awesome provides 2 sources:
--
-- * `awful.rules`: A declarative matcher
-- * `awful.spawn`: Launch clients with pre-defined properties
--
-- It is possible to register new callbacks to modify the properties table
-- before it is applied. Each provider is executed sequentially and modifies the
-- same table. If the first provider set a property, then the second can
-- override it, then the third, etc. Once the providers are exhausted, the
-- properties are applied on the client.
--
-- It is important to note that properties themselves have their own
-- dependencies. For example, a `tag` property implies a `screen`. Therefor, if
-- a `screen` is already specified, then it will be ignored when the rule is
-- executed. Properties also have their own priorities. For example, the
-- `titlebar` and `border_width` need to be applied before the `x` and `y`
-- positions are set. Otherwise, it will be off or the client will shift
-- upward everytime Awesome is restarted. A rule source *cannot* change this.
-- It is up to the callback to be aware of the dependencies and avoid to
-- introduce issues. For example, if the source wants to set a `screen`, it has
-- to check if the `tag`, `tags` or `new_tag` are on that `screen` or remove
-- those properties. Otherwise, they will be ignored once the rule is applied.
--
-- @tparam string name The provider name. It must be unique.
-- @tparam function callback The callback that is called to produce properties.
-- @tparam client callback.c The client
-- @tparam table callback.properties The current properties. The callback should
-- add to and overwrite properties in this table
-- @tparam table callback.callbacks A table of all callbacks scheduled to be
-- executed after the main properties are applied.
-- @tparam[opt={}] table depends_on A list of names of sources this source depends on
-- (sources that must be executed *before* `name`.
-- @tparam[opt={}] table precede A list of names of sources this source have a
-- priority over.
-- @treturn boolean Returns false if a dependency conflict was found.
-- @staticfct ruled.client.add_rule_source
function module.add_rule_source(name, cb, ...)
local function callback(_, ...)
cb(...)
end
return crules:add_matching_function(name, callback, ...)
end
--- The default `ruled.client` source.
--
-- It is called `awful.rules` for historical reasons.
--
-- **Has priority over:**
--
-- *nothing*
--
-- @rulesources awful.rules
crules:add_matching_rules("awful.rules", {}, {"awful.spawn"}, {})
-- Add startup_id overridden properties
local function apply_spawn_rules(c, props, callbacks)
if c.startup_id and aspawn.snid_buffer[c.startup_id] then
local snprops, sncb = unpack(aspawn.snid_buffer[c.startup_id])
-- The SNID tag(s) always have precedence over the rules one(s)
if snprops.tag or snprops.tags or snprops.new_tag then
props.tag, props.tags, props.new_tag = nil, nil, nil
end
gtable.crush(props, snprops)
gtable.merge(callbacks, sncb)
end
end
--- The rule source for clients spawned by `awful.spawn`.
--
-- **Has priority over:**
--
-- * `awful.rules`
--
-- @rulesources awful.spawn
module.add_rule_source("awful.spawn", apply_spawn_rules, {}, {"awful.rules"})
local function apply_singleton_rules(c, props, callbacks)
local persis_id, info = c.single_instance_id, nil
-- This is a persistent property set by `awful.spawn`
if capi.awesome.startup and persis_id then
info = aspawn.single_instance_manager.by_uid[persis_id]
elseif c.startup_id then
info = aspawn.single_instance_manager.by_snid[c.startup_id]
aspawn.single_instance_manager.by_snid[c.startup_id] = nil
elseif aspawn.single_instance_manager.by_pid[c.pid] then
info = aspawn.single_instance_manager.by_pid[c.pid].matcher(c) and
aspawn.single_instance_manager.by_pid[c.pid] or nil
end
if info then
c.single_instance_id = info.hash
if info.rules then
gtable.crush(props, info.rules)
end
table.insert(callbacks, info.callback)
table.insert(info.instances, c)
-- Prevent apps with multiple clients from re-using this too often in
-- the first 30 seconds before the PID is cleared.
aspawn.single_instance_manager.by_pid[c.pid] = nil
end
end
--- The rule source for clients spawned by `awful.spawn.once` and `single_instance`.
--
-- **Has priority over:**
--
-- * `awful.rules`
--
-- **Depends on:**
--
-- * `awful.spawn`
--
-- @rulesources awful.spawn_once
module.add_rule_source("awful.spawn_once", apply_singleton_rules, {"awful.spawn"}, {"awful.rules"})
local function add_to_tag(c, t)
if not t then return end
local tags = c:tags()
table.insert(tags, t)
c:tags(tags)
end
--- Extra rules properties.
--
-- These properties are used in the rules only and are not sent to the client
-- afterward.
--
-- To add a new properties, just do:
--
-- function ruled.client.extra_properties.my_new_property(c, value, props)
-- -- do something
-- end
--
-- By default, the table has the following functions:
--
-- * geometry
-- * placement
--
-- @tfield table ruled.client.extra_properties
module.extra_properties = {}
--- Extra high priority properties.
--
-- Some properties, such as anything related to tags, geometry or focus, will
-- cause a race condition if set in the main property section. This is why
-- they have a section for them.
--
-- To add a new properties, just do:
--
-- function ruled.client.high_priority_properties.my_new_property(c, value, props)
-- -- do something
-- end
--
-- By default, the table has the following functions:
--
-- * tag
-- * new_tag
--
-- @tfield table ruled.client.high_priority_properties
module.high_priority_properties = {}
--- Delayed properties.
-- Properties applied after all other categories.
-- @tfield table ruled.client.delayed_properties
-- By default, the table has the following functions:
--
-- * switch_to_tags
module.delayed_properties = {}
local force_ignore = {
titlebars_enabled=true, focus=true, screen=true, x=true,
y=true, width=true, height=true, geometry=true,placement=true,
border_width=true,floating=true,size_hints_honor=true
}
function module.high_priority_properties.tag(c, value, props)
if value then
if type(value) == "string" then
local name = value
value = atag.find_by_name(c.screen, value)
if not value and not props.screen then
value = atag.find_by_name(nil, name)
end
if not value then
gdebug.print_error("ruled.client-rule specified "
.. "tag = '" .. name .. "', but no such tag exists")
return
end
end
-- In case the tag has been forced to another screen, move the client
if c.screen ~= value.screen then
c.screen = value.screen
props.screen = value.screen -- In case another rule query it
end
c:tags{ value }
end
end
function module.delayed_properties.switch_to_tags(c, value)
if not value then return end
atag.viewmore(c:tags(), c.screen)
end
function module.delayed_properties.switchtotag(c, value)
gdebug.deprecate("Use switch_to_tags instead of switchtotag", {deprecated_in=5})
module.delayed_properties.switch_to_tags(c, value)
end
function module.extra_properties.geometry(c, _, props)
local cur_geo = c:geometry()
local new_geo = type(props.geometry) == "function"
and props.geometry(c, props) or props.geometry or {}
for _, v in ipairs {"x", "y", "width", "height"} do
new_geo[v] = type(props[v]) == "function" and props[v](c, props)
or props[v] or new_geo[v] or cur_geo[v]
end
c:geometry(new_geo) --TODO use request::geometry
end
function module.high_priority_properties.new_tag(c, value, props)
local ty = type(value)
local t = nil
if ty == "boolean" then
-- Create a new tag named after the client class
t = atag.add(c.class or "N/A", {screen=c.screen, volatile=true})
elseif ty == "string" then
-- Create a tag named after "value"
t = atag.add(value, {screen=c.screen, volatile=true})
elseif ty == "table" then
-- Assume a table of tags properties. Set the right screen, but
-- avoid editing the original table
local values = value.screen and value or gtable.clone(value)
values.screen = values.screen or c.screen
t = atag.add(value.name or c.class or "N/A", values)
-- In case the tag has been forced to another screen, move the client
c.screen = t.screen
props.screen = t.screen -- In case another rule query it
else
assert(false)
end
add_to_tag(c, t)
return t
end
function module.extra_properties.placement(c, value, props)
-- Avoid problems
if capi.awesome.startup and
(c.size_hints.user_position or c.size_hints.program_position) then
return
end
local ty = type(value)
local args = {
honor_workarea = props.honor_workarea ~= false,
honor_padding = props.honor_padding ~= false
}
if ty == "function" or (ty == "table" and
getmetatable(value) and getmetatable(value).__call
) then
value(c, args)
elseif ty == "string" and a_place[value] then
a_place[value](c, args)
end
end
function module.high_priority_properties.tags(c, value, props)
local current = c:tags()
local tags, s = {}, nil
for _, t in ipairs(value) do
if type(t) == "string" then
t = atag.find_by_name(c.screen, t)
end
if t and ((not s) or t.screen == s) then
table.insert(tags, t)
s = s or t.screen
end
end
if s and s ~= c.screen then
c.screen = s
props.screen = s -- In case another rule query it
end
if #current == 0 or (value[1] and value[1].screen ~= current[1].screen) then
c:tags(tags)
else
c:tags(gtable.merge(current, tags))
end
end
--- Apply properties and callbacks to a client.
-- @tparam client c The client.
-- @tparam table props Properties to apply.
-- @tparam[opt] table callbacks Callbacks to apply.
-- @staticfct ruled.client.execute
-- @request client titlebars rules granted The `titlebars_enabled` is set in the
-- rules.
crules._execute = function(_, c, props, callbacks)
-- Set the default buttons and keys
local btns = amouse._get_client_mousebindings()
local keys = akeyboard._get_client_keybindings()
props.keys = props.keys or keys
props.buttons = props.buttons or btns
-- Border width will also cause geometry related properties to fail
if props.border_width then
c.border_width = type(props.border_width) == "function" and
props.border_width(c, props) or props.border_width
end
-- This has to be done first, as it will impact geometry related props.
if props.titlebars_enabled and (type(props.titlebars_enabled) ~= "function"
or props.titlebars_enabled(c,props)) then
c:emit_signal("request::titlebars", "rules", {properties=props})
c._request_titlebars_called = true
end
-- Size hints will be re-applied when setting width/height unless it is
-- disabled first
if props.size_hints_honor ~= nil then
c.size_hints_honor = type(props.size_hints_honor) == "function" and props.size_hints_honor(c,props)
or props.size_hints_honor
end
-- Geometry will only work if floating is true, otherwise the "saved"
-- geometry will be restored.
if props.floating ~= nil then
c.floating = type(props.floating) == "function" and props.floating(c,props)
or props.floating
end
-- Before requesting a tag, make sure the screen is right
if props.screen then
c.screen = type(props.screen) == "function" and capi.screen[props.screen(c,props)]
or capi.screen[props.screen]
end
-- Some properties need to be handled first. For example, many properties
-- require that the client is tagged, this isn't yet the case.
for prop, handler in pairs(module.high_priority_properties) do
local value = props[prop]
if value ~= nil then
if type(value) == "function" then
value = value(c, props)
end
handler(c, value, props)
end
end
-- Make sure the tag is selected before the main rules are called.
-- Otherwise properties like "urgent" or "focus" may fail (if they were
-- overridden by other callbacks).
-- Previously this was done in a second client.manage callback, but caused
-- a race condition where the order of modules being loaded would change
-- the outcome.
c:emit_signal("request::tag", nil, {reason="rules", screen = c.screen})
-- By default, rc.lua uses no_overlap+no_offscreen placement. This has to
-- be executed before x/y/width/height/geometry as it would otherwise
-- always override the user specified position with the default rule.
if props.placement then
-- It may be a function, so this one doesn't execute it like others
module.extra_properties.placement(c, props.placement, props)
end
-- Handle the geometry (since tags and screen are set).
if props.height or props.width or props.x or props.y or props.geometry then
module.extra_properties.geometry(c, nil, props)
end
-- Apply the remaining properties (after known race conditions are handled).
for property, value in pairs(props) do
if property ~= "focus" and property ~= "shape" and type(value) == "function" then
value = value(c, props)
end
local ignore = module.high_priority_properties[property] or
module.delayed_properties[property] or force_ignore[property]
if not ignore then
if module.extra_properties[property] then
module.extra_properties[property](c, value, props)
elseif type(c[property]) == "function" then
c[property](c, value)
else
c[property] = value
end
end
end
-- Apply all callbacks.
if callbacks then
for _, callback in pairs(callbacks) do
protected_call(callback, c)
end
end
-- Apply the delayed properties
for prop, handler in pairs(module.delayed_properties) do
if not force_ignore[prop] then
local value = props[prop]
if value ~= nil then
if type(value) == "function" then
value = value(c, props)
end
handler(c, value, props)
end
end
end
-- Do this at last so we do not erase things done by the focus signal.
if props.focus and (type(props.focus) ~= "function" or props.focus(c)) then
c:emit_signal('request::activate', "rules", {raise=not capi.awesome.startup})
end
end
function module.execute(...) crules:_execute(...) end
-- TODO v5 deprecate this
function module.completed_with_payload_callback(c, props, callbacks)
module.execute(c, props, callbacks)
end
gobject._setup_class_signals(module)
capi.client.connect_signal("request::manage", module.apply)
-- Request rules to be added **after** all modules are loaded, but before the
-- clients are managed. This allows module to listen to rules being added and
-- either modify them or add their own in the right order.
local function request_rules()
module.emit_signal("request::rules")
end
capi.client.connect_signal("scanning", request_rules)
--@DOC_rule_COMMON@
return setmetatable(module, {
__newindex = function(_, k, v)
if k == "rules" then
gdebug.deprecate(
"Use ruled.client.append_rules instead awful.rules.rules",
{deprecated_in=5}
)
-- Clearing the rule was supported, so it still has to be. This is
-- a bad idea. There is no plan to make this API public.
if not next(v) then
-- It isn't possible to just set it to {}, there is other
-- references to the table.
for k2 in pairs(crules._matching_rules["awful.rules"]) do
crules._matching_rules["awful.rules"][k2] = nil
end
else
crules:append_rules("awful.rules", v)
end
else
rawset(k, v)
end
end,
__index = function(_, k)
if k == "rules" then
gdebug.deprecate(
"Accessing `ruled.rules` isn't recommended, to modify rules, "..
"use `ruled.client.remove_rule()` and add a new one.",
{deprecated_in=5}
)
if not crules._matching_rules["awful.rules"] then
crules:add_matching_rules("awful.rules", {}, {}, {})
end
return crules._matching_rules["awful.rules"]
end
end
})
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

3
lib/ruled/init.lua Normal file
View File

@ -0,0 +1,3 @@
return {
client = require("ruled.client");
}

View File

@ -150,7 +150,7 @@ end
-- --
-- The default implementation does nothing, this must be re-implemented by -- The default implementation does nothing, this must be re-implemented by
-- all layout and container widgets. -- all layout and container widgets.
-- @tab children A table composed of valid widgets. -- @tparam table children A table composed of valid widgets.
-- @method set_children -- @method set_children
function base.widget:set_children(children) -- luacheck: no unused function base.widget:set_children(children) -- luacheck: no unused
-- Nothing on purpose -- Nothing on purpose
@ -309,7 +309,7 @@ end
-- This calls the widget's `:fit` callback and caches the result for later use. -- This calls the widget's `:fit` callback and caches the result for later use.
-- Never call `:fit` directly, but always through this function! -- Never call `:fit` directly, but always through this function!
-- @tparam widget parent The parent widget which requests this information. -- @tparam widget parent The parent widget which requests this information.
-- @tab context The context in which we are fit. -- @tparam table context The context in which we are fit.
-- @tparam widget widget The widget to fit (this uses -- @tparam widget widget The widget to fit (this uses
-- `widget:fit(context, width, height)`). -- `widget:fit(context, width, height)`).
-- @tparam number width The available width for the widget. -- @tparam number width The available width for the widget.
@ -358,7 +358,7 @@ end
-- However, normally there shouldn't be any reason why you need to use this -- However, normally there shouldn't be any reason why you need to use this
-- function. -- function.
-- @tparam widget parent The parent widget which requests this information. -- @tparam widget parent The parent widget which requests this information.
-- @tab context The context in which we are laid out. -- @tparam table context The context in which we are laid out.
-- @tparam widget widget The widget to layout (this uses -- @tparam widget widget The widget to layout (this uses
-- `widget:layout(context, width, height)`). -- `widget:layout(context, width, height)`).
-- @tparam number width The available width for the widget. -- @tparam number width The available width for the widget.
@ -574,7 +574,7 @@ end
--- Set a declarative widget hierarchy description. --- Set a declarative widget hierarchy description.
-- --
-- See [The declarative layout system](../documentation/03-declarative-layout.md.html). -- See [The declarative layout system](../documentation/03-declarative-layout.md.html).
-- @tab args A table containing the widget's disposition. -- @tparam table args A table containing the widget's disposition.
-- @method setup -- @method setup
function base.widget:setup(args) function base.widget:setup(args)
local f,ids = self.set_widget or self.add or self.set_first,{} local f,ids = self.set_widget or self.add or self.set_first,{}
@ -601,7 +601,7 @@ end
--- Create a widget from a declarative description. --- Create a widget from a declarative description.
-- --
-- See [The declarative layout system](../documentation/03-declarative-layout.md.html). -- See [The declarative layout system](../documentation/03-declarative-layout.md.html).
-- @tab args A table containing the widgets disposition. -- @tparam table args A table containing the widgets disposition.
-- @constructorfct wibox.widget.base.make_widget_declarative -- @constructorfct wibox.widget.base.make_widget_declarative
function base.make_widget_declarative(args) function base.make_widget_declarative(args)
local ids = {} local ids = {}

File diff suppressed because it is too large Load Diff

View File

@ -1803,7 +1803,7 @@ luaA_screen_fake_resize(lua_State *L)
* *
* @DOC_sequences_screen_swap_EXAMPLE@ * @DOC_sequences_screen_swap_EXAMPLE@
* *
* @client s A screen to swap with. * @tparam client s A screen to swap with.
* @method swap * @method swap
*/ */
static int static int

View File

@ -240,12 +240,12 @@
/** When a client gets tagged with this tag. /** When a client gets tagged with this tag.
* @signal tagged * @signal tagged
* @client c The tagged client. * @tparam client c The tagged client.
*/ */
/** When a client gets untagged with this tag. /** When a client gets untagged with this tag.
* @signal untagged * @signal untagged
* @client c The untagged client. * @tparam client c The untagged client.
*/ */
/** /**

View File

@ -1,7 +1,7 @@
local spawn = require("awful.spawn") local spawn = require("awful.spawn")
-- This file provide a simple, yet flexible, test client. -- This file provide a simple, yet flexible, test client.
-- It is used to test the `awful.rules` -- It is used to test the `ruled.client`
local test_client_source = [[ local test_client_source = [[
pcall(require, 'luarocks.loader') pcall(require, 'luarocks.loader')

View File

@ -1,5 +1,4 @@
local timer = require("gears.timer") local timer = require("gears.timer")
local awful = require("awful")
local gtable = require("gears.table") local gtable = require("gears.table")
local runner = { local runner = {
@ -8,15 +7,6 @@ local runner = {
local verbose = os.getenv('VERBOSE') == '1' local verbose = os.getenv('VERBOSE') == '1'
-- Helpers.
--- Add some rules to awful.rules.rules, after the defaults.
local default_rules = gtable.clone(awful.rules.rules)
runner.add_to_default_rules = function(r)
awful.rules.rules = gtable.clone(default_rules)
table.insert(awful.rules.rules, r)
end
-- Was the runner started already? -- Was the runner started already?
local running = false local running = false

View File

@ -11,7 +11,7 @@ local c = client.gen_fake {hide_first=true} --DOC_HIDE
place.maximize(c, {honor_padding=true, honor_workarea=true}) --DOC_HIDE place.maximize(c, {honor_padding=true, honor_workarea=true}) --DOC_HIDE
-- Create a titlebar for the client. -- Create a titlebar for the client.
-- By default, `awful.rules` will create one, but all it does is to call this -- By default, `ruled.client` will create one, but all it does is to call this
-- function. -- function.
local top_titlebar = awful.titlebar(c, { local top_titlebar = awful.titlebar(c, {

View File

@ -0,0 +1,55 @@
--DOC_GEN_IMAGE --DOC_NO_USAGE
local module = ... --DOC_HIDE
local ruled = {client = require("ruled.client") } --DOC_HIDE
local awful = {tag = require("awful.tag"), layout = require("awful.layout")} --DOC_HIDE
awful.placement = require("awful.placement") --DOC_HIDE
require("awful.ewmh") --DOC_HIDE
screen[1]:fake_resize(0, 0, 1280, 720) --DOC_HIDE
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, screen[1], awful.layout.suit.corner.nw) --DOC_HIDE
function awful.spawn(name) --DOC_HIDE
client.gen_fake{class = name, name = name, x = 10, y=10, width = 60, height =50} --DOC_HIDE
end --DOC_HIDE
client.connect_signal("request::rules", function() --DOC_HIDE
ruled.client.append_rule {
rule = { class = "mplayer" },
properties = {
floating = true,
placement = awful.placement.centered,
width = 640,
height = 480,
},
}
end) --DOC_HIDE
client.emit_signal("request::rules") --DOC_HIDE
--DOC_NEWLINE
module.add_event("Spawn xterm", function() --DOC_HIDE
-- Spawn xterm
for _=1, 5 do
awful.spawn("xterm")
end
end) --DOC_HIDE
--DOC_NEWLINE
module.display_tags() --DOC_HIDE
module.add_event("Spawn mplayer", function() --DOC_HIDE
-- Spawn mplayer
awful.spawn("mplayer")
for _, c in ipairs(client.get()) do --DOC_HIDE
assert(#c:tags() == 1) --DOC_HIDE
assert(c.floating == (c.class == "mplayer")) --DOC_HIDE
end --DOC_HIDE
end) --DOC_HIDE
module.display_tags() --DOC_HIDE
module.execute { display_screen = true , display_clients = true , --DOC_HIDE
display_label = false, display_client_name = true } --DOC_HIDE

View File

@ -0,0 +1,38 @@
--DOC_GEN_IMAGE --DOC_NO_USAGE
local module = ... --DOC_HIDE
local ruled = {client = require("ruled.client") } --DOC_HIDE
local awful = {tag = require("awful.tag"), layout = require("awful.layout")} --DOC_HIDE
require("awful.ewmh") --DOC_HIDE
screen[1]:fake_resize(0, 0, 1280, 720) --DOC_HIDE
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, screen[1], awful.layout.layouts[1]) --DOC_HIDE
function awful.spawn(name) --DOC_HIDE
client.gen_fake{class = name, name = name, x = 10, y=10, width = 60, height =50} --DOC_HIDE
end --DOC_HIDE
client.connect_signal("request::rules", function() --DOC_HIDE
ruled.client.append_rule {
rule = { class = "xterm" },
properties = {
maximized_vertical = true,
maximized_horizontal = true
},
}
end) --DOC_HIDE
client.emit_signal("request::rules") --DOC_HIDE
--DOC_NEWLINE
module.add_event("Spawn xterm", function() --DOC_HIDE
-- Spawn xterm
awful.spawn("xterm")
assert(client.get()[1].maximized_vertical ) --DOC_HIDE
assert(client.get()[1].maximized_horizontal) --DOC_HIDE
end) --DOC_HIDE
module.display_tags() --DOC_HIDE
module.execute { display_screen = true , display_clients = true , --DOC_HIDE
display_label = false, display_client_name = true } --DOC_HIDE

View File

@ -0,0 +1,68 @@
--DOC_GEN_IMAGE --DOC_NO_USAGE
local module = ... --DOC_HIDE
local ruled = {client = require("ruled.client") } --DOC_HIDE
local awful = {tag = require("awful.tag"), layout = require("awful.layout")} --DOC_HIDE
require("awful.ewmh") --DOC_HIDE
screen[1]._resize {x = 0, width = 128, height = 96} --DOC_HIDE
awful.tag({ "one", "two", "three", "four", "five" }, screen[1], awful.layout.layouts[1]) --DOC_HIDE
function awful.spawn(name) --DOC_HIDE
client.gen_fake{class = name, name = name, x = 10, y=10, width = 60, height =50} --DOC_HIDE
end --DOC_HIDE
module.display_tags() --DOC_HIDE
client.connect_signal("request::rules", function() --DOC_HIDE
-- Create a new tags with some properties:
ruled.client.append_rule {
rule = { class = "firefox" },
properties = {
switch_to_tags = true,
new_tag = {
name = "My_new_tag!", -- The tag name.
layout = awful.layout.suit.max, -- Set the tag layout.
volatile = true, -- Remove the tag when the client is closed.
}
}
}
--DOC_NEWLINE
-- Create a new tag with just a name:
ruled.client.append_rule {
rule = { class = "thunderbird" },
properties = {
switch_to_tags = true,
new_tag = "JUST_A_NAME!",
}
}
--DOC_NEWLINE
-- Create a new tag using the client metadata:
ruled.client.append_rule {
rule = { class = "xterm" },
properties = {
switch_to_tags = true,
new_tag = true,
}
}
end) --DOC_HIDE
client.emit_signal("request::rules") --DOC_HIDE
--DOC_NEWLINE
module.add_event("Spawn some apps", function() --DOC_HIDE
-- Spawn firefox
awful.spawn("firefox")
awful.spawn("thunderbird")
awful.spawn("xterm")
end) --DOC_HIDE
module.display_tags() --DOC_HIDE
module.execute { display_screen = false, display_clients = true , --DOC_HIDE
display_label = false, display_client_name = true } --DOC_HIDE

View File

@ -0,0 +1,43 @@
--DOC_GEN_IMAGE --DOC_NO_USAGE
local module = ... --DOC_HIDE
local ruled = {client = require("ruled.client") } --DOC_HIDE
local awful = {tag = require("awful.tag"), layout = require("awful.layout")} --DOC_HIDE
awful.placement = require("awful.placement") --DOC_HIDE
require("awful.ewmh") --DOC_HIDE
screen[1]:fake_resize(0, 0, 1280, 720) --DOC_HIDE
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, screen[1], awful.layout.suit.corner.nw) --DOC_HIDE
function awful.spawn(name) --DOC_HIDE
client.gen_fake{class = name, name = name, x = 10, y=10, width = 60, height =50} --DOC_HIDE
end --DOC_HIDE
client.connect_signal("request::rules", function() --DOC_HIDE
ruled.client.append_rule {
rule = { class = "mplayer" },
properties = {
floating = true,
placement = awful.placement.centered,
width = 640,
height = 480,
},
}
end) --DOC_HIDE
client.emit_signal("request::rules") --DOC_HIDE
--DOC_NEWLINE
module.add_event("Spawn mplayer", function() --DOC_HIDE
-- Spawn mplayer
awful.spawn("mplayer")
for _, c in ipairs(client.get()) do --DOC_HIDE
assert(#c:tags() == 1) --DOC_HIDE
assert(c.floating == (c.class == "mplayer")) --DOC_HIDE
end --DOC_HIDE
end) --DOC_HIDE
module.display_tags() --DOC_HIDE
module.execute { display_screen = true , display_clients = true , --DOC_HIDE
display_label = false, display_client_name = true } --DOC_HIDE

View File

@ -0,0 +1,85 @@
--DOC_GEN_IMAGE --DOC_NO_USAGE
local module = ... --DOC_HIDE
local ruled = {client = require("ruled.client") } --DOC_HIDE
local awful = {tag = require("awful.tag"), layout = require("awful.layout")} --DOC_HIDE
awful.placement = require("awful.placement") --DOC_HIDE
require("awful.ewmh") --DOC_HIDE
screen[1]:fake_resize(0, 0, 1024, 768) --DOC_HIDE
screen.fake_add(1034, 0, 1024, 768).outputs = {["eVGA1"] = {mm_height=60, mm_width=80 }} --DOC_HIDE
screen.fake_add(2074, 0, 1024, 768).outputs = {["DVI1" ] = {mm_height=60, mm_width=80 }} --DOC_HIDE
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, screen[1], awful.layout.suit.corner.nw) --DOC_HIDE
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, screen[2], awful.layout.suit.corner.nw) --DOC_HIDE
awful.tag({ "1", "2", "3", "4", "5", "6", "7", "8", "9" }, screen[3], awful.layout.suit.corner.nw) --DOC_HIDE
function awful.spawn(name) --DOC_HIDE
client.gen_fake{class = name, name = name, x = 10, y=10, width = 60, height =50} --DOC_HIDE
end --DOC_HIDE
mouse.coords {x = 2500, y = 100 }
assert(mouse.screen == screen[3]) --DOC_HIDE
--DOC_NEWLINE
client.connect_signal("request::rules", function() --DOC_HIDE
-- Screen by IDs:
ruled.client.append_rule {
rule_any = {
class = {"firefox"}
},
properties = {
screen = 2,
tag = "1", --DOC_HIDE
width = 640, height =480, floating = true, --DOC_HIDE
},
}
--DOC_NEWLINE
-- Screen by object:
ruled.client.append_rule {
rule_any = {
class = {"thunderbird"}
},
properties = {
screen = mouse.screen,
tag = "1", --DOC_HIDE
width = 640, height =480, floating = true, --DOC_HIDE
},
}
--DOC_NEWLINE
-- Screen by output name:
ruled.client.append_rule {
rule_any = {
class = {"xterm"}
},
properties = {
screen = "LVDS1",
tag = "1", --DOC_HIDE
width = 640, height =480, floating = true, --DOC_HIDE
},
}
end) --DOC_HIDE
client.emit_signal("request::rules") --DOC_HIDE
--DOC_NEWLINE
module.add_event("Spawn some applications", function() --DOC_HIDE
-- Spawn firefox, thunderbird and xterm
awful.spawn("firefox")
awful.spawn("thunderbird")
awful.spawn("xterm")
assert(client.get()[1].screen == screen[2]) --DOC_HIDE
assert(client.get()[2].screen == screen[3]) --DOC_HIDE
assert(client.get()[3].screen == screen[1]) --DOC_HIDE
assert(client.get()[1]:tags()[1] == screen[2].selected_tag) --DOC_HIDE
assert(client.get()[2]:tags()[1] == screen[3].selected_tag) --DOC_HIDE
assert(client.get()[3]:tags()[1] == screen[1].selected_tag) --DOC_HIDE
end) --DOC_HIDE
module.display_tags() --DOC_HIDE
module.execute { display_screen = true , display_clients = true, --DOC_HIDE
display_label = true , display_client_name = true, --DOC_HIDE
display_mouse = true , --DOC_HIDE
} --DOC_HIDE

View File

@ -0,0 +1,40 @@
--DOC_GEN_IMAGE --DOC_NO_USAGE
local module = ... --DOC_HIDE
local ruled = {client = require("ruled.client") } --DOC_HIDE
local awful = {tag = require("awful.tag"), layout = require("awful.layout")} --DOC_HIDE
require("awful.ewmh") --DOC_HIDE
screen[1]._resize {x = 0, width = 128, height = 96} --DOC_HIDE
awful.tag({ "one", "two", "three", "four", "five" }, screen[1], awful.layout.layouts[1]) --DOC_HIDE
function awful.spawn(name) --DOC_HIDE
client.gen_fake{class = name, name = name, x = 10, y=10, width = 60, height =50} --DOC_HIDE
end --DOC_HIDE
module.display_tags() --DOC_HIDE
client.connect_signal("request::rules", function() --DOC_HIDE
-- Select tag by object reference:
ruled.client.append_rule {
rule = { class = "firefox" },
properties = {
tag = screen[1].tags[4],
switch_to_tags = true
}
}
end) --DOC_HIDE
client.emit_signal("request::rules") --DOC_HIDE
--DOC_NEWLINE
module.add_event("Spawn xterm", function() --DOC_HIDE
-- Spawn firefox
awful.spawn("firefox")
end) --DOC_HIDE
module.display_tags() --DOC_HIDE
module.execute { display_screen = false, display_clients = true , --DOC_HIDE
display_label = false, display_client_name = true } --DOC_HIDE

View File

@ -0,0 +1,51 @@
--DOC_GEN_IMAGE --DOC_NO_USAGE
local module = ... --DOC_HIDE
local ruled = {client = require("ruled.client") } --DOC_HIDE
local awful = {tag = require("awful.tag"), layout = require("awful.layout")} --DOC_HIDE
require("awful.ewmh") --DOC_HIDE
screen[1]._resize {x = 0, width = 128, height = 96} --DOC_HIDE
awful.tag({ "one", "two", "three", "four", "five" }, screen[1], awful.layout.layouts[1]) --DOC_HIDE
function awful.spawn(name) --DOC_HIDE
client.gen_fake{class = name, name = name, x = 10, y=10, width = 60, height =50} --DOC_HIDE
end --DOC_HIDE
client.connect_signal("request::rules", function() --DOC_HIDE
-- Select tag by object reference:
ruled.client.append_rule {
rule_any = {
class = {"firefox"}
},
properties = {
tag = screen[1].tags[3],
},
}
--DOC_NEWLINE
-- Select tag by name:
ruled.client.append_rule {
rule_any = {
class = {"thunderbird"}
},
properties = {
tag = "five",
},
}
end) --DOC_HIDE
client.emit_signal("request::rules") --DOC_HIDE
--DOC_NEWLINE
module.add_event("Spawn xterm", function() --DOC_HIDE
-- Spawn firefox and thunderbird
awful.spawn("firefox")
awful.spawn("thunderbird")
end) --DOC_HIDE
module.display_tags() --DOC_HIDE
module.execute { display_screen = false, display_clients = true , --DOC_HIDE
display_label = false, display_client_name = true } --DOC_HIDE

View File

@ -1,5 +1,7 @@
local awful = require("awful") local awful = require("awful")
local test_client = require("_client") local test_client = require("_client")
local cruled = require("ruled.client")
local gdebug = require("gears.debug")
local has_spawned = false local has_spawned = false
local steps = { local steps = {
@ -177,7 +179,10 @@ end)
local has_error local has_error
-- Disable awful.screen.preferred(c) -- Disable awful.screen.preferred(c)
awful.rules.rules[1].properties.screen = nil local dep = gdebug.deprecate
gdebug.deprecate = function() end
cruled.rules[1].properties.screen = nil
gdebug.deprecate = dep
table.insert(steps, function() table.insert(steps, function()
-- Make sure there is no extra callbacks that causes double screen changes -- Make sure there is no extra callbacks that causes double screen changes

View File

@ -1,6 +1,7 @@
local awful = require("awful") local awful = require("awful")
local test_client = require("_client") local test_client = require("_client")
local runner = require("_runner") local runner = require("_runner")
local cruled = require("ruled.client")
-- This test makes some assumptions about the no_overlap behavior which may not -- This test makes some assumptions about the no_overlap behavior which may not
-- be correct if the screen is in the portrait orientation. -- be correct if the screen is in the portrait orientation.
@ -27,7 +28,8 @@ local rule = {
placement = awful.placement.no_overlap + awful.placement.no_offscreen placement = awful.placement.no_overlap + awful.placement.no_offscreen
} }
} }
table.insert(awful.rules.rules, rule)
cruled.append_rule(rule)
local function check_geometry(c, x, y, width, height) local function check_geometry(c, x, y, width, height)
local g = c:geometry() local g = c:geometry()

View File

@ -1,4 +1,5 @@
local awful = require("awful") local awful = require("awful")
local ruledc = require("ruled.client")
local gears = require("gears") local gears = require("gears")
local test_client = require("_client") local test_client = require("_client")
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1) local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
@ -12,8 +13,8 @@ local tests = {}
-- local border_width = beautiful.border_width -- local border_width = beautiful.border_width
-- Detect "request::manage" race conditions -- Detect "request::manage" race conditions
local real_apply = awful.rules.apply local real_apply = ruledc.apply
function awful.rules.apply(c) function ruledc.apply(c)
assert(#c:tags() == 0) assert(#c:tags() == 0)
return real_apply(c) return real_apply(c)
end end
@ -33,7 +34,7 @@ local function test_rule(rule)
rule.test = nil rule.test = nil
end end
table.insert(awful.rules.rules, rule) ruledc.append_rule(rule)
end end
-- Helper function to search clients -- Helper function to search clients
@ -263,20 +264,20 @@ test_rule {
} }
-- Test the custom sources -- Test the custom sources
assert(awful.rules.add_rule_source("high_priority", function(c, props, _) assert(ruledc.add_rule_source("high_priority", function(c, props, _)
assert(type(c) == "client") assert(type(c) == "client")
assert(props.random2) assert(props.random2)
props.random1 = true props.random1 = true
end, {"awful.spawn"}, {"awful.rules", "low_priority"})) end, {"awful.spawn"}, {"awful.rules", "low_priority"}))
assert(awful.rules.add_rule_source("before2", function() assert(ruledc.add_rule_source("before2", function()
error("This function should not be called") error("This function should not be called")
end, {"awful.spawn"}, {"awful.rules"})) end, {"awful.spawn"}, {"awful.rules"}))
assert(awful.rules.remove_rule_source("before2")) assert(ruledc.remove_rule_source("before2"))
assert(awful.rules.add_rule_source("low_priority", function(c, props, _) assert(ruledc.add_rule_source("low_priority", function(c, props, _)
assert(type(c) == "client") assert(type(c) == "client")
assert(not props.random1) assert(not props.random1)
@ -285,7 +286,7 @@ end, {"awful.spawn", "high_priority"}, {"void", "awful.rules"}))
local temp = gears.debug.print_warning local temp = gears.debug.print_warning
gears.debug.print_warning = function() end gears.debug.print_warning = function() end
assert(not awful.rules.add_rule_source("invalid_source", function() assert(not ruledc.add_rule_source("invalid_source", function()
assert(false, "This cannot happen") assert(false, "This cannot happen")
end, {"awful.rules"}, {"awful.spawn"})) end, {"awful.rules"}, {"awful.spawn"}))
gears.debug.print_warning = temp gears.debug.print_warning = temp

View File

@ -4,21 +4,38 @@ local runner = require( "_runner" )
local awful = require( "awful" ) local awful = require( "awful" )
local wibox = require( "wibox" ) local wibox = require( "wibox" )
local beautiful = require( "beautiful" ) local beautiful = require( "beautiful" )
local cruled = require("ruled.client")
local gdebug = require("gears.debug")
local w = nil local w = nil
local w1_draw, w2_draw local w1_draw, w2_draw
-- Replacing the rules is not supported anymore.
local dep = gdebug.deprecate
local function set_rules(new_rules)
gdebug.deprecate = function() end
cruled.rules = {}
cruled.append_rules(new_rules)
gdebug.deprecate = dep
end
-- Disable automatic placement -- Disable automatic placement
awful.rules.rules = { set_rules {
{ rule = { }, properties = { {
border_width = 0, rule = { },
size_hints_honor = false, properties = {
x = 0, border_width = 0,
y = 0, size_hints_honor = false,
width = 100, x = 0,
height = 100, y = 0,
border_color = beautiful.border_color_normal width = 100,
} height = 100,
border_color = beautiful.border_color_normal
}
} }
} }
@ -52,7 +69,7 @@ local steps = {
end end
end, end,
function() function()
awful.rules.rules = { set_rules {
-- All clients will match this rule. -- All clients will match this rule.
{ rule = { },properties = { { rule = { },properties = {
titlebars_enabled = true, titlebars_enabled = true,

View File

@ -1,7 +1,8 @@
local runner = require("_runner") local runner = require("_runner")
local titlebar = require("awful.titlebar") local titlebar = require("awful.titlebar")
local rules = require("awful.rules") local rules = require("ruled.client")
local spawn = require("awful.spawn") local spawn = require("awful.spawn")
local gdebug = require("gears.debug")
local tiny_client_code_template = [[ local tiny_client_code_template = [[
pcall(require, 'luarocks.loader') pcall(require, 'luarocks.loader')
@ -25,7 +26,10 @@ window.decorated = false
} }
-- Use the test client props -- Use the test client props
local dep = gdebug.deprecate
gdebug.deprecate = function() end
rules.rules = {} rules.rules = {}
gdebug.deprecate = dep
-- Too bad there's no way to disconnect the rc.lua request::titlebars function -- Too bad there's no way to disconnect the rc.lua request::titlebars function

View File

@ -2,6 +2,8 @@
local awful = require("awful") local awful = require("awful")
local runner = require("_runner") local runner = require("_runner")
local cruled = require("ruled.client")
-- Some basic assertion that the tag is not marked "urgent" already. -- Some basic assertion that the tag is not marked "urgent" already.
assert(awful.tag.getproperty(awful.screen.focused().tags[2], "urgent") == nil) assert(awful.tag.getproperty(awful.screen.focused().tags[2], "urgent") == nil)
@ -31,7 +33,7 @@ local steps = {
-- Select first tag. -- Select first tag.
awful.screen.focused().tags[1]:view_only() awful.screen.focused().tags[1]:view_only()
runner.add_to_default_rules({ rule = { class = "XTerm" }, cruled.append_rule({ rule = { class = "XTerm" },
properties = { tag = "2", focus = true } }) properties = { tag = "2", focus = true } })
awful.spawn("xterm") awful.spawn("xterm")
@ -71,7 +73,7 @@ local steps = {
-- Select first tag. -- Select first tag.
awful.screen.focused().tags[1]:view_only() awful.screen.focused().tags[1]:view_only()
runner.add_to_default_rules({ rule = { class = "XTerm" }, cruled.append_rule({ rule = { class = "XTerm" },
properties = { tag = "2", focus = true, switch_to_tags = true }}) properties = { tag = "2", focus = true, switch_to_tags = true }})
awful.spawn("xterm") awful.spawn("xterm")
@ -93,7 +95,7 @@ local steps = {
client.get()[1]:kill() client.get()[1]:kill()
manage_cb_done = false manage_cb_done = false
runner.add_to_default_rules({rule = { class = "XTerm" }, cruled.append_rule({rule = { class = "XTerm" },
properties = { tag = "2", focus = false }}) properties = { tag = "2", focus = false }})
awful.spawn("xterm") awful.spawn("xterm")