diff options
Diffstat (limited to 'awesome/lib/naughty')
-rw-r--r-- | awesome/lib/naughty/core.lua | 688 | ||||
-rw-r--r-- | awesome/lib/naughty/dbus.lua | 261 | ||||
-rw-r--r-- | awesome/lib/naughty/init.lua | 14 |
3 files changed, 0 insertions, 963 deletions
diff --git a/awesome/lib/naughty/core.lua b/awesome/lib/naughty/core.lua deleted file mode 100644 index 764afe2..0000000 --- a/awesome/lib/naughty/core.lua +++ /dev/null @@ -1,688 +0,0 @@ ----------------------------------------------------------------------------- ---- Notification library --- --- @author koniu <gkusnierz@gmail.com> --- @copyright 2008 koniu --- @module naughty ----------------------------------------------------------------------------- - --- Package environment -local pairs = pairs -local table = table -local type = type -local string = string -local pcall = pcall -local capi = { screen = screen, - awesome = awesome } -local timer = require("gears.timer") -local button = require("awful.button") -local screen = require("awful.screen") -local util = require("awful.util") -local bt = require("beautiful") -local wibox = require("wibox") -local surface = require("gears.surface") -local cairo = require("lgi").cairo -local dpi = require("beautiful").xresources.apply_dpi - -local function get_screen(s) - return s and capi.screen[s] -end - -local naughty = {} - ---[[-- -Naughty configuration - a table containing common popup settings. - -@table naughty.config -@tfield[opt=apply_dpi(4)] int padding Space between popups and edge of the - workarea. -@tfield[opt=apply_dpi(1)] int spacing Spacing between popups. -@tfield[opt={"/usr/share/pixmaps/"}] table icon_dirs List of directories - that will be checked by `getIcon()`. -@tfield[opt={ "png", "gif" }] table icon_formats List of formats that will be - checked by `getIcon()`. -@tfield[opt] function notify_callback Callback used to modify or reject -notifications, e.g. - naughty.config.notify_callback = function(args) - args.text = 'prefix: ' .. args.text - return args - end - -@tfield table presets Notification presets. See `config.presets`. - -@tfield table defaults Default values for the params to `notify()`. These can - optionally be overridden by specifying a preset. See `config.defaults`. - ---]] --- -naughty.config = { - padding = dpi(4), - spacing = dpi(1), - icon_dirs = { "/usr/share/pixmaps/", }, - icon_formats = { "png", "gif" }, - notify_callback = nil, -} - ---- Notification presets for `naughty.notify`. --- This holds presets for different purposes. A preset is a table of any --- parameters for `notify()`, overriding the default values --- (`naughty.config.defaults`). --- --- You have to pass a reference of a preset in your `notify()` as the `preset` --- argument. --- --- The presets `"low"`, `"normal"` and `"critical"` are used for notifications --- over DBUS. --- --- @table config.presets --- @tfield table low The preset for notifications with low urgency level. --- @tfield[opt=5] int low.timeout --- @tfield[opt=empty] table normal The default preset for every notification without a --- preset that will also be used for normal urgency level. --- @tfield table critical The preset for notifications with a critical urgency --- level. --- @tfield[opt="#ff0000"] string critical.bg --- @tfield[opt="#ffffff"] string critical.fg --- @tfield[opt=0] string critical.timeout -naughty.config.presets = { - low = { - timeout = 5 - }, - normal = {}, - critical = { - bg = "#ff0000", - fg = "#ffffff", - timeout = 0, - } -} - ---- Defaults for `naughty.notify`. --- --- @table config.defaults --- @tfield[opt=5] int timeout --- @tfield[opt=""] string text --- @tfield[opt] int screen Defaults to `awful.screen.focused`. --- @tfield[opt=true] boolean ontop --- @tfield[opt=apply_dpi(5)] int margin --- @tfield[opt=apply_dpi(1)] int border_width --- @tfield[opt="top_right"] string position -naughty.config.defaults = { - timeout = 5, - text = "", - screen = nil, - ontop = true, - margin = dpi(5), - border_width = dpi(1), - position = "top_right" -} - -naughty.notificationClosedReason = { - silent = -1, - expired = 1, - dismissedByUser = 2, - dismissedByCommand = 3, - undefined = 4 -} - --- Counter for the notifications --- Required for later access via DBUS -local counter = 1 - --- True if notifying is suspended -local suspended = false - ---- Index of notifications per screen and position. --- See config table for valid 'position' values. --- Each element is a table consisting of: --- --- @field box Wibox object containing the popup --- @field height Popup height --- @field width Popup width --- @field die Function to be executed on timeout --- @field id Unique notification id based on a counter --- @table notifications -naughty.notifications = { suspended = { } } -screen.connect_for_each_screen(function(s) - naughty.notifications[s] = { - top_left = {}, - top_middle = {}, - top_right = {}, - bottom_left = {}, - bottom_middle = {}, - bottom_right = {}, - } -end) - -capi.screen.connect_signal("removed", function(scr) - -- Destroy all notifications on this screen - for _, list in pairs(naughty.notifications[scr]) do - while #list > 0 do - naughty.destroy(list[1]) - end - end - naughty.notifications[scr] = nil -end) - ---- Notification state -function naughty.is_suspended() - return suspended -end - ---- Suspend notifications -function naughty.suspend() - suspended = true -end - ---- Resume notifications -function naughty.resume() - suspended = false - for _, v in pairs(naughty.notifications.suspended) do - v.box.visible = true - if v.timer then v.timer:start() end - end - naughty.notifications.suspended = { } -end - ---- Toggle notification state -function naughty.toggle() - if suspended then - naughty.resume() - else - naughty.suspend() - end -end - ---- Evaluate desired position of the notification by index - internal --- --- @param s Screen to use --- @param position top_right | top_left | bottom_right | bottom_left --- | top_middle | bottom_middle --- @param idx Index of the notification --- @param[opt] width Popup width. --- @param height Popup height --- @return Absolute position and index in { x = X, y = Y, idx = I } table -local function get_offset(s, position, idx, width, height) - s = get_screen(s) - local ws = s.workarea - local v = {} - idx = idx or #naughty.notifications[s][position] + 1 - width = width or naughty.notifications[s][position][idx].width - - -- calculate x - if position:match("left") then - v.x = ws.x + naughty.config.padding - elseif position:match("middle") then - v.x = (ws.width / 2) - (width / 2) - else - v.x = ws.x + ws.width - (width + naughty.config.padding) - end - - -- calculate existing popups' height - local existing = 0 - for i = 1, idx-1, 1 do - existing = existing + naughty.notifications[s][position][i].height + naughty.config.spacing - end - - -- calculate y - if position:match("top") then - v.y = ws.y + naughty.config.padding + existing - else - v.y = ws.y + ws.height - (naughty.config.padding + height + existing) - end - - -- Find old notification to replace in case there is not enough room. - -- This tries to skip permanent notifications (without a timeout), - -- e.g. critical ones. - local find_old_to_replace = function() - for i = 1, idx-1 do - local n = naughty.notifications[s][position][i] - if n.timeout > 0 then - return n - end - end - -- Fallback to first one. - return naughty.notifications[s][position][1] - end - - -- if positioned outside workarea, destroy oldest popup and recalculate - if v.y + height > ws.y + ws.height or v.y < ws.y then - naughty.destroy(find_old_to_replace()) - idx = idx - 1 - v = get_offset(s, position, idx, width, height) - end - if not v.idx then v.idx = idx end - - return v -end - ---- Re-arrange notifications according to their position and index - internal --- --- @return None -local function arrange(s) - for p in pairs(naughty.notifications[s]) do - for i,notification in pairs(naughty.notifications[s][p]) do - local offset = get_offset(s, p, i, notification.width, notification.height) - notification.box:geometry({ x = offset.x, y = offset.y }) - notification.idx = offset.idx - end - end -end - ---- Destroy notification by notification object --- --- @param notification Notification object to be destroyed --- @param reason One of the reasons from notificationClosedReason --- @return True if the popup was successfully destroyed, nil otherwise -function naughty.destroy(notification, reason) - if notification and notification.box.visible then - if suspended then - for k, v in pairs(naughty.notifications.suspended) do - if v.box == notification.box then - table.remove(naughty.notifications.suspended, k) - break - end - end - end - local scr = notification.screen - table.remove(naughty.notifications[scr][notification.position], notification.idx) - if notification.timer then - notification.timer:stop() - end - notification.box.visible = false - arrange(scr) - if notification.destroy_cb and reason ~= naughty.notificationClosedReason.silent then - notification.destroy_cb(reason or naughty.notificationClosedReason.undefined) - end - return true - end -end - ---- Get notification by ID --- --- @param id ID of the notification --- @return notification object if it was found, nil otherwise -function naughty.getById(id) - -- iterate the notifications to get the notfications with the correct ID - for s in pairs(naughty.notifications) do - for p in pairs(naughty.notifications[s]) do - for _, notification in pairs(naughty.notifications[s][p]) do - if notification.id == id then - return notification - end - end - end - end -end - ---- Install expiration timer for notification object. --- @tparam notification notification Notification object. --- @tparam number timeout Time in seconds to be set as expiration timeout. -local function set_timeout(notification, timeout) - local die = function (reason) - naughty.destroy(notification, reason) - end - if timeout > 0 then - local timer_die = timer { timeout = timeout } - timer_die:connect_signal("timeout", function() die(naughty.notificationClosedReason.expired) end) - if not suspended then - timer_die:start() - end - notification.timer = timer_die - end - notification.die = die -end - ---- Set new notification timeout. --- @tparam notification notification Notification object, which timer is to be reset. --- @tparam number new_timeout Time in seconds after which notification disappears. --- @return None. -function naughty.reset_timeout(notification, new_timeout) - if notification.timer then notification.timer:stop() end - - local timeout = new_timeout or notification.timeout - set_timeout(notification, timeout) - notification.timeout = timeout - - notification.timer:start() -end - ---- Escape and set title and text for notification object. --- @tparam notification notification Notification object. --- @tparam string title Title of notification. --- @tparam string text Main text of notification. --- @return None. -local function set_text(notification, title, text) - local escape_pattern = "[<>&]" - local escape_subs = { ['<'] = "<", ['>'] = ">", ['&'] = "&" } - - local textbox = notification.textbox - - local function setMarkup(pattern, replacements) - return textbox:set_markup_silently(string.format('<b>%s</b>%s', title, text:gsub(pattern, replacements))) - end - local function setText() - textbox:set_text(string.format('%s %s', title, text)) - end - - -- Since the title cannot contain markup, it must be escaped first so that - -- it is not interpreted by Pango later. - title = title:gsub(escape_pattern, escape_subs) - -- Try to set the text while only interpreting <br>. - if not setMarkup("<br.->", "\n") then - -- That failed, escape everything which might cause an error from pango - if not setMarkup(escape_pattern, escape_subs) then - -- Ok, just ignore all pango markup. If this fails, we got some invalid utf8 - if not pcall(setText) then - textbox:set_markup("<i><Invalid markup or UTF8, cannot display message></i>") - end - end - end -end - ---- Replace title and text of an existing notification. --- @tparam notification notification Notification object, which contents are to be replaced. --- @tparam string new_title New title of notification. If not specified, old title remains unchanged. --- @tparam string new_text New text of notification. If not specified, old text remains unchanged. --- @return None. -function naughty.replace_text(notification, new_title, new_text) - local title = new_title - - if title then title = title .. "\n" else title = "" end - - set_text(notification, title, new_text) -end - ---- Create a notification. --- --- @tab args The argument table containing any of the arguments below. --- @string[opt=""] args.text Text of the notification. --- @string[opt] args.title Title of the notification. --- @int[opt=5] args.timeout Time in seconds after which popup expires. --- Set 0 for no timeout. --- @int[opt] args.hover_timeout Delay in seconds after which hovered popup disappears. --- @tparam[opt=focused] integer|screen args.screen Target screen for the notification. --- @string[opt="top_right"] args.position Corner of the workarea displaying the popups. --- Values: `"top_right"`, `"top_left"`, `"bottom_left"`, --- `"bottom_right"`, `"top_middle"`, `"bottom_middle"`. --- @bool[opt=true] args.ontop Boolean forcing popups to display on top. --- @int[opt=auto] args.height Popup height. --- @int[opt=auto] args.width Popup width. --- @string[opt=beautiful.font or awesome.font] args.font Notification font. --- @string[opt] args.icon Path to icon. --- @int[opt] args.icon_size Desired icon size in px. --- @string[opt=`beautiful.fg_focus` or `'#ffffff'`] args.fg Foreground color. --- @string[opt=`beautiful.bg_focus` or `'#535d6c'`] args.bg Background color. --- @int[opt=1] args.border_width Border width. --- @string[opt=`beautiful.border_focus` or `'#535d6c'`] args.border_color Border color. --- @tparam[opt] func args.run Function to run on left click. The notification --- object will be passed to it as an argument. --- You need to call e.g. --- `notification.die(naughty.notificationClosedReason.dismissedByUser)` from --- there to dismiss the notification yourself. --- @tparam[opt] func args.destroy Function to run when notification is destroyed. --- @tparam[opt] table args.preset Table with any of the above parameters. --- Note: Any parameters specified directly in args will override ones defined --- in the preset. --- @tparam[opt] int args.replaces_id Replace the notification with the given ID. --- @tparam[opt] func args.callback Function that will be called with all arguments. --- The notification will only be displayed if the function returns true. --- Note: this function is only relevant to notifications sent via dbus. --- @tparam[opt] table args.actions Mapping that maps a string to a callback when this --- action is selected. --- @usage naughty.notify({ title = "Achtung!", text = "You're idling", timeout = 0 }) --- @treturn ?table The notification object, or nil in case a notification was --- not displayed. -function naughty.notify(args) - if naughty.config.notify_callback then - args = naughty.config.notify_callback(args) - if not args then return end - end - - -- gather variables together - local preset = util.table.join(naughty.config.defaults or {}, - args.preset or naughty.config.presets.normal or {}) - local timeout = args.timeout or preset.timeout - local icon = args.icon or preset.icon - local icon_size = args.icon_size or preset.icon_size - local text = args.text or preset.text - local title = args.title or preset.title - local s = get_screen(args.screen or preset.screen or screen.focused()) - if not s then - local err = "naughty.notify: there is no screen available to display the following notification:" - err = string.format("%s title='%s' text='%s'", err, tostring(title or ""), tostring(text or "")) - require("gears.debug").print_warning(err) - return - end - local ontop = args.ontop or preset.ontop - local width = args.width or preset.width - local height = args.height or preset.height - local hover_timeout = args.hover_timeout or preset.hover_timeout - local opacity = args.opacity or preset.opacity - local margin = args.margin or preset.margin - local border_width = args.border_width or preset.border_width - local position = args.position or preset.position - local actions = args.actions - local destroy_cb = args.destroy - - -- beautiful - local beautiful = bt.get() - local font = args.font or preset.font or beautiful.font or capi.awesome.font - local fg = args.fg or preset.fg or beautiful.fg_normal or '#ffffff' - local bg = args.bg or preset.bg or beautiful.bg_normal or '#535d6c' - local border_color = args.border_color or preset.border_color or beautiful.bg_focus or '#535d6c' - local notification = { screen = s, destroy_cb = destroy_cb, timeout = timeout } - - -- replace notification if needed - if args.replaces_id then - local obj = naughty.getById(args.replaces_id) - if obj then - -- destroy this and ... - naughty.destroy(obj, naughty.notificationClosedReason.silent) - end - -- ... may use its ID - if args.replaces_id <= counter then - notification.id = args.replaces_id - else - counter = counter + 1 - notification.id = counter - end - else - -- get a brand new ID - counter = counter + 1 - notification.id = counter - end - - notification.position = position - - if title then title = title .. "\n" else title = "" end - - -- hook destroy - set_timeout(notification, timeout) - local die = notification.die - - local run = function () - if args.run then - args.run(notification) - else - die(naughty.notificationClosedReason.dismissedByUser) - end - end - - local hover_destroy = function () - if hover_timeout == 0 then - die(naughty.notificationClosedReason.expired) - else - if notification.timer then notification.timer:stop() end - notification.timer = timer { timeout = hover_timeout } - notification.timer:connect_signal("timeout", function() die(naughty.notificationClosedReason.expired) end) - notification.timer:start() - end - end - - -- create textbox - local textbox = wibox.widget.textbox() - local marginbox = wibox.container.margin() - marginbox:set_margins(margin) - marginbox:set_widget(textbox) - textbox:set_valign("middle") - textbox:set_font(font) - - notification.textbox = textbox - - set_text(notification, title, text) - - local actionslayout = wibox.layout.fixed.vertical() - local actions_max_width = 0 - local actions_total_height = 0 - if actions then - for action, callback in pairs(actions) do - local actiontextbox = wibox.widget.textbox() - local actionmarginbox = wibox.container.margin() - actionmarginbox:set_margins(margin) - actionmarginbox:set_widget(actiontextbox) - actiontextbox:set_valign("middle") - actiontextbox:set_font(font) - actiontextbox:set_markup(string.format('☛ <u>%s</u>', action)) - -- calculate the height and width - local w, h = actiontextbox:get_preferred_size(s) - local action_height = h + 2 * margin - local action_width = w + 2 * margin - - actionmarginbox:buttons(util.table.join( - button({ }, 1, callback), - button({ }, 3, callback) - )) - actionslayout:add(actionmarginbox) - - actions_total_height = actions_total_height + action_height - if actions_max_width < action_width then - actions_max_width = action_width - end - end - end - - -- create iconbox - local iconbox = nil - local iconmargin = nil - local icon_w, icon_h = 0, 0 - if icon then - -- Is this really an URI instead of a path? - if type(icon) == "string" and string.sub(icon, 1, 7) == "file://" then - icon = string.sub(icon, 8) - end - -- try to guess icon if the provided one is non-existent/readable - if type(icon) == "string" and not util.file_readable(icon) then - icon = util.geticonpath(icon, naughty.config.icon_formats, naughty.config.icon_dirs, icon_size) or icon - end - - -- is the icon file readable? - icon = surface.load_uncached(icon) - - -- if we have an icon, use it - if icon then - iconbox = wibox.widget.imagebox() - iconmargin = wibox.container.margin(iconbox, margin, margin, margin, margin) - if icon_size then - local scaled = cairo.ImageSurface(cairo.Format.ARGB32, icon_size, icon_size) - local cr = cairo.Context(scaled) - cr:scale(icon_size / icon:get_height(), icon_size / icon:get_width()) - cr:set_source_surface(icon, 0, 0) - cr:paint() - icon = scaled - end - iconbox:set_resize(false) - iconbox:set_image(icon) - icon_w = icon:get_width() - icon_h = icon:get_height() - end - end - - -- create container wibox - notification.box = wibox({ fg = fg, - bg = bg, - border_color = border_color, - border_width = border_width, - type = "notification" }) - - if hover_timeout then notification.box:connect_signal("mouse::enter", hover_destroy) end - - -- calculate the width - if not width then - local w, _ = textbox:get_preferred_size(s) - width = w + (iconbox and icon_w + 2 * margin or 0) + 2 * margin - end - - if width < actions_max_width then - width = actions_max_width - end - - -- calculate the height - if not height then - local w = width - (iconbox and icon_w + 2 * margin or 0) - 2 * margin - local h = textbox:get_height_for_width(w, s) - if iconbox and icon_h + 2 * margin > h + 2 * margin then - height = icon_h + 2 * margin - else - height = h + 2 * margin - end - end - - height = height + actions_total_height - - -- crop to workarea size if too big - local workarea = s.workarea - if width > workarea.width - 2 * (border_width or 0) - 2 * (naughty.config.padding or 0) then - width = workarea.width - 2 * (border_width or 0) - 2 * (naughty.config.padding or 0) - end - if height > workarea.height - 2 * (border_width or 0) - 2 * (naughty.config.padding or 0) then - height = workarea.height - 2 * (border_width or 0) - 2 * (naughty.config.padding or 0) - end - - -- set size in notification object - notification.height = height + 2 * (border_width or 0) - notification.width = width + 2 * (border_width or 0) - - -- position the wibox - local offset = get_offset(s, notification.position, nil, notification.width, notification.height) - notification.box.ontop = ontop - notification.box:geometry({ width = width, - height = height, - x = offset.x, - y = offset.y }) - notification.box.opacity = opacity - notification.box.visible = true - notification.idx = offset.idx - - -- populate widgets - local layout = wibox.layout.fixed.horizontal() - if iconmargin then - layout:add(iconmargin) - end - layout:add(marginbox) - - local completelayout = wibox.layout.fixed.vertical() - completelayout:add(layout) - completelayout:add(actionslayout) - notification.box:set_widget(completelayout) - - -- Setup the mouse events - layout:buttons(util.table.join(button({ }, 1, run), - button({ }, 3, function() - die(naughty.notificationClosedReason.dismissedByUser) - end))) - - -- insert the notification to the table - table.insert(naughty.notifications[s][notification.position], notification) - - if suspended then - notification.box.visible = false - table.insert(naughty.notifications.suspended, notification) - end - - -- return the notification - return notification -end - -return naughty - --- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/awesome/lib/naughty/dbus.lua b/awesome/lib/naughty/dbus.lua deleted file mode 100644 index c49dc7e..0000000 --- a/awesome/lib/naughty/dbus.lua +++ /dev/null @@ -1,261 +0,0 @@ ---------------------------------------------------------------------------- --- DBUS/Notification support --- Notify --- --- @author koniu <gkusnierz@gmail.com> --- @copyright 2008 koniu --- @module naughty.dbus ---------------------------------------------------------------------------- - -assert(dbus) - --- Package environment -local pairs = pairs -local type = type -local string = string -local capi = { awesome = awesome, - dbus = dbus } -local util = require("awful.util") -local cairo = require("lgi").cairo - -local schar = string.char -local sbyte = string.byte -local tcat = table.concat -local tins = table.insert -local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1) -local naughty = require("naughty.core") - ---- Notification library, dbus bindings -local dbus = { config = {} } - --- DBUS Notification constants -local urgency = { - low = "\0", - normal = "\1", - critical = "\2" -} - ---- DBUS notification to preset mapping. --- The first element is an object containing the filter. --- If the rules in the filter match, the associated preset will be applied. --- The rules object can contain the following keys: urgency, category, appname. --- The second element is the preset. --- @tfield table 1 low urgency --- @tfield table 2 normal urgency --- @tfield table 3 critical urgency --- @table config.mapping -dbus.config.mapping = { - {{urgency = urgency.low}, naughty.config.presets.low}, - {{urgency = urgency.normal}, naughty.config.presets.normal}, - {{urgency = urgency.critical}, naughty.config.presets.critical} -} - -local function sendActionInvoked(notificationId, action) - if capi.dbus then - capi.dbus.emit_signal("session", "/org/freedesktop/Notifications", - "org.freedesktop.Notifications", "ActionInvoked", - "u", notificationId, - "s", action) - end -end - -local function sendNotificationClosed(notificationId, reason) - if capi.dbus then - capi.dbus.emit_signal("session", "/org/freedesktop/Notifications", - "org.freedesktop.Notifications", "NotificationClosed", - "u", notificationId, - "u", reason) - end -end - -local function convert_icon(w, h, rowstride, channels, data) - -- Do the arguments look sane? (e.g. we have enough data) - local expected_length = rowstride * (h - 1) + w * channels - if w < 0 or h < 0 or rowstride < 0 or (channels ~= 3 and channels ~= 4) or - string.len(data) < expected_length then - w = 0 - h = 0 - end - - local format = cairo.Format[channels == 4 and 'ARGB32' or 'RGB24'] - - -- Figure out some stride magic (cairo dictates rowstride) - local stride = cairo.Format.stride_for_width(format, w) - local append = schar(0):rep(stride - 4 * w) - local offset = 0 - - -- Now convert each row on its own - local rows = {} - - for _ = 1, h do - local this_row = {} - - for i = 1 + offset, w * channels + offset, channels do - local R, G, B, A = sbyte(data, i, i + channels - 1) - tins(this_row, schar(B, G, R, A or 255)) - end - - -- Handle rowstride, offset is stride for the input, append for output - tins(this_row, append) - tins(rows, tcat(this_row)) - - offset = offset + rowstride - end - - return cairo.ImageSurface.create_for_data(tcat(rows), format, w, h, stride) -end - -capi.dbus.connect_signal("org.freedesktop.Notifications", function (data, appname, replaces_id, icon, title, text, actions, hints, expire) - local args = { } - if data.member == "Notify" then - if text ~= "" then - args.text = text - if title ~= "" then - args.title = title - end - else - if title ~= "" then - args.text = title - else - return - end - end - if appname ~= "" then - args.appname = appname - end - for _, obj in pairs(dbus.config.mapping) do - local filter, preset = obj[1], obj[2] - if (not filter.urgency or filter.urgency == hints.urgency) and - (not filter.category or filter.category == hints.category) and - (not filter.appname or filter.appname == appname) then - args.preset = util.table.join(args.preset, preset) - end - end - local preset = args.preset or naughty.config.defaults - local notification - if actions then - args.actions = {} - - for i = 1,#actions,2 do - local action_id = actions[i] - local action_text = actions[i + 1] - - if action_id == "default" then - args.run = function() - sendActionInvoked(notification.id, "default") - naughty.destroy(notification, naughty.notificationClosedReason.dismissedByUser) - end - elseif action_id ~= nil and action_text ~= nil then - args.actions[action_text] = function() - sendActionInvoked(notification.id, action_id) - naughty.destroy(notification, naughty.notificationClosedReason.dismissedByUser) - end - end - end - end - args.destroy = function(reason) - sendNotificationClosed(notification.id, reason) - end - if not preset.callback or (type(preset.callback) == "function" and - preset.callback(data, appname, replaces_id, icon, title, text, actions, hints, expire)) then - if icon ~= "" then - args.icon = icon - elseif hints.icon_data or hints.image_data then - if hints.icon_data == nil then hints.icon_data = hints.image_data end - - -- icon_data is an array: - -- 1 -> width - -- 2 -> height - -- 3 -> rowstride - -- 4 -> has alpha - -- 5 -> bits per sample - -- 6 -> channels - -- 7 -> data - local w, h, rowstride, _, _, channels, icon_data = unpack(hints.icon_data) - args.icon = convert_icon(w, h, rowstride, channels, icon_data) - end - if replaces_id and replaces_id ~= "" and replaces_id ~= 0 then - args.replaces_id = replaces_id - end - if expire and expire > -1 then - args.timeout = expire / 1000 - end - notification = naughty.notify(args) - return "u", notification.id - end - return "u", "0" - elseif data.member == "CloseNotification" then - local obj = naughty.getById(appname) - if obj then - naughty.destroy(obj, naughty.notificationClosedReason.dismissedByCommand) - end - elseif data.member == "GetServerInfo" or data.member == "GetServerInformation" then - -- name of notification app, name of vender, version, specification version - return "s", "naughty", "s", "awesome", "s", capi.awesome.version, "s", "1.0" - elseif data.member == "GetCapabilities" then - -- We actually do display the body of the message, we support <b>, <i> - -- and <u> in the body and we handle static (non-animated) icons. - return "as", { "s", "body", "s", "body-markup", "s", "icon-static", "s", "actions" } - end -end) - -capi.dbus.connect_signal("org.freedesktop.DBus.Introspectable", function (data) - if data.member == "Introspect" then - local xml = [=[<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object - Introspection 1.0//EN" - "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> - <node> - <interface name="org.freedesktop.DBus.Introspectable"> - <method name="Introspect"> - <arg name="data" direction="out" type="s"/> - </method> - </interface> - <interface name="org.freedesktop.Notifications"> - <method name="GetCapabilities"> - <arg name="caps" type="as" direction="out"/> - </method> - <method name="CloseNotification"> - <arg name="id" type="u" direction="in"/> - </method> - <method name="Notify"> - <arg name="app_name" type="s" direction="in"/> - <arg name="id" type="u" direction="in"/> - <arg name="icon" type="s" direction="in"/> - <arg name="summary" type="s" direction="in"/> - <arg name="body" type="s" direction="in"/> - <arg name="actions" type="as" direction="in"/> - <arg name="hints" type="a{sv}" direction="in"/> - <arg name="timeout" type="i" direction="in"/> - <arg name="return_id" type="u" direction="out"/> - </method> - <method name="GetServerInformation"> - <arg name="return_name" type="s" direction="out"/> - <arg name="return_vendor" type="s" direction="out"/> - <arg name="return_version" type="s" direction="out"/> - <arg name="return_spec_version" type="s" direction="out"/> - </method> - <method name="GetServerInfo"> - <arg name="return_name" type="s" direction="out"/> - <arg name="return_vendor" type="s" direction="out"/> - <arg name="return_version" type="s" direction="out"/> - </method> - <signal name="NotificationClosed"> - <arg name="id" type="u" direction="out"/> - <arg name="reason" type="u" direction="out"/> - </signal> - <signal name="ActionInvoked"> - <arg name="id" type="u" direction="out"/> - <arg name="action_key" type="s" direction="out"/> - </signal> - </interface> - </node>]=] - return "s", xml - end -end) - --- listen for dbus notification requests -capi.dbus.request_name("session", "org.freedesktop.Notifications") - -return dbus - --- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 diff --git a/awesome/lib/naughty/init.lua b/awesome/lib/naughty/init.lua deleted file mode 100644 index 71dee9f..0000000 --- a/awesome/lib/naughty/init.lua +++ /dev/null @@ -1,14 +0,0 @@ ---------------------------------------------------------------------------- --- @author Uli Schlachter <psychon@znc.in> --- @copyright 2014 Uli Schlachter --- @module naughty ---------------------------------------------------------------------------- - -local naughty = require("naughty.core") -if dbus then - naughty.dbus = require("naughty.dbus") -end - -return naughty - --- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 |