notification: Add rules for notifications.

This commit introduce the new "ruled" module. This new top level
module will eventually host all "rules" related modules.

As for the content of the commit, it adds rules for notification. They
are mostly identical to the client rules and can be used to customize
or filter the notifications. It replaces the old "preset" API. The
preset API inner working was mostly a duplication of the early
`awful.rules` API, but was never as flexible. Thus the idea behind this
work is to converge all "core" classes to use a similar declarative API.
This commit is contained in:
Emmanuel Lepage Vallee 2019-08-18 01:50:43 -04:00
parent 9f5a17ed98
commit afe58d6cd2
3 changed files with 206 additions and 27 deletions

View File

@ -276,32 +276,6 @@ end
local conns = gobject._setup_class_signals(naughty)
--- Connect a global signal on the notification engine.
--
-- Functions connected to this signal source will be executed when any
-- notification object emits the signal.
--
-- It is also used for some generic notification signals such as
-- `request::display`.
--
-- @tparam string name The name of the signal
-- @tparam function func The function to attach
-- @staticfct naughty.connect_signal
-- @usage naughty.connect_signal("added", function(notif)
-- -- do something
-- end)
--- Emit a notification signal.
-- @tparam string name The signal name.
-- @param ... The signal callback arguments
-- @staticfct naughty.emit_signal
--- Disconnect a signal from a source.
-- @tparam string name The name of the signal
-- @tparam function func The attached function
-- @staticfct naughty.disconnect_signal
-- @treturn boolean If the disconnection was successful
local function resume()
properties.suspended = false
for _, v in pairs(naughty.notifications.suspended) do
@ -741,6 +715,8 @@ end
naughty.connect_signal("property::screen" , update_index)
naughty.connect_signal("property::position", update_index)
--@DOC_signals_COMMON@
return setmetatable(naughty, {__index = index_miss, __newindex = set_index_miss})
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

View File

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

202
lib/ruled/notification.lua Normal file
View File

@ -0,0 +1,202 @@
---------------------------------------------------------------------------
--- Rules for notifications.
--
--@DOC_wibox_nwidget_rules_urgency_EXAMPLE@
--
-- In this example, we setup a different widget template for some music
-- notifications:
--
--@DOC_wibox_nwidget_rules_widget_template_EXAMPLE@
--
-- In this example, we add action to a notification that originally lacked
-- them:
--
--@DOC_wibox_nwidget_rules_add_actions_EXAMPLE@
--
-- Here is a list of all properties available in the `properties` section of
-- a rule:
--
--@DOC_notification_rules_index_COMMON@
--
-- @author Emmanuel Lepage Vallee <elv1313@gmail.com>
-- @copyright 2017-2019 Emmanuel Lepage Vallee
-- @ruleslib ruled.notifications
---------------------------------------------------------------------------
local capi = {screen = screen, client = client, awesome = awesome}
local matcher = require("gears.matcher")
local gtable = require("gears.table")
local gobject = require("gears.object")
local naughty = require("naughty")
--- The notification is attached to the focused client.
--
-- This is useful, along with other matching properties and the `ignore`
-- notification property, to prevent focused application from spamming with
-- useless notifications.
--
--@DOC_wibox_nwidget_rules_has_focus_EXAMPLE@
--
-- @matchingproperty has_focus
-- @param boolean
--- The notification is attached to a client with this class.
--
--@DOC_wibox_nwidget_rules_has_class_EXAMPLE@
--
-- @matchingproperty has_class
-- @param string
-- @see has_instance
--- The notification is attached to a client with this instance name.
--
--@DOC_wibox_nwidget_rules_has_instance_EXAMPLE@
--
-- @matchingproperty has_instance
-- @param string
-- @see has_class
--- Append some actions to a notification.
--
-- Using `actions` directly is destructive since it will override existing
-- actions.
--
-- @clientruleproperty append_actions
-- @param table
local nrules = matcher()
local function client_match_common(n, prop, value)
local clients = n.clients
if #clients == 0 then return false end
for _, c in ipairs(clients) do
if c[prop] == value then
return true
end
end
return false
end
nrules:add_property_matcher("has_class", function(n, value)
return client_match_common(n, "class", value)
end)
nrules:add_property_matcher("has_instance", function(n, value)
return client_match_common(n, "instance", value)
end)
nrules:add_property_matcher("has_focus", function(n)
local clients = n.clients
if #clients == 0 then return false end
for _, c in ipairs(clients) do
if c == capi.client.focus then
return true
end
end
return false
end)
nrules:add_property_setter("append_actions", function(n, value)
local new_actions = gtable.clone(n.actions or {}, false)
n.actions = gtable.merge(new_actions, value)
end)
local module = {}
gobject._setup_class_signals(module)
--- Remove a source.
-- @tparam string name The source name.
-- @treturn boolean If the source was removed.
-- @staticfct ruled.notification.remove_rule_source
function module.remove_rule_source(name)
return nrules:remove_matching_source(name)
end
--- Apply the tag rules to a client.
--
-- This is useful when it is necessary to apply rules after a tag has been
-- created. Many workflows can make use of "blank" tags which wont match any
-- rules until later.
--
-- @tparam naughty.notification n The notification.
-- @staticfct ruled.notification.apply
function module.apply(n)
local callbacks, props = {}, {}
for _, v in ipairs(nrules._matching_source) do
v.callback(nrules, n, props, callbacks)
end
nrules:_execute(n, props, callbacks)
end
--- Add a new rule to the default set.
-- @tparam table rule A valid rule.
-- @staticfct ruled.notification.append_rule
function module.append_rule(rule)
nrules:append_rule("ruled.notifications", rule)
end
--- Add a new rules to the default set.
-- @tparam table rule A table with rules.
-- @staticfct ruled.notification.append_rules
function module.append_rules(rules)
nrules:append_rules("ruled.notifications", rules)
end
--- Remove a new rule to the default set.
-- @tparam table rule A valid rule.
-- @staticfct ruled.notification.remove_rule
function module.remove_rule(rule)
nrules:remove_rule("ruled.notifications", rule)
module.emit_signal("rule::removed", rule)
end
--- Add a new rule source.
--
-- A rule source is a provider called when a client initially request tags. It
-- allows to configure, select or create a tag (or many) to be attached to the
-- client.
--
-- @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.notifications.add_rule_source
function module.add_rule_source(name, cb, ...)
return nrules:add_matching_function(name, cb, ...)
end
-- Add signals.
local conns = gobject._setup_class_signals(module)
-- First time getting a notification? Request some rules.
capi.awesome.connect_signal("startup", function()
if conns["request::rules"] and #conns["request::rules"] > 0 then
module.emit_signal("request::rules")
-- This will disable the legacy preset support.
naughty.connect_signal("request::preset", function(n)
module.apply(n)
end)
end
end)
--@DOC_rule_COMMON@
return module