gen2brain / beeep

Go cross-platform library for sending desktop notifications, alerts and beeps
BSD 2-Clause "Simplified" License
1.43k stars 89 forks source link

Allow for notifications from any user on Linux #33

Open dustin-decker opened 4 years ago

dustin-decker commented 4 years ago

It looks like it is possible for OSX: https://github.com/gen2brain/beeep/pull/13

It does not currently work for Linux though.

gen2brain commented 4 years ago

It is already like that in code https://github.com/gen2brain/beeep/blob/master/alert_darwin.go#L14, i.e. tell System Events. Did you try to use it, what happens and what is expected?

dustin-decker commented 4 years ago

On Linux the notifications only work for the user that the function is run as.

Running beeep with sudo will not create notifications for the user on Linux.

It would be nice if beeep as root would notify users of the system.

gen2brain commented 4 years ago

There is support currently for sw-notify-send that I use, repo is here https://github.com/mgorny/libtinynotify-systemwide/ .

As written there "All it does is looking over procfs (/proc) for all D-Bus session buses, and trying to send the notification to every one of them". I think all that can be reproduced in Go, just not sure about the fork() and setreuid(), it seems it is needed and Go still has some issues with it.

dustin-decker commented 4 years ago

Thanks @gen2brain I will look into that a little more.

thediveo commented 4 years ago

Go doesn't support fork() in the way used by libtinynotify-systemwide, due to the way the Golang runtime works: it needs multiple Go routines which might map to multiple OS-level threads. After a fork() syscall only the current OS-level thread would be running in the child, with the other OS-level threads lost, which might happen to have the garbage collector, background IO handlers, et cetera.

Go only supports running a new process (as a child) from some binary. What actually is possible (and what I am doing in a the lxkns package), is to run the same binary /proc/self/exe again as a child process via Command.Start(). You can pass some special env variable or CLI flag to tell the child to just carry out connecting to a dedicated dbus instance. Of course, you need to write all the parameter passing from parent to re-executed child.

pymq commented 3 years ago

If someone stumbles on this issue, here is workaround I found: https://github.com/godbus/dbus/issues/246

You can rename main function to init in reproducer code from the issue above and in new main function run beeep.Notify and it will just work.

Note: you need dbus version from this pr: https://github.com/godbus/dbus/pull/247