Skip to content

Commit

Permalink
Improve DND for Linux (#1523)
Browse files Browse the repository at this point in the history
  • Loading branch information
hovancik authored Dec 24, 2024
1 parent ee8c7fb commit b3198ce
Show file tree
Hide file tree
Showing 5 changed files with 355 additions and 292 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Changed
- improved break window loading
- improve DND detection for Linux
- updated many translations
- better icons for "Show time in tray"
- `showBreakActionsInStrictMode` migrated to `showTrayMenuInStrictMode`
Expand Down
108 changes: 77 additions & 31 deletions app/utils/dndManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class DndManager extends EventEmitter {
this.timer = null
this.isOnDnd = false

this._unsupDEErrorShown = false

if (process.platform === 'win32') {
this.windowsFocusAssist = require('windows-focus-assist')
this.windowsQuietHours = require('windows-quiet-hours')
Expand Down Expand Up @@ -42,39 +44,67 @@ class DndManager extends EventEmitter {
}

async _isDndEnabledLinux () {
try {
const obj = await this.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 this.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
}
const de = process.env.XDG_CURRENT_DESKTOP.toLowerCase()
// https://specifications.freedesktop.org/mime-apps-spec/latest/file.html
// https://specifications.freedesktop.org/menu-spec/latest/onlyshowin-registry.html

try {
const exec = this.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
switch (true) {
case de.includes('kde'):
try {
const obj = await this.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) { }
break
case de.includes('xfce'):
try {
const obj = await this.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) { }
break
case de.includes('gnome'):
try {
const exec = this.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) { }
break
case de.includes('cinnamon'):
try {
const exec = this.util.promisify(require('node:child_process').exec)
const { stdout } = await exec('gsettings get org.cinnamon.desktop.notifications display-notifications')
if (stdout.replace(/[^0-9a-zA-Z]/g, '') === 'false') {
return true
}
} catch (e) { }
break
case de.includes('mate'):
try {
const exec = this.util.promisify(require('node:child_process').exec)
const { stdout } = await exec('gsettings get org.mate.NotificationDaemon do-not-disturb')
if (stdout.replace(/[^0-9a-zA-Z]/g, '') === 'true') {
return true
}
} catch (e) { }
break
case de.includes('lxqt'):
return await this._getConfigValue('~/.config/lxqt/notifications.conf', 'doNotDisturb')
default:
if (!this._unsupDEErrorShown) {
log.info(`Stretchly: ${process.env.XDG_CURRENT_DESKTOP} not supported for DND detection, yet.`)
this._unsupDEErrorShown = true
}
return false
}

return false
}

async _doNotDisturb () {
Expand All @@ -97,6 +127,22 @@ class DndManager extends EventEmitter {
}
}

async _getConfigValue (filePath, key) {
try {
const data = await require('fs').promises.readFile(filePath, 'utf8')
const lines = data.split('\n')
for (const line of lines) {
const [configKey, value] = line.split('=')
if (configKey.trim() === key) {
return value.trim().toLowerCase() === 'true'
}
}
return false
} catch (e) {
return false
}
}

_checkDnd () {
this.timer = setInterval(async () => {
const doNotDisturb = await this._doNotDisturb()
Expand Down
Loading

0 comments on commit b3198ce

Please sign in to comment.