Skip to content

An extension to StumpWM providing floating windows with dynamic tiling.

Notifications You must be signed in to change notification settings

jcguu95/stumpwm-dynamic-float

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 

Repository files navigation

StumpWM Extension

Dynamic Tiling & Floating Windows

This extension stumpwm-dynamic-float provides StumpWM users a (gapped) dynamic tiling experience based on its floating windows.

Watch the demo videos to immediately grasp what it does.

Installation

  1. Have a working stumpwm on your machine.
  2. If you use quicklisp, download the repo into your quicklisp local directory. To check if it would work properly, with quicklisp loaded in your CL implementation, load the system by (ql:quickload :stumpwm-dynamic-float). Finally, if it works out well, add that form into your StumpWM init config.
  3. To start enjoying stumpwm-dynamic-float, see the configuration example below.

Configuration Example

Key-bindings

Commonly used commands defined in stumpwm-dynamic-float are included in this configuration example.

;; Navigation
(define-key *top-map* (kbd "s-j") "window-focus-next")
(define-key *top-map* (kbd "s-k") "window-focus-prev")
(define-key *top-map* (kbd "s-J") "permute-window")
(define-key *top-map* (kbd "s-K") "permute-window-reverse")
;; Master Ratio
(define-key *top-map* (kbd "s-+") "master-ratio-increase")
(define-key *top-map* (kbd "s--") "master-ratio-decrease")
(define-key *top-map* (kbd "s-=") "master-ratio-set-default")
;; Layout Selection
(define-key *top-map* (kbd "s-f") "layout-toggle-fullscreen")
(define-key *top-map* (kbd "s-F") "layout-change-next")
;; Gaps
(define-key *top-map* (kbd "s-[") "gap-toggle")
(define-key *top-map* (kbd "s-]") "gap-set-default")
(define-key *top-map* (kbd "s-}") "gap-increase")
(define-key *top-map* (kbd "s-{") "gap-decrease")
;; Window Status: 'tiled, 'foreground, 'background.
(define-key *top-map* (kbd "s-_") "window-status-tile-at-point")
(define-key *top-map* (kbd "s-|") "window-status-make-all-tiled")

Group Creation

I put the following code in my StumpWM config so whenever it starts it create 10 dynamic floating windows for me, named 0 to 9.

;; Groups creation
(grename "1")
(loop for n in '(2 3 4 5 6 7 8 9 0)
      do (stumpwm-dynamic-float:gnew-dyn-float-bg (format nil "~a" n)))
(gkill)
(stumpwm-dynamic-float:gnew-dyn-float "1")

To bind group-navigation and window-throwing in batch, use the following code.

(in-package :stumpwm)
;; Keybindings for selecting and navigating among groups.
;; E.g. =super-3= navigates to the third group, while =super-#=
;; throws the current window at point to the third group.
(mapcar (lambda (n)
          (define-key *top-map*
              (kbd (format nil "s-~a" n))
            (format nil "gselect ~a" n))
          (let ((shift-keys '(")" "!" "@" "#" "$"
                              "%" "^" "&" "*" "(")))
            (define-key *top-map*
                (kbd (format nil "s-~a" (nth n shift-keys)))
              (format nil "gmove ~a" n))))
        '(1 2 3 4 5 6 7 8 9 0))

Customized New Window Behavior

By default, this extension tiles every new window introduced into the group. To alter this behavior, add a customized hook into the variable *new-window-spec-hooks*. For example, the following code forces any new window with title starting from "[TOP]" to have the spec specified in the car of the cons.

(push (cons (lambda (w) (equal 0 (search "[TOP]" (window-title w))))
            (list ;; :x 300 :y 300 :height 300 :width 300
                  :status 'foreground))
      stumpwm-dynamic-float:*new-window-spec-hooks*)

Remark. Probably it is a better approach to use stumpwm’s window class and hooks to alter the behavior of certain new windows. Please let me know if you figure out how to do so.

Layout and Customization

Currently, supported layouts are '(left-vertical horizontal fullscreen). To define your own, check out their source codes and the macro #'deflayout. The simplest example is 'fullscreen:

(deflayout fullscreen
  "A layout where every tiled windows are fully expanded."
  (list :x x0 :y y0 :width sw :height sh))

The macro defines a function #'fullscreen, which will be called to calculate the desired values (:x :y :width :height) of the floating windows that are supposed to be tiled. Then something else use this calculated information to redraw the window. See 'left-vertical for a more complicated example (but not too bad).

Implementation Notes

Each dyn-float-group keeps a private list of data called dfg-data. Each dfg-datum corresponds to a floating window internal to stumpwm. Whenever a window is added, removed, or dragged, #'sync! updates the dfg-data (see group-add-window, group-delete-window, and group-button-press).

A layout is implemented as a pure function that computes the values (x, y, width, height) of the kth window among the N-many windows that are supposed to be tiled. The dynamic tiling functionality is enforced by #'apply-data!, in which #'stumpwm::float-window-move-resize redraws the windows based the current layout of the group.

TODOs

  • Use emacs to replace dmenu, rofi, and notify-send.

Comments

  • Only tested on SBCL.
  • Any feedback is welcome (especially lisp-fu related).

About

An extension to StumpWM providing floating windows with dynamic tiling.

Resources

Stars

Watchers

Forks