├── screen.png ├── package.lisp ├── .gitignore ├── swm-gaps.asd ├── README.org └── swm-gaps.lisp /screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lepisma/swm-gaps/HEAD/screen.png -------------------------------------------------------------------------------- /package.lisp: -------------------------------------------------------------------------------- 1 | ;;;; package.lisp 2 | 3 | (defpackage #:swm-gaps 4 | (:use #:cl :stumpwm)) 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.FASL 2 | *.fasl 3 | *.lisp-temp 4 | *.dfsl 5 | *.pfsl 6 | *.d64fsl 7 | *.p64fsl 8 | *.lx64fsl 9 | *.lx32fsl 10 | *.dx64fsl 11 | *.dx32fsl 12 | *.fx64fsl 13 | *.fx32fsl 14 | *.sx64fsl 15 | *.sx32fsl 16 | *.wx64fsl 17 | *.wx32fsl 18 | -------------------------------------------------------------------------------- /swm-gaps.asd: -------------------------------------------------------------------------------- 1 | ;;;; swm-calibre.asd 2 | 3 | (asdf:defsystem #:swm-gaps 4 | :description "Pretty (useless) gaps for StumpWM" 5 | :author "vlnx , Abhinav Tushar " 6 | :depends-on (#:stumpwm) 7 | :serial t 8 | :components ((:file "package") 9 | (:file "swm-gaps"))) 10 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | #+TITLE: swm-gaps 2 | 3 | *NOTICE*: This module now lives in the StumpWM's [[https://github.com/stumpwm/stumpwm-contrib][contrib repository]]. Issues should 4 | be filed in that repository instead of here. 5 | 6 | Pretty (useless) gaps for [[https://stumpwm.github.io/][StumpWM]]. 7 | 8 | [[./screen.png]] 9 | 10 | This is a packed version of *useless-gaps* by [[https://gist.github.com/vlnx/5651256][vlnx]] with added outer borders. 11 | Credit goes to the original author. 12 | 13 | #+BEGIN_QUOTE 14 | This modifies StumpWM's internal functions ~maximize-window~ and ~neighbour~, so 15 | might not work as expected if those definitions change in the core. Currently 16 | works with ~v1.0.0~. 17 | #+END_QUOTE 18 | 19 | #+BEGIN_SRC common-lisp 20 | (load-module "swm-gaps") 21 | 22 | ;; Inner gaps run along all the 4 borders of a frame 23 | (setf swm-gaps:*inner-gaps-size* 10) 24 | 25 | ;; Outer gaps add more padding to the outermost borders 26 | ;; (touching the screen border) 27 | (setf swm-gaps:*outer-gaps-size* 20) 28 | 29 | ;; Call command 30 | ;; toggle-gaps 31 | #+END_SRC 32 | -------------------------------------------------------------------------------- /swm-gaps.lisp: -------------------------------------------------------------------------------- 1 | ;;;; swm-gaps.lisp 2 | 3 | (in-package #:swm-gaps) 4 | 5 | (export '(*inner-gaps-size* *outer-gaps-size* toggle-gaps)) 6 | 7 | (defvar *inner-gaps-size* 5) 8 | (defvar *outer-gaps-size* 10) 9 | (defvar *gaps-on* nil) 10 | 11 | ;; Redefined - with `if`s for *inner-gaps-on* 12 | (defun stumpwm::maximize-window (win) 13 | "Maximize the window." 14 | (multiple-value-bind (x y wx wy width height border stick) 15 | (stumpwm::geometry-hints win) 16 | 17 | (if (and *gaps-on* (not (stumpwm::window-transient-p win))) 18 | (setf width (- width (* 2 *inner-gaps-size*)) 19 | height (- height (* 2 *inner-gaps-size*)) 20 | x (+ x *inner-gaps-size*) 21 | y (+ y *inner-gaps-size*))) 22 | 23 | (dformat 4 "maximize window ~a x: ~d y: ~d width: ~d height: ~d border: ~d stick: ~s~%" win x y width height border stick) 24 | ;; This is the only place a window's geometry should change 25 | (set-window-geometry win :x wx :y wy :width width :height height :border-width 0) 26 | (xlib:with-state ((window-parent win)) 27 | ;; FIXME: updating the border doesn't need to be run everytime 28 | ;; the window is maximized, but only when the border style or 29 | ;; window type changes. The overhead is probably minimal, 30 | ;; though. 31 | (setf (xlib:drawable-x (window-parent win)) x 32 | (xlib:drawable-y (window-parent win)) y 33 | (xlib:drawable-border-width (window-parent win)) border) 34 | ;; the parent window should stick to the size of the window 35 | ;; unless it isn't being maximized to fill the frame. 36 | (if (or stick 37 | (find *window-border-style* '(:tight :none))) 38 | (setf (xlib:drawable-width (window-parent win)) (window-width win) 39 | (xlib:drawable-height (window-parent win)) (window-height win)) 40 | (let ((frame (stumpwm::window-frame win))) 41 | (setf (xlib:drawable-width (window-parent win)) (- (frame-width frame) 42 | (* 2 (xlib:drawable-border-width (window-parent win))) 43 | (if (and *gaps-on* (not (stumpwm::window-transient-p win))) (* 2 *inner-gaps-size*) 0)) 44 | (xlib:drawable-height (window-parent win)) (- (stumpwm::frame-display-height (window-group win) frame) 45 | (* 2 (xlib:drawable-border-width (window-parent win))) 46 | (if (and *gaps-on* (not (stumpwm::window-transient-p win))) (* 2 *inner-gaps-size*) 0))))) 47 | ;; update the "extents" 48 | (xlib:change-property (window-xwin win) :_NET_FRAME_EXTENTS 49 | (list wx wy 50 | (- (xlib:drawable-width (window-parent win)) width wx) 51 | (- (xlib:drawable-height (window-parent win)) height wy)) 52 | :cardinal 32)))) 53 | 54 | (defun reset-all-windows () 55 | "Reset the size for all tiled windows" 56 | (let ((windows (mapcan (lambda (g) 57 | (mapcar (lambda (w) w) (stumpwm::sort-windows g))) 58 | (stumpwm::sort-groups (current-screen))))) 59 | (mapcar (lambda (w) 60 | (if (string= (class-name (class-of w)) "TILE-WINDOW") 61 | (stumpwm::maximize-window w))) windows))) 62 | 63 | ;; Redefined neighbour for working with outer gaps 64 | (defun stumpwm::neighbour (direction frame frameset) 65 | "Returns the best neighbour of FRAME in FRAMESET on the DIRECTION edge. 66 | Valid directions are :UP, :DOWN, :LEFT, :RIGHT. 67 | eg: (NEIGHBOUR :UP F FS) finds the frame in FS that is the 'best' 68 | neighbour above F." 69 | (let ((src-edge (ecase direction 70 | (:up :top) 71 | (:down :bottom) 72 | (:left :left) 73 | (:right :right))) 74 | (opposite (ecase direction 75 | (:up :bottom) 76 | (:down :top) 77 | (:left :right) 78 | (:right :left))) 79 | (best-frame nil) 80 | (best-overlap 0) 81 | (nearest-edge-diff nil)) 82 | (multiple-value-bind (src-s src-e src-offset) 83 | (stumpwm::get-edge frame src-edge) 84 | 85 | ;; Get the edge distance closest in the required direction 86 | (dolist (f frameset) 87 | (multiple-value-bind (s e offset) 88 | (stumpwm::get-edge f opposite) 89 | (let ((offset-diff (abs (- src-offset offset)))) 90 | (if nearest-edge-diff 91 | (if (< offset-diff nearest-edge-diff) 92 | (setf nearest-edge-diff offset-diff)) 93 | (setf nearest-edge-diff offset-diff))))) 94 | 95 | (dolist (f frameset) 96 | (multiple-value-bind (s e offset) 97 | (stumpwm::get-edge f opposite) 98 | (let ((overlap (- (min src-e e) 99 | (max src-s s)))) 100 | ;; Two edges are neighbours if they have the same offset and their starts and ends 101 | ;; overlap. We want to find the neighbour that overlaps the most. 102 | (when (and (= (abs (- src-offset offset)) nearest-edge-diff) 103 | (> overlap best-overlap)) 104 | (setf best-frame f) 105 | (setf best-overlap overlap)))))) 106 | best-frame)) 107 | 108 | (defun add-outer-gaps () 109 | "Add extra gap to the outermost borders" 110 | (mapcar (lambda (head) 111 | (let* ((height (stumpwm::head-height head)) 112 | (width (stumpwm::head-width head)) 113 | (x (stumpwm::head-x head)) 114 | (y (stumpwm::head-y head)) 115 | (gap *outer-gaps-size*) 116 | (new-height (- height (* 2 gap))) 117 | (new-width (- width (* 2 gap)))) 118 | (stumpwm::resize-head 119 | (stumpwm::head-number head) 120 | (+ x gap) (+ y gap) 121 | new-width new-height))) 122 | (screen-heads (current-screen)))) 123 | 124 | (defcommand toggle-gaps () () 125 | "Toggle gaps" 126 | (setf *gaps-on* (null *gaps-on*)) 127 | (if *gaps-on* 128 | (progn 129 | (add-outer-gaps) 130 | (reset-all-windows)) 131 | (stumpwm::refresh-heads))) 132 | --------------------------------------------------------------------------------