aboutsummaryrefslogtreecommitdiffstats
path: root/oni/home/services/dunst.scm
blob: 079f40b6fc36d89297f7a3b2fb4c1f970c9f55a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
(define-module (oni home services dunst)
  #:use-module (ice-9 match)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-2)
  #:use-module (gnu services configuration)
  #:use-module (gnu packages dunst)
  #:use-module (gnu home services)
  #:use-module (gnu home services shepherd)
  #:use-module (gnu home services utils)
  #:use-module (guix packages)
  #:use-module (guix gexp)

  #:export (home-dunst-service-type
            home-dunst-configuration))

(define (color? value)
  (and (string? value)
       (= 7 (string-length value))
       (string-prefix? "#" value)))

(define (hyphen->underscore str)
  (string-join (string-split str #\-) "_"))

(define (integer-or-list-of-numbers? value)
  (or (integer? value)
      (list-of-numbers? value)))

(define (list-of-numbers? value)
  (and (list? value)
       (every integer? value)))

(define (list-of-strings? value)
  (and (list? value)
       (every string? value)))

(define (serialize-alist field value)
  (apply string-append (map serialize-rule value)))

(define (serialize-boolean field value)
  (serialize-string field (if value "true" "false")))

(define (serialize-color field value)
  (serialize-string field (string-append "\"" value "\"")))

(define (serialize-integer field value)
  (serialize-string field (number->string value)))

(define (serialize-integer-or-list-of-numbers field value)
  (match value
    ((? integer? _) (serialize-integer field value))
    ((? list? _) (serialize-list-of-numbers field value))
    (_ (error "Unknown type of value, not integer or list" value))))

(define (serialize-list-of-numbers field value)
  (match field
    ('offset (serialize-string field (string-join (map number->string value) "x")))
    (_ (serialize-string field (string-append "(" (string-join (map number->string value) ", ") ")")))))

(define (serialize-list-of-strings field value)
  (serialize-string field (string-join value ":")))

(define (serialize-rule value)
  (string-append "[" (car value) "]\n"
                 (string-join (map serialize-rule-property (cdr value)) "\n")
                 "\n"))

(define (serialize-rule-property value)
  (string-append (hyphen->underscore (symbol->string (car value))) " = " (object->string (cadr value))))

(define (serialize-string field value)
  (let ((field-key (hyphen->underscore (symbol->string field))))
    (string-append field-key " = " value "\n")))

(define (serialize-symbol field value)
  (serialize-string field (symbol->string value)))

(define (serialize-symbol-or-color field value)
  (match value
    ((? symbol? _) (serialize-symbol field value))
    ((? color? _) (serialize-color field value))
    (_ (error "Unknown type of value, not symbol or color" value))))

(define (symbol-or-color? value)
  (or (symbol? value)
      (color? value)))

(define-maybe color)
(define-maybe integer-or-list-of-numbers)
(define-maybe integer)
(define-maybe list-of-numbers)
(define-maybe list-of-strings)
(define-maybe string)

(define-configuration home-dunst-configuration
  (package
   (package dunst)
   "Package to use for setting Dunst")
  (font
   maybe-string
   "Display font")
  (markup
   (symbol 'no)
   "Allow pango markup")
  (format
   maybe-string
   "Specifies how various attributes of the notification should be formatted on
the notification window.")
  (sort
   (boolean #t)
   "If set to true, display notifications with higher urgency above the others.")
  (indicate-hidden
   (boolean #t)
   "If this is set to true, a notification indicating how many notifications are
not being displayed due to the notification limit will be shown in place of the
last notification slot.")
  (alignment
   (symbol 'left)
   "Defines how the text should be aligned within the notification.")
  (show-age-threshold
   (integer 60)
   "Show age of message if message is older than this time.")
  (word-wrap
   (boolean #t)
   "Specifies whether to wrap the text if the line gets longer than the maximum
notification width.")
  (ignore-newline
   (boolean #f)
   "If set to true, replace newline characters in notifications with whitespace.")
  (width
   maybe-integer-or-list-of-numbers
   "The width of the notification window in height.")
  (height
   maybe-integer
   "The maximum height of a single notification.")
  (notification-limit
   maybe-integer
   "The number of notifications that can appear at one time.")
  (offset
   maybe-list-of-numbers
   "Respectively the horizontal and vertical offset in pixels from the corner of
the screen specified by define.")
  (transparency
   maybe-integer
   "A 0-100 range on how transparent the notification window should be, with 0
being fully opaque and 100 invisible.")
  (idle-threshold
   maybe-integer
   "Don't timeout notifications if user is idle longer than this time.")
  (monitor
   maybe-integer
   "Specifies on which monitor the notifications should be displayed in, count
starts at 0.")
  (follow
   (symbol 'none)
   "Defines where the notifications should be placed in a multi-monitor setup.")
  (sticky-history
   (boolean #t)
   "If set to true, notifications that have been recalled from history will not
time out automatically.")
  (line-height
   (integer 0)
   "The amount of extra spacing between text lines in pixels.")
  (separator-height
   (integer 2)
   "The height in pixels of the separator between notifications, if set to 0 there
will be no separating line between notifications.")
  (padding
   (integer 8)
   "The distance in pixels from the content to the spearator/border of the window
in the vertical axis.")
  (horizontal-padding
   (integer 8)
   "The distance in pixels from the content to the border of the window in the
horizontal axis.")
  (separator-color
   (symbol-or-color 'frame)
   "Sets the color of the separator line between two notifications.")
  (dmenu
   maybe-string
   "The command that will be run when opening the context menu.")
  (browser
   maybe-string
   "The command that will be run when opening a URL.")
  (icon-position
   (symbol 'left)
   "Defines the position of the icon in the notification window.")
  (icon-path
   maybe-list-of-strings
   "Can be set to a list of paths to search for icons to use with notifications.")
  (frame-width
   (integer 3)
   "Defines width in pixels of frame around the notification window.")
  (frame-color
   maybe-color
   "The frame color of the notifications.")
  (max-icon-size
   (integer 128)
   "Defines the maximum size in pixels for the icons.")
  (corner-radius
   (integer 0)
   "Define the corner radius in pixels.")
  (rules
   (alist '())
   "Rules allow the conditional modification of notifications."))

(define (add-dunst-packages config)
  (list (home-dunst-configuration-package config)))

(define (serialize-dunst-configuration config)
  #~(string-append
     "[global]\n"
     #$(serialize-configuration config home-dunst-configuration-fields)))

(define (home-dunst-config-dunstrc config)
  (computed-file "dunstrc"
                 #~(call-with-output-file #$output
                     (lambda (port)
                       (display #$(serialize-dunst-configuration config)
                                port)))))

(define (home-dunst-config-files config)
  `(("dunst/dunstrc" ,(home-dunst-config-dunstrc config))))

(define (home-dunst-shepherd-service config)
  (list
   (shepherd-service
    (documentation "Start dunst")
    (provision '(dunst))
    (auto-start? #t)
    (start
     #~(make-forkexec-constructor
        (list #$(file-append (home-dunst-configuration-package config) "/bin/dunst")
              "--config" #$(home-dunst-config-dunstrc config))
        #:log-file (format #f "~a/.local/var/log/dunst.log" (getenv "HOME"))))
    (stop #~(make-kill-destructor)))))

(define home-dunst-service-type
  (service-type (name 'home-dunst)
                (extensions
                 (list (service-extension
                        home-xdg-configuration-files-service-type
                        home-dunst-config-files)
                       (service-extension
                        home-profile-service-type
                        add-dunst-packages)
                       (service-extension
                        home-shepherd-service-type
                        home-dunst-shepherd-service)))
                (default-value (home-dunst-configuration))
                (description "Configure dunst")))