stumpwm-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Spatial organization of windows in StumpWM


From: Russell Adams
Subject: Spatial organization of windows in StumpWM
Date: Mon, 7 Mar 2022 20:11:42 +0100

I composed a short video about using spatial groups in StumpWM to
share. I've tried to explain the idea of spatial grouping before on
IRC, and I felt a demonstration would be clearer.

http://demosthenes.org/tmp/StumpWMSpatialGroups.mp4

Please pardon the rough edges. I'm not starting a Youtube channel,
just trying to have a conversation about how to manage windows and
groups in Stump.

Spatial grouping abuses Stump's ability to dynamically create groups
to create a sparse 3d array of groups, visualized as multiple desktops
of a 2d grid of screens. Hotkeys use arrows to navigate the grid and
swap desktops in a way which emulates a larger physical screen
surface.

Using this method allows me to group windows by project, adjacent to
each other. This allows absolute navigation to each window, as opposed
to relative navigation (ie: alt-tab).

I'm not grouping related application windows on the same screen, but
rather organizing patterns of groups to keep related application
windows cognitively near each other. I still may use splits and tile
windows within a screen, but not as often.

I'm hoping to inspire further discussion on the matter. Critically, I
have not tested multiple monitor support.

Concepts:
 Spatial groups use a 3d coordinate system: “x,y,z”
 Valid groups are “0,0,0”, “-1,2,0”, etc.
 Z is used as the desktop index

Keys:
 Control-Shift-{Left,Right}: Change desktop (Z axis)
 Control-Arrows: Navigate virtual screens on current desktop
 Control-Shift-Up: Return to 0,0 on current desktop (Z)
 Shift-Arrows: Navigate splits on current screen group

Relevant code:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(ql:quickload 'cl-ppcre)

(in-package :stumpwm)

;; change the prefix key to something else
(set-prefix-key (kbd "s-."))

;; fix scroll wheel?
(setf (getenv "GDK_CORE_DEVICE_EVENTS") "1")

;; early define global vars
(defparameter *z-cursors* '()
  "Association list of groups by Z coordinate for preserving last position on 
that plane.")

(defparameter *last-cursor* NIL
  "Previous group for popping back.")

;; Change focus
(set-focus-color "darkblue") ;; Set the border around the current frame
(setf *suppress-frame-indicator* t) ;; Stop the popup on the current frame

;; Modeline settings
(enable-mode-line (current-screen) (current-head) t)
(setf *mode-line-timeout* 60)
(setf *screen-mode-line-format* (list "[^B%n^b] %d |" "| %W"))

;; Shift arrows between adjacent windows
(define-key *top-map* (kbd "S-Up")    "move-focus up")
(define-key *top-map* (kbd "S-Down")  "move-focus down")
(define-key *top-map* (kbd "S-Left")  "move-focus left")
(define-key *top-map* (kbd "S-Right") "move-focus right")

;; Control arrows between groups
(defcommand coord-left      () () (coord-group-change -1  0  0))
(defcommand coord-right     () () (coord-group-change  1  0  0))
(defcommand coord-up        () () (coord-group-change  0  1  0))
(defcommand coord-down      () () (coord-group-change  0 -1  0))
(defcommand coord-taskleft  () () (coord-group-change  0  0 -1))
(defcommand coord-taskright () () (coord-group-change  0  0  1))

;; return to 0,0 on the current taskplane as a shortcut to return to the core 
task
(defcommand coord-taskorigin () ()
  (gselect
   (group-name
    (my-find-group (current-screen)
                   (format nil "~{~a~^,~}" (list 0 0 (parse-integer (third 
(cl-ppcre:split "," (group-name (current-group)))))))))))

;; pop back to last location
(defcommand coord-taskpop () () (when *last-cursor* (my-gselect *last-cursor*)))

(define-key *top-map* (kbd "C-Left")    "coord-left")
(define-key *top-map* (kbd "C-Right")   "coord-right")
(define-key *top-map* (kbd "C-Up")      "coord-up")
(define-key *top-map* (kbd "C-Down")    "coord-down")
(define-key *top-map* (kbd "C-S-Left")  "coord-taskleft")
(define-key *top-map* (kbd "C-S-Right") "coord-taskright")
(define-key *top-map* (kbd "C-S-Up")    "coord-taskorigin")
(define-key *top-map* (kbd "C-S-Down")  "coord-taskpop")

(define-key *top-map* (kbd "s-S-SPC") "fullscreen")


;; Groups will manage the coordinate system
;; format: 0,0,0 with positive and negative numbers
;; create groups on the fly as needed
;; only supports one screen atm, would like multimonitor support later

(gnew "0,0,0") ; create origin on startup

(defun my-find-group (screen name)
  (find name (screen-groups screen) :key 'group-name :test 'string=))

(defun my-gselect (name)
  "Preserve prior location for pop, and handle when group is new"
  (banish)
  (setf *last-cursor* (group-name (current-group)))
  (gselect (group-name
          (or (my-find-group (current-screen) name)
          (gnew name)))))

(defun coord-group-change (xo yo zo)
  "Navigate a 3d array of groups using x,y,z coordinates by passing the offset 
of the change."
  (let* ((current-coords
          (mapcar #'parse-integer
                  (cl-ppcre:split "," (group-name (current-group)))))
         (new-coords (mapcar #'+ current-coords (list xo yo zo)))
         (new-group-name (format nil "~{~a~^,~}" new-coords)) )

    (if (= 0 zo)

        ;; Not changing taskplanes, so just move by coordinates
        (my-gselect new-group-name)

        ;; Changing Z across taskplanes, RESTORE z-cursor for that plane
        (let ((old-z (third current-coords))
              (new-z (third new-coords)))

          (if (assoc old-z *z-cursors*)
              (setf (cdr (assoc old-z *z-cursors*)) (current-group))
              (push (cons old-z (current-group)) *z-cursors*))

          (let ((z-cursor (cdr (or (assoc new-z *z-cursors*) '(nil . nil)))))
            (if z-cursor
                ;; Restore saved location
                (my-gselect (group-name z-cursor))
                ;; create new taskplane
                (my-gselect new-group-name)))))))

(defun my-startup () (my-gselect "0,0,0"))

(when *initializing* (my-startup))




------------------------------------------------------------------
Russell Adams                            RLAdams@AdamsInfoServ.com

PGP Key ID:     0x1160DCB3           http://www.adamsinfoserv.com/

Fingerprint:    1723 D8CA 4280 1EC9 557F  66E8 1154 E018 1160 DCB3



reply via email to

[Prev in Thread] Current Thread [Next in Thread]