2022-02-10 00:29:21 +00:00
|
|
|
(local lgi (require :lgi))
|
|
|
|
(local dbus (require :dbus_proxy))
|
|
|
|
(local Gio lgi.Gio)
|
|
|
|
(local GLib lgi.GLib)
|
|
|
|
(local GV lgi.GLib.Variant)
|
2022-02-11 09:46:57 +00:00
|
|
|
(local GtkLayerShell lgi.GtkLayerShell)
|
2022-02-10 00:29:21 +00:00
|
|
|
(local variant dbus.variant)
|
|
|
|
(local Gtk lgi.Gtk)
|
|
|
|
|
2022-02-11 09:46:57 +00:00
|
|
|
(local inspect (require :inspect))
|
|
|
|
|
2022-02-10 00:29:21 +00:00
|
|
|
|
|
|
|
(local dbus-service-attrs
|
|
|
|
{
|
|
|
|
:bus dbus.Bus.SESSION
|
|
|
|
:name "org.freedesktop.Notifications"
|
|
|
|
:interface "org.freedesktop.Notifications"
|
|
|
|
:path "/org/freedesktop/Notifications"
|
|
|
|
})
|
|
|
|
|
|
|
|
(local bus (dbus.Proxy:new
|
|
|
|
{
|
|
|
|
:bus dbus.Bus.SESSION
|
|
|
|
:name "org.freedesktop.DBus"
|
|
|
|
:interface "org.freedesktop.DBus"
|
|
|
|
:path "/org/freedesktop/DBus"
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
(local DBUS_NAME_FLAG_DO_NOT_QUEUE 4)
|
|
|
|
(local DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1)
|
|
|
|
(local DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2)
|
|
|
|
(local DBUS_REQUEST_NAME_REPLY_EXISTS 3)
|
|
|
|
(local DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4)
|
|
|
|
|
|
|
|
|
|
|
|
(let [ret (bus:RequestName dbus-service-attrs.name
|
|
|
|
DBUS_NAME_FLAG_DO_NOT_QUEUE)]
|
|
|
|
(match ret
|
|
|
|
DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
|
|
|
|
true
|
|
|
|
|
|
|
|
DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
|
|
|
|
true
|
|
|
|
|
|
|
|
DBUS_REQUEST_NAME_REPLY_IN_QUEUE
|
|
|
|
(error "unexpected DBUS_REQUEST_NAME_REPLY_IN_QUEUE")
|
|
|
|
|
|
|
|
DBUS_REQUEST_NAME_REPLY_EXISTS
|
|
|
|
(error "already running")))
|
|
|
|
|
2022-02-11 09:46:57 +00:00
|
|
|
;; for each open message there is a widget
|
|
|
|
;; when a message is closed, we need to find its widget
|
|
|
|
;; and remove it from the container
|
|
|
|
;; if there are no messages left, hide the windox
|
|
|
|
|
|
|
|
(fn make-window []
|
2022-02-11 22:50:20 +00:00
|
|
|
(let [window (Gtk.Window {:on_destroy Gtk.main_quit})
|
2022-02-11 09:46:57 +00:00
|
|
|
box (Gtk.Box {
|
|
|
|
:orientation Gtk.Orientation.VERTICAL
|
|
|
|
})]
|
|
|
|
(window:add box)
|
|
|
|
(when true
|
|
|
|
(GtkLayerShell.init_for_window window)
|
|
|
|
(GtkLayerShell.set_layer window GtkLayerShell.Layer.TOP)
|
|
|
|
(GtkLayerShell.auto_exclusive_zone_enable window)
|
|
|
|
(GtkLayerShell.set_margin window GtkLayerShell.Edge.TOP 1)
|
|
|
|
(GtkLayerShell.set_margin window GtkLayerShell.Edge.BOTTOM 10)
|
2022-02-11 22:50:20 +00:00
|
|
|
|
|
|
|
(GtkLayerShell.set_anchor window GtkLayerShell.Edge.TOP 1)
|
|
|
|
(GtkLayerShell.set_anchor window GtkLayerShell.Edge.LEFT 1)
|
|
|
|
(GtkLayerShell.set_anchor window GtkLayerShell.Edge.RIGHT 1))
|
2022-02-11 09:46:57 +00:00
|
|
|
(window:hide)
|
|
|
|
{:window window :box box}))
|
|
|
|
|
|
|
|
(local window (make-window))
|
|
|
|
|
|
|
|
(local notifications {})
|
|
|
|
|
|
|
|
(fn update-window []
|
|
|
|
(each [id widget (pairs notifications)]
|
|
|
|
(print id (widget:get_parent))
|
|
|
|
(if (not (widget:get_parent))
|
|
|
|
(window.box:pack_start widget false false 5)))
|
|
|
|
(if (next notifications) (window.window:show_all) (window:hide)))
|
|
|
|
|
2022-02-10 00:29:21 +00:00
|
|
|
(var notification-id 10)
|
2022-02-11 09:46:57 +00:00
|
|
|
(fn next-notification-id []
|
2022-02-10 00:29:21 +00:00
|
|
|
(set notification-id (+ notification-id 1))
|
|
|
|
notification-id)
|
|
|
|
|
2022-02-11 09:46:57 +00:00
|
|
|
(fn update-notification-widget [widget noti]
|
|
|
|
(set widget.label noti.summary))
|
|
|
|
|
|
|
|
(fn add-notification [noti]
|
|
|
|
(let [id (if (= noti.id 0) (next-notification-id) noti.id)
|
|
|
|
widget (or (. notifications id)
|
|
|
|
(Gtk.Label))]
|
|
|
|
(update-notification-widget widget noti)
|
|
|
|
(tset notifications id widget)
|
|
|
|
(update-window)
|
|
|
|
id))
|
|
|
|
|
|
|
|
(fn make-notification [params]
|
|
|
|
{
|
|
|
|
:sender (. params 1)
|
|
|
|
:id (. params 2)
|
|
|
|
:summary (. params 4)
|
|
|
|
:body (. params 6)
|
|
|
|
})
|
2022-02-10 00:29:21 +00:00
|
|
|
|
|
|
|
(fn handle-dbus-method-call [conn sender path interface method params invocation]
|
|
|
|
(when (and (= path dbus-service-attrs.path)
|
|
|
|
(= interface dbus-service-attrs.interface))
|
|
|
|
(match method
|
|
|
|
"GetCapabilities"
|
|
|
|
(invocation:return_value (GV "as" ["actions"]))
|
|
|
|
|
|
|
|
"GetServerInformation"
|
|
|
|
(invocation:return_value
|
|
|
|
(GV "(ssss)" ["crier"
|
|
|
|
"telent"
|
|
|
|
"0.1"
|
|
|
|
"1.2"]))
|
|
|
|
|
|
|
|
"Notify"
|
2022-02-11 09:46:57 +00:00
|
|
|
(let [p (dbus.variant.strip params)
|
|
|
|
n (make-notification p)]
|
|
|
|
(invocation:return_value (GV "(u)"
|
|
|
|
[(add-notification n)])))
|
|
|
|
)))
|
2022-02-10 00:29:21 +00:00
|
|
|
|
|
|
|
(fn handle-dbus-get [conn sender path interface name]
|
|
|
|
(when (and (= path dbus-service-attrs.path)
|
|
|
|
(= interface dbus-service-attrs.interface)
|
|
|
|
(= name "Visible"))
|
|
|
|
(lgi.GLib.Variant "b" true)))
|
|
|
|
|
|
|
|
(local interface-info
|
|
|
|
(let [xml (: (io.open "interface.xml" "r") :read "*a")
|
|
|
|
node-info (Gio.DBusNodeInfo.new_for_xml xml)]
|
|
|
|
(. node-info.interfaces 1)))
|
|
|
|
|
|
|
|
(Gio.DBusConnection.register_object
|
|
|
|
bus.connection
|
|
|
|
dbus-service-attrs.path
|
|
|
|
interface-info
|
|
|
|
(lgi.GObject.Closure handle-dbus-method-call)
|
|
|
|
(lgi.GObject.Closure handle-dbus-get)
|
|
|
|
(lgi.GObject.Closure (fn [a] (print "set"))))
|
|
|
|
|
|
|
|
(Gtk:main)
|