Add support for OSD of volume changes
This commit is contained in:
parent
2e63bcff13
commit
94bbd26205
128
pw-ui.el
128
pw-ui.el
@ -33,6 +33,39 @@
|
|||||||
:type 'number
|
:type 'number
|
||||||
:group 'pipewire)
|
:group 'pipewire)
|
||||||
|
|
||||||
|
(defcustom pipewire-osd-enable t
|
||||||
|
"If non-nil, display on screen display indicator for some operations.
|
||||||
|
The indicator is displayed only on graphical terminals."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'pipewire)
|
||||||
|
|
||||||
|
(defcustom pipewire-osd-timeout 3
|
||||||
|
"Number of seconds to show an on screen display indicator."
|
||||||
|
:type 'number
|
||||||
|
:group 'pipewire)
|
||||||
|
|
||||||
|
(defcustom pipewire-osd-width (/ 100 pipewire-volume-step)
|
||||||
|
"Width of the on screen display indicator in characters."
|
||||||
|
:type 'natnum
|
||||||
|
:group 'pipewire)
|
||||||
|
|
||||||
|
(defcustom pipewire-osd-volume-on-color "lime green"
|
||||||
|
"Color to use in the on screen display indicator for active volume."
|
||||||
|
:type 'color
|
||||||
|
:group 'pipewire)
|
||||||
|
|
||||||
|
(defcustom pipewire-osd-volume-off-color "pale green"
|
||||||
|
"Color to use in the on screen display indicator for inactive volume."
|
||||||
|
:type 'color
|
||||||
|
:group 'pipewire)
|
||||||
|
|
||||||
|
(defcustom pipewire-osd-frame-parameters
|
||||||
|
`((left . (+ 50))
|
||||||
|
(top . (- 50)))
|
||||||
|
"Alist of frame parameters for the on screen display indicator."
|
||||||
|
:type '(alist :key-type symbol :value-type sexp)
|
||||||
|
:group 'pip-frame)
|
||||||
|
|
||||||
(defface pipewire-label-face
|
(defface pipewire-label-face
|
||||||
'((t (:weight bold :overline t)))
|
'((t (:weight bold :overline t)))
|
||||||
"Face to use for PipeWire node group labels."
|
"Face to use for PipeWire node group labels."
|
||||||
@ -121,16 +154,11 @@
|
|||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(forward-line (1- current-line))))
|
(forward-line (1- current-line))))
|
||||||
|
|
||||||
(defun pw-ui--update (&optional message)
|
(defun pw-ui--current-object-id ()
|
||||||
(if (get-buffer pipewire-buffer)
|
(get-text-property (point) 'pw-object-id))
|
||||||
(with-current-buffer pipewire-buffer
|
|
||||||
(pipewire-refresh))
|
|
||||||
(pw-lib-refresh))
|
|
||||||
(when message
|
|
||||||
(message message)))
|
|
||||||
|
|
||||||
(defun pw-ui--current-object (&optional use-default-p allowed-types)
|
(defun pw-ui--current-object (&optional use-default-p allowed-types)
|
||||||
(let* ((id (get-text-property (point) 'pw-object-id))
|
(let* ((id (pw-ui--current-object-id))
|
||||||
(object (when id (pw-lib-get-object id))))
|
(object (when id (pw-lib-get-object id))))
|
||||||
(when (and object
|
(when (and object
|
||||||
(not (null allowed-types))
|
(not (null allowed-types))
|
||||||
@ -140,6 +168,84 @@
|
|||||||
(setq object (pw-lib-default-audio-sink)))
|
(setq object (pw-lib-default-audio-sink)))
|
||||||
object))
|
object))
|
||||||
|
|
||||||
|
(defvar pw-ui--osd-timer nil)
|
||||||
|
(defvar pw-ui--osd-frame nil)
|
||||||
|
(defvar pw-ui--osd-buffer nil)
|
||||||
|
(defvar pw-ui--osd-buffer-name "*pipewire-osd*")
|
||||||
|
|
||||||
|
(defun pw-ui--osd-display (string)
|
||||||
|
(when pw-ui--osd-timer
|
||||||
|
(cancel-timer pw-ui--osd-timer))
|
||||||
|
(let ((frame-width (+ 2 (length string))))
|
||||||
|
(when (and pw-ui--osd-frame
|
||||||
|
(not (= frame-width (frame-width pw-ui--osd-frame))))
|
||||||
|
(delete-frame pw-ui--osd-frame)
|
||||||
|
(setq pw-ui--osd-frame nil))
|
||||||
|
(with-current-buffer (setq pw-ui--osd-buffer (get-buffer-create pw-ui--osd-buffer-name))
|
||||||
|
(erase-buffer)
|
||||||
|
(insert " " string)
|
||||||
|
(setq mode-line-format nil)
|
||||||
|
(unless pw-ui--osd-frame
|
||||||
|
(setq pw-ui--osd-frame (make-frame `((unsplittable . t)
|
||||||
|
,@pipewire-osd-frame-parameters
|
||||||
|
(minibuffer . nil)
|
||||||
|
(width . ,(+ 2 (length string)))
|
||||||
|
(height . 1)
|
||||||
|
(min-width . 1)
|
||||||
|
(min-height . 1)
|
||||||
|
(left-fringe . 0)
|
||||||
|
(right-fringe . 0)
|
||||||
|
(no-other-frame . t)
|
||||||
|
(undecorated . t)
|
||||||
|
(vertical-scroll-bars . nil)
|
||||||
|
(horizontal-scroll-bars . nil)
|
||||||
|
(menu-bar-lines . 0)
|
||||||
|
(tool-bar-lines . 0)
|
||||||
|
(tab-bar-lines . 0)
|
||||||
|
(cursor-type . nil)))))))
|
||||||
|
(setq pw-ui--osd-timer
|
||||||
|
(run-with-timer
|
||||||
|
pipewire-osd-timeout nil
|
||||||
|
#'(lambda ()
|
||||||
|
(when pw-ui--osd-frame
|
||||||
|
(ignore-errors (delete-frame pw-ui--osd-frame)))
|
||||||
|
(when pw-ui--osd-buffer
|
||||||
|
(ignore-errors (kill-buffer pw-ui--osd-buffer)))
|
||||||
|
(setq pw-ui--osd-frame nil
|
||||||
|
pw-ui--osd-timer nil
|
||||||
|
pw-ui--osd-buffer nil)))))
|
||||||
|
|
||||||
|
(defmacro pw-ui--osd (&rest body)
|
||||||
|
(declare (indent defun))
|
||||||
|
(let (($string (gensym)))
|
||||||
|
`(when (and window-system pipewire-osd-enable)
|
||||||
|
(if-let ((,$string (progn ,@body)))
|
||||||
|
(pw-ui--osd-display ,$string)))))
|
||||||
|
|
||||||
|
(defun pw-ui--update (&optional message)
|
||||||
|
(if (get-buffer pipewire-buffer)
|
||||||
|
(with-current-buffer pipewire-buffer
|
||||||
|
(pipewire-refresh))
|
||||||
|
(pw-lib-refresh))
|
||||||
|
(when message
|
||||||
|
(message message)))
|
||||||
|
|
||||||
|
(defun pw-ui--osd-volume (object)
|
||||||
|
(pw-ui--osd
|
||||||
|
(unless (eq (pw-ui--current-object-id) (pw-lib-object-id object))
|
||||||
|
(let* ((object* (pw-lib-get-object (pw-lib-object-id object))) ; refreshed version
|
||||||
|
(volume (pw-lib-volume object*))
|
||||||
|
(muted-p (pw-lib-muted-p object*))
|
||||||
|
(step (/ 100.0 pipewire-osd-width))
|
||||||
|
(mark (if muted-p ?- ?|))
|
||||||
|
(n-active (round (/ volume step)))
|
||||||
|
(n-inactive (- pipewire-osd-width n-active)))
|
||||||
|
(format "%s%s"
|
||||||
|
(propertize (make-string n-active mark)
|
||||||
|
'face `(:background ,pipewire-osd-volume-on-color))
|
||||||
|
(propertize (make-string n-inactive mark)
|
||||||
|
'face `(:background ,pipewire-osd-volume-off-color)))))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun pipewire-toggle-muted ()
|
(defun pipewire-toggle-muted ()
|
||||||
"Switch mute status of an audio output or input.
|
"Switch mute status of an audio output or input.
|
||||||
@ -148,7 +254,8 @@ object. Otherwise apply it on the default audio sink."
|
|||||||
(interactive)
|
(interactive)
|
||||||
(let* ((object (pw-ui--current-object t '("Node" "Port")))
|
(let* ((object (pw-ui--current-object t '("Node" "Port")))
|
||||||
(muted-p (pw-lib-toggle-mute object)))
|
(muted-p (pw-lib-toggle-mute object)))
|
||||||
(pw-ui--update (format "%s %s" (pw-ui--object-name object) (if muted-p "muted" "unmuted")))))
|
(pw-ui--update (format "%s %s" (pw-ui--object-name object) (if muted-p "muted" "unmuted")))
|
||||||
|
(pw-ui--osd-volume object)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun pipewire-set-volume (volume &optional object single-p)
|
(defun pipewire-set-volume (volume &optional object single-p)
|
||||||
@ -162,7 +269,8 @@ Otherwise apply it on the default audio sink."
|
|||||||
(unless object
|
(unless object
|
||||||
(setq object (pw-ui--current-object t '("Node" "Port"))))
|
(setq object (pw-ui--current-object t '("Node" "Port"))))
|
||||||
(pw-lib-set-volume volume object single-p)
|
(pw-lib-set-volume volume object single-p)
|
||||||
(pw-ui--update (format "Volume %s for %s" volume (pw-ui--object-name object))))
|
(pw-ui--update (format "Volume %s for %s" volume (pw-ui--object-name object)))
|
||||||
|
(pw-ui--osd-volume object))
|
||||||
|
|
||||||
(defun pw-ui--change-volume (step &optional single-p)
|
(defun pw-ui--change-volume (step &optional single-p)
|
||||||
(let* ((object (pw-ui--current-object t '("Node" "Port")))
|
(let* ((object (pw-ui--current-object t '("Node" "Port")))
|
||||||
|
Loading…
Reference in New Issue
Block a user