#+property: header-args :lexical t :tangle yes :comments yes :results silent :shebang ";; -*- lexical-binding: t; -*-" :tangle-mode (identity #o644)
#+title: exwm configuration
#+auto_tangle: t

* Load and basic config
  #+begin_src emacs-lisp
    (defvar jao-exwm--use-afio t)

    (jao-load-path "exwm")

    (use-package exwm
      :ensure t
      :init (setq exwm-debug nil
                  exwm-workspace-number 1
                  exwm-workspace-show-all-buffers t
                  exwm-workspace-warp-cursor nil
                  exwm-layout-show-all-buffers t
                  exwm-floating-border-color
                  (if (jao-colors-scheme-dark-p) "black" "grey90")))

    (use-package exwm-edit :ensure t)
    (require 'exwm)
  #+end_src
* Frame(s) as workspaces
  #+begin_src emacs-lisp
    (defun jao-exwm--new-frame-p ()
      (not (frame-parameter nil 'jao-frames-initialized)))

    (defun jao-exwm--mark-frame (force)
      (prog1 (or force (jao-exwm--new-frame-p))
        (set-frame-parameter nil 'jao-frames-initialized t)))

    (defun jao-exwm--goto-main (&optional init)
      (interactive "P")
      (exwm-workspace-switch-create 1)
      (when (jao-exwm--mark-frame init) (jao-trisect)))

    (defun jao-exwm--goto-mail (&optional init)
      (interactive "P")
      (exwm-workspace-switch-create 2)
      (when (jao-exwm--mark-frame init)
        (jao-afio-open-gnus)))

    (defun jao-exwm--goto-www (&optional init)
      (interactive "P")
      (exwm-workspace-switch-create 5)
      (when (jao-exwm--mark-frame init)
        (jao-afio-open-www)
        (let ((scroll-bar-mode 'left))
          (toggle-scroll-bar 1)
          (set-frame-parameter (window-frame) 'scroll-bar-width 12))
        (jao-toggle-inactive-mode-line)))

    (defun jao-exwm--goto-docs (&optional init)
      (interactive "P")
      (exwm-workspace-switch-create 4)
      (when (jao-exwm--mark-frame init)
        (jao-afio-open-doc)))

    (defun jao-exwm-open-doc (file)
      (jao-exwm--goto-docs)
      (jao-find-or-open file))

    (defun jao-exwm-no-afio-setup ()
      (interactive)
      (defalias 'jao-open-gnus-frame 'jao-exwm--goto-mail)
      (defalias 'jao-goto-www-frame 'jao-exwm--goto-www)
      (setq jao-open-doc-fun #'jao-exwm-open-doc)
      (setq minibuffer-follows-selected-frame t)
      (global-set-key "\C-cf" 'jao-exwm--goto-main)
      (global-set-key "\C-cg" 'jao-exwm--goto-mail)
      (global-set-key "\C-cw" 'jao-exwm--goto-www)
      (global-set-key "\C-cz" 'jao-exwm--goto-docs))

    (if jao-exwm--use-afio
        (setq minibuffer-follows-selected-frame nil)
      (jao-exwm-no-afio-setup))
  #+end_src
* Tracking
  #+begin_src emacs-lisp
    (add-hook 'exwm-workspace-switch-hook 'tracking-remove-visible-buffers)
  #+end_src
* Buffer names
  #+begin_src emacs-lisp
    (defun jao-exwm--use-title-p ()
      (and exwm-title (not (string-blank-p exwm-title))))

    (defun jao-exwm-rename-buffer/class ()
      (unless (jao-exwm--use-title-p)
        (exwm-workspace-rename-buffer exwm-class-name)))

    (defun jao-exwm-rename-buffer/title ()
      (cond ((or (not exwm-instance-name)
                 (jao-exwm--use-title-p))
             (exwm-workspace-rename-buffer exwm-title))
            ((string= "Zathura" exwm-class-name)
             (exwm-workspace-rename-buffer
              (format "zathura: %s" (file-name-nondirectory exwm-title))))))

    (defun jao-exwm--set-exwm-name ()
      (when (not jao-exwm--name)
        (setq jao-exwm--name jao-exwm--current-name
              jao-exwm--current-name nil)))

    (add-hook 'exwm-mode-hook 'jao-exwm--set-exwm-name)
    (add-hook 'exwm-update-class-hook 'jao-exwm-rename-buffer/class)
    (add-hook 'exwm-update-title-hook 'jao-minibuffer-refresh)
    (add-hook 'exwm-update-title-hook 'jao-exwm-rename-buffer/title)
  #+end_src
* Float windows
  #+begin_src emacs-lisp
    (defvar jao-exwm-max-x (x-display-pixel-width))
    (defvar jao-exwm-max-y (x-display-pixel-height))

    (defun jao-exwm--float-to (x y &optional w h)
      (let* ((w (or w (frame-pixel-width)))
             (h (or h (frame-pixel-height)))
             (x (if (< x 0) (- jao-exwm-max-x (- x) w) x))
             (y (if (< y 0) (- jao-exwm-max-y (- y) h) y))
             (p (or (frame-parameter nil 'jao-position) (frame-position))))
        (exwm-floating-move (- x (car p)) (- y (cdr p)))
        (exwm-layout-enlarge-window-horizontally (- w (frame-pixel-width)))
        (exwm-layout-enlarge-window (- h (frame-pixel-height)))
        (set-frame-parameter nil 'jao-position (cons x y))))

    (defun jao-exwm--center-float (&optional w h)
      (interactive)
      (let* ((mx jao-exwm-max-x)
             (my jao-exwm-max-y)
             (w (or w (frame-pixel-width)))
             (h (or h (/ (* w my) mx))))
        (jao-exwm--float-to (/ (- mx w) 2) (/ (- my h) 2) w h)))

    (defun jao-exwm--setup-float ()
      (set-frame-parameter nil 'jao-position nil)
      (cond ((string= "Firefox" exwm-class-name)
             (jao-exwm--center-float 900 600))
            ((member exwm-class-name '("mpv" "vlc"))
             (jao-exwm--center-float 1200))))

    (defvar jao-exwm-floating-classes '("mpv" "vlc"))
    (setq jao-exwm-floating-classes nil)

    (defun jao-exwm--maybe-float ()
      (when (member exwm-class-name jao-exwm-floating-classes)
        (when (not exwm--floating-frame)
          (exwm-floating-toggle-floating))))

    (add-hook 'exwm-floating-setup-hook #'jao-exwm--setup-float)
    (add-hook 'exwm-manage-finish-hook #'jao-exwm--maybe-float)

  #+end_src
* Minibuffer
  #+begin_src emacs-lisp
    (setq jao-minibuffer-frame-width 271)
    (add-hook 'exwm-workspace-switch-hook #'jao-minibuffer-refresh)
  #+end_src
* System tray
  #+begin_src emacs-lisp
    (require 'exwm-systemtray)
    (exwm-systemtray-enable)

    (defun jao-exwm--watch-tray (sym newval op where)
      (setq jao-minibuffer-right-margin (* 2 (length newval)))
      (jao-minibuffer-refresh))

    (add-variable-watcher 'exwm-systemtray--list #'jao-exwm--watch-tray)
  #+end_src
* Switch to buffer / app
  #+begin_src emacs-lisp
    (defvar-local jao-exwm--name nil)
    (defvar jao-exwm--current-name nil)

    (defun jao-exwm--check-name (name)
      (or (string= jao-exwm--name name)
          (string= (buffer-name) name)
          (string= exwm-class-name name)
          (string= exwm-title name)))

    (defun jao-exwm-find-class-buffer (cln)
      (if (jao-exwm--check-name cln)
          (current-buffer)
        (let* ((cur-buff (current-buffer))
               (bfs (seq-filter (lambda (b)
                                  (and (not (eq b cur-buff))
                                       (with-current-buffer b
                                         (jao-exwm--check-name cln))))
                                (buffer-list))))
          (when (car bfs) (car (reverse bfs))))))

    (defun jao-exwm-switch-to-class/title (cln)
      (interactive)
      (when cln
        (if (jao-exwm--check-name cln)
            (current-buffer)
          (when-let ((b (jao-exwm-find-class-buffer cln)))
            (pop-to-buffer b)))))

    (defun jao-exwm-switch-to-next-class ()
      (interactive)
      (jao-exwm-switch-to-class/title exwm-class-name))

    (defun jao-exwm-switch-to-next-x ()
      (interactive)
      (let ((bfs (seq-filter (lambda (b) (buffer-local-value 'exwm-class-name b))
                             (buffer-list (window-frame)))))
        (when (car bfs) (switch-to-buffer (car (reverse bfs))))))

  #+end_src
* App runner helpers
  #+begin_src emacs-lisp
    (defun jao-exwm-run (command)
      (interactive
       (list (read-shell-command "$ "
                                 (if current-prefix-arg
                                     (cons (concat " " (buffer-file-name)) 0)
                                   ""))))
      (setq jao-exwm--current-name nil)
      (start-process-shell-command command nil command))

    (defmacro jao-exwm-runner (&rest args)
      `(lambda () (interactive) (start-process "" nil ,@args)))

    (defun jao-exwm-workspace (n)
      (if jao-exwm--use-afio
          (jao-afio-goto-nth n)
        (exwm-workspace-switch-create n)))

    (defmacro jao-def-exwm-runner (name ws class &rest args)
      `(defun ,name (&rest other-args)
         (interactive)
         ,@(when ws `((jao-exwm-workspace ,ws)))
         (if (jao-exwm-switch-to-class/title ,class)
             ,(cond ((equal ws 5) '(delete-other-windows))
                    ((stringp (car args)) (cdr args))
                    (t args))
           (setq jao-exwm--current-name ,class)
           ,(if (stringp (car args))
                `(start-process-shell-command ,(car args)
                                              "* exwm - console *"
                                              (string-join (append (list ,@args)
                                                                   other-args)
                                                           " "))
              args))))

    (defmacro jao-def-exwm-toggler (name ws class &rest args)
      (let ((toggler (intern (format "%s*" name)))
            (arg (gensym)))
        `(progn (jao-def-exwm-runner ,name ,ws ,class ,@args)
                (defun ,toggler (,arg)
                  (interactive "P")
                  (if (and (not ,arg) (equal exwm-class-name ,class))
                      (jao-afio--goto-main)
                    (,name))))))

    (defun jao-exwm--send-str (str)
      (dolist (k (string-to-list (kbd str)))
        (exwm-input--fake-key k)))

  #+end_src
* Runners
  #+begin_src emacs-lisp
    (jao-def-exwm-runner jao-exwm-vlc 4 "VLC" "vlc")

    (jao-def-exwm-runner jao-exwm-slack 0 "Slack" "slack")
    (jao-def-exwm-runner jao-exwm-signal 0 "Signal" "signal-desktop")

    (jao-def-exwm-runner jao-exwm-proton-bridge 0 "*proton-bridge*" "protonmail-bridge")

    ;; (jao-def-exwm-runner jao-exwm-htop 0 "htop-xterm"
    ;;                 "xterm" "-title" "htop-xterm" "-e" "htop")
    (jao-def-exwm-runner jao-exwm-htop 0 "htop" jao-term-htop)

    ;; (jao-def-exwm-runner jao-exwm-aptitude 0 "aptitude-xterm"
    ;;                 "xterm" "-title" "aptitude-xterm" "-e" "aptitude")
    (jao-def-exwm-runner jao-exwm-aptitude 0 "aptitude" jao-term-aptitude)

    (jao-def-exwm-runner jao-exwm-blueman 0 "Blueman-manager" "blueman-manager")
    (jao-def-exwm-runner jao-exwm-ncmpcpp 0 "ncmpcpp" "xterm" "-e" "ncmpcpp" "-p" "6669")
    (jao-def-exwm-runner jao-exwm-mpc 0 "*MPC-Status*" mpc)

    (jao-def-exwm-runner jao-exwm-proton-vpn 0 "*pvpn*" proton-vpn-status)
    (jao-def-exwm-runner jao-exwm-enwc 0 "*ENWC*" enwc)
    (jao-def-exwm-runner jao-exwm-bluetooth 0 "*Bluetooth*" bluetooth-list-devices)
    (jao-def-exwm-runner jao-exwm-packages 0 "*Packages*" list-packages nil)
    (jao-def-exwm-runner jao-exwm-proced 0 "*Proced*" proced)

    (jao-def-exwm-runner jao-exwm-open-with-zathura nil nil "zathura" (buffer-file-name))
    (jao-def-exwm-runner jao-exwm-open-with-mupdf nil nil "mupdf" (buffer-file-name))
    (jao-def-exwm-runner jao-exwm-xterm 0 nil "xterm")

    (jao-def-exwm-toggler jao-exwm-tidal 5 "tidal-hifi" "tidal-hifi")
    (defalias 'jao-streaming-list #'jao-exwm-tidal)

    (defun jao-exwm-import-screen (&optional area)
      (interactive "P")
      (when (not (file-directory-p "/tmp/screenshot"))
        (make-directory "/tmp/screenshot"))
      (let ((c (format "import %s %s"
                       (if area "" "-window root")
                       "/tmp/screenshot/$(date +'%g%m%d-%H%M%S').png")))
        (start-process-shell-command "import" "* exwm - console *" c)))

  #+end_src
* Zathura support
  #+begin_src emacs-lisp
    (defun jao-zathura--buffer-p (b)
      (string= "Zathura" (or (buffer-local-value 'exwm-class-name b) "")))

    (defun jao-zathura--buffers ()
      (seq-filter #'jao-zathura--buffer-p (buffer-list)))

    (defun jao-zathura--file-info (b)
      (with-current-buffer b
        (jao-zathura-file-info (or exwm-title ""))))

    (defun jao-zathura-goto-page (page-no)
      (jao-exwm--send-str (format "%sg" page-no)))

    (defun jao-zathura-open-doc (&optional file-name page-no height)
      (interactive)
      (let* ((file-name (expand-file-name (or file-name (buffer-file-name))))
             (buffer (seq-find `(lambda (b)
                                    (string= ,file-name
                                             (car (jao-zathura--file-info b))))
                               (jao-zathura--buffers)))
             (page-no (or page-no (jao-doc-view-current-page))))
        (if jao-exwm--use-afio (jao-afio--goto-docs) (jao-exwm--goto-docs))
        (if (not buffer)
            (jao-exwm-run (if page-no
                              (format "zathura -P %s '%s'" page-no file-name)
                            (format "zathura '%s'" file-name)))
          (pop-to-buffer buffer)
          (when page-no (jao-zathura-goto-page page-no)))
        (current-buffer)))

    (defun jao-exwm--zathura-setup ()
      (when (and (string= exwm-class-name "Zathura")
                 (not jao-doc-view--imenu-file))
        (let ((info (jao-zathura--file-info (current-buffer))))
          (jao-doc-view-session-mark (car info))
          (jao-doc-view-save-session)
          (jao-doc-view--enable-imenu (car info) #'jao-zathura-goto-page))))

    (add-hook 'exwm-update-title-hook #'jao-exwm--zathura-setup t)

    (defun jao-exwm-pdf-zathura-close-all ()
      (interactive)
      (dolist (b (jao-zathura--buffers))
        (ignore-errors
          (switch-to-buffer b)
          (jao-exwm--send-str "q")))
      t)

    (defun jao-exwm-zathura-goto-org (&optional arg)
      (interactive "P")
      (when-let ((info (jao-zathura--file-info (current-buffer))))
        (when-let ((file (jao-org-pdf-to-org-file (car info))))
          (let ((newp (not (file-exists-p file))))
            (when (or arg newp) (org-store-link nil t))
            (find-file-other-window file)
            (when newp
              (jao-org-insert-doc-skeleton)
              (org-insert-link))))))

    (defun jao-exwm-zathura-goto-org* ()
      (interactive)
      (jao-exwm-zathura-goto-org t))

    (defun jao-exwm-org-store-zathura-link ()
      (when-let ((info (jao-zathura--file-info (current-buffer))))
        (let* ((file-name (car info))
               (page (cadr info))
               (desc (jao-doc-view-section-title page file-name)))
          (jao-org-links-store-pdf-link file-name page desc))))

    (defun jao-exwm-pdf-enable-zathura ()
      (interactive)
      (add-hook 'kill-emacs-query-functions #'jao-exwm-pdf-zathura-close-all t)
      (setq jao-org-open-pdf-fun #'jao-zathura-open-doc)
      (setq jao-org-links-pdf-store-fun #'jao-exwm-org-store-zathura-link)
      (setq jao-open-doc-fun #'jao-zathura-open-doc))

    (defun jao-exwm-pdf-disable-zathura ()
      (interactive)
      (define-key org-mode-map (kbd "C-c o") #'jao-org-org-goto-pdf)
      (remove-hook 'kill-emacs-query-functions #'jao-exwm-pdf-zathura-close-all)
      (setq jao-org-open-pdf-fun #'jao-find-or-open)
      (setq jao-org-links-pdf-store-fun nil)
      (setq jao-open-doc-fun #'jao-find-or-open))

    (defun jao-exwm-zathura-goto-pdf ()
      (interactive)
      (if jao-browse-doc-use-emacs-p
          (jao-org-org-goto-pdf)
        (when-let (pdf (jao-org-org-to-pdf-file))
          (jao-zathura-open-doc pdf))))

    (with-eval-after-load "org"
      (define-key org-mode-map (kbd "C-c o") #'jao-exwm-zathura-goto-pdf))

    (when (not jao-browse-doc-use-emacs-p)
      (jao-exwm-pdf-enable-zathura))

    (defun jao-exwm-select-pdf ()
      (interactive)
      (let ((b (read-buffer "Document: " nil t
                            (lambda (b)
                              (let ((b (cdr b)))
                                (or (jao-zathura--buffer-p b)
                                    (member (buffer-local-value 'major-mode b)
                                            '(pdf-view-mode doc-view-mode))))))))
        (jao-afio--goto-docs)
        (pop-to-buffer b)))


    (let ((viewers ["External viewers"
                    ("z" "open with zathura" jao-zathura-open-doc)
                    ("m" "open with mupdf" jao-exwm-open-with-mupdf)]))
      (jao-transient-major-mode+ pdf-view viewers)
      (jao-transient-major-mode+ doc-view viewers))

  #+end_src
* Firefox support
  #+begin_src emacs-lisp
    (jao-def-exwm-toggler jao-exwm-firefox 5 "Firefox" "firefox")

    (defun jao-exwm-browse-with-firefox (&rest args)
      (jao-exwm-firefox)
      (apply #'browse-url-firefox args))

    (setq browse-url-secondary-browser-function #'jao-exwm-browse-with-firefox)

    (defun jao-exwm-kill-firefox-url ()
      (interactive)
      (when-let (b (jao-exwm-find-class-buffer "Firefox"))
        (let ((cb (current-buffer)))
          (switch-to-buffer b)
          (jao-exwm--send-str "yy")
          (prog1 (current-kill 1)
           (switch-to-buffer cb)))))

  #+end_src
* Transients
  #+begin_src emacs-lisp
    (defun jao-exwm--floating-p () exwm--floating-frame)
    (defun jao-exwm--m0-5 () (interactive nil exwm-mode) (exwm-floating-move 0 -5))
    (defun jao-exwm--m05 () (interactive nil exwm-mode) (exwm-floating-move 0 5))
    (defun jao-exwm--m-50 () (interactive nil exwm-mode) (exwm-floating-move -5 0))
    (defun jao-exwm--m50 () (interactive nil exwm-mode) (exwm-floating-move 5 0))
    (defun jao-exwm--e-5 () (interactive nil exwm-mode) (exwm-layout-enlarge-window -5))
    (defun jao-exwm--e5 () (interactive nil exwm-mode) (exwm-layout-enlarge-window 5))
    (defun jao-exwm--eh5 () (interactive nil exwm-mode) (exwm-layout-enlarge-window 5 t))
    (defun jao-exwm--eh-5 () (interactive nil exwm-mode) (exwm-layout-enlarge-window -5 t))
    (defun jao-exwm--tl () (interactive nil exwm-mode) (jao-exwm--float-to 20 20))
    (defun jao-exwm--tr () (interactive nil exwm-mode) (jao-exwm--float-to -20 20))
    (defun jao-exwm--bl () (interactive nil exwm-mode) (jao-exwm--float-to 20 -20))
    (defun jao-exwm--br () (interactive nil exwm-mode) (jao-exwm--float-to -20 -20))

    (defun jao-exwm--def-center-float ()
      (interactive)
      (exwm-floating-toggle-floating)
      (jao-exwm--center-float 900 600))

    (transient-define-prefix jao-transient-float ()
      "Operations on EXWM floating windows."
      :transient-non-suffix 'transient--do-quit-one
      [["Float"
        ("f" "float" exwm-floating-toggle-floating)
        ("F" "full" exwm-layout-toggle-fullscreen)
        ("c" "center" jao-exwm--center-float :if jao-exwm--floating-p)
        ("c" "float and resize" jao-exwm--def-center-float
         :if-not jao-exwm--floating-p)
        ("x" "hide" exwm-floating-hide :if jao-exwm--floating-p)]
       ["Slide" :if jao-exwm--floating-p
        ("k" "up" jao-exwm--m0-5 :transient t)
        ("j" "down" jao-exwm--m05 :transient t)
        ("h" "left" jao-exwm--m-50 :transient t)
        ("l" "right" jao-exwm--m50 :transient t)]
       ["Resize" :if jao-exwm--floating-p
        ("K" "up" jao-exwm--e5 :transient t)
        ("J" "down" jao-exwm--e-5 :transient t)
        ("H" "left" jao-exwm--eh5 :transient t)
        ("L" "right" jao-exwm--eh-5 :transient t)]
       ["Nudge" :if jao-exwm--floating-p
        ("t" "top-left" jao-exwm--tl)
        ("T" "top-right" jao-exwm--tr)
        ("b" "bottom-left" jao-exwm--bl)
        ("B" "bottom-right " jao-exwm--br)]])

    (defun jao-exwm--buffer ()
      (interactive)
      (jao-buffer-same-mode 'exwm-mode nil 'exwm-workspace-switch-to-buffer))

  #+end_src
* Keybindings
  #+begin_src emacs-lisp
    (define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
    (define-key exwm-mode-map [?\s-f] #'jao-transient-float)
    (define-key exwm-mode-map (kbd "C-c o") #'jao-exwm-zathura-goto-org)
    (define-key exwm-mode-map (kbd "C-c O") #'jao-exwm-zathura-goto-org*)
    (define-key exwm-mode-map (kbd "M-o") #'other-window)
    (define-key exwm-mode-map (kbd "M-p") #'jao-prev-window)

    (setq
     exwm-input-global-keys
     '(([?\s-0] . jao-afio--goto-scratch)
       ([?\s-1] . jao-afio--goto-main)
       ([?\s-2] . jao-afio--goto-mail)
       ([?\s-3] . jao-afio--goto-www)
       ([?\s-4] . jao-afio--goto-docs)
       ([?\s-A] . org-agenda-list)
       ([?\s-a] . jao-first-window)
       ([?\s-b] . jao-transient-org-blog)
       ;; ([?\s-d] . jao-exwm-tidal*)
       ([?\s-d] . jao-mpc-echo-current)
       ([?\s-e] . jao-exwm-firefox*)
       ([?\s-m] . jao-transient-media)
       ;; ([?\s-O] . jao-transpose-windows)
       ;; ([?\s-o] . jao-other-window)
       ;; ([?\s-P] . jao-transpose-windows-prev)
       ([?\s-O] . ace-swap-window)
       ([?\s-o] . ace-window)
       ([?\s-p] . jao-prev-window)
       ([?\s-R] . app-launcher-run-app)
       ([?\s-r] . jao-recoll-transient)
       ([?\s-s] . jao-transient-streaming)
       ([?\s-t] . vterm)
       ([?\s-w] . jao-transient-utils)
       ([?\s-z] . jao-transient-sleep)
       ([XF86AudioMute] . jao-mixer-master-toggle)
       ([XF86AudioPlay] . jao-player-toggle)
       ([XF86AudioPause] . jao-player-toggle)
       ([XF86AudioNext] . jao-player-next)
       ([XF86AudioPrev] . jao-player-previous)
       ([XF86AudioStop] . jao-player-stop)
       ([XF86AudioRaiseVolume] . jao-mixer-master-up)
       ([XF86AudioLowerVolume] . jao-mixer-master-down)
       ([XF86MonBrightnessUp] . jao-bright-up)
       ([XF86MonBrightnessDown] . jao-bright-down)
       ([?\s-\`] . jao-exwm-switch-to-next-x)
       ([s-tab] . jao-exwm-switch-to-next-class)
       ([print] . jao-exwm-import-screen)
       ([f5] . jao-weather)
       ([f6] . jao-toggle-audio-applet)
       ([f8] . jao-toggle-nm-applet)
       ([f9] . jao-bright-show)))

    ;; (customize-set-variable 'exwm-input-global-keys exwm-input-global-keys)

  #+end_src