All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
3 Licensed under GNU General Public License v2
4 * (c) 2017, Simon Désaulniers <sim.desaulniers@gmail.com>
5 * (c) 2017, Uli Schlachter
6 * (c) 2017, Jeferson Siqueira <jefersonlsiq@gmail.com>
10 -- Menu iterator with Naughty notifications
11 -- lain.util.menu_iterator
13 local naughty = require("naughty")
14 local helpers = require("lain.helpers")
15 local util = require("lain.util")
16 local atable = require("awful.util").table
19 local tconcat = table.concat
20 local unpack = unpack or table.unpack -- lua 5.1 retro-compatibility
22 local state = { cid = nil }
24 local function naughty_destroy_callback(reason)
25 local closed = naughty.notificationClosedReason
26 if reason == closed.expired or reason == closed.dismissedByUser then
27 local actions = state.index and state.menu[state.index - 1][2]
29 for _,action in pairs(actions) do
30 -- don't try to call nil callbacks
31 if action then action() end
38 -- Iterates over a menu.
39 -- After the timeout, callbacks associated to the last visited choice are
41 -- * menu: a list of {label, {callbacks}} pairs
42 -- * timeout: time to wait before confirming the menu selection
43 -- * icon: icon to display in the notification of the chosen label
44 local function iterate(menu, timeout, icon)
45 local timeout = timeout or 4 -- default timeout for each menu entry
46 local icon = icon or nil -- icon to display on the menu
48 -- Build the list of choices
49 if not state.index then
54 -- Select one and display the appropriate notification
56 local next = state.menu[state.index]
57 state.index = state.index + 1
63 label, _ = unpack(next)
66 state.cid = naughty.notify({
70 screen = mouse.screen,
71 replaces_id = state.cid,
72 destroy = naughty_destroy_callback
76 -- Generates a menu compatible with the first argument of `iterate` function and
77 -- suitable for the following cases:
78 -- * all possible choices individually (partition of singletons);
79 -- * all possible subsets of the set of choices (powerset).
82 -- * args: an array containing the following members:
83 -- * choices: Array of choices (string) on which the menu will be
85 -- * name: Displayed name of the menu (in the form "name: choices").
86 -- * selected_cb: Callback to execute for each selected choice. Takes
87 -- the choice as a string argument. Can be `nil` (no action
89 -- * rejected_cb: Callback to execute for each rejected choice (possible
90 -- choices which are not selected). Takes the choice as a
91 -- string argument. Can be `nil` (no action to execute).
92 -- * extra_choices: An array of extra { choice_str, callback_fun } pairs to be
93 -- added to the menu. Each callback_fun can be `nil`.
94 -- * combination: The combination of choices to generate. Possible values:
95 -- "powerset" and "single" (default).
97 -- * m: menu to be iterated over.
98 local function menu(args)
99 local choices = assert(args.choices or args[1])
100 local name = assert(args.name or args[2])
101 local selected_cb = args.selected_cb
102 local rejected_cb = args.rejected_cb
103 local extra_choices = args.extra_choices or {}
105 local ch_combinations = args.combination == "powerset" and helpers.powerset(choices) or helpers.trivial_partition_set(choices)
107 for _,c in pairs(extra_choices) do
108 ch_combinations = atable.join(ch_combinations, {{c[1]}})
111 local m = {} -- the menu
113 for _,c in pairs(ch_combinations) do
118 for _,ch in pairs(c) do
119 if atable.hasitem(choices, ch) then
120 cbs[#cbs + 1] = selected_cb and function() selected_cb(ch) end or nil
125 for _,ch in pairs(choices) do
126 if not atable.hasitem(c, ch) and atable.hasitem(choices, ch) then
127 cbs[#cbs + 1] = rejected_cb and function() rejected_cb(ch) end or nil
131 -- add user extra choices (like the choice "None" for example)
132 for _,x in pairs(extra_choices) do
138 m[#m + 1] = { name .. ": " .. tconcat(c, " + "), cbs }
145 return { iterate = iterate, menu = menu }