├── screenshot.png ├── exwm-outer-gaps.el └── README.org /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucasgruss/exwm-outer-gaps/HEAD/screenshot.png -------------------------------------------------------------------------------- /exwm-outer-gaps.el: -------------------------------------------------------------------------------- 1 | ;;; exwm-outer-gaps.el -*- lexical-binding: t; -*- 2 | (require 'exwm-workspace) 3 | (require 'exwm-core) 4 | (require 'exwm) 5 | (require 'xelb) 6 | 7 | (defgroup exwm-outer-gaps nil 8 | "Outer gaps for exwm." 9 | :group 'appearance 10 | :prefix "exwm-outer-gaps") 11 | 12 | (defcustom exwm-outer-gaps-width [15 15 15 15] 13 | "Value for the outer gaps to the left, right, top and bottom of 14 | the emacs frames.") 15 | 16 | (defcustom exwm-outer-gaps-increment-step 5 17 | "Default increment/decrement value for gaps.") 18 | 19 | (defun exwm-outer-gaps-compute-gaps () 20 | "Hook to be ran after exwm-workspace--update-workareas-hook" 21 | (let (workareas frames) 22 | (dolist (w exwm-workspace--workareas) 23 | (setf (aref w 0) (+ (aref w 0) (aref exwm-outer-gaps-width 0)) ; x for top left corner 24 | (aref w 1) (+ (aref w 1) (aref exwm-outer-gaps-width 2)) ; y for top left corner 25 | (aref w 2) (- (aref w 2) (+ (aref exwm-outer-gaps-width 0) (aref exwm-outer-gaps-width 1))) ; width of frame 26 | (aref w 3) (- (aref w 3) (+ (aref exwm-outer-gaps-width 2) (aref exwm-outer-gaps-width 3))))))) ; height of frame 27 | 28 | (defun exwm-outer-gaps-apply () 29 | "Function used to apply gaps to the emacs frames." 30 | (exwm-workspace--update-workareas) 31 | (dolist (f exwm-workspace--list) 32 | (exwm-workspace--set-fullscreen f))) 33 | 34 | (defun exwm-outer-gaps-set (border width increment) 35 | "Set border in {left, right, top, bottom} to width. 36 | increment (bool) indicates whether the width should be used as 37 | absolute width or as increment value." 38 | (aset exwm-outer-gaps-width 39 | border 40 | (+ (if increment 41 | (aref exwm-outer-gaps-width border) 42 | 0) 43 | width))) 44 | 45 | (defun exwm-outer-gaps-set-all (width increment) 46 | "Set all gaps. Increment (bool) determines whether the width 47 | should be used as absolute width or as increment value" 48 | (dotimes (border 4) 49 | (exwm-outer-gaps-set border width increment))) 50 | 51 | (defun exwm-outer-gaps-increment (arg) 52 | "Increment the outer gaps. If arg {0, 1, 2, 3} is passed, 53 | increment the corresponding {left, right, top, bottom} border. 54 | Else, increment all borders by the same 55 | exwm-outer-gaps-increment-step" 56 | (interactive "P") 57 | (when exwm-outer-gaps-mode 58 | (if arg 59 | (exwm-outer-gaps-set arg exwm-outer-gaps-increment-step t) 60 | (exwm-outer-gaps-set-all exwm-outer-gaps-increment-step t)) 61 | (exwm-outer-gaps-apply))) 62 | 63 | (defun exwm-outer-gaps-decrement (arg) 64 | "Decrement the outer gaps. If arg {0, 1, 2, 3} is passed, 65 | decrement the corresponding {left, right, top, bottom} border. 66 | Else, decrement all borders by the same 67 | exwm-outer-gaps-increment-step" 68 | (interactive "P") 69 | (when exwm-outer-gaps-mode 70 | (if arg 71 | (exwm-outer-gaps-set arg (- exwm-outer-gaps-increment-step) t) 72 | (exwm-outer-gaps-set-all (- exwm-outer-gaps-increment-step) t)) 73 | (exwm-outer-gaps-apply))) 74 | 75 | (defun exwm-outer-gaps-balance (border) 76 | "Set all gaps to the width of border" 77 | (interactive "P") 78 | (if border 79 | (exwm-outer-gaps-set-all (aref exwm-outer-gaps-width border) nil) 80 | (exwm-outer-gaps-set-all (aref exwm-outer-gaps-width 0) nil)) 81 | (exwm-outer-gaps-apply)) 82 | 83 | ;;;###autoload 84 | (define-minor-mode exwm-outer-gaps-mode 85 | "Add useless outer gaps to exwm." 86 | :global t 87 | (if exwm-outer-gaps-mode 88 | (add-hook 'exwm-workspace--update-workareas-hook 89 | #'exwm-outer-gaps-compute-gaps) 90 | (remove-hook 'exwm-workspace--update-workareas-hook 91 | #'exwm-outer-gaps-compute-gaps)) 92 | (exwm-outer-gaps-apply)) 93 | 94 | (provide 'exwm-outer-gaps) 95 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | #+TITLE: EXWM-outer-gaps 2 | #+Author: Lucas Gruss 3 | 4 | * Introduction 5 | 6 | A lot of window managers provide a feature called "gaps". It is useless, it is 7 | pretty but most importantly *it is a feature*. And therefore Emacs must have 8 | it. Sorry, I don't make the rules. 9 | 10 | This package provides a minor mode to have outer gaps around the workspaces, 11 | and some utility functions to control them. 12 | 13 | It's my first elisp package, and I wanted to try my hand at something 14 | rather easy. If the code sucks, don't hesitate to open an issue and tell me 15 | why (in fact, please do !). 16 | 17 | [[screenshot.png]] 18 | 19 | * Installation 20 | 21 | I might go the extra mile and submit it to MELPA someday, but in the meantime 22 | I suggest using straight. I personally use Doom Emacs, which has its own 23 | package manager based on straight. I have the following in my configuration: 24 | 25 | #+begin_src emacs-lisp :tangle no 26 | ;; in packages.el 27 | (package! exwm-outer-gaps 28 | :recipe 29 | (:host github 30 | :repo "lucasgruss/exwm-outer-gaps")) 31 | 32 | ;; in config.el 33 | (use-package exwm-outer-gaps 34 | :after (exwm xelb) 35 | :config 36 | (exwm-outer-gaps-mode +1)) 37 | #+end_src 38 | 39 | I also bind =exwm-outer-gaps-mode= to a keybinding in order to easily toggle 40 | the mode and change dimensions of the gaps. 41 | 42 | #+begin_src emacs-lisp 43 | ;; in your config for exwm, you can adapt exwm-input-global-keys 44 | (setq exwm-input-global-keys 45 | `( ;; ... 46 | ([?\s-O] . exwm-outer-gaps-mode) 47 | ([?\s-p] . exwm-outer-gaps-increment) 48 | ([?\s-y] . exwm-outer-gaps-decrement) 49 | ;; ... 50 | )) 51 | #+end_src 52 | 53 | Each gap can be set/incremented individually. In my configuration, I also 54 | leverage [[https://gitlab.com/jjzmajic/hercules.el][hercules.el]] in order to create a "menu" that can be invoked to set each 55 | gap interactively. 56 | 57 | #+begin_src emacs-lisp 58 | (defvar exwm-outer-gaps-keymap nil 59 | "keymap to resize gaps") 60 | (setq exwm-outer-gaps-keymap (make-sparse-keymap)) 61 | 62 | ;; map! is a doom specific macro 63 | (map! (:map exwm-outer-gaps-keymap 64 | :desc "Decrease left" "h" (lambda () (interactive) (exwm-outer-gaps-decrement 0)) 65 | :desc "Increase left" "H" (lambda () (interactive) (exwm-outer-gaps-increment 0)) 66 | :desc "Decrease right" "l" (lambda () (interactive) (exwm-outer-gaps-decrement 1)) 67 | :desc "Increase right" "L" (lambda () (interactive) (exwm-outer-gaps-increment 1)) 68 | :desc "Decrease top" "k" (lambda () (interactive) (exwm-outer-gaps-decrement 2)) 69 | :desc "Increase top" "K" (lambda () (interactive) (exwm-outer-gaps-increment 2)) 70 | :desc "Decrease bottom" "j" (lambda () (interactive) (exwm-outer-gaps-decrement 3)) 71 | :desc "Increase bottom" "J" (lambda () (interactive) (exwm-outer-gaps-increment 3)))) 72 | 73 | (hercules-def 74 | :toggle-funs (defun lg/exwm-outer-gaps-menu () (interactive)) 75 | :keymap 'exwm-outer-gaps-keymap 76 | :transient t) 77 | #+end_src 78 | 79 | * How it works 80 | 81 | There is nothing to write home about, exwm comes with all the facility to 82 | implement this. For each exwm workspace (i.e. non-floating frame), there is a 83 | workarea that sets its geometry. Usually, each workarea takes up the whole 84 | screen/monitor but exwm provides =exwm-workspace--update-workareas-hooks= that 85 | we can use to add gaps. 86 | 87 | Since we only have control over the geometry of the frame, the gaps provided 88 | by this package are only "outer gaps", which means that "inner gaps" (gaps 89 | between emacs windows) is out of scope for this package. I do intend to write 90 | a package for inner gaps in the future by leveraging =window-divider-mode= and 91 | =xcb-shape= from =xelb=. 92 | 93 | Each side (left, right, top and bottom) has its own gap, so there is some 94 | level of granularity available. 95 | 96 | There are three user-facing functions that are =exwm-outer-gaps-increment=, 97 | =exwm-outer-gaps-decrement= and =exwm-outer-gaps-balance=, which respectively 98 | increment all four gaps at the same time, decrement all four gaps and balance all 99 | four gaps to be the same width (in case gaps where changed to not be all equal). 100 | --------------------------------------------------------------------------------