#+PROPERTY: header-args:emacs-lisp :tangle "~/.emacs.d/config-exwm.el" :comments both

* exwm
#+begin_src emacs-lisp
  ;; This will be the hardest to write :/
  (when my-ec/enable-exwm
    (use-exwm
     :config
     (use-package exwm-x)
     (exwm-global-set-key (kbd "s-e") #'exwm-edit--compose)

     ;; Editting with Emacs in X-windows
     (use-package exwm-edit
       :init
       (setq exwm-edit-bind-default-keys nil)
       :config
       (exwm-global-set-key (kbd "s-e") #'exwm-edit--compose))

     (define-key exwm-mode-map (kbd "M-q") #'exwm-input-send-next-key)
     ;; (add-to-list 'exwm-input-global-keys (cons (kbd "M-q") #'exwm-input-send-next-key))
     ;; M-ESC?
     ;; exwm-input--set-key

     ;; System tray
     (require 'exwm-systemtray)
     (exwm-systemtray-enable)

     ;; Multi monitor support
     (require 'exwm-randr)
     (exwm-enable)
     (exwm-randr-enable)

     ;; This is a new-frame hack. Don't copy faces for floating windows
     (require 'face-copier)

     (unless (eq 'hash-table (type-of face-new-frame-defaults))
       (def-face-copier1 my/frame-dont-copy-faces (sym)
         (let ((name (symbol-name sym)))
           (string-match-p "^doom-.*" name))
         mode-line
         mode-line-inactive
         variable-pitch
         diredp-file-suffix
         font-lock-type-face)

       (defun my/exwm-floating--advise-make-frame (orig id)
         (override1-face my/frame-dont-copy-faces
           (funcall orig id)))

       (advice-add #'exwm-floating--set-floating
                   :around
                   #'my/exwm-floating--advise-make-frame)

       (def-face-copier x-show-tip-faces (sym)
         nil
         tooltip)

       (defun dont-copy-faces-for-x-show-tip (orig &rest args)
         (override1-face x-show-tip-faces
           (apply orig args)))

       (advice-add #'x-show-tip
                   :around
                   #'dont-copy-faces-for-x-show-tip))

     ;; Startup programs
     (add-hook 'emacs-startup-hook 'server-start)

     ;; Actually launch programs
     (require 'exwm-launch-program)
     (define-key *root-map* (kbd "C-p") #'exwmx-launch-program)

     ;; Shut down
     (add-hook 'exwm-exit-hook 'org-save-all-org-buffers)

     ;; Reminder: Hooks execute in order. Make sure megasync launches after systemtray is enabled
     (require 'exwm-startup)
     (add-hook 'exwm-init-hook 'call-startup-programs)

     (require 'exwm-systemtray)
     (exwm-systemtray-enable)

     ;; Setup screens before anything else
     (require 'exwm-screens)
     (add-hook 'exwm-init-hook 'my/setup-screens)

     ;; This lets me do rapid emacs iteration
     (defun ignore-emacs ()
       (when (and exwm-class-name (string= exwm-class-name "Emacs"))
         (call-interactively #'exwm-input-release-keyboard)))

     (add-hook 'exwm-manage-finish-hook
               #'ignore-emacs)))
#+end_src

* keybindings
#+begin_src emacs-lisp
  (defun lock-screen ()
    (interactive)
    (shell-command "~/Github/my-projects/i3lock-fancy/i3lock-fancy & disown"))

  (exwm-global-set-key (kbd "s-r") #'exwm-reset)
  (require 'keyboard-toggle)

  (setq exwm-input-simulation-keys
        '(;; movement
          ([?\C-b] . left)
          ([?\M-b] . C-left)
          ([?\C-f] . right)
          ([?\M-f] . C-right)
          ([?\C-p] . up)
          ([?\C-n] . down)
          ([?\C-a] . home)
          ([?\M-<] . home)
          ([?\C-e] . end)
          ([?\M->] . end)
          ([?\M-v] . prior)
          ([?\C-v] . next)
          ([?\C-d] . delete)
          ([?\M-d] . backspace)
          ([?\C-k] . (S-end delete))
          ;; cut/paste.
          ([?\C-w] . ?\C-x)
          ([?\M-w] . ?\C-c)
          ([?\C-y] . ?\C-v)
          ;; search
          ([?\C-s] . ?\C-f)
          ([?\C-.] . ?\C-w)
          ([?\C-/] . ?\C-z)
          ([?\C-x ?\C-s] . ?\C-s)
          ([?\M-E] . ?\C-a)))
#+end_src
* exwm-background
#+begin_src emacs-lisp
  (add-to-list 'load-path (ef "submodule/exwm-background/"))
  (require 'exwm-background)

  (let ((wm (shell-command-to-string "wmctrl -m")))
    (when (and (string-match "Name: \\(.*\\)\n" wm)
               (not (string= "EXWM"
                             (match-string 1 wm))))
      (setq exwm-background/current-transparency 95)))

  (define-key *window-map* (kbd "t") 'exwm-background/window-transparency-hydra/body)
  (exwm-global-set-key (kbd "s-v") #'exwm-background/toggle-viewing-background)
  (exwm-global-set-key (kbd "s-b") #'exwm-background/exwm-background-window) ;; TODO: Fix keybinding
  ;; (define-key desktop-environment-mode-map (kbd "<S-XF86MonBrightnessDown>") #'exwm-background/decrease-transparency)
  ;; (define-key desktop-environment-mode-map (kbd "<S-XF86MonBrightnessUp>") #'exwm-background/increase-transparency)
  (define-key *window-map* (kbd "b") #'exwm-background/exwm-background-window)
  (define-key *root-map* (kbd "k") #'exwm-background/exwm-send-key-to-background)
  (define-key *root-map* (kbd "C-k") #'exwm-background/exwm-send-key-to-background-loop)
#+end_src
* tags
#+begin_src emacs-lisp
  ;; Need my tags
  (require 'exwm-tag)
#+end_src
* Don't show these buffers in buffer-list
#+begin_src emacs-lisp
(defvar my/exclude-buffer-modes '(helm-major-mode messages-buffer-mode special-mode))

(defun my-buffer-predicate (buf)
  (with-current-buffer buf
    (if (memq major-mode my/exclude-buffer-modes)
        nil
      (exwm-layout--other-buffer-predicate buf))))

(add-hook 'exwm-init-hook
          (lambda ()
            (interactive) 
            (modify-all-frames-parameters
             '((buffer-predicate . my-buffer-predicate)))))
#+end_src
* switch-window
#+begin_src emacs-lisp
  (use-package switch-window)
  (setq switch-window-shortcut-style 'qwerty)
  (setq switch-window-qwerty-shortcuts
        '("a" "o" "e" "u" "i" "d" "h" "t" "n" "s"))
#+end_src
* restart emacs custom
#+begin_src emacs-lisp
  (defun my/exwm-restart ()
    "Restart EXWM."
    (interactive)
    (exwm--log)
    (when (exwm--confirm-kill-emacs "[EXWM] Restart? " 'no-check)
      (let* ((attr (process-attributes (emacs-pid)))
             (args (cdr (assq 'args attr)))
             (ppid (cdr (assq 'ppid attr)))
             (pargs (cdr (assq 'args (process-attributes ppid)))))
        (shell-command "emacs & disown")
        (kill-emacs))))
#+end_src
* exwm fix
#+begin_src emacs-lisp
  (defun my/exwm-input--fake-last-command ()
    "Fool some packages into thinking there is a change in the buffer."
    (setq last-command #'exwm-input--noop)
    (condition-case hook-error
        (progn
          (run-hooks 'pre-command-hook)
          (run-hooks 'post-command-hook))
      ((error)
       (exwm--log "Error occurred while running command hooks: %s\n\nBacktrace:\n\n%s"
                  hook-error
                  (with-temp-buffer
                    (setq-local standard-output (current-buffer))
                    (backtrace)
                    (buffer-string))))))

  (advice-add #'exwm-input--fake-last-command
              :override
              #'my/exwm-input--fake-last-command)
#+end_src
* Disable Pop-ups mode
#+begin_src emacs-lisp
  (defun my/pop-buffer-ignore-exwm (buffer &optional norecord)
    (not (eq 'exwm-mode
             (with-current-buffer buffer
               major-mode))))

  (define-minor-mode exwm-disable-popups ""
    :global t
    (if exwm-disable-popups
        (advice-add #'pop-to-buffer-same-window
                    :before-while
                    #'my/pop-buffer-ignore-exwm)
      (advice-remove #'pop-to-buffer-same-window
                     #'my/pop-buffer-ignore-exwm)))
#+end_src
