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 using naughty.notify
12 local naughty = require("naughty")
13 local util = require("lain.util")
15 local state = { cid = nil }
17 local function naughty_destroy_callback(reason)
18 if reason == naughty.notificationClosedReason.expired or
19 reason == naughty.notificationClosedReason.dismissedByUser then
20 local actions = state.index and state.menu[state.index - 1][2]
22 for _,action in pairs(actions) do
23 -- don't try to call nil callbacks
24 if action then action() end
31 -- Iterates over a list of pairs {label, {callbacks}}. After timeout, the last
32 -- visited choice associated callbacks are executed.
33 -- * menu: a list of pairs {label, {callbacks}
34 -- * timeout: time to wait before confirming menu selection
35 -- * icon: icon to display left to the choiced label
36 local function iterate(menu, timeout, icon)
37 timeout = timeout or 4 -- default timeout for each menu entry
38 icon = icon or nil -- icon to display on the menu
40 -- Build the list of choices
41 if not state.index then
46 -- Select one and display the appropriate notification
48 local next = state.menu[state.index]
49 state.index = state.index + 1
55 label, _ = unpack(next)
57 state.cid = naughty.notify({
61 screen = mouse.screen,
62 replaces_id = state.cid,
63 destroy = naughty_destroy_callback
67 -- Generates a menu compatible with the iterate function argument and suitable
68 -- for the following cases:
69 -- * all possible choices individually.
70 -- * all possible choices are all the possible subsets of the set of individual
71 -- choices (the powerset)
73 -- The following describes the function arguments:
74 -- * args: an array containing the following members:
75 -- * choices: the list of choices from which to generate the menu
76 -- * name: the displayed name of the menu (in the form "name: choices")
77 -- * selected_cb: the callback to execute for each selected choice. Takes
78 -- the choice as a string argument. The function
79 -- menu_iterator.naughty_destroy_callback will handle nil
80 -- callbacks. It is then fine to pass nil callbacks.
81 -- * rejected_cb: the callback to execute for each rejected choice (in the
82 -- set of possible choices, but not selected). Takes the
83 -- choice as a string argument. The function
84 -- menu_iterator.naughty_destroy_callback will handle nil
85 -- callbacks. It is then fine to pass nil callbacks.
86 -- * extra_choices: an array of pairs { choice_text, cb } for extra choices to
87 -- be added to the menu. The function
88 -- menu_iterator.naughty_destroy_callback will handle nil
89 -- callbacks. It is then fine to pass nil callbacks.
90 -- * combination: the combination of choice to generate. Possible choices
91 -- are "powerset" and "single" (the default).
92 local function menu(args)
93 local choices = assert(args.choices or args[1])
94 local name = assert(args.name or args[2])
95 local selected_cb = args.selected_cb
96 local rejected_cb = args.rejected_cb
97 local extra_choices = args.extra_choices or {}
99 local ch_combinations = args.combination == "powerset" and helpers.powerset(choices) or helpers.trivial_partition_set(choices)
100 for _,c in pairs(extra_choices) do
101 ch_combinations = awful.util.table.join(ch_combinations, {{c[1]}})
105 for _,c in pairs(ch_combinations) do
109 for _,ch in pairs(c) do
110 if awful.util.table.hasitem(choices, ch) then
111 cbs[#cbs + 1] = selected_cb and function() selected_cb(ch) end or nil
116 for _,ch in pairs(choices) do
117 if not awful.util.table.hasitem(c, ch) and awful.util.table.hasitem(choices, ch) then
118 cbs[#cbs + 1] = rejected_cb and function() rejected_cb(ch) end or nil
122 -- add user extra choices (like the choice "None" for e.g.)
123 for _,x in pairs(extra_choices) do
129 m[#m + 1] = { name .. ": " .. table.concat(c, " + "), cbs }