Merge pull request #3029 from Elv13/notification_markup
Fix most reported notification issues.
This commit is contained in:
commit
1e1f5380a6
|
@ -1478,9 +1478,11 @@ for _, prop in ipairs { "border_width", "border_color", "opacity" } do
|
||||||
return self["_"..prop]
|
return self["_"..prop]
|
||||||
end
|
end
|
||||||
client.object["set_"..prop] = function(self, value)
|
client.object["set_"..prop] = function(self, value)
|
||||||
|
if value ~= nil then
|
||||||
self._private["_user_"..prop] = true
|
self._private["_user_"..prop] = true
|
||||||
self["_"..prop] = value
|
self["_"..prop] = value
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Activate (focus) a client.
|
--- Activate (focus) a client.
|
||||||
|
|
|
@ -323,6 +323,13 @@ function notif_methods.Notify(sender, object_path, interface, method, parameters
|
||||||
notification[k] = v
|
notification[k] = v
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Update the icon if necessary.
|
||||||
|
if app_icon ~= notification._private.app_icon then
|
||||||
|
notification._private.app_icon = app_icon
|
||||||
|
notification._private.icon = nil
|
||||||
|
notification:emit_signal("property::icon")
|
||||||
|
end
|
||||||
|
|
||||||
-- Even if no property changed, restart the timeout.
|
-- Even if no property changed, restart the timeout.
|
||||||
notification:reset_timeout()
|
notification:reset_timeout()
|
||||||
else
|
else
|
||||||
|
|
|
@ -618,6 +618,17 @@ for _, prop in ipairs(properties) do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Changing the image will change the icon, make sure property::icon is emitted.
|
||||||
|
for _, prop in ipairs {"image", "images" } do
|
||||||
|
local cur = notification["set_"..prop]
|
||||||
|
|
||||||
|
notification["set_"..prop] = function(self, value)
|
||||||
|
cur(self, value)
|
||||||
|
self._private.icon = nil
|
||||||
|
self:emit_signal("property::icon")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local hints_default = {
|
local hints_default = {
|
||||||
urgency = "normal",
|
urgency = "normal",
|
||||||
resident = false,
|
resident = false,
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
local beautiful = require("beautiful")
|
||||||
|
|
||||||
|
local module = {}
|
||||||
|
|
||||||
|
-- Since some escaping needs to be undone, we have to escape the escaped <>.
|
||||||
|
local pre_escape = {["<"] = "&zzlt;", [">"] = "&zzgt;"}
|
||||||
|
|
||||||
|
local escape_pattern = "[<>&]"
|
||||||
|
local escape_subs = { ['<'] = "<", ['>'] = ">", ['&'] = "&" }
|
||||||
|
|
||||||
|
-- Also reverse escaping some allowed tags because people actually use them.
|
||||||
|
local escape_undo = {['<span '] = "<span "}
|
||||||
|
|
||||||
|
for _, allowed in ipairs {'b', 'i', 'u', 'span'} do
|
||||||
|
escape_undo['<' ..allowed..'>'] = "<" ..allowed..">"
|
||||||
|
escape_undo['</'..allowed..'>'] = "</"..allowed..">"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Best effort attempt to allow a subset of pango markup in the text while
|
||||||
|
-- removing invalid content. If invalid content is present, nothing is
|
||||||
|
-- displayed.
|
||||||
|
local function escape_text(text)
|
||||||
|
-- Take care of the already escaped content.
|
||||||
|
for pattern, subs in pairs(pre_escape) do
|
||||||
|
text = text:gsub(pattern, subs)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Try to set the text while only interpreting <br>.
|
||||||
|
text = text:gsub("<br[ /]*>", "\n")
|
||||||
|
|
||||||
|
-- Since the title cannot contain markup, it must be escaped first so that
|
||||||
|
-- it is not interpreted by Pango later.
|
||||||
|
text = text:gsub(escape_pattern, escape_subs)
|
||||||
|
|
||||||
|
-- Restore a subset of markup tags.
|
||||||
|
for pattern, subs in pairs(escape_undo) do
|
||||||
|
text = text:gsub(pattern, subs)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Restore pre-escaped content.
|
||||||
|
for subs, pattern in pairs(pre_escape) do
|
||||||
|
text = text:gsub(pattern, subs)
|
||||||
|
end
|
||||||
|
|
||||||
|
return text
|
||||||
|
end
|
||||||
|
|
||||||
|
function module.set_markup(wdg, text, fg, font)
|
||||||
|
local ret = escape_text(text or "")
|
||||||
|
fg = fg or beautiful.notification_fg
|
||||||
|
|
||||||
|
wdg:set_font(font or beautiful.notification_font)
|
||||||
|
|
||||||
|
if fg then
|
||||||
|
ret = "<span color='" .. fg .. "'>" .. ret .. "</span>"
|
||||||
|
end
|
||||||
|
|
||||||
|
wdg:set_markup_silently(ret)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
return module
|
|
@ -65,7 +65,10 @@ function icon:draw(_, cr, width, height)
|
||||||
|
|
||||||
local x, y = 0, 0
|
local x, y = 0, 0
|
||||||
|
|
||||||
if (strategy == "center" and aspect > 1) or strategy == "resize" then
|
if (strategy == "center" and aspect < 1) or strategy == "resize" then
|
||||||
|
x = math.floor((width - w*aspect) / 2)
|
||||||
|
y = math.floor((height - h*aspect) / 2)
|
||||||
|
elseif strategy == "center" and aspect > 1 then
|
||||||
x = math.floor((width - w) / 2)
|
x = math.floor((width - w) / 2)
|
||||||
y = math.floor((height - h) / 2)
|
y = math.floor((height - h) / 2)
|
||||||
end
|
end
|
||||||
|
@ -153,10 +156,11 @@ local function new(args)
|
||||||
gtable.crush(tb, icon, true)
|
gtable.crush(tb, icon, true)
|
||||||
|
|
||||||
function tb._private.icon_changed_callback()
|
function tb._private.icon_changed_callback()
|
||||||
|
|
||||||
local icn = gsurface.load_silently(tb._private.notification.icon)
|
local icn = gsurface.load_silently(tb._private.notification.icon)
|
||||||
|
|
||||||
if icn then
|
if icn then
|
||||||
tb:set_image()
|
tb:set_image(icn)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -17,22 +17,10 @@
|
||||||
local textbox = require("wibox.widget.textbox")
|
local textbox = require("wibox.widget.textbox")
|
||||||
local gtable = require("gears.table")
|
local gtable = require("gears.table")
|
||||||
local beautiful = require("beautiful")
|
local beautiful = require("beautiful")
|
||||||
|
local markup = require("naughty.widget._markup").set_markup
|
||||||
|
|
||||||
local message = {}
|
local message = {}
|
||||||
|
|
||||||
local function markup(notif, wdg)
|
|
||||||
local ret = notif.message or ""
|
|
||||||
local fg = notif.fg or beautiful.notification_fg
|
|
||||||
|
|
||||||
wdg:set_font(notif.font or beautiful.notification_font)
|
|
||||||
|
|
||||||
if fg then
|
|
||||||
ret = "<span color='" .. fg .. "'>" .. ret .. "</span>"
|
|
||||||
end
|
|
||||||
|
|
||||||
return ret
|
|
||||||
end
|
|
||||||
|
|
||||||
--- The attached notification.
|
--- The attached notification.
|
||||||
-- @property notification
|
-- @property notification
|
||||||
-- @tparam naughty.notification notification
|
-- @tparam naughty.notification notification
|
||||||
|
@ -48,7 +36,7 @@ function message:set_notification(notif)
|
||||||
self._private.message_changed_callback)
|
self._private.message_changed_callback)
|
||||||
end
|
end
|
||||||
|
|
||||||
self:set_markup(markup(notif, self))
|
markup(self, notif.message, notif.fg, notif.font)
|
||||||
|
|
||||||
self._private.notification = notif
|
self._private.notification = notif
|
||||||
|
|
||||||
|
@ -73,7 +61,12 @@ local function new(args)
|
||||||
gtable.crush(tb, message, true)
|
gtable.crush(tb, message, true)
|
||||||
|
|
||||||
function tb._private.message_changed_callback()
|
function tb._private.message_changed_callback()
|
||||||
tb:set_markup(markup(tb._private.notification, tb))
|
markup(
|
||||||
|
tb,
|
||||||
|
tb._private.notification.message,
|
||||||
|
tb._private.notification.fg,
|
||||||
|
tb._private.notification.font
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
if args.notification then
|
if args.notification then
|
||||||
|
|
|
@ -17,22 +17,10 @@
|
||||||
local textbox = require("wibox.widget.textbox")
|
local textbox = require("wibox.widget.textbox")
|
||||||
local gtable = require("gears.table")
|
local gtable = require("gears.table")
|
||||||
local beautiful = require("beautiful")
|
local beautiful = require("beautiful")
|
||||||
|
local markup = require("naughty.widget._markup").set_markup
|
||||||
|
|
||||||
local title = {}
|
local title = {}
|
||||||
|
|
||||||
local function markup(notif, wdg)
|
|
||||||
local ret = "<b>"..(notif.title or "").."</b>"
|
|
||||||
local fg = notif.fg or beautiful.notification_fg
|
|
||||||
|
|
||||||
wdg:set_font(notif.font or beautiful.notification_font)
|
|
||||||
|
|
||||||
if fg then
|
|
||||||
ret = "<span color='" .. fg .. "'>" .. ret .. "</span>"
|
|
||||||
end
|
|
||||||
|
|
||||||
return ret
|
|
||||||
end
|
|
||||||
|
|
||||||
--- The attached notification.
|
--- The attached notification.
|
||||||
-- @property notification
|
-- @property notification
|
||||||
-- @tparam naughty.notification notification
|
-- @tparam naughty.notification notification
|
||||||
|
@ -48,7 +36,7 @@ function title:set_notification(notif)
|
||||||
self._private.title_changed_callback)
|
self._private.title_changed_callback)
|
||||||
end
|
end
|
||||||
|
|
||||||
self:set_markup(markup(notif, self))
|
markup(self, notif.title, notif.fg, notif.font)
|
||||||
|
|
||||||
self._private.notification = notif
|
self._private.notification = notif
|
||||||
self._private.title_changed_callback()
|
self._private.title_changed_callback()
|
||||||
|
@ -74,7 +62,12 @@ local function new(args)
|
||||||
gtable.crush(tb, title, true)
|
gtable.crush(tb, title, true)
|
||||||
|
|
||||||
function tb._private.title_changed_callback()
|
function tb._private.title_changed_callback()
|
||||||
tb:set_markup(markup(tb._private.notification, tb))
|
markup(
|
||||||
|
tb,
|
||||||
|
tb._private.notification.title,
|
||||||
|
tb._private.notification.fg,
|
||||||
|
tb._private.notification.font
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
if args.notification then
|
if args.notification then
|
||||||
|
|
|
@ -1095,6 +1095,11 @@ table.insert(steps, function()
|
||||||
assert(not n._private.widget_template_failed)
|
assert(not n._private.widget_template_failed)
|
||||||
assert(not n.box)
|
assert(not n.box)
|
||||||
|
|
||||||
|
-- Check adding messages later
|
||||||
|
n.title = "foo"
|
||||||
|
n.message = "bar"
|
||||||
|
n.icon = big_icon
|
||||||
|
|
||||||
n:destroy()
|
n:destroy()
|
||||||
handler_called = false
|
handler_called = false
|
||||||
|
|
||||||
|
@ -1111,6 +1116,12 @@ table.insert(steps, function()
|
||||||
assert(had_error)
|
assert(had_error)
|
||||||
assert(not n.box)
|
assert(not n.box)
|
||||||
|
|
||||||
|
-- Check changing existing content.
|
||||||
|
n.title = "bar"
|
||||||
|
n.message = "foo"
|
||||||
|
n.icon = big_icon
|
||||||
|
n.image = small_icon
|
||||||
|
|
||||||
handler_called = false
|
handler_called = false
|
||||||
had_error = false
|
had_error = false
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue