aboutsummaryrefslogtreecommitdiffstats
path: root/internal/notify/policy.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/notify/policy.go')
-rw-r--r--internal/notify/policy.go95
1 files changed, 95 insertions, 0 deletions
diff --git a/internal/notify/policy.go b/internal/notify/policy.go
new file mode 100644
index 0000000..c1dc647
--- /dev/null
+++ b/internal/notify/policy.go
@@ -0,0 +1,95 @@
+// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+package notify
+
+import "github.com/godbus/dbus/v5"
+
+// Urgency is the freedesktop urgency level.
+type Urgency string
+
+const (
+ Low Urgency = "low"
+ Normal Urgency = "normal"
+ Critical Urgency = "critical"
+)
+
+// DefaultTimeoutMS is the balloon lifetime for an urgency when the client sends
+// expire_timeout 0. Critical never expires, which is 0 here.
+func DefaultTimeoutMS(u Urgency) int64 {
+ switch u {
+ case Low, Normal:
+ return 10_000
+ default:
+ return 0
+ }
+}
+
+// EffectiveTimeoutMS resolves the client's expire_timeout: 0 means the urgency
+// default, -1 means never, anything positive is milliseconds and wins.
+func EffectiveTimeoutMS(expire int32, u Urgency) int64 {
+ switch {
+ case expire == -1:
+ return 0
+ case expire == 0:
+ return DefaultTimeoutMS(u)
+ default:
+ return int64(expire)
+ }
+}
+
+// UrgencyFromHints reads the urgency byte: 0 low, 1 normal, 2 critical. A
+// missing or malformed value is normal, the same default libnotify uses.
+func UrgencyFromHints(hints map[string]dbus.Variant) Urgency {
+ v, ok := hints["urgency"]
+ if !ok {
+ return Normal
+ }
+ switch n := v.Value().(type) {
+ case uint8:
+ switch n {
+ case 0:
+ return Low
+ case 2:
+ return Critical
+ }
+ case int32:
+ switch n {
+ case 0:
+ return Low
+ case 2:
+ return Critical
+ }
+ }
+ return Normal
+}
+
+// StackTagFromHints reads the dunst stack tag, then the danix spelling. Both
+// mean the same thing and dunst wins when a client sends both.
+func StackTagFromHints(hints map[string]dbus.Variant) string {
+ for _, key := range []string{"x-dunst-stack-tag", "x-danix-stack-tag"} {
+ if v, ok := hints[key]; ok {
+ if s, ok := v.Value().(string); ok && s != "" {
+ return s
+ }
+ }
+ }
+ return ""
+}
+
+// ParseActions turns the spec's flat [key, label, key, label] array into pairs.
+func ParseActions(flat []string) [][2]string {
+ out := make([][2]string, 0, len(flat)/2)
+ for i := 0; i+1 < len(flat); i += 2 {
+ out = append(out, [2]string{flat[i], flat[i+1]})
+ }
+ return out
+}