How do detect Do Not Disturb via DBUS

Hi there,

for my open-source app, I am trying to detect when my users are in DND to not disturb them. I have this working for KDE, XFCE and trying to do for Gnome now.

I am in node, so using some dbus library, and would like to do the same for Gnome.

    const dbus = require('dbus-next')
    const bus = dbus.sessionBus()
    try {
      const obj = await bus.getProxyObject('org.freedesktop.Notifications', '/org/freedesktop/Notifications')
      const properties = obj.getInterface('org.freedesktop.DBus.Properties')
      const dndEnabled = await properties.Get('org.freedesktop.Notifications', 'Inhibited')
      if (await dndEnabled.value) {
        return true
      }
    } catch (e) {
      // KDE is not running
    }

    try {
      const obj = await bus.getProxyObject('org.xfce.Xfconf', '/org/xfce/Xfconf')
      const properties = obj.getInterface('org.xfce.Xfconf')
      const dndEnabled = await properties.GetProperty('xfce4-notifyd', '/do-not-disturb')
      if (await dndEnabled.value) {
        return true
      }
    } catch (e) {
      // XFCE is not running
    }

I am trying to deduct with d-feet based on some ai / google help but can’t find the right place where it is:

image

Any help appreciated!

I’m not aware of a freedesktop.org spec for Do Not Disturb.

Here is what I get in GNOME when I switch the Do Not Disturb on:

$ dconf watch /
/org/gnome/desktop/notifications/show-banners
  false

So it uses a GSettings key.

My suggestion is to look for the GSettings documentation and try with that. (dconf is one of the backends of GSettings).

If there is a freedesktop.org spec, then it’s better to use it of course.

Thanks for the hint, it gave me idea to watch for dbus messages with dbus-monitor:

signal time=1698415947.190391 sender=:1.49 -> destination=(null destination) serial=67 path=/ca/desrt/dconf/Writer/user; interface=ca.desrt.dconf.Writer; member=Notify
   string "/org/gnome/desktop/notifications/show-banners"
   array [
      string ""
   ]
   string ":1.49:user:27"

On KDE, this happens when switching DND:

signal time=1698417416.459941 sender=:1.20 -> destination=(null destination) serial=885 path=/org/freedesktop/Notifications; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
  string "org.freedesktop.Notifications"
  array [
     dict entry(
        string "Inhibited"
        variant             boolean false
     )
  ]
  array [
  ]

On XFCE

signal time=1698418027.633894 sender=:1.12 -> destination=(null destination) serial=392 path=/org/xfce/Xfconf; interface=org.xfce.Xfconf; member=PropertyChanged
   string "xfce4-notifyd"
   string "/do-not-disturb"
   variant       boolean true

I am not sure how to proceed with this, though.

I think there is no API to know if the desktop is in Do Not Disturb mode, because apps are supposed to send notifications as usual, it’s just that the user won’t be disturbed by them and can see the notifications afterwards.

What are you trying to achieve? What’s your goal by detecting the Do Not Disturb?

The fact that the system can be introspected (with D-Bus or other methods) when desktop settings are modified doesn’t mean that there is a guaranteed stable API for it.

@swilmet I have an electron app that reminds people to take a break when working on computer: GitHub - hovancik/stretchly: The break time reminder app

It works by showing a window in specified intervals with some break / stretch idea. For MacOS / Windows I have a functionality where people can choose to not be shown breaks in DND mode. I want to have the same for Linux.

Here’s my PR where I am adding this (currently working on KDE, XFCE): basically when user enables DND, I pause showing of breaks and when DND ends breaks are resumed

So in the end I did this, hopefully it works :slight_smile:

    try {
      const util = require('node:util')
      const exec = util.promisify(require('node:child_process').exec)
      const { stdout } = await exec('gsettings get org.gnome.desktop.notifications show-banners')
      if (stdout.replace(/[^0-9a-zA-Z]/g, '') === 'false') {
        return true
      }
    } catch (e) {
      // Gnome / gsettings is not running
    }

That’s a solution, running the gsettings command in a sub-process. Probably good enough :slight_smile:

Otherwise I don’t know if you have access to the GSettings API, part of the GIO library, from the programming language that you use. You can check https://gtk.org/ to see the language bindings.

Edit: GSettings has an introspectable part in its API, to look if the schema and key is present. Otherwise if you try to get a value directly, and the gsettings schema or key is not present on the system, the program crashes. In C it’s the g_settings_schema_has_key() function.

This topic was automatically closed 45 days after the last reply. New replies are no longer allowed.