From d93e7e0b05b1f1c467b4aa80cd5b23d59f13d36f Mon Sep 17 00:00:00 2001 From: Apex077 <143308884+Apex077@users.noreply.github.com> Date: Sun, 9 Aug 2026 19:26:47 +0530 Subject: [PATCH] fix(eyecare): respect Noctalia sound settings (#316) * fix(eyecare): reflect configurable break duration in notification message Fixes #63 * fix(eyecare): respect Noctalia global sound settings --- eyecare/README.md | 4 +- eyecare/service.luau | 74 +++++++++++++++++++++++++++++++++++- eyecare/translations/en.json | 2 +- 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/eyecare/README.md b/eyecare/README.md index e9be2ac..b09221a 100644 --- a/eyecare/README.md +++ b/eyecare/README.md @@ -29,7 +29,7 @@ The **Eye-Care Reminders** plugin provides a status bar widget that displays eit | --- | --- | --- | --- | | `active_duration_minutes` | `int` | `20` | Active screen time before triggering a break (minutes) | | `break_duration_seconds` | `int` | `20` | Required duration for eye-care breaks (seconds) | -| `enable_sound` | `bool` | `true` | Play notification sound when breaks start or finish | +| `enable_sound` | `bool` | `true` | Play notification sound when breaks start or finish (also requires Noctalia global sounds to be enabled) | | `enable_notifications` | `bool` | `true` | Show system-level notifications for reminders | ## IPC @@ -52,5 +52,5 @@ noctalia msg plugin apex077/eyecare:eyecare-service all reset ## Notes - **Zero-Config Idle Detection**: If `dbus-monitor` is installed, the service automatically monitors screensaver and login lock session state without manual compositor configuration. -- **Sound Players**: Sound notifications automatically try `canberra-gtk-play`, `paplay`, `pw-play`, and `aplay` to play system sounds. +- **Sound Players**: Sound notifications use Noctalia's native sound API if available, falling back to system audio players (`canberra-gtk-play`, `paplay`, `pw-play`, `aplay`), while respecting Noctalia's global sound settings. - **Grace Period**: When starting a break, a grace period (default 10 seconds or the break duration, whichever is smaller) protects against accidental inputs aborting the break immediately. diff --git a/eyecare/service.luau b/eyecare/service.luau index 7ed0da4..8ed5b4a 100644 --- a/eyecare/service.luau +++ b/eyecare/service.luau @@ -27,10 +27,80 @@ function onConfigChanged() updateState() end --- Play a notification sound using system players +-- Get Noctalia global sound volume (normalized between 0.0 and 1.0) +local function getSoundVolume() + local rawVol = noctalia.getConfig("sound_volume") + if rawVol == nil then rawVol = noctalia.getConfig("soundVolume") end + if rawVol == nil then rawVol = noctalia.getConfig("audio.sound_volume") end + if rawVol == nil and noctalia.sound and type(noctalia.sound.getVolume) == "function" then + rawVol = noctalia.sound.getVolume() + end + local vol = tonumber(rawVol) + if vol == nil then + return 1.0 + end + if vol > 1.0 then + vol = vol / 100.0 + end + return math.clamp(vol, 0.0, 1.0) +end + +-- Check whether sound cues are permitted by both plugin and Noctalia global configuration +local function isSoundAllowed() + if not settings.enable_sound then + return false + end + + -- Check Noctalia global sound configuration options + local enableSounds = noctalia.getConfig("enable_sounds") + if enableSounds == false then + return false + end + + local soundEnabled = noctalia.getConfig("sound_enabled") + if soundEnabled == false then + return false + end + + local audioEnableSounds = noctalia.getConfig("audio.enable_sounds") + if audioEnableSounds == false then + return false + end + + if noctalia.sound and type(noctalia.sound.isEnabled) == "function" then + if not noctalia.sound.isEnabled() then + return false + end + end + + if getSoundVolume() <= 0 then + return false + end + + return true +end + +-- Play a notification sound using Noctalia runtime sound API if available, falling back to system players with volume scaling local function playSound(soundName) + if not isSoundAllowed() then + return + end + + local vol = getSoundVolume() + + if noctalia.sound and type(noctalia.sound.play) == "function" then + noctalia.sound.play(soundName, vol) + return + elseif type(noctalia.playSound) == "function" then + noctalia.playSound(soundName, vol) + return + end + local path = "/usr/share/sounds/freedesktop/stereo/" .. soundName .. ".oga" - noctalia.runAsync("canberra-gtk-play -i " .. soundName .. " || paplay " .. path .. " || pw-play " .. path .. " || aplay " .. path .. " || true") + local paVol = math.floor(vol * 65536) + local pwVol = string.format("%.2f", vol) + + noctalia.runAsync(string.format("canberra-gtk-play -i %s || paplay --volume=%d %s || pw-play --volume=%s %s || aplay %s || true", soundName, paVol, path, pwVol, path, path)) end local lastLoggedIdle = nil diff --git a/eyecare/translations/en.json b/eyecare/translations/en.json index 73a1aee..f75d3b8 100644 --- a/eyecare/translations/en.json +++ b/eyecare/translations/en.json @@ -23,4 +23,4 @@ "label": "Enable Audio Feedback" } } -} +} \ No newline at end of file