diff --git a/lib/naughty/init.lua b/lib/naughty/init.lua
index 2a096df5..4450538c 100644
--- a/lib/naughty/init.lua
+++ b/lib/naughty/init.lua
@@ -10,7 +10,9 @@ if dbus then
end
naughty.action = require("naughty.action")
+naughty.list = require("naughty.list")
naughty.layout = require("naughty.layout")
+naughty.widget = require("naughty.widget")
naughty.notification = require("naughty.notification")
return naughty
diff --git a/lib/naughty/layout/init.lua b/lib/naughty/layout/init.lua
index c6df968a..5b49aba3 100644
--- a/lib/naughty/layout/init.lua
+++ b/lib/naughty/layout/init.lua
@@ -5,5 +5,5 @@
---------------------------------------------------------------------------
return {
- legacy = require("naughty.layout.legacy")
+ legacy = require( "naughty.layout.legacy" );
}
diff --git a/lib/naughty/list/actions.lua b/lib/naughty/list/actions.lua
new file mode 100644
index 00000000..cc37d703
--- /dev/null
+++ b/lib/naughty/list/actions.lua
@@ -0,0 +1,324 @@
+----------------------------------------------------------------------------
+--- Manage a notification action list.
+--
+-- A notification action is a "button" that will trigger an action on the sender
+-- process. `notify-send` doesn't support actions, but `libnotify` based
+-- applications do.
+--
+--@DOC_wibox_nwidget_actionlist_simple_EXAMPLE@
+--
+-- This example has a custom vertical widget template:
+--
+--@DOC_wibox_nwidget_actionlist_fancy_EXAMPLE@
+--
+-- This example has a horizontal widget template and icons:
+--
+--@DOC_wibox_nwidget_actionlist_fancy_icons_EXAMPLE@
+--
+-- This example uses the theme/style variables instead of the template. This is
+-- less flexible, but easier to put in the theme file. Note that each style
+-- variable has a `beautiful` equivalent.
+--
+--@DOC_wibox_nwidget_actionlist_style_EXAMPLE@
+--
+-- @author Emmanuel Lepage Vallee <elv1313@gmail.com>
+-- @copyright 2017 Emmanuel Lepage Vallee
+-- @widgetmod naughty.list.actions
+-- @see awful.widget.common
+----------------------------------------------------------------------------
+
+local wibox = require("wibox")
+local awcommon = require("awful.widget.common")
+local abutton = require("awful.button")
+local gtable = require("gears.table")
+local beautiful= require("beautiful")
+
+local module = {}
+
+--- Whether or not to underline the action name.
+-- @beautiful beautiful.notification_action_underline_normal
+-- @param[opt=true] boolean
+
+--- Whether or not to underline the selected action name.
+-- @beautiful beautiful.notification_action_underline_selected
+-- @param[opt=true] boolean
+
+--- Whether or not the action label should be shown.
+-- @beautiful beautiful.notification_action_icon_only
+-- @param[opt=false] boolean
+
+--- Whether or not the action icon should be shown.
+-- @beautiful beautiful.notification_action_label_only
+-- @param[opt=false] boolean
+
+--- The shape used for a normal action.
+-- @beautiful beautiful.notification_action_shape_normal
+-- @tparam[opt=gears.shape.rectangle] gears.shape shape
+-- @see gears.shape
+
+--- The shape used for a selected action.
+-- @beautiful beautiful.notification_action_shape_selected
+-- @tparam[opt=gears.shape.rectangle] gears.shape shape
+-- @see gears.shape
+
+--- The shape border color for normal actions.
+-- @beautiful beautiful.notification_action_shape_border_color_normal
+-- @param color
+-- @see gears.color
+
+--- The shape border color for selected actions.
+-- @beautiful beautiful.notification_action_shape_border_color_selected
+-- @param color
+-- @see gears.color
+
+--- The shape border width for normal actions.
+-- @beautiful beautiful.notification_action_shape_border_width_normal
+-- @param[opt=0] number
+
+--- The shape border width for selected actions.
+-- @beautiful beautiful.notification_action_shape_border_width_selected
+-- @param[opt=0] number
+
+--- The action icon size.
+-- @beautiful beautiful.notification_action_icon_size_normal
+-- @param[opt=0] number
+
+--- The selected action icon size.
+-- @beautiful beautiful.notification_action_icon_size_selected
+-- @param[opt=0] number
+
+--- The background color for normal actions.
+-- @beautiful beautiful.notification_action_bg_normal
+-- @param color
+-- @see gears.color
+
+--- The background color for selected actions.
+-- @beautiful beautiful.notification_action_bg_selected
+-- @param color
+-- @see gears.color
+
+--- The foreground color for normal actions.
+-- @beautiful beautiful.notification_action_fg_normal
+-- @param color
+-- @see gears.color
+
+--- The foreground color for selected actions.
+-- @beautiful beautiful.notification_action_fg_selected
+-- @param color
+-- @see gears.color
+
+--- The background image for normal actions.
+-- @beautiful beautiful.notification_action_bgimage_normal
+-- @tparam gears.surface|string action_bgimage_normal
+-- @see gears.surface
+
+--- The background image for selected actions.
+-- @beautiful beautiful.notification_action_bgimage_selected
+-- @tparam gears.surface|string action_bgimage_selected
+-- @see gears.surface
+
+local default_buttons = gtable.join(
+ abutton({ }, 1, function(a) a:invoke() end)
+)
+
+local props = {"shape_border_color", "bg_image" , "fg",
+ "shape_border_width", "underline", "bg",
+ "shape", "icon_size", }
+
+-- Use a cached loop instead of an large function like the taglist and tasklist
+local function update_style(self)
+ self._private.style_cache = self._private.style_cache or {}
+
+ for _, state in ipairs {"normal", "selected"} do
+ local s = {}
+
+ for _, prop in ipairs(props) do
+ if self._private.style[prop.."_"..state] ~= nil then
+ s[prop] = self._private.style[prop.."_"..state]
+ else
+ s[prop] = beautiful["notification_action_"..prop.."_"..state]
+ end
+ end
+
+ -- Set a fallback for the icon size to prevent them from being gigantic
+ s.icon_size = s.icon_size
+ or beautiful.get_font_height(beautiful.font) * 1.5
+
+ self._private.style_cache[state] = s
+ end
+end
+
+local function wb_label(action, self)
+ -- Get the name
+ local name = action.name
+
+ local style = self._private.style_cache[action.selected and "selected" or "normal"]
+
+ -- Add the underline
+ name = style.underline ~= false and
+ (""..name.."") or name
+
+ local icon = beautiful.notification_action_label_only ~= true and action.icon or nil
+
+ if style.fg then
+ name = "" .. name .. ""
+ end
+
+ if action.icon_only or beautiful.notification_action_icon_only then
+ name = nil
+ end
+
+ return name, style.bg, style.bg_image, icon, style
+end
+
+local function update(self)
+ if not self._private.layout or not self._private.notification then return end
+
+ awcommon.list_update(
+ self._private.layout,
+ default_buttons,
+ function(o) return wb_label(o, self) end,
+ self._private.data,
+ self._private.notification.actions,
+ {
+ widget_template = self._private.widget_template
+ }
+ )
+end
+
+local actionlist = {}
+
+--- The actionlist parent notification.
+-- @property notification
+-- @param notification
+-- @see naughty.notification
+
+--- The actionlist layout.
+-- If no layout is specified, a `wibox.layout.fixed.horizontal` will be created
+-- automatically.
+-- @property layout
+-- @param widget
+-- @see wibox.layout.fixed.horizontal
+
+--- The actionlist parent notification.
+-- @property widget_template
+-- @param table
+
+--- A table with values to override each `beautiful.notification_action` values.
+-- @property style
+-- @param table
+
+function actionlist:set_notification(notif)
+ self._private.notification = notif
+
+ if not self._private.layout then
+ self._private.layout = wibox.layout.fixed.horizontal()
+ end
+
+ update(self)
+
+ self:emit_signal("widget::layout_changed")
+ self:emit_signal("widget::redraw_needed")
+end
+
+function actionlist:set_base_layout(layout)
+ self._private.layout = layout
+
+ update(self)
+
+ self:emit_signal("widget::layout_changed")
+ self:emit_signal("widget::redraw_needed")
+end
+
+function actionlist:set_widget_template(widget_template)
+ self._private.widget_template = widget_template
+
+ -- Remove the existing instances
+ self._private.data = {}
+
+ update(self)
+
+ self:emit_signal("widget::layout_changed")
+ self:emit_signal("widget::redraw_needed")
+end
+
+function actionlist:set_style(style)
+ self._private.style = style or {}
+
+ update_style(self)
+ update(self)
+
+ self:emit_signal("widget::layout_changed")
+ self:emit_signal("widget::redraw_needed")
+end
+
+function actionlist:get_notification()
+ return self._private.notification
+end
+
+function actionlist:layout(_, width, height)
+ if self._private.layout then
+ return { wibox.widget.base.place_widget_at(self._private.layout, 0, 0, width, height) }
+ end
+end
+
+function actionlist:fit(context, width, height)
+ if not self._private.layout then
+ return 0, 0
+ end
+
+ return wibox.widget.base.fit_widget(self, context, self._private.layout, width, height)
+end
+
+--- Create an action list.
+--
+-- @tparam table args
+-- @tparam naughty.notification args.notification The notification/
+-- @tparam widget args.base_layout The action layout.
+-- @tparam table args.style Override the beautiful values.
+-- @tparam boolean args.style.underline_normal
+-- @tparam boolean args.style.underline_selected
+-- @tparam gears.shape args.style.shape_normal
+-- @tparam gears.shape args.style.shape_selected
+-- @tparam gears.color|string args.style.shape_border_color_normal
+-- @tparam gears.color|string args.style.shape_border_color_selected
+-- @tparam number args.style.shape_border_width_normal
+-- @tparam number args.style.shape_border_width_selected
+-- @tparam number args.style.icon_size
+-- @tparam gears.color|string args.style.bg_normal
+-- @tparam gears.color|string args.style.bg_selected
+-- @tparam gears.color|string args.style.fg_normal
+-- @tparam gears.color|string args.style.fg_selected
+-- @tparam gears.surface|string args.style.bgimage_normal
+-- @tparam gears.surface|string args.style.bgimage_selected
+-- @tparam[opt] table widget_template A custom widget to be used for each action.
+-- @treturn widget The action widget.
+-- @constructorfct naughty.list.actions
+
+local function new(_, args)
+ args = args or {}
+
+ local wdg = wibox.widget.base.make_widget(nil, nil, {
+ enable_properties = true,
+ })
+
+ gtable.crush(wdg, actionlist, true)
+
+ wdg._private.data = {}
+
+ gtable.crush(wdg, args)
+
+ wdg._private.style = wdg._private.style or {}
+
+ update_style(wdg)
+
+ return wdg
+end
+
+--@DOC_widget_COMMON@
+
+--@DOC_object_COMMON@
+
+return setmetatable(module, {__call = new})
+
+-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
diff --git a/lib/naughty/list/init.lua b/lib/naughty/list/init.lua
new file mode 100644
index 00000000..6e74e739
--- /dev/null
+++ b/lib/naughty/list/init.lua
@@ -0,0 +1,9 @@
+---------------------------------------------------------------------------
+-- @author Emmanuel Lepage Vallee <elv1313@gmail.com>
+-- @copyright 2017-2019 Emmanuel Lepage Vallee
+-- @module naughty.list
+---------------------------------------------------------------------------
+
+return {
+ actions = require( "naughty.list.actions" );
+}
diff --git a/lib/naughty/widget/init.lua b/lib/naughty/widget/init.lua
new file mode 100644
index 00000000..b76f3cab
--- /dev/null
+++ b/lib/naughty/widget/init.lua
@@ -0,0 +1,8 @@
+---------------------------------------------------------------------------
+-- @author Emmanuel Lepage Vallee <elv1313@gmail.com>
+-- @copyright 2017 Emmanuel Lepage Vallee
+-- @module naughty.widget
+---------------------------------------------------------------------------
+
+return {
+}