hluk / CopyQ

Clipboard manager with advanced features
GNU General Public License v3.0
8.84k stars 450 forks source link

Native Notifications #1503

Open hluk opened 4 years ago

hluk commented 4 years ago

CopyQ uses own implementation of notifications. This has few drawbacks:

Advantages of using own implementation:

Solution could be to use KNotifications. Test code is in branch knotifications. This has currently following blockers (tested with KNotifications v5.75.0):

Update (2020/10/31)

Windows build crashes with KNotifications+SnoreToast when updating notifications, e.g.:

copyq:
for (var i = 0; i < 2; ++i) {
    notification('.message', 'TEST ' + i, '.id', 'TEST')
}

SnoteToast doesn't show buttons when -appID argument is also used (set by KNotifications), e.g.:

SnoreToast.exe -t TITLE -m MESSAGE -appID copyq -b OK

Update (2020/11/02)

After applying some patches to KNotifications, everything seems to work (except appID is not set and notification shows SnoreToast instead of CopyQ - see bug report below).

Builds on macOS take 40 minutes (25 minutes previously) and there doesn't seem to be a simple way to enable Homebrew cache for the KDE Frameworks libraries.

Patch to fix the crashes: https://invent.kde.org/frameworks/knotifications/-/merge_requests/15

Bug report for missing buttons: https://invent.kde.org/libraries/snoretoast/-/issues/1

Update (2020/11/03)

Just tested on macOS Catalina with KNotifications: custom notification buttons are missing. :(

Related Issues

amerlyq commented 4 years ago

Can't we simply use notify-send(1) under linux from libnotify package? After all it uses standard API and everyone is able to customize his own notification daemon, whatever their desktop environment provides (or whatever they like). Why hardcode KDE deps?

hluk commented 4 years ago

AFAIK, notify-send doesn't support buttons in notifications. Example command to create such notification in CopyQ:

copyq notification .title TITLE .message MESSAGE .button OK "copyq popup 'OK clicked' -" "data 1" .button Close "copyq popup 'Close clicked' -" "data 2"

image

I believe that in most Linux distributions it wouldn't be a big issue to use KNotifications. It's definitely much simpler to set up than in Windows.

It would be probably useful to set a custom command for notifications anyway. Currently, it's partially possible by overriding popup() and notification() script functions, but sometimes the notifications are created directly without calling the functions.

[Command]
Command="
    global.popup = function(title, message, time) {
        if (!time)
            time = 4000

        if (!message)
            message = ''

        execute(
            'notify-send',
            '--app-name=CopyQ',
            '--icon=copyq-normal',
            '--expire-time=' + time,
            title, message)
    }

    // This ignores custom buttons.
    global.notification = function() {
        var args = ['notify-send', '--app-name=CopyQ']
        var summary = ''
        var body = ''
        for (var i in arguments) {
            var arg = arguments[i]
            if (arg == '.title') {
                summary = str(arguments[++i])
            } else if (arg == '.message') {
                body = str(arguments[++i])
            } else if (arg == '.time') {
                args.push('--expire-time=' + arguments[++i])
            } else if (arg == '.icon') {
                args.push('--icon=' + arguments[++i])
            }
        }
        args.push(summary)
        args.push(body)

        execute.apply(this, args)
    }"
Icon=\xf0a1
IsScript=true
Name=Native Notifications
resolritter commented 3 years ago

@hluk

AFAIK, notify-send doesn't support buttons in notifications.

It believe it does.

Of course, the notification daemon actually has to support the feature. I use one which does (deadd-notification-center). e.g. Ubuntu comes with a different one built-in and I'm not sure if works there.

hluk commented 3 years ago

@resolritter That looks like a different script. On my machine:

❯ notify-send --version
notify-send 0.7.9

❯ notify-send --help                                                                           
Usage:
  notify-send [OPTION…] <SUMMARY> [BODY] - create a notification

Help Options:
  -?, --help                        Show help options

Application Options:
  -u, --urgency=LEVEL               Specifies the urgency level (low, normal, critical).
  -t, --expire-time=TIME            Specifies the timeout in milliseconds at which to expire the notification.
  -a, --app-name=APP_NAME           Specifies the app name for the icon
  -i, --icon=ICON[,ICON...]         Specifies an icon filename or stock icon to display.
  -c, --category=TYPE[,TYPE...]     Specifies the notification category.
  -h, --hint=TYPE:NAME:VALUE        Specifies basic extra data to pass. Valid types are int, double, string and byte.
  -v, --version                     Version of the package.

The executable (not Python script) is provided by libnotify package on Fedora 33.

resolritter commented 3 years ago

Oh yes, sorry, I've jumped to conclusions. I thought it was implied that libnotify can't do buttons on notifications, which I believe it can... I wanted to clarify that notify-send (the program) doesn't have this option and that this limitation is not tied to how the underlying library works. You should be able to have the button interactions using libnotify without needing this custom notification runtime, if that was the only showstopper.

The mechanism for those events can be read here. And I've showed that "actions", which describes the buttons, is part of the specification. The Arch Wiki page lists a couple of notification servers here, including the one I've mentioned before (deadd-notification-center) which does have support for buttons. I have not searched if other notification servers also support it but, again, since it's part of the specification, it's more likely to be widespread.