1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
local astal = require("astal")
local Widget = astal.Widget
local GLib = astal.GLib
local bind = astal.bind
local timeout = astal.timeout
local map = require("lib").map
local lookup_icon = require("lib").lookup_icon
local Notifd = astal.require("AstalNotifd")
local notifd = Notifd.get_default()
local NOTIFICATION_TIMEOUTMS = 5000
local function NotificationIcon(n)
local icon = "dialog-information-symbolic"
if n.app_icon and GLib.file_test(n.app_icon, "EXISTS") then
return Widget.Box({ css = string.format('background-image: url("%s");', n.app_icon) })
elseif n.app_icon and lookup_icon(n.app_icon) then
icon = n.app_icon
elseif n.app_name and lookup_icon(n.app_name) then
icon = n.app_name
end
return Widget.Icon({
icon = icon,
})
end
local function Notification(n)
local icon = Widget.Box({
valign = "START",
class_name = "icon",
NotificationIcon(n),
})
local title = Widget.Label({
class_name = "title",
xalign = 0,
justify = "LEFT",
hexpand = true,
max_width_chars = 24,
wrap = true,
ellipsize = "END",
use_markup = true,
label = n.summary,
})
local body = Widget.Label({
class_name = "body",
hexpand = true,
use_markup = true,
xalign = 0,
justify = "LEFT",
wrap = true,
label = n.body,
})
local actions = Widget.Box({
class_name = "actions",
map(n.actions, function(action)
return Widget.Button({
on_click_release = function()
return n:invoke(action.id)
end,
class_name = "action-button",
hexpand = true,
label = action.label,
})
end),
})
return Widget.EventBox({
Widget.Box({
class_name = "notification",
orientation = "VERTICAL",
Widget.Box({
icon,
Widget.Box({
orientation = "VERTICAL",
title,
body,
}),
}),
actions,
}),
})
end
return function(gdkmonitor)
local n_list = {}
local list = Widget.Box({
orientation = "VERTICAL",
setup = function(self)
self:hook(notifd, "notified", function(_, id)
local n = notifd:get_notification(id)
n_list[id] = Notification(n)
self:add(n_list[id])
local timeout_ms = n.expire_timeout > 0 and n.expire_timeout or NOTIFICATION_TIMEOUTMS
timeout(timeout_ms, function()
return n:dismiss()
end)
end)
self:hook(notifd, "resolved", function(_, id)
if n_list[id] then
n_list[id]:destroy()
n_list[id] = nil
end
end)
end,
})
return Widget.Window({
namespace = "notifications",
gdkmonitor = gdkmonitor,
anchor = astal.Astal.WindowAnchor.TOP,
layer = "OVERLAY",
class_name = "notification-popups",
visible = bind(list, "children"):as(function(v)
return v and #v > 0
end),
list,
})
end
|