local awful = require "awful" local beautiful = require "beautiful" local gshape = require "gears.shape" local naughty = require "naughty" local qanim = require "quarrel.animation" local qui = require "quarrel.ui" local qvars = require "quarrel.vars" local wibox = require "wibox" local rtimed = require("lib.rubato").timed local easing = require("lib.rubato").easing local consts = require "ui.wicked.consts" local gtimer = require "gears.timer" local qcolor = require "quarrel.color" local qmarkup = require "quarrel.markup" local M = require "ui.wicked.consts" function M.new(n, _, n_args) local intertext_margin = (n.title ~= "" or n.message ~= "") and qui.PADDING or 0 local title_height = n.title ~= "" and qui.CHAR_HEIGHT or 0 local message_height = n.message ~= "" and qui.CHAR_HEIGHT or 0 local app_name if n.app_name == "" then app_name = n._private._foreign and "Unknown" or "Awesome" else app_name = n.app_name end local w_progress, t_progress local level_color = consts.LEVEL_COLORS[n_args.level] or (n.urgency == "critical" and qcolor.palette.yellow()) if n.timeout > 0 then w_progress = wibox.widget { widget = wibox.container.radialprogressbar, max_value = M.NOTIF_TIMEOUT, border_color = qcolor.palette.bg.lowest, color = qcolor.palette.yellow(), border_width = qui.PADDING / 2, forced_height = qui.CHAR_HEIGHT, forced_width = qui.CHAR_HEIGHT, } t_progress = rtimed { duration = n.timeout, pos = 0, easing = easing.none, clamp_position = true, subscribed = function(pos) w_progress.value = pos end, } end local w_notif = naughty.layout.box { notification = n, placement = function(d) return awful.placement.right(d, { margins = beautiful.useless_gap * 2, }) end, bg = qcolor.palette.transparent, border_width = 0, shape = gshape.rectangle, widget_template = { widget = wibox.container.constraint, height = qui.BIG_PADDING * 2 + qui.CHAR_HEIGHT + qui.BORDER_WIDTH + qui.BIG_PADDING * 2 -- + title_height -- + message_height -- + intertext_margin, + (n.icon and qui.CHAR_HEIGHT * 2 + qui.PADDING or (title_height + message_height + intertext_margin)), strategy = "exact", { qui.styled { widget = wibox.container.background, forced_width = beautiful.notification_max_width, -- border_color = border_color, point = function(geo, args) return { x = args.parent.width, y = args.parent.height - geo.height, } end, { widget = wibox.container.margin, margins = qui.BIG_PADDING, { { widget = wibox.container.constraint, width = beautiful.notification_max_width - (qui.BIG_PADDING + qui.BORDER_WIDTH) * 2 - (level_color and qui.BIG_PADDING + qui.PADDING or 0), strategy = "max", { widget = wibox.container.place, content_fill_horizontal = true, { { { widget = wibox.widget.textbox, markup = qmarkup(app_name, { bold = true }), }, nil, w_progress, layout = wibox.layout.align.horizontal, }, { widget = wibox.container.constraint, height = qui.BORDER_WIDTH, strategy = "exact", { widget = wibox.container.background, bg = qcolor.palette.border(), }, }, { widget = wibox.container.constraint, height = n.icon and qui.CHAR_HEIGHT * 2 + qui.PADDING or (title_height + message_height + intertext_margin), strategy = "exact", { { widget = naughty.widget.icon, shape = qui.shape, notification = n, }, { { widget = wibox.container.constraint, height = title_height, strategy = "exact", { widget = wibox.widget.textbox, text = n.title or "", }, }, { widget = wibox.container.constraint, height = message_height, strategy = "exact", { widget = wibox.widget.textbox, text = n.message or "", }, }, spacing = intertext_margin, layout = wibox.layout.fixed.vertical, }, fill_space = true, spacing = n.icon and qui.BIG_PADDING, layout = wibox.layout.fixed.horizontal, }, }, layout = wibox.layout.fixed.vertical, spacing = qui.BIG_PADDING, }, }, }, -- { -- widget = wibox.container.constraint, -- strategy = "max", -- widget = wibox.container.place, { forced_width = qui.PADDING, widget = wibox.container.background, bg = level_color, shape = qui.shape, -- }, }, layout = wibox.layout.fixed.horizontal, spacing = level_color and qui.BIG_PADDING, -- expand = "outside" }, }, id = "bg", }, layout = wibox.layout.manual, }, }, } local hiding = false local old_destroy = w_notif._private.destroy_callback local t_position = qanim:new { duration = qvars.anim_duration, pos = 0, easing = qvars.easing, subscribed = function(pos) gtimer.delayed_call(function() w_notif.widget.widget:move(1, function(geo, args) if pos == 0 and hiding then old_destroy() end return { x = args.parent.width - pos, y = args.parent.height - geo.height, } end) end) end, } local t_opacity = rtimed { duration = qvars.anim_duration, intro = qvars.anim_intro, easing = easing.quadratic, pos = 0, clamp_position = true, subscribed = function(pos) w_notif.opacity = pos end, } n:disconnect_signal("destroyed", w_notif._private.destroy_callback) function w_notif._private.destroy_callback() t_opacity.target = 0 t_position:set(0) hiding = true end n:weak_connect_signal("destroyed", w_notif._private.destroy_callback) t_opacity.target = 1 t_position:set(beautiful.notification_max_width) if t_progress then t_progress.target = M.NOTIF_TIMEOUT end end return setmetatable(M, { __call = function(_, ...) return M.new(...) end, })