keepassxreboot / keepassxc

KeePassXC is a cross-platform community-driven port of the Windows application “Keepass Password Safe”.
https://keepassxc.org/
Other
20.26k stars 1.42k forks source link

Libnotify support on Linux #9191

Open ghost opened 1 year ago

ghost commented 1 year ago

Summary

I would appreciate it if KeePassXC could use libnotify on Linux systems. Currently, all notifications in the taskbar look like they were custom-made (see screenshot).

2023-03-01_21-33-43

Examples

In this screenshot, you can see how it would look like using dunst for example.

2023-03-01_21-37-45

Context

Libnotify support would allow KeePassXC to integrate with the system's notification daemon and look a bit more uniform.

droidmonkey commented 1 year ago

Does Qt support this integration? The current notifications are from Qt api.

luzpaz commented 11 months ago

Opened a ticket to ask in https://gitlab.gnome.org/GNOME/libnotify/-/issues/33

phoerious commented 11 months ago

QSystemTrayIcon should use the correct API or protocol for showing notifications on your desktop. Back in the day, you needed to install libnotify-qt to enable this integration, but I don't think that's needed anymore. To me it looks like you are using the AppImage, which may not be able to interact with your system properly.

vetu104 commented 5 months ago

I found that for notifications to work in keepassxc, your dbus must provide a Status Notifier Host, specifically the IsStatusNotifierHostRegistered property must be true, when keepassxc is starting.

System trays in modern desktop environments seem to implement this specification, but I'm using a minimal setup with window manager only. Other Qt applications such as qBittorrent send notifications correctly even without the service. Anyway, my solution was to create a python script which lies about the existence of such service, now notifications are showing correctly in org.freedesktop.Notifications providers, instead of like shown in the OP:

#!/usr/bin/env python

import sys
import gi

from gi.repository import Gio
from gi.repository import GLib

loop = GLib.MainLoop()

NODE_INFO = Gio.DBusNodeInfo.new_for_xml("""
<?xml version="1.0" encoding="UTF-8"?>
<node>
    <interface name="org.kde.StatusNotifierWatcher">
        <method name="RegisterStatusNotifierItem">
            <arg type="s" direction="in"/>
        </method>
        <method name="RegisterStatusNotifierHost">
            <arg type="s" direction="in"/>
        </method>
        <property name="RegisteredStatusNotifierItems" type="as" access="read">
        </property>
        <property name="IsStatusNotifierHostRegistered" type="b" access="read">
        </property>
    </interface>
</node>""")

def on_call(conn, sender, path, interface, method, params, invocation):
    if method == "Get" and params[1] == "IsStatusNotifierHostRegistered":
        invocation.return_value(GLib.Variant("(v)", [GLib.Variant("b", True)]))
        conn.flush()

def on_name_acquired(conn, name):
    interface = NODE_INFO.interfaces[0]

    conn.register_object(
            "/StatusNotifierWatcher", interface, on_call)

def on_name_lost(conn, name):
    sys.exit(f"Could not acquire {name}.")

def main():
    owner_id = Gio.bus_own_name(
            Gio.BusType.SESSION,
            "org.kde.StatusNotifierWatcher",
            Gio.BusNameOwnerFlags.NONE,
            None,  # on_bus_acquired
            on_name_acquired,
            on_name_lost,
            )
    try:
        loop.run()
    except KeyboardInterrupt:
        sys.exit(0)
    finally:
        Gio.bus_unown_name(owner_id)

main()

Credits to the original script I used as base: https://github.com/xi/polybar-status-indicators

I don't usually need a system tray, so I keep it hidden/disabled and therefore I am unable to get notifications from keepassxc without this script. Most Qt applications seem to send notifications directly via the dbus interface (QDBusConnection) instead of going through the tray icon.