Created
February 12, 2023 09:43
-
-
Save alexforsale/7d2390700ac9d6f130854747acc8c7e7 to your computer and use it in GitHub Desktop.
WIP exwm configuration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; Config --- Exwm Configuration -*- emacs-lisp -*- | |
;;; Commentary: | |
;;; Code: | |
;; system-tray | |
(use-package exwm) | |
(use-package desktop-environment) | |
(use-package pinentry) | |
(use-package exwm-modeline) | |
(use-package perspective) | |
(use-package perspective-exwm) | |
(use-package which-key) | |
(require 'exwm-systemtray) | |
(exwm-systemtray-enable) | |
(setq exwm-systemtray-height 12) ; default 16 | |
(require 'exwm) | |
;; variables | |
(setq exwm-workspace-show-all-buffers nil ; keep buffers per workspace | |
exwm-workspace-warp-cursor t ; after workspace switch | |
mouse-autoselect-window t ; like any other tiling window manager | |
focus-follows-mouse nil | |
exwm-workspace-number 1 | |
) | |
;; hooks | |
;; things that should runs after initializing exwm | |
(defun +config/exwm-init-hook () | |
"Things that should run after initialization." | |
(when (file-exists-p "~/.fehbg") | |
(exwm/run-in-background "~/.fehbg")) | |
(exwm/run-in-background "xrdg -merge ~/.Xresources") | |
(exwm/run-in-background "xsetroot -cursor_name left_ptr") | |
(exwm/run-in-background "xset r rate 300 30") | |
(exwm/run-in-background "nm-applet") | |
(exwm/run-in-background "iwgtk -i") | |
(exwm/run-in-background "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1") | |
(exwm/run-in-background "picom") | |
(exwm/run-in-background "udiskie -t") | |
(exwm/run-in-background "dunst -conf ~/.config/dunst/dunstrc") | |
(exwm/run-in-background "light-locker") | |
(exwm/run-in-background "wal --theme solarized") | |
(exwm/run-in-background "blueman-applet") | |
(exwm/run-in-background "volumeicon") | |
(exwm/run-in-background "xsettingsd") | |
(exwm/run-in-background "unclutter") | |
(exwm/run-in-background "greenclip daemon>/dev/null") | |
(exwm/run-in-background "/usr/lib/geoclue-2.0/demos/agent") | |
;;(exwm/run-in-background "keepassxc ~/Sync/Password.kdbx") | |
) | |
;; normal hook run when `exwm' has just finished initializing | |
(add-hook 'exwm-init-hook #'+config/exwm-init-hook) | |
(add-hook 'exwm-init-hook #'exwm-modeline-mode) | |
(defun +config/fix-exwm-floating-windows () | |
"Fix behaviour when switching to floating." | |
(setq-local exwm-workspace-warp-cursor nil) | |
(setq-local mouse-autoselect-window nil) | |
(setq-local focus-follows-mouse nil)) | |
;; normal hook run when an X window has been made floating | |
(add-hook 'exwm-floating-setup-hook | |
(progn | |
#'+config/fix-exwm-floating-windows | |
(lambda () | |
(exwm-layout-hide-mode-line)))) | |
;; normal hook run when window title is updated | |
(add-hook 'exwm-update-title-hook | |
(lambda () | |
(when (or (not exwm-instance-name) | |
(string-prefix-p "sun-awt-X11-" exwm-instance-name) | |
(string= "gimp" exwm-instance-name)) | |
(exwm-workspace-rename-buffer exwm-title)))) | |
;; Make buffer name more meaningful | |
(add-hook 'exwm-update-class-hook | |
(progn | |
(lambda () | |
(exwm-workspace-rename-buffer exwm-class-name)) | |
(lambda () | |
(pcase exwm-class-name | |
("firefox" (exwm-workspace-rename-buffer (format "%s" exwm-title))))))) | |
(defvar +config/exwm-workspace--switch-history-hack (cons exwm-workspace-current-index '())) | |
(defun +config/exwm-workspace-switch-to-last () | |
"Switch to last visited workspace." | |
(interactive) | |
"Switch to the workspace that was used before current workspace" | |
(exwm-workspace-switch (cdr +config/exwm-workspace--switch-history-hack))) | |
;; normal hook run after switching workspace | |
(add-hook 'exwm-workspace-switch-hook | |
(lambda () | |
(setq +config/exwm-workspace--switch-history-hack | |
(cons exwm-workspace-current-index | |
(car +config/exwm-workspace--switch-history-hack))))) | |
(defun exwm/run-in-background (command) | |
"Run COMMAND in background if exists." | |
(let ((command-parts (split-string command "[ ]+"))) | |
(when (executable-find (car command-parts)) | |
(apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts)))))) | |
(defun +config/raise-or-run (suffix &optional cmd) | |
"Raises the buffer with SUFFIX otherwise runs the CMD (if provided) or SUFFIX" | |
(let ((existing-buffer | |
(mb/buffer-with-suffix suffix))) | |
(if existing-buffer | |
(if (string= (buffer-name (current-buffer)) (buffer-name existing-buffer)) | |
(bury-buffer) | |
(if (get-buffer-window existing-buffer) | |
(pop-to-buffer existing-buffer) | |
(exwm-workspace-switch-to-buffer existing-buffer))) | |
(start-process-shell-command suffix nil cmd)))) | |
(setq +config/exwm-manage-configurations | |
;; workspace 0 reserved for terminal emulators | |
'(((string= exwm-class-name "Xterm") workspace 0) | |
((string= exwm-class-name "Termite") workspace 0) | |
((string= exwm-class-name "URxvt") workspace 0) | |
;; windows 1 is exclusively for `Emacs' | |
;; windows 2 is for web browsers | |
((string= exwm-class-name "firefox") workspace 2) | |
((string= exwm-class-name "Nyxt") workspace 2) | |
((string= exwm-class-name "qutebrowser") workspace 2) | |
;; workspace 3 for mail apps | |
((string= exwm-class-name "Thunderbird") workspace 3) | |
((string= exwm-class-name "Mail") workspace 3) | |
;; workspace 4 is for Multimedia apps | |
((string= exwm-class-name "Spotify") workspace 4) | |
((string= exwm-class-name "Cheese") workspace 4) | |
((string= exwm-class-name "Picard") workspace 4) | |
((string= exwm-class-name "hakuneko-desktop") workspace 4) | |
((string= exwm-class-name "mpv") workspace 4) | |
((string= exwm-class-name "vlc") workspace 4) | |
((string= exwm-class-name "Gimp") workspace 4) | |
;; workspace 5 for Network apps | |
((string= exwm-class-name "Org.remmina.Remmina") workspace 5) | |
((string= exwm-class-name "Virt-manager") workspace 5) | |
((string= exwm-class-name "Vncviewer") workspace 5) | |
;; workspace 6 for messaging | |
((string= exwm-class-name "TelegramDesktop") workspace 6) | |
;; workspace 7 for other editors | |
((string= exwm-class-name "libreoffice-startcenter") workspace 7) | |
((string= exwm-class-name "libreoffice-calc") workspace 7) | |
((string= exwm-class-name "libreoffice-draw") workspace 7) | |
((string= exwm-class-name "libreoffice-math") workspace 7) | |
((string= exwm-class-name "libreoffice-writer") workspace 7) | |
)) | |
(defun +config/exwm-logout () | |
"Logout cleanly from EXWM." | |
(interactive) | |
(recentf-save-list) | |
(save-some-buffers) | |
(save-buffers-kill-terminal)) | |
(defun +config/exwm-terminal () | |
"Set the default terminal." | |
(interactive) | |
(let ((terminal | |
(or | |
(getenv "TERMINAL") | |
(executable-find "xterm") | |
(executable-find "urxvt") | |
(executable-find "termite")))) | |
(exwm/run-in-background terminal) | |
(message "s-<f11> to toggle fullscreen"))) | |
(defun +config/rofi-launcher () | |
"Run rofi." | |
(interactive) | |
(exwm/run-in-background "rofi -show drun -theme exwm")) | |
(defun +config/greenclip-launcher () | |
"Run greenclip." | |
(interactive) | |
(exwm/run-in-background "rofi-greenclip exwm")) | |
;; (customize-set-variable 'persp-initial-frame-name "Main") | |
;; (if (boundp '+emacs-data-dir) | |
;; (customize-set-variable 'persp-state-default-file (expand-file-name "statesave" +emacs-data-dir)) | |
;; (progn (let ((emacs-data-dir (expand-file-name ".local/share/emacs" (getenv "HOME")))) | |
;; (customize-set-variable 'persp-state-default-file (expand-file-name "statesave" emacs-data-dir))))) | |
;; (customize-set-variable 'persp-mode-prefix-key (kbd "C-c b")) | |
;; Disable menu-bar, tool-bar and scroll-bar to increase the usable space. | |
(menu-bar-mode -1) | |
(tool-bar-mode -1) | |
(scroll-bar-mode -1) | |
;; Also shrink fringes to 1 pixel. | |
(fringe-mode 1) | |
(require 'time) | |
(setq display-time-default-load-average nil) | |
(customize-set-variable 'display-time-24hr-format t) | |
(customize-set-variable 'display-time-day-and-date t) | |
(display-time-mode 1) | |
;; (cond ((not (directory-empty-p "/sys/class/power_supply/")) | |
;; (display-battery-mode))) | |
(if (and (fboundp 'server-running-p) | |
(not (server-running-p))) | |
(server-start)) | |
(require 'recentf) | |
;; (setq-default persp-mode-prefix-key (kbd "C-c TAB")) | |
(require 'perspective) | |
(require 'perspective-exwm) | |
(customize-set-variable 'persp-mode-prefix-key (kbd "C-c TAB")) | |
(unless (equal persp-mode t) | |
(persp-mode)) | |
(customize-set-variable 'perspective-exwm-override-initial-name | |
'((0 . "Term") | |
(1 . "Dev") | |
(2 . "Web") | |
(3 . "Files") | |
(4 . "Multimedia") | |
(5 . "Chat") | |
(6 . "Remotes") | |
(7 . "Games") | |
(8 . "Work") | |
(9 . "Others"))) | |
(setenv "GPG_AGENT_INFO" nil) ;; use emacs pinentry | |
(setq auth-source-debug t) | |
(setq epg-gpg-program "gpg2") ;; not necessary | |
(require 'epa-file) | |
(unless (featurep 'epa) | |
(epa-file-enable)) | |
(setq epg-pinentry-mode 'loopback) | |
(pinentry-start) | |
(require 'org-crypt) | |
(org-crypt-use-before-save-magic) | |
(require 'which-key) | |
(which-key-setup-side-window-right-bottom) | |
(customize-set-variable 'desktop-environment-brightness-small-increment "1%+") | |
(customize-set-variable 'desktop-environment-brightness-small-decrement "1%-") | |
(customize-set-variable 'desktop-environment-brightness-normal-increment "1%+") | |
(customize-set-variable 'desktop-environment-brightness-normal-decrement "1%-") | |
(customize-set-variable 'desktop-environment-volume-normal-decrement "1%-") | |
(customize-set-variable 'desktop-environment-volume-normal-increment "1%+") | |
(customize-set-variable 'desktop-environment-screenshot-command "flameshot gui") | |
(customize-set-variable 'desktop-environment-screenshot-directory (expand-file-name "Screenshots/" (getenv "XDG_PICTURES_DIR"))) | |
(unless (file-directory-p desktop-environment-screenshot-directory) | |
(make-directory desktop-environment-screenshot-directory :parents)) | |
(when (featurep 'emms) | |
(with-eval-after-load 'desktop-environment | |
(customize-set-variable 'desktop-environment-music-next-command nil) | |
(customize-set-variable 'desktop-environment-music-previous-command nil) | |
(customize-set-variable 'desktop-environment-music-stop-command nil) | |
(customize-set-variable 'desktop-environment-music-toggle-command nil) | |
(define-key desktop-environment-mode-map (kbd "<XF86AudioNext>") #'emms-next) | |
(define-key desktop-environment-mode-map (kbd "<XF86AudioPrev>") #'emms-previous) | |
(define-key desktop-environment-mode-map (kbd "<XF86AudioPlay>") #'emms-pause) | |
(global-set-key (kbd "M-s-<f12>") #'emms-next) | |
(global-set-key (kbd "M-s-<f11>") #'emms-pause) | |
(global-set-key (kbd "M-s-<f10>") #'emms-previous) | |
(global-set-key (kbd "M-s-<f9>") 'desktop-environment-volume-increment) | |
(global-set-key (kbd "M-s-<f8>") 'desktop-environment-volume-decrement) | |
(global-set-key (kbd "M-s-<f7>") 'desktop-environment-toggle-mute))) | |
(unless (featurep 'emms) | |
(with-eval-after-load 'desktop-environment | |
(global-set-key (kbd "M-s-<f12>") 'desktop-environment-music-next) | |
(global-set-key (kbd "M-s-<f11>") 'desktop-environment-toggle-music) | |
(global-set-key (kbd "M-s-<f10>") 'desktop-environment-music-previous) | |
(global-set-key (kbd "M-s-<f9>") 'desktop-environment-volume-increment) | |
(global-set-key (kbd "M-s-<f8>") 'desktop-environment-volume-decrement) | |
(global-set-key (kbd "M-s-<f7>") 'desktop-environment-toggle-mute))) | |
(desktop-environment-mode) | |
(require 'battery) | |
(with-eval-after-load 'battery | |
(when | |
(or | |
(eq battery-status-function | |
'battery-upower) | |
(eq battery-status-function | |
'battery-bsd-apm) | |
(eq battery-status-function | |
'battery-linux-sysfs) | |
(eq battery-status-function | |
'battery-linux-proc-apm) | |
(eq battery-status-function | |
'battery-linux-proc-acpi)) | |
(display-battery-mode))) | |
(exwm-input-set-key (kbd "C-x C-c") '+config/exwm-logout) | |
;; (exwm-input-set-key (kbd "s-F3") ) | |
(defun +config/setup-header-line-format () | |
"Hide header line if required." | |
(set-window-parameter (next-window) 'header-line-format | |
(unless (window-at-side-p (next-window) 'top) | |
'none))) | |
(add-hook 'window-configuration-change-hook #'+config/setup-header-line-format) | |
(setq exwm-input-global-keys | |
`( | |
;; Bind "s-r" to exit char-mode and fullscreen mode. | |
([?\s-r] . exwm-reset) | |
;; Bind "s-w" to switch workspace interactively. | |
([?\s-w] . exwm-workspace-switch) | |
([?\s-q] . delete-window) | |
([?\s-j] . next-buffer) | |
([?\s-k] . previous-buffer) | |
([?\s-m] . exwm-layout-toggle-mode-line) | |
;; Bind "s-0" to "s-9" to switch to a workspace by its index. | |
,@(mapcar (lambda (i) | |
`(,(kbd (format "s-%d" i)) . | |
(lambda () | |
(interactive) | |
(exwm-workspace-switch-create ,i)))) | |
(number-sequence 0 9)) | |
([s-tab] . +config/exwm-workspace-switch-to-last) | |
;; ([s-return] . +config/exwm-terminal) | |
([?\s-d] . +config/rofi-launcher) | |
([?\s-c] . +config/greenclip-launcher) | |
;; Bind "s-&" to launch applications ('M-&' also works if the output | |
;; buffer does not bother you). | |
([?\s-D] . (lambda (command) | |
(interactive (list (read-shell-command "$ "))) | |
(start-process-shell-command command nil command))) | |
([s-f11] . exwm-layout-toggle-fullscreen) | |
;; Bind "s-<f2>" to "slock", a simple X display locker. | |
([s-f1] . (lambda () | |
(interactive) | |
(start-process "" nil "/usr/bin/slock"))))) | |
;; Ctrl+Q will enable the next key to be sent directly | |
(define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key) | |
;; Make Doom's leader work. | |
;; (when (featurep 'doom) | |
;; (exwm-input-set-key (kbd doom-leader-alt-key) doom-leader-map)) | |
;;(setq exwm-workspace-minibuffer-position 'bottom) | |
(setq +config/simulation-key-window-classes | |
'(google-chrome firefox qutebrowser)) | |
(add-hook 'exwm-manage-finish-hook | |
(lambda () | |
(when (and exwm-class-name (member exwm-class-name +config/simulation-key-window-classes)) | |
(exwm-input-set-local-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]) | |
([?\C-e] . [end]) | |
([?\M-v] . [prior]) | |
([?\C-v] . [next]) | |
([?\C-d] . [delete]) | |
;;([?\C-k] . [S-end delete]) | |
;; cut/paste. | |
([?\C-w] . [?\C-x]) | |
([?\M-w] . [?\C-c]) | |
([?\C-y] . [?\C-v]) | |
([?\C-c ?\C-c] . [?\C-c]) | |
([?\C-w ?\C-w] . [?\C-w]) | |
([?\C-v ?\C-v] . [?\C-v]) | |
;; search | |
([?\C-s] . [?\C-f])))))) | |
;; (when (featurep doom) | |
;; (exwm-input-set-key (kbd "<s-return>") '+vterm/here)) | |
;; firefox | |
(exwm-input-set-key (kbd "<s-b>") | |
(lambda () | |
(interactive) | |
(+config/raise-or-run "Firefox" "firefox"))) | |
(with-eval-after-load 'all-the-icons | |
(add-to-list 'all-the-icons-mode-icon-alist | |
'(exwm-mode all-the-icons-faicon "desktop" | |
:height 1.0 :face all-the-icons-purple))) | |
;;(start-process-shell-command "xrandr" nil "xrandr --output Virtual-0 --mode 1366x768") | |
(require 'perspective-exwm) | |
(perspective-exwm-mode) | |
(require 'exwm-randr) | |
(exwm-randr-enable) | |
(when (featurep 'diminish) | |
(diminish 'desktop-environment-mode)) | |
(exwm-enable) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment