summaryrefslogtreecommitdiff
path: root/pkgs/astal/src/widget
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-06-18 11:34:06 -0400
committerFreya Murphy <freya@freyacat.org>2025-06-18 11:34:06 -0400
commitf11ff2f2ea4bd8ad65aa8a4fbae6f4c083117672 (patch)
treea3b4425f1e87b1aef2f0e93d6570b1d3f3c69d8d /pkgs/astal/src/widget
parentupdate hyprland config (diff)
downloaddotfiles-nix-f11ff2f2ea4bd8ad65aa8a4fbae6f4c083117672.tar.gz
dotfiles-nix-f11ff2f2ea4bd8ad65aa8a4fbae6f4c083117672.tar.bz2
dotfiles-nix-f11ff2f2ea4bd8ad65aa8a4fbae6f4c083117672.zip
add notifications to astal
Diffstat (limited to 'pkgs/astal/src/widget')
-rw-r--r--pkgs/astal/src/widget/bar/tray.lua2
-rw-r--r--pkgs/astal/src/widget/deck/init.lua18
-rw-r--r--pkgs/astal/src/widget/deck/notifications.lua136
3 files changed, 155 insertions, 1 deletions
diff --git a/pkgs/astal/src/widget/bar/tray.lua b/pkgs/astal/src/widget/bar/tray.lua
index 9046494..f0460b9 100644
--- a/pkgs/astal/src/widget/bar/tray.lua
+++ b/pkgs/astal/src/widget/bar/tray.lua
@@ -28,7 +28,7 @@ return function()
return Widget.Box({
class_name = "tray",
- visible = bind(tray, "items"):as(lib.empty):as(lib.neg),
+ visible = bind(tray, "items"):as(lib.is_true),
bind(tray, "items"):as(Items)
})
end
diff --git a/pkgs/astal/src/widget/deck/init.lua b/pkgs/astal/src/widget/deck/init.lua
new file mode 100644
index 0000000..0df5bb4
--- /dev/null
+++ b/pkgs/astal/src/widget/deck/init.lua
@@ -0,0 +1,18 @@
+local astal = require("astal")
+local Widget = require("astal.gtk3.widget")
+
+local Notifications = require("widget.deck.notifications")
+
+return function(gdkmonitor)
+ local Anchor = astal.require('Astal').WindowAnchor
+
+ return Widget.Window({
+ class_name = "deck",
+ gdkmonitor = gdkmonitor,
+ anchor = Anchor.TOP + Anchor.RIGHT,
+ Widget.Box({
+ vertical = true,
+ Notifications(),
+ }),
+ })
+end
diff --git a/pkgs/astal/src/widget/deck/notifications.lua b/pkgs/astal/src/widget/deck/notifications.lua
new file mode 100644
index 0000000..e40a815
--- /dev/null
+++ b/pkgs/astal/src/widget/deck/notifications.lua
@@ -0,0 +1,136 @@
+local astal = require("astal")
+local Widget = require("astal.gtk3").Widget
+local Gtk = require("astal.gtk3").Gtk
+local Variable = require("astal").Variable
+local Notifd = astal.require("AstalNotifd")
+local lib = require("lib")
+local bind = astal.bind
+local timeout = astal.timeout
+
+local TIMEOUT_DELAY = 5000
+
+local notifd = Notifd.get_default()
+local notifs = Variable({})
+local map = {}
+
+function update()
+ local arr = {}
+ for id,_ in pairs(map) do
+ table.insert(arr, id)
+ end
+ notifs:set(arr)
+end
+
+function set(_, id)
+ map[id] = true
+ update()
+end
+
+function delete(id)
+ map[id] = nil
+ update()
+end
+
+notifd.on_notified = set
+
+function Header(notif)
+ local show_icon = lib.is_true(notif.app_icon) or
+ lib.is_true(notif.desktop_entry)
+
+ return Widget.Box({
+ class_name = "header",
+ show_icon and Widget.Icon({
+ class_name = "app-icon",
+ icon = notif.app_icon or notif.desktop_entry,
+ }),
+ Widget.Label({
+ class_name = "app-name",
+ halign = "START",
+ ellipsize = "END",
+ label = notif.app_name or "",
+ }),
+ Widget.Label({
+ class_name = "time",
+ hexpand = true,
+ halign = "END",
+ label = lib.time(notif.time),
+ }),
+ Widget.Button({
+ on_clicked = function() delete(notif.id) end,
+ Widget.Icon({ icon = "window-close-symbolic" }),
+ }),
+ })
+end
+
+function Content(notif)
+ return Widget.Box({
+ class_name = "content",
+ (notif.image and lib.file_exists(notif.image)) and Widget.Box({
+ valign = "START",
+ class_name = "image",
+ css = string.format("background-image: url('%s')", notif.image),
+ }),
+ (notif.image and lib.is_icon(notif.image)) and Widget.Box({
+ valign = "START",
+ class_name = "icon-image",
+ Widget.Icon({
+ icon = notif.image,
+ hexpand = true,
+ vexpand = true,
+ halign = "CENTER",
+ valign = "CENTER",
+ }),
+ }),
+ Widget.Box({
+ vertical = true,
+ Widget.Label({
+ class_name = "summary",
+ halign = "START",
+ xalign = 0,
+ ellipsize = "END",
+ label = notif.summary,
+ }),
+ Widget.Label({
+ class_name = "body",
+ wrap = true,
+ use_markup = true,
+ halign = "START",
+ xalign = 0,
+ justify = "FILL",
+ label = notif.body,
+ }),
+ }),
+ })
+end
+
+function Notification(id)
+ local notif = notifd:get_notification(id)
+
+ local function destroy()
+ delete(id)
+ end
+
+ local function setup()
+ timeout(TIMEOUT_DELAY, destroy)
+ end
+
+ return Widget.EventBox({
+ class_name = "notification",
+ setup = setup,
+ on_hover_lost = destroy,
+ Widget.Box({
+ vertical = true,
+ Header(notif),
+ Gtk.Separator({ visible = true }),
+ Content(notif),
+ }),
+ })
+end
+
+function Notifications(ids)
+ return lib.map(ids, Notification)
+end
+
+return function()
+ return bind(notifs):as(Notifications)
+end