naughty: popup size can now adjust to icon height

* If icon is present, popup height will now be adjusted to the greater
  of text-height and icon-height.
* Reorganized notify() into more logical order to allow this.

Signed-off-by: koniu <gkusnierz@gmail.com>
This commit is contained in:
koniu 2008-11-15 16:55:38 +00:00
parent 3cc64ab081
commit edeabd1a8b
1 changed files with 45 additions and 51 deletions

View File

@ -30,7 +30,7 @@ module("naughty")
-- Valid values: 'top_right', 'top_left', 'bottom_right', 'bottom_left'. -- Valid values: 'top_right', 'top_left', 'bottom_right', 'bottom_left'.
-- Default: 'top_right' -- Default: 'top_right'
-- @field margin Space between popups and edge of the workarea. Default: 4 -- @field margin Space between popups and edge of the workarea. Default: 4
-- @field height Height of a single-line popup. Default: 16 -- @field height Height of a single line of text. Default: 16
-- @field width Width of a popup. Default: 300 -- @field width Width of a popup. Default: 300
-- @field gap Spacing between popups. Default: 1 -- @field gap Spacing between popups. Default: 1
-- @field ontop Boolean forcing popups to display on top. Default: true -- @field ontop Boolean forcing popups to display on top. Default: true
@ -67,8 +67,8 @@ config.hover_timeout = nil
--- Index of notifications. See config table for valid 'position' values. --- Index of notifications. See config table for valid 'position' values.
-- Each element is a table consisting of: -- Each element is a table consisting of:
-- @field box Wibox object containing the popup -- @field box Wibox object containing the popup
-- @field lines Number of lines in title..text -- @field height Popup height
-- @field timer Function to be executed on timeout -- @field die Function to be executed on timeout
-- @name notifications[position] -- @name notifications[position]
-- @class table -- @class table
@ -79,14 +79,13 @@ notifications = {
bottom_right = {}, bottom_right = {},
} }
--- Evaluate desired position of the notification by index - internal --- Evaluate desired position of the notification by index - internal
-- @param idx Index of the notification -- @param idx Index of the notification
-- @param position top_right | top_left | bottom_right | bottom_left -- @param position top_right | top_left | bottom_right | bottom_left
-- @param lines Number of text lines in the notification -- @param height Popup height
-- @return Absolute position in {x, y} dictionary -- @return Absolute position in {x, y} dictionary
local function get_offset(idx, position, lines) local function get_offset(idx, position, height)
local ws = capi.screen[config.screen].workarea local ws = capi.screen[config.screen].workarea
local v = {} local v = {}
@ -100,21 +99,21 @@ local function get_offset(idx, position, lines)
-- calculate existing popups' height -- calculate existing popups' height
local existing = 0 local existing = 0
for i = 1, idx-1, 1 do for i = 1, idx-1, 1 do
existing = existing + config.height*notifications[position][i].lines + config.gap + config.border_width*2 existing = existing + notifications[position][i].height + config.gap + config.border_width*2
end end
-- calculate y -- calculate y
if position:match("top") then if position:match("top") then
v.y = ws.y + config.margin + existing v.y = ws.y + config.margin + existing
else else
v.y = ws.y + ws.height - (config.margin + config.border_width + config.height*lines + existing) v.y = ws.y + ws.height - (config.margin + config.border_width + height + existing)
end end
-- if positioned outside workarea, destroy oldest popup and recalculate -- if positioned outside workarea, destroy oldest popup and recalculate
if v.y + config.height*lines > ws.y + ws.height or v.y < ws.y then if v.y + height > ws.y + ws.height or v.y < ws.y then
idx = idx - 1 idx = idx - 1
destroy(notifications[position][1]) destroy(notifications[position][1])
v = get_offset(idx, position, lines) v = get_offset(idx, position, height)
end end
return v return v
@ -125,8 +124,8 @@ end
local function arrange() local function arrange()
for p,pos in pairs(notifications) do for p,pos in pairs(notifications) do
for i,notification in pairs(notifications[p]) do for i,notification in pairs(notifications[p]) do
local offset = get_offset(i, p, notification.lines) local offset = get_offset(i, p, notification.height)
notification.box:geometry({ x = offset.x, y = offset.y, width = config.width, height = notification.lines * config.height }) notification.box:geometry({ x = offset.x, y = offset.y, width = config.width, height = notification.height })
notification.idx = i notification.idx = i
end end
end end
@ -160,51 +159,22 @@ end
-- @param run Function to run on left click -- @param run Function to run on left click
-- @usage naughty.notify({ title = 'Achtung!', text = 'You\'re idling', timeout = 0 }) -- @usage naughty.notify({ title = 'Achtung!', text = 'You\'re idling', timeout = 0 })
function notify(args) function notify(args)
-- gather settings together -- gather variables together
local timeout = args.timeout or config.timeout local timeout = args.timeout or config.timeout
local position = args.position or config.position
local icon = args.icon or config.icon local icon = args.icon or config.icon
local icon_size = args.icon_size or config.icon_size local icon_size = args.icon_size or config.icon_size
local text = args.text or "" local text = args.text or ""
local screen = args.screen or config.screen local screen = args.screen or config.screen
local ontop = args.ontop or config.ontop local ontop = args.ontop or config.ontop
local notification = {}
notification.position = args.position or config.position
notification.idx = #notifications[notification.position] + 1
local title = "" local title = ""
if args.title then if args.title then title = " " .. args.title .. "\n" end
title = " " .. args.title .. "\n"
end
local lines = 1
for i in string.gmatch(title..text, "\n") do
lines = lines + 1
end
-- create the container wibox
local idx = #notifications[position] + 1
local box = wibox({ name = "not" .. idx,
position = "floating",
fg = args.fg or config.fg,
bg = args.bg or config.bg,
border_color = config.border_color,
border_width = config.border_width })
-- position the wibox
local offset = get_offset(idx, position, lines)
box:geometry({ width = config.width,
height = config.height * lines,
x = offset.x,
y = offset.y })
box.ontop = ontop
box.screen = screen
local notification = {
box = box,
lines = lines,
position = position,
idx = idx
}
-- hook destroy
local die = function () destroy(notification) end local die = function () destroy(notification) end
hooks.timer.register(timeout, die) hooks.timer.register(timeout, die)
notification.die = die notification.die = die
@ -216,7 +186,7 @@ function notify(args)
else hooks.timer.register(config.hover_timeout, die) end else hooks.timer.register(config.hover_timeout, die) end
end end
-- populate the wibox with widgets -- create textbox
local textbox = widget({ type = "textbox", name = "text", align = "flex" }) local textbox = widget({ type = "textbox", name = "text", align = "flex" })
textbox:buttons({ button({ }, 1, run), textbox:buttons({ button({ }, 1, run),
button({ }, 3, die) }) button({ }, 3, die) })
@ -224,6 +194,7 @@ function notify(args)
config.font, title, text) config.font, title, text)
if config.hover_timeout then textbox.mouse_enter = hover_destroy end if config.hover_timeout then textbox.mouse_enter = hover_destroy end
-- create iconbox
local iconbox = nil local iconbox = nil
if icon then if icon then
iconbox = widget({ type = "imagebox", name = "icon", align = "left" }) iconbox = widget({ type = "imagebox", name = "icon", align = "left" })
@ -238,10 +209,33 @@ function notify(args)
if config.hover_timeout then iconbox.mouse_enter = hover_destroy end if config.hover_timeout then iconbox.mouse_enter = hover_destroy end
end end
box.widgets = { iconbox, textbox } -- create container wibox
notification.box = wibox({ name = "not" .. notification.idx,
position = "floating",
fg = args.fg or config.fg,
bg = args.bg or config.bg,
border_color = config.border_color,
border_width = config.border_width })
-- position the wibox
local lines = 1; for i in string.gmatch(title..text, "\n") do lines = lines + 1 end
if iconbox and iconbox.image.height > lines * config.height then
notification.height = iconbox.image.height
else
notification.height = lines * config.height end
local offset = get_offset(notification.idx, notification.position, notification.height)
notification.box:geometry({ width = config.width,
height = notification.height,
x = offset.x,
y = offset.y })
notification.box.ontop = ontop
notification.box.screen = screen
-- populate widgets
notification.box.widgets = { iconbox, textbox }
-- insert the notification to the table -- insert the notification to the table
table.insert(notifications[position],notification) table.insert(notifications[notification.position],notification)
end end
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80