Naughty
| Languages: |
English • Français |
Naughty is a lua library that implements popup notifications for awesome3 (git). It's included in current awesome git master. Development branch can be found at naughty branch of awesome git mirror.
Contents |
Setting up Naughty
First, you have to include the library in your rc.lua:
require('naughty')
For gentoo users, you must add dbus use for awesome:
sudo flaggie awesome +dbus
If you wish to change default settings, you can redefine any of the following fields. For details refer to luadoc.
naughty.config.default_preset.timeout = 5 naughty.config.default_preset.screen = 1 naughty.config.default_preset.position = "top_right" naughty.config.default_preset.margin = 4 naughty.config.default_preset.height = 16 naughty.config.default_preset.width = 300 naughty.config.default_preset.gap = 1 naughty.config.default_preset.ontop = true naughty.config.default_preset.font = beautiful.font or "Verdana 8" naughty.config.default_preset.icon = nil naughty.config.default_preset.icon_size = 16 naughty.config.default_preset.fg = beautiful.fg_focus or '#ffffff' naughty.config.default_preset.bg = beautiful.bg_focus or '#535d6c' naughty.config.presets.normal.border_color = beautiful.border_focus or '#535d6c' naughty.config.default_preset.border_width = 1 naughty.config.default_preset.hover_timeout = nil
Using Naughty
To create a notification popup call naughty.notify({args}). Typically you should use
naughty.notify({ text="notification content", icon="/path/to/icon" })
Note that arguments to naughty.notify() are optional. The above example will use pre-configured settings resulting in uniform looking popups with custom text and icon. If you wish to set things on a per-popup basis you can override the defaults by passing required settings with arguments:
naughty.notify({
text = "notification",
title = "title",
position = "top_left"|"top_right"|"bottom_left"|"bottom_right",
timeout = 5,
icon="/path/to/image",
fg="#ffggcc",
bg="#bbggcc",
screen = 1,
ontop = false,
run = function () awful.util.spawn("wicd-client") end
})
Also note that you can use some html tags with naughty and thus any spare < will not display.
Feeding Naughty
Merely loading Naughty into your config will not produce any popups - the main problem is feeding it data.
- To test the module you can call naughty.notify from Lua prompt.
- You can call the function from any part of rc.lua (good for extra info from widgets?)
- To call the function from anything that can execute commands, use awesome-client:
echo 'naughty.notify({title = "testing", text = "naughty", timeout = 10})' | awesome-client -
The last method is good for feeding data from acpid/ivman/etc.
Examples
Ivman
Taken from ~/.ivman/IvmConfigActions.xml:
<ivm:Match name="hal.info.linux.driver" value="usb">
<ivm:Option name="exec" value="echo naughty.notify\({timeout=15, title=\'USB device\',\
text=\'$hal.info.product$\'}\) | awesome-client -" />
</ivm:Match>
<ivm:Match name="hal.volume.is_mounted" value="true">
<ivm:Option name="exec" \
value="echo naughty.notify\({timeout=15,\ title=\'Mounted\',\
text=\'$hal.block.device$ at $hal.volume.mount_point$ \($hal.volume.size$\)\'}\)\
| awesome-client -" />
</ivm:Match>
<ivm:Match name="hal.info.category" value="storage">
<ivm:Match name="hal.storage.drive_type" value="disk">
<ivm:Option name="exec" value="echo naughty.notify\({timeout=15, title=\'New Volume\',\
text=\'$hal.info.vendor$ $hal.info.product$ $hal.storage.size$\'}\) | awesome-client -" />
</ivm:Match>
</ivm:Match>
rc.lua + curl / hack for *WRT/AutoAP network switch
AutoAP is a daemon script allowing OpenWRT/DD-WRT/etc. switch networks according to signal quality which is additionally monitored with ping. See DD-WRT Wiki for more info.
function dump_autoap()
os.execute('curl -s http://gw/user/autoap.htm > /tmp/.awesome.autoap &')
end
last_ap = "none"
function get_autoap()
local ap = ""
if info then return end
local f = io.open('/tmp/.awesome.autoap')
if not f then return end
local line = f:read()
f:close()
if not line then return end
local aar, beg = line:find('<title>')
if line:sub(beg+32, beg+32) == 'S' then ap = "<span color=\"#FF602E\">searching...</span>"
elseif line:sub(beg+32,beg+32) == 'C' then
endd = line:find('</title>', beg)
ap = line:sub(beg+47,endd-2)
end
if ap ~= last_ap then
naughty.notify({title = "AutoAP network", text = ap, timeout = 10})
last_ap = ap
end
return ap
end
function hook_10s()
dump_autoap()
get_autoap()
end
awful.hooks.timer.register(10, hook_10s)
rc.lua + dict / dictionary prompt with naughty output
keybinding({ modkey}, "d", function ()
info = true
awful.prompt.run({ fg_cursor = "black",bg_cursor="orange", prompt = "<span color='#008DFA'>Dict:</span> " },
mypromptbox[mouse.screen],
function(word)
local f = io.popen("dict -d wn " .. word .. " 2>&1")
local fr = ""
for line in f:lines() do
fr = fr .. line .. '\n'
end
f:close()
naughty.notify({ text = '<span font_desc="Sans 7">'..fr..'</span>', timeout = 0, width = 400 })
end,
nil, awful.util.getdir("cache") .. "/dict")
end):add()
rc.lua / calculator prompt with naughty output
The below keybinding displays a calculator prompt (prefilled with the last result if exists) and displays a naughty popup with value of the expression. When clicked, the value is copied to the clipboard for pasting somewhere else. screenshot
val = nil
keybinding({ modkey}, "c", function ()
awful.prompt.run({ text = val and tostring(val),
selectall = true,
fg_cursor = "black",bg_cursor="orange",
prompt = "<span color='#00A5AB'>Calc:</span> " }, mypromptbox,
function(expr)
val = awful.util.eval(expr)
naughty.notify({ text = expr .. ' = <span color="white">' .. val .. "</span>",
timeout = 0,
run = function() io.popen("echo ".. val .. " | xsel -i"):close() end, })
end,
nil, awful.util.getdir("cache") .. "/calc")
end):add()
Using naughty for debugging lua code
With naughty it's very simple to check value of variables at any time you want. Forget print() and checking the console. To save yourself hassle of full syntax, you can put this function before the code you want to debug:
function dbg(vars)
local text = ""
for i=1, #vars do text = text .. vars[i] .. " | " end
naughty.notify({ text = text, timeout = 0 })
end
Now in the code you want to debug you can use the following line to see values in popups in realtime!
dbg({list, of, variables})
Popup calendar
If you don't have much desktop space and your clock only shows the time, you can have the date/calendar popup on mouse hover. Use your scroll wheel to change the month you are viewing (screenshot)
local calendar = nil
local offset = 0
function remove_calendar()
if calendar ~= nil then
naughty.destroy(calendar)
calendar = nil
offset = 0
end
end
function add_calendar(inc_offset)
local save_offset = offset
remove_calendar()
offset = save_offset + inc_offset
local datespec = os.date("*t")
datespec = datespec.year * 12 + datespec.month - 1 + offset
datespec = (datespec % 12 + 1) .. " " .. math.floor(datespec / 12)
local cal = awful.util.pread("cal -m " .. datespec)
cal = string.gsub(cal, "^%s*(.-)%s*$", "%1")
calendar = naughty.notify({
text = string.format('<span font_desc="%s">%s</span>', "monospace", os.date("%a, %d %B %Y") .. "\n" .. cal),
timeout = 0, hover_timeout = 0.5,
width = 160,
})
end
-- change clockbox for your clock widget (e.g. mytextclock)
mytextclock:add_signal("mouse::enter", function()
add_calendar(0)
end)
mytextclock:add_signal("mouse::leave", remove_calendar)
mytextclock:buttons(awful.util.table.join(
button({ }, 4, function()
add_calendar(-1)
end),
button({ }, 5, function()
add_calendar(1)
end)
))
Feeding naughty via dbus
Get the latest awesome-git (next branch), naughty will listen on the dbus interface. You can create notifications using notify-me, dbus-send, d-feet or just open any dbus-notification cable application e.g. gajim.
Using notify-send:
notify-send "awesome is" "getting naughty"
Note that on Debian/Ubuntu systems, having the notification-daemon package installed will make notify-send calls be intercepted by Gnome (the notifications won't be displayed by naughty).
Using dbus-send:
dbus-send --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.Notifications.Notify string:"" uint32:0 string:"" \ string:"title" string:"text" array:string:"" array:string:"" int32:-1
Suspending/Resuming Naughty
You can disable naughty temporarily, say when you are watching a movie, by calling naughty.suspend(), and re-enable it later, by calling naughty.resume(). Naughty stores all notifications that were send while it was suspended, and plays them back when resumed.
Replacing Notifications
Certain events, changing volume for example, may require you to generate popups one after the other immediately. But you don't want these popups to stack together (making the window underneath inaccessible). And Awesome doesn't have the notify-osd yet. Here is a workaround shared by 'psychon' on the users' mailing list:
$ echo 'return naughty.notify({ text = "foo", timeout = 0 }).id' | awesome-client
double 1551
$ echo 'return naughty.notify({ text = "foo2", timeout = 0, replaces_id = 1551 }).id' | awesome-client
double 1552
In essence, replace the previous notification with the newer one.
To be naughtier
- stacking - new popups appearing 'before' old ones
- urgency levels