Naughty

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.

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.defaults.timeout         = 5 naughty.config.defaults.screen          = 1 naughty.config.defaults.position        = "top_right" naughty.config.defaults.margin          = 4 naughty.config.defaults.height          = 16 naughty.config.defaults.width           = 300 naughty.config.defaults.gap             = 1 naughty.config.defaults.ontop           = true naughty.config.defaults.font            = beautiful.font or "Verdana 8" naughty.config.defaults.icon            = nil naughty.config.defaults.icon_size       = 16 naughty.config.defaults.fg              = beautiful.fg_focus or '#ffffff' naughty.config.defaults.bg              = beautiful.bg_focus or '#535d6c' naughty.config.presetss.border_color    = beautiful.border_focus or '#535d6c' naughty.config.defaults.border_width    = 1 naughty.config.defaults.hover_timeout   = nil

NOTE: in older versions of awesome `naughty.config.default_preset` appears to have been used (the example above works for 3.5.2).

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.

echo 'naughty.notify({title = "testing", text = "naughty", timeout = 10})' | awesome-client -
 * 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:

The last method is good for feeding data from acpid/ivman/etc.

Ivman
Taken from ~/.ivman/IvmConfigActions.xml:   

       

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(' ') if line:sub(beg+32, beg+32) == 'S' then ap = "searching... " elseif line:sub(beg+32,beg+32) == 'C' then endd = line:find(' ', 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 = " Dict: " }, 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 = ''..fr..' ', 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 = " Calc: " }, mypromptbox, function(expr) val = awful.util.eval(expr) naughty.notify({ text = expr .. ' = ' .. val .. " ",                              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})

screenshot

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('%s ', "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, and re-enable it later, by calling. 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